VisualAge for Smalltalk Handbook Volume 1:
Fundamentals

International Technical Organization

<figure><img src="image_1.png" /></figure>

To cite this version:

International Technical Organization. VisualAge for Smalltalk Handbook Volume 1: Fundamentals. 1997. hal-05342501

HAL Id: hal-05342501

https://inria.hal.science/hal-05342501v1

Submitted on 2 Nov 2025

HAL is a multi-disciplinary open access
archive for the deposit and dissemination of sci-
entific research documents, whether they are pub-
lished or not. The documents may come from
teaching and research institutions in France or
abroad, or from public or private research centers.

L'archive ouverte pluridisciplinaire HAL, est
destinée au dépôt et à la diffusion de documents
scientifiques de niveau recherche, publiés ou non,
émanant des établissements d'enseignement et de
recherche français ou étrangers, des laboratoires
publics ou privés.

<figure><img src="image_2.png" /></figure>
# VisualAge for Smalltalk Handbook
## Volume 1: Fundamentals

September 1997

<figure><img src="image_3.png" /></figure>

IBM
International Technical Support Organization
San Jose Center
<figure><img src="image_4.png" /></figure>
International Technical Support Organization

VisualAge for Smalltalk Handbook
Volume 1: Fundamentals

September 1997
**Take Note!**

Before using this information and the product it supports, be sure to read the general information
in Appendix A, "Special Notices."

First Edition (September 1997)

This edition applies to VisualAge for Smalltalk, Versions 2, 3, and 4, for use with OS/2, AIX, and Microsoft Windows 95/NT.

Comments may be addressed to:
IBM Corporation, International Technical Support Organization
Dept. QXXE Building 80-E2
650 Harry Road
San Jose, California 95120-6099

When you send information to IBM, you grant IBM a non-exclusive right to use or distribute the
information in any way it believes appropriate without incurring any obligation to you.

© Copyright International Business Machines Corporation 1997. All rights reserved.

Note to U.S. Government Users — Documentation related to restricted rights — Use, duplication or
disclosure is subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corp.
## Contents

<table><tr><td>Preface</td><td>xv</td></tr><tr><td>How This Redbook Is Organized</td><td>xvi</td></tr><tr><td>ITSO on the Internet</td><td>xvii</td></tr><tr><td>VisualAge Support on CompuServe</td><td>xix</td></tr><tr><td>About the Authors</td><td>xix</td></tr><tr><td>Acknowledgments</td><td>xx</td></tr><tr><td>Comments Welcome</td><td>xxi</td></tr></table>

<table><tr><td>Chapter 1. What Is VisualAge for Smalltalk?</td><td>1</td></tr><tr><td>Description of VisualAge for Smalltalk</td><td>1</td></tr><tr><td>VisualAge for Smalltalk Technology</td><td>1</td></tr><tr><td>Description of Smalltalk</td><td>2</td></tr><tr><td>Description of ENVY</td><td>2</td></tr><tr><td>Stability and Maturity</td><td>2</td></tr><tr><td>Openness</td><td>3</td></tr><tr><td>Team or Professional Version</td><td>3</td></tr><tr><td>Advantages of VisualAge</td><td>3</td></tr><tr><td>Advantages of Smalltalk</td><td>4</td></tr><tr><td>VisualAge for Smalltalk and VisualAge Generator</td><td>5</td></tr><tr><td>VisualAge for Smalltalk and C++</td><td>5</td></tr><tr><td>Visualizer</td><td>6</td></tr><tr><td>Team Connection</td><td>6</td></tr><tr><td>Supported Platforms</td><td>6</td></tr><tr><td>Smalltalk Strategy</td><td>7</td></tr><tr><td>Smalltalk and Java</td><td>7</td></tr><tr><td>Configuration Management</td><td>7</td></tr><tr><td>Packaging Support</td><td>8</td></tr><tr><td>Database Support</td><td>8</td></tr><tr><td>Communication Protocol Support</td><td>8</td></tr><tr><td>Legacy Code</td><td>9</td></tr><tr><td>Runtime Distribution Fees</td><td>9</td></tr><tr><td>Distributing Smalltalk Compiler</td><td>9</td></tr><tr><td>Source Code Availability</td><td>9</td></tr><tr><td>Upward Compatibility</td><td>10</td></tr><tr><td>Common User Access Compliance</td><td>10</td></tr><tr><td>Multiple Inheritance</td><td>10</td></tr><tr><td>Porting Smalltalk Applications</td><td>10</td></tr><tr><td>Sources of Support</td><td>11</td></tr><tr><td>TalkLink</td><td>11</td></tr><tr><td>CompuServe</td><td>12</td></tr><tr><td>Usenet</td><td>12</td></tr></table>
<table><tr><td>Resource Catalog</td><td>12</td></tr><tr><td>Learning Courses</td><td>13</td></tr><tr><td>New Features in Version 3</td><td>13</td></tr><tr><td>New Features in Version 4</td><td>14</td></tr></table>

<table><tr><td>Chapter 2. General Information</td><td>23</td></tr><tr><td>Cleaning Up the Image</td><td>23</td></tr><tr><td>Creating a New Image</td><td>23</td></tr><tr><td>Reducing Image Size</td><td>24</td></tr><tr><td>Preventing Image Growth</td><td>25</td></tr><tr><td>AbtScrubImage</td><td>25</td></tr><tr><td>Ghosts</td><td>26</td></tr><tr><td>Image Growth after Packaging</td><td>26</td></tr><tr><td>Keeping Multiple Versions on the Same System</td><td>26</td></tr><tr><td>Replacing the Default Icon</td><td>27</td></tr><tr><td>Escaping an Infinite Loop</td><td>27</td></tr><tr><td>File-In and File-Out</td><td>28</td></tr><tr><td>Separate Threads</td><td>28</td></tr><tr><td>Capturing Stack Information</td><td>28</td></tr><tr><td>Renaming a Class</td><td>29</td></tr><tr><td>Environment Variable</td><td>29</td></tr><tr><td>Registered Connection</td><td>30</td></tr><tr><td>Loading Different Image</td><td>30</td></tr><tr><td>Deferred Update Part</td><td>30</td></tr><tr><td>Renaming a Visual Part</td><td>31</td></tr><tr><td>Hover Help for Buttons</td><td>32</td></tr><tr><td>Customizing Connection Menu</td><td>33</td></tr><tr><td>Live Updating of Images</td><td>33</td></tr><tr><td>Passing Parameters Between Windows</td><td>34</td></tr><tr><td>Generating Archival Code</td><td>34</td></tr><tr><td>Deleting Parts with Instances</td><td>35</td></tr><tr><td>Change Table Format</td><td>36</td></tr><tr><td>Error Messages</td><td>36</td></tr><tr><td>Removing Archival Code</td><td>37</td></tr><tr><td>Apply Push Button</td><td>38</td></tr><tr><td>Inspector</td><td>38</td></tr><tr><td>Multimedia</td><td>38</td></tr><tr><td>Default Memory</td><td>39</td></tr><tr><td>Storing Settings</td><td>39</td></tr><tr><td>Extending Classes</td><td>40</td></tr><tr><td>Running VisualAge from External SCSI Drive</td><td>40</td></tr><tr><td>Damaged Classes</td><td>40</td></tr><tr><td>Extending Classes</td><td>41</td></tr><tr><td>Modifying the System Menu</td><td>41</td></tr></table>
<table><tr><td>Organizer Views</td><td>42</td></tr><tr><td>File in Use</td><td>43</td></tr><tr><td>OS/2 Shutdown</td><td>43</td></tr><tr><td>BRW Format Generator</td><td>43</td></tr><tr><td>Loaded Method</td><td>44</td></tr><tr><td>Missing Character Set</td><td>44</td></tr><tr><td>Event Triggering</td><td>44</td></tr><tr><td>Part not Visible</td><td>45</td></tr><tr><td>Removed Class</td><td>45</td></tr><tr><td>Synchronizing Attributes</td><td>45</td></tr><tr><td>Keeping the Packaged Image Small</td><td>46</td></tr><tr><td>Including Classes in a Package</td><td>46</td></tr><tr><td>Packaging for AIX from OS/2</td><td>47</td></tr><tr><td>Loading Application in a Run-time Image</td><td>47</td></tr><tr><td>Packaging an Application for Windows</td><td>48</td></tr><tr><td>Icons and DLLs</td><td>48</td></tr><tr><td>Packaging a Workspace</td><td>48</td></tr><tr><td>Image Reduction</td><td>48</td></tr><tr><td>Ensuring that Needed Classes are Packaged</td><td>49</td></tr><tr><td>Class Modifications and Packaging</td><td>49</td></tr><tr><td>Merging Application Files into Run-time Image</td><td>49</td></tr><tr><td>Missing Icons</td><td>50</td></tr><tr><td>Required .CAT Files</td><td>50</td></tr><tr><td>Packaging Pool Dictionaries</td><td>51</td></tr><tr><td>Application Prerequisites</td><td>52</td></tr><tr><td>Missing Classes in the Run-time Image</td><td>52</td></tr><tr><td>Missing Method in Package</td><td>53</td></tr><tr><td>Run-time Image Packaging Problem</td><td>54</td></tr><tr><td>Generating Getters and Setters</td><td>54</td></tr><tr><td>High Performance Trace Logging</td><td>54</td></tr><tr><td>Closing a DLL from Smalltalk</td><td>55</td></tr><tr><td>Unloading When Instances Exist</td><td>56</td></tr><tr><td>Testing When Looping Walkbacks Occur</td><td>56</td></tr><tr><td>Quickly Disabling Methods</td><td>56</td></tr><tr><td>Specifying Public or Private with TrailBlazer</td><td>57</td></tr><tr><td>Browse and Find in the Pop-Up Menu</td><td>57</td></tr><tr><td>Versioning Applications Not Owned</td><td>61</td></tr><tr><td>Client Not Supported</td><td>61</td></tr><tr><td>AbtRecord</td><td>62</td></tr><tr><td>Indexed Message Editor</td><td>62</td></tr><tr><td>Corrupted MRI File</td><td>63</td></tr><tr><td>Class Naming Convention</td><td>63</td></tr><tr><td>Category Naming</td><td>66</td></tr><tr><td>Archival Code is Missing</td><td>68</td></tr></table>
<table><tr><td>Meaning of Application Errors</td><td>68</td></tr><tr><td>Error: 'Undefined Object does not understand messageString'</td><td>69</td></tr><tr><td>Error on Saving a Part</td><td>69</td></tr><tr><td>Inappropriate VisualAge Icon</td><td>70</td></tr><tr><td>Double Execution of Script</td><td>70</td></tr><tr><td>Error 203</td><td>71</td></tr><tr><td>Removing Elements from a View</td><td>71</td></tr><tr><td>Class EmLibraryStatistics</td><td>71</td></tr><tr><td>Error: rc=12</td><td>72</td></tr><tr><td>Error: SYS317x</td><td>72</td></tr><tr><td>Error: Primitive Error Codes 52 through 55</td><td>73</td></tr><tr><td>Error: Does Not Understand Format</td><td>73</td></tr><tr><td>Menu on Windows NT 4.0</td><td>74</td></tr><tr><td>Back-tabbing in Container Details Views</td><td>74</td></tr><tr><td>Properties Views and Notebook Settings Views</td><td>75</td></tr><tr><td>Code Page Conversion Errors</td><td>75</td></tr><tr><td>Determining Required ICs</td><td>75</td></tr><tr><td>Required CAT and MPR Files for an IC Run-time Image</td><td>76</td></tr><tr><td>Required CAT and MPR Files for a Reduced Run-time Image</td><td>78</td></tr><tr><td>Format Change for CTLs</td><td>80</td></tr><tr><td>Unloading the Visualization Feature</td><td>82</td></tr><tr><td>Manager Access</td><td>82</td></tr><tr><td>Opening Multimedia Devices</td><td>84</td></tr><tr><td>Using Digital Video Player on OS/2</td><td>84</td></tr><tr><td>Video Disk Player</td><td>84</td></tr><tr><td>Crystal Wave and MWave Audio Cards</td><td>85</td></tr><tr><td>AVA Playback Windows</td><td>85</td></tr><tr><td>Lotus Notes</td><td>85</td></tr><tr><td><strong>Chapter 3. Graphical User Interface</strong></td><td><strong>87</strong></td></tr><tr><td>GUI Architecture</td><td>87</td></tr><tr><td>Mapping Widgets Across Systems</td><td>87</td></tr><tr><td>Motif Documentation</td><td>88</td></tr><tr><td>Interface to Windows 95</td><td>88</td></tr><tr><td>Applications with Multiple Windows</td><td>89</td></tr><tr><td>Exit Dialog Message Box</td><td>89</td></tr><tr><td>Window Location</td><td>90</td></tr><tr><td>Positioning Window at Cursor</td><td>90</td></tr><tr><td>Maximizing a Window</td><td>91</td></tr><tr><td>Opening Window Maximized</td><td>92</td></tr><tr><td>Display Resolution</td><td>92</td></tr><tr><td>Opening Window Centered</td><td>93</td></tr><tr><td>Window Space Planning</td><td>93</td></tr><tr><td>Iterating over Widgets</td><td>94</td></tr></table>
<table><tr><td>Modal Dialog</td><td>94</td></tr><tr><td>Capturing the Minimize Request</td><td>94</td></tr><tr><td>Window Synchronization</td><td>95</td></tr><tr><td>Closing a Window</td><td>95</td></tr><tr><td>Resolution-Independent Screen</td><td>95</td></tr><tr><td>Setting Minimum Window Size</td><td>96</td></tr><tr><td>Closing a Widget from a Script</td><td>96</td></tr><tr><td>Removing the Close Menu Option</td><td>97</td></tr><tr><td>Widget Warning: Circular Reference</td><td>97</td></tr><tr><td>Always-on-Top Window</td><td>98</td></tr><tr><td>Changing the Mouse Pointer</td><td>98</td></tr><tr><td>Busy Cursor</td><td>100</td></tr><tr><td>Caret Shape Cursor</td><td>102</td></tr><tr><td>Mouse Pointer Location</td><td>102</td></tr><tr><td>Icon as Cursor</td><td>103</td></tr><tr><td>Animated Busy Cursor</td><td>105</td></tr><tr><td>Adding Pull-Down Menu Choices Dynamically</td><td>105</td></tr><tr><td>Toggle Buttons in Menu</td><td>105</td></tr><tr><td>Disabling Push Buttons on Pop-Up Menus</td><td>106</td></tr><tr><td>Pop-up Menus for Icon Gadgets</td><td>107</td></tr><tr><td>Sharing a Menu Between Containers</td><td>108</td></tr><tr><td>Dragging Versus Pop-Up</td><td>108</td></tr><tr><td>Icons on a Menu Bar</td><td>108</td></tr><tr><td>Creating a Tool Bar</td><td>109</td></tr><tr><td>Synchronizing a Combo Box</td><td>109</td></tr><tr><td>Adding Items to Combo Box</td><td>110</td></tr><tr><td>Drag-and-Drop Support on List Boxes</td><td>110</td></tr><tr><td>List Box Behavior</td><td>112</td></tr><tr><td>Identifying Last Selected Item</td><td>112</td></tr><tr><td>Default Action Requested</td><td>113</td></tr><tr><td>Combo Box Behaviour</td><td>114</td></tr><tr><td>Skipping through a Notebook</td><td>114</td></tr><tr><td>Bitmap on Notebook Tab</td><td>115</td></tr><tr><td>Hiding and Showing Pages</td><td>116</td></tr><tr><td>Porting Notebooks across Platforms</td><td>117</td></tr><tr><td>Navigating between Columns</td><td>117</td></tr><tr><td>Selecting Valid Items</td><td>117</td></tr><tr><td>Validating Input Fields</td><td>118</td></tr><tr><td>Container Column List Box</td><td>119</td></tr><tr><td>Columns with GUI Elements</td><td>119</td></tr><tr><td>Adding Records to Container</td><td>120</td></tr><tr><td>Changing Labels</td><td>120</td></tr><tr><td>Deselecting Details Tree Items</td><td>121</td></tr><tr><td>Resizing Container Columns</td><td>123</td></tr></table>
<table><tr><td>Changing Scroll Bar Size</td><td>124</td></tr><tr><td>Container Details Tree Children</td><td>124</td></tr><tr><td>Hiding the Heading on a Container Details View</td><td>124</td></tr><tr><td>Disabling a Notebook Tab</td><td>125</td></tr><tr><td>List with Icon Column</td><td>125</td></tr><tr><td>Hiding a Column</td><td>125</td></tr><tr><td>Removing an Icon</td><td>125</td></tr><tr><td>Adding Icons Dynamically</td><td>126</td></tr><tr><td>Refreshing a Container Details View</td><td>127</td></tr><tr><td>Access to Container Object Attribute</td><td>128</td></tr><tr><td>Removing an Icon</td><td>128</td></tr><tr><td>Error: "Attribute Does Not Exist"</td><td>129</td></tr><tr><td>Adding an Icon to A List Part</td><td>129</td></tr><tr><td>Drag-and-Drop</td><td>129</td></tr><tr><td>Multiline Text</td><td>130</td></tr><tr><td>Window Titles</td><td>131</td></tr><tr><td>Querying the Caret Position in Text</td><td>131</td></tr><tr><td>Color Bitmap Resolution</td><td>131</td></tr><tr><td>Automatic Tab Moving</td><td>132</td></tr><tr><td>User Input Error</td><td>133</td></tr><tr><td>Closing the Window</td><td>134</td></tr><tr><td>Transparent Background</td><td>135</td></tr><tr><td>Getting the Anchor Block Handle</td><td>135</td></tr><tr><td>Turning Off Error Message</td><td>135</td></tr><tr><td>Locating the Focus</td><td>136</td></tr><tr><td>Bitmaps on Buttons</td><td>136</td></tr><tr><td>Progress Indicator Window</td><td>137</td></tr><tr><td>Hot Spots</td><td>138</td></tr><tr><td>Links</td><td>138</td></tr><tr><td>Wallpaper</td><td>138</td></tr><tr><td>Labels on Message Prompter</td><td>139</td></tr><tr><td>Visual Part Reuse</td><td>140</td></tr><tr><td>Supported Image Formats</td><td>140</td></tr><tr><td>Click-Sensitive Bitmap</td><td>140</td></tr><tr><td>Setting Help</td><td>141</td></tr><tr><td>Modifying Data Entry Parts</td><td>141</td></tr><tr><td>Reacting to Keyboard Input</td><td>141</td></tr><tr><td>Using Esc to Close Nonmodal Dialog</td><td>142</td></tr><tr><td>Multiline Edit Part and Tab Order</td><td>143</td></tr><tr><td>Using Predefined Function Keys</td><td>143</td></tr><tr><td>Grabbing Typed Words</td><td>144</td></tr><tr><td>Dropping an Item on a Push Button</td><td>144</td></tr><tr><td>Changing a Part's Settings View</td><td>145</td></tr><tr><td>Hiding Table Columns Dynamically</td><td>145</td></tr></table>
<table><tr><td>Initializing a View Wrapper</td><td>146</td></tr><tr><td>Adding Columns to Tables</td><td>146</td></tr><tr><td>Synchronize Table Scrolling</td><td>148</td></tr><tr><td>Changing Table Size</td><td>149</td></tr><tr><td>Table List Part</td><td>149</td></tr><tr><td>Reusable Table Part</td><td>149</td></tr><tr><td>Changing a Table Cell</td><td>149</td></tr><tr><td>Selecting Multiple Rows</td><td>150</td></tr><tr><td>Changing Push Button Activation</td><td>150</td></tr><tr><td>Event Handling in Windows, AIX, and OS/2</td><td>151</td></tr><tr><td>Part Validation</td><td>152</td></tr><tr><td>Moving Icons</td><td>152</td></tr><tr><td>Printing a Form with a Visual Part</td><td>152</td></tr><tr><td>Text Box Problem</td><td>153</td></tr><tr><td>Reusable Table Part</td><td>153</td></tr><tr><td>Trap the Enter Key for Tabbing</td><td>153</td></tr><tr><td>Creating an Operation-in-Progress Window</td><td>155</td></tr><tr><td>Progress Messages</td><td>156</td></tr><tr><td>Limiting the Number of Lines in Multiple-Line Editor</td><td>156</td></tr><tr><td>Disabling a Button</td><td>156</td></tr><tr><td>Accelerator Keys</td><td>157</td></tr><tr><td>Hover-Help on Widgets</td><td>157</td></tr><tr><td>Improving Performance</td><td>158</td></tr><tr><td>Tabbing Order</td><td>158</td></tr><tr><td>Ctrl-Click Events</td><td>159</td></tr><tr><td>Creating Push Buttons</td><td>160</td></tr><tr><td>Changing Part Labels</td><td>160</td></tr><tr><td>Adding BMP Files to Buttons</td><td>161</td></tr><tr><td>Creating a Prompter</td><td>161</td></tr><tr><td>Setting Focus to Next Entry Field</td><td>162</td></tr><tr><td>Missing Carriage Return in Multiple-Line Editor</td><td>162</td></tr><tr><td>Action on PFkey Pressed</td><td>163</td></tr><tr><td><strong>Chapter 4. IBM Smalltalk Programming Language</strong></td><td><strong>165</strong></td></tr><tr><td>Smalltalk Books</td><td>165</td></tr><tr><td>Smalltalk Standardization</td><td>166</td></tr><tr><td><code>##()</code> Construct</td><td>167</td></tr><tr><td>Taking Actions Automatically at Class Recompilation</td><td>168</td></tr><tr><td>Weak Pointers</td><td>170</td></tr><tr><td>Utility of Weak Pointers</td><td>170</td></tr><tr><td>Object Finalization</td><td>171</td></tr><tr><td>Standard Methods not in API Category</td><td>172</td></tr><tr><td>Using the Correct Variable Type</td><td>172</td></tr><tr><td>Smalltalk <code>printf()</code>-like Formatter</td><td>173</td></tr></table>
<table><tr><td>Testing Instances and Classes</td><td>173</td></tr><tr><td>Garbage Collection Rate</td><td>174</td></tr><tr><td>Inherited Messages</td><td>175</td></tr><tr><td>File System</td><td>176</td></tr><tr><td>File Existence</td><td>177</td></tr><tr><td>Accessing COM Ports</td><td>178</td></tr><tr><td>Catching Errors</td><td>179</td></tr><tr><td>File System Errors</td><td>180</td></tr><tr><td>Catching All Errors</td><td>181</td></tr><tr><td>Exception-Handling Code</td><td>182</td></tr><tr><td>Fixed Decimal Class</td><td>182</td></tr><tr><td>Object Class Identification</td><td>182</td></tr><tr><td>Floating Point Numbers</td><td>182</td></tr><tr><td>Reversing Collections</td><td>186</td></tr><tr><td>Substrings</td><td>186</td></tr><tr><td>Implementation of #become:</td><td>187</td></tr><tr><td>#to: Method</td><td>189</td></tr><tr><td>Interval&gt;&gt;reverse Method</td><td>190</td></tr><tr><td>Updating Widgets</td><td>191</td></tr><tr><td>Incremental Compiler</td><td>191</td></tr><tr><td>Caching Compiler</td><td>192</td></tr><tr><td>Creation of Blocks at Run-time</td><td>192</td></tr><tr><td>Pool Dictionaries</td><td>193</td></tr><tr><td>Text Color Changes</td><td>193</td></tr><tr><td>Sorting SortedCollections</td><td>194</td></tr><tr><td>Compiler Severity Level</td><td>195</td></tr><tr><td>Finding the Sender Signature</td><td>195</td></tr><tr><td>Sender Context</td><td>196</td></tr><tr><td>Pool Dictionary Tips</td><td>197</td></tr><tr><td>Text Display on Update</td><td>197</td></tr><tr><td>Pool Dictionary</td><td>198</td></tr><tr><td>Swapper Error</td><td>198</td></tr><tr><td>Hover-Help Behavior</td><td>198</td></tr><tr><td>Aborting a Process Stack</td><td>199</td></tr><tr><td>Exiting an Image</td><td>199</td></tr><tr><td>Configured Subsystems</td><td>199</td></tr><tr><td>Image Copyright</td><td>200</td></tr><tr><td>Command Line Arguments</td><td>200</td></tr><tr><td>Run-Time Image</td><td>200</td></tr><tr><td>EsWeakSet and Finalization</td><td>201</td></tr><tr><td>Continue Background Process</td><td>201</td></tr><tr><td>Automatic Log-Off</td><td>202</td></tr><tr><td>Synchronizing a Visual Part</td><td>202</td></tr><tr><td>Execution Start</td><td>203</td></tr></table>

<figure><img src="image_5.png" /></figure>
<table><tr><td>Inheritance of Visual Parts</td><td>204</td></tr><tr><td>Multithreading</td><td>204</td></tr><tr><td>Global Variable</td><td>205</td></tr><tr><td>Updating Class Attributes in a Run-time Image</td><td>205</td></tr><tr><td>Class Methods at Run-Time</td><td>206</td></tr><tr><td>Objects's Knowledge of Reference</td><td>206</td></tr><tr><td>Smalltalk Class or AbtAppBldrPart</td><td>208</td></tr><tr><td>Cleaning Up Unused File Handles</td><td>208</td></tr><tr><td>Initializing Class Variables</td><td>209</td></tr><tr><td>Forking and Cycles</td><td>209</td></tr><tr><td>Converting Numbers Using printString</td><td>210</td></tr><tr><td>Garbage Collection of Instances</td><td>211</td></tr><tr><td>4-Digit Years</td><td>212</td></tr><tr><td>Fixing Date Years</td><td>212</td></tr><tr><td>ABTPATH</td><td>213</td></tr><tr><td>Double-Triggering of Changed Events</td><td>213</td></tr><tr><td>Inheriting Visuals Associated with a View Class</td><td>215</td></tr><tr><td>Garbage Collector Problems</td><td>216</td></tr><tr><td>Integer Representation</td><td>216</td></tr><tr><td>Method Tracing</td><td>216</td></tr><tr><td>Storing Object of Unlimited Size</td><td>217</td></tr><tr><td>Collections and #do:</td><td>218</td></tr><tr><td>Fixed Object Space</td><td>219</td></tr><tr><td>Parsing Strings with Date/Time</td><td>219</td></tr><tr><td>Identity Test on String</td><td>221</td></tr><tr><td>Replacing Character in String</td><td>222</td></tr><tr><td>Padding Strings</td><td>223</td></tr><tr><td>Trimming a String</td><td>223</td></tr><tr><td>Inhibiting List Selection</td><td>223</td></tr><tr><td>Resizable Table Rows</td><td>224</td></tr><tr><td>Adding WMUser Messages</td><td>224</td></tr><tr><td>New Operating System Event</td><td>225</td></tr><tr><td>Class Instance Variables</td><td>225</td></tr><tr><td>Class Naming</td><td>226</td></tr><tr><td>Reusing the Settings View</td><td>227</td></tr><tr><td>Exception: #doesNotUnderstand</td><td>228</td></tr><tr><td>Creating Classes from Smalltalk Script</td><td>229</td></tr><tr><td>Keyboard Event Handler</td><td>230</td></tr><tr><td>Changing Object Class</td><td>231</td></tr><tr><td>Cleaning Up the Image</td><td>232</td></tr><tr><td>Finding Methods Containing a String</td><td>232</td></tr><tr><td>Free Disk Space</td><td>233</td></tr><tr><td>Using LookupTable Instead of Dictionary</td><td>234</td></tr><tr><td>Concatenation and Streams</td><td>237</td></tr></table>
<table><tr><td>Comparing Floating-Point Values</td><td>239</td></tr><tr><td>Immutable Objects and Identity Objects</td><td>240</td></tr></table>

<table><tr><td><strong>Chapter 5. ENVY</strong></td><td>243</td></tr><tr><td>Working with the Team Environment</td><td>243</td></tr><tr><td>Shared Library Password Protection</td><td>244</td></tr><tr><td>Libraries</td><td>244</td></tr><tr><td>Import and Export</td><td>245</td></tr><tr><td>Loading Applications</td><td>245</td></tr><tr><td>Moving Components Between Libraries</td><td>246</td></tr><tr><td>Archival Code</td><td>246</td></tr><tr><td>Identifying the Released Version</td><td>246</td></tr><tr><td>Change Management for Flat Files</td><td>247</td></tr><tr><td>Date Stamp for Versioned Classes</td><td>247</td></tr><tr><td>Applications and Subapplications</td><td>248</td></tr><tr><td>Connecting to a Cloned Library</td><td>248</td></tr><tr><td>Reloading an Application</td><td>249</td></tr><tr><td>Loading Previous Editions of Application</td><td>249</td></tr><tr><td>Deleting an Application</td><td>249</td></tr><tr><td>Creating a New Application</td><td>250</td></tr><tr><td>Removing an Application</td><td>250</td></tr><tr><td>Deleting Old Versions of Classes</td><td>250</td></tr><tr><td>Getting Rid of Damaged Classes</td><td>251</td></tr><tr><td>Prompting for Ownership</td><td>251</td></tr><tr><td>Moving Development Code</td><td>251</td></tr><tr><td>Distributing an Application for OS/2 and AIX</td><td>252</td></tr><tr><td>Exporting an Application to a Non-LAN PC</td><td>252</td></tr><tr><td>Associating .DAT files with Features</td><td>253</td></tr><tr><td>Manager Consistency</td><td>253</td></tr><tr><td>Exporting a Pool Dictionary</td><td>254</td></tr><tr><td>Exporting Configuration Maps</td><td>254</td></tr><tr><td>Manager Growth Rate</td><td>254</td></tr><tr><td>Class Changes versus Alternatives</td><td>255</td></tr><tr><td>Moving Windows Library to AIX</td><td>255</td></tr><tr><td>Identical Users</td><td>256</td></tr><tr><td>Classes Available in the Library</td><td>257</td></tr><tr><td>ENVY/Windows95/Novell</td><td>257</td></tr></table>

<table><tr><td><strong>Chapter 6. Microsoft Windows</strong></td><td>259</td></tr><tr><td>Sizing the Windows 95 Toolbar</td><td>259</td></tr><tr><td>Windows 95 TreeView</td><td>259</td></tr><tr><td>Deactivation of OLE Embedded WordPro Document</td><td>260</td></tr><tr><td>Copying from Windows Explorer into an OLE Client Part</td><td>260</td></tr><tr><td>Generating OLE Methods</td><td>260</td></tr></table>
<table><tr><td>Free Disk Space on Windows Platform</td><td>261</td></tr><tr><td><strong>Chapter 7. National Language Support</strong></td><td><strong>263</strong></td></tr><tr><td>Code Page Support</td><td>263</td></tr><tr><td>Code Page and MPR Problems</td><td>263</td></tr><tr><td>Required CAT Files</td><td>264</td></tr><tr><td>Decimal Point Representations</td><td>264</td></tr><tr><td>Using Multiple National Languages</td><td>265</td></tr><tr><td>Adding French Characters to English</td><td>265</td></tr><tr><td>Problems with National Language Support in Version 3</td><td>266</td></tr><tr><td>Code Page Conversion between OS/2 and Windows</td><td>266</td></tr><tr><td>Double-Byte Character Set</td><td>267</td></tr><tr><td><strong>Appendix A. Special Notices</strong></td><td><strong>269</strong></td></tr><tr><td><strong>Appendix B. Related Publications</strong></td><td><strong>271</strong></td></tr><tr><td>International Technical Support Organization Publications</td><td>271</td></tr><tr><td>Redbooks on CD-ROMs</td><td>272</td></tr><tr><td>Other Publications</td><td>272</td></tr><tr><td><strong>How to Get ITSO Redbooks</strong></td><td><strong>275</strong></td></tr><tr><td>How IBM Employees Can Get ITSO Redbooks</td><td>275</td></tr><tr><td>How Customers Can Get ITSO Redbooks</td><td>276</td></tr><tr><td>IBM Redbook Order Form</td><td>277</td></tr><tr><td><strong>Glossary</strong></td><td><strong>279</strong></td></tr><tr><td><strong>List of Abbreviations</strong></td><td><strong>305</strong></td></tr><tr><td><strong>Index</strong></td><td><strong>307</strong></td></tr><tr><td><strong>ITSO Redbook Evaluation</strong></td><td><strong>309</strong></td></tr></table>
Preface

This book addresses many common questions in the VisualAge for Smalltalk development arena. It covers various aspects of VisualAge and IBM Smalltalk through answers to frequently asked questions, hints and tips from users and developers, and online bulletin boards inside and outside of IBM.

This redbook will help VisualAge for Smalltalk developers find answers to their everyday questions. The book provides usage guidelines for areas such as change management, performance, database access, and transaction processing, to help developers avoid common programming pitfalls.

The *VisualAge for Smalltalk Handbook* has two volumes:

* Volume 1: Fundamentals

Volume 1 covers general programming questions on such topics as image maintenance, graphical user interfaces, naming conventions, and the IBM Smalltalk language.

* Volume 2: Features

Volume 2 focuses on VisualAge for Smalltalk features, such as AS/400 Connection, Communications and Transactions, Distributed, Reports, and Web Connection.

This book is written for VisualAge for Smalltalk programmers, project leaders, and developers. Understanding many of the questions and answers in this book requires substantial knowledge of the VisualAge for Smalltalk product and the Smalltalk language.

This book does not discuss questions related to methodologies, analysis and design. For a discussion of object-oriented analysis and design with VisualAge for Smalltalk, refer to *Visual Modeling Technique*.
# How This Redbook Is Organized

This redbook contains 362 pages. It is organized as follows:

* Volume 1: Fundamentals

This book sets the stage for programming with VisualAge for Smalltalk. It contains questions and answers dealing with the base product and everyday programming pitfalls.

- Chapter 1, "What Is VisualAge for Smalltalk?"

This chapter provides some non-technical discussion of programming with VisualAge for Smalltalk.

- Chapter 2, "General Information"

This chapter provides general programming tips, from image maintenance and packaging to troubleshooting.

- Chapter 3, "Graphical User Interface"

This chapter provides a discussion of graphical user interface parts, such as containers, notebooks, buttons, or tables.

- Chapter 4, "IBM Smalltalk Programming Language"

This chapter provides questions and answers regarding the IBM Smalltalk programming language.

- Chapter 5, "ENVY"

This chapter provides a discussion of the ENVY team programming environment.

- Chapter 6, "Microsoft Windows"

This chapter provides a discussion of programming issues related to the Microsoft Windows platform.

- Chapter 7, "National Language Support"

This chapter discusses national language support with VisualAge for Smalltalk.

* Volume 2: Features

This book details on the various VisualAge for Smalltalk features, some of which are packaged with the base product and some others are separately orderable.

- Chapter 1, "AS/400 Connection"

This chapter provides a discussion of the AS/400 Connection feature and related items such as ClientAccess/400 and DB2/400.
- Chapter 2, "Communications/Transactions"

This chapter provides a discussion of the Communications/Transactions feature and its protocols, such as TCP/IP, APPC, CICS, or NetBIOS.

- Chapter 3, "Interface to External Routines"

This chapter discusses the use of external routines, such as C or COBOL programs.

- Chapter 4, "CICS and IMS Connection"

This chapter provides a discussion of the CICS/IMS Connection feature.

- Chapter 5, "Database"

This chapter covers questions and answers related to database access from VisualAge for Smalltalk, such as DB2 or Oracle.

- Chapter 6, "Distributed"

This chapter provides insight into the VisualAge for Smalltalk Distributed feature, for example, remote objects or object spaces.

- Chapter 7, "Reports"

This chapter covers the VisualAge for Smalltalk Reports feature.

- Chapter 8, "SOM/DSOM"

This chapter provides a discussion of the System Object Model and the Distributed System Object Model.

- Chapter 9, "Web Connection"

This chapter discusses the Web Connection feature of VisualAge for Smalltalk.

## ITSO on the Internet

Internet users may find additional material about new redbooks on the ITSO World Wide Web home page. Point your Web browser to the following URL:

http://www.redbooks.ibm.com/redbooks

IBM internal users may also download redbooks or scan through redbook abstracts. Point your Web browser to the internal IBM Redbooks home page:

http://w3.itso.ibm.com/redbooks
If you do not have World Wide Web access, you can obtain the list of all
current redbooks through the Internet by anonymous FTP to:

ftp.almaden.ibm.com

cd /redbooks

get itsopub.txt

The FTP server, ftp.almaden.ibm.com, also stores the sample software from
the diskettes accompanying some of the redbooks. To retrieve the sample
files, issue the following commands from the /redbooks directory:

cd SG24xxxx ← Redbook number

binary

get SampleFile.EXE

ascii

get SampleFile.TXT

All users of ITSO publications are encouraged to provide feedback to
improve quality over time. Send questions about and feedback on redbooks
to:

redbook@vnet.ibm.com or

REDBOOK at WTSCPOK or

USIB5FWN at IBMMAIL

If you find an error in the software that is supplied with a redbook, please
send a bug report with a description of the problem to

bugs@vnet.ibm.com

To receive regular updates on new redbooks and general IBM
announcements, you can subscribe to the IBM Announcement Listserver. It
automatically supplies an Internet e-mail user with timely new
announcement information (titles and optionally the letter or abstract) from
selected categories. To get started, send an e-mail to

announce@webster.ibmlink.ibm.com

The keyword SUBSCRIBE must be the only word in the body of the e-mail;
leave the subject line blank. You will receive a category form and listserver
details. To immediately start your subscription to, for example, AS/400
announcements, put the words SELECT HW120 in the body of the note. On
the afternoon of an announcement day, you will receive e-mail with the
announcement, along with a list of newly available redbook titles. To obtain
a full abstract of a particular redbook, use GET SG242535 in the note.
## VisualAge Support on CompuServe

VisualAge users are encouraged to use CompuServe® to ask questions about VisualAge and its features. When logged on to your CompuServe account, type GO VISUALAGE to get into the IBM Workstation Rapid Application Development (WRAD) conference. You will find sections to discuss the following and other VisualAge topics:

* Installation/Begin

* Communication/Languages

* Database

* AS/400 Connection

* Web Connection

## About the Authors

This redbook was produced by a team of specialists from around the world working at the International Technical Support Organization, San Jose, CA.

**Andi Bitterer** works as a consultant for the International Technical Support Organization at the Almaden Research Center in San Jose, California. He graduated with a degree in computer science from the Technical University in Darmstadt, Germany. Andi joined IBM in 1987 and worked as an application development specialist in large customer projects for IBM Integration Systems Services and at the German AS/400 Field Support Center. Since joining the ITSO in 1994, he has taught workshops worldwide on object-oriented application development and the Internet. Andi is the author of three other VisualAge for Smalltalk books published by Prentice Hall. You can reach him by e-mail at bit@acm.org.

**Vincent Dijkstra** works as an Education Consultant at the IBM International Education Center, La Hulpe, Belgium. He holds Bachelor of Arts and Master of Arts degrees in Technology and Policy from the Eindhoven Technical University. Vincent started working for IBM in 1992 on a learning resource to assist managers and teams in transforming their organizations. In 1994 he joined the IBM Object Technology University, where he teaches Smalltalk, VisualAge, and more recently Java and analysis and design techniques. You can reach Vincent by e-mail at vdijkstra@vnet.ibm.com

**Boris Shingarov** received his Master of Science degree in Quantum Fields at Moscow State University, M.V.Lomonosov, in Russia. He is the head of the Center for VisualAge and IBM Smalltalk, Dialogue/MSU, providing VisualAge consulting and services all over Russia. Currently, Boris teaches VisualAge for Smalltalk courses at MSU. He can be reached by email at boris@visualage.dialogue.msu.su.
## Acknowledgments

This book has been a team effort par excellence, even though most contributors were not even aware of being a team. However, we want to acknowledge everyone, inside and outside of IBM, who, knowingly or unknowingly, added information to the collection of invaluable hints and tips in this book.

Thanks go to Dave Allison, Rainer Angstmann, Jean-Pierre Augias, Wayne Beaton, Jan Belik, Paul Berglund, Jonathan Bezuidenho, Debu Bhattacharya, Franco Biaggi, Peter Boonen, Chris Bosman-Clark, Toufic Boubez, David Bourke, Dave Bowman, Mamie Branch, Michel Brassard, Chuck Bridgham, Robert Brown, Jordi Buj, Jerry Callistein, Jon Capezzuto, Tony Carlier, Janelle Carroll, Ron Cherveny, George Chiu, Chris Clark, Eric Clayberg, Stephen Cooper, Ellis Covington, Tim Cowan, Mark Cresswell, Jim Crossgrove, Greg Curfman, James Curtis, Chris Davia, Kirk Davis, Gordon Davis, John DeBinder, Ricardo Devis, Bill Dickenson, Stef van Dijk, Sue Dubbeling, John Earle, Ralf Eberhardt, Kevin Egolf, Linda Fargo, Ahmed Fattah, Gerald Fischer, Hans Forsberg, Mike French, Annick Fron, Sabine Gaissert, Ken Gelsinger, Chris Gerken, Michel Giroux, Erick Godoy, Tom Gordon, Chris Grindstaff, Juergen Guenauer, Sven Guyet, Tim Hanis, Brad Hanks, John Hansen, Nicla Havrup, Chris Hayes, Frank Haynes, Pam Helyar, Andy Heys, Hal Hildebrand, Tim Hilgenberg, Andrew Hobbs, Steve Hobson, Bryan Hogan, Andreas Huber, Greg Hutchinson, Mike Jacobs, Charif Jaouhar, Chuck Jaynes, Christopher Joak, Greg Johnson, Tom Johnson, Jane Jones, Gary Karasiuk, Gijsbert Karens, Dan Kehn, John Kellington, Dave Kennedy, Brian Kent, Kelly Keplinger, Alan Knight, George Kober, Martin Kunz, Bruce Lambert, Micky Lim, Michael Linderman, Daniel Lipp, Grace Liu, Bill Lockard, Tom Logan, Mark Lorenz, Pablo Lorenzo, Sabina Luzzatti, Stewart MacLean, Bill Mathews, Cynthia McCrickard, David McGee, John McIntosh, Ted McKnight, Gerald Meazell, Eric Meredith, Jim Mickelson, Gonzalo Mourino, Pat Mueller, Gen Nagatsuka, Martin Nally, Binh Nguyen, Jimmy Nguyen, Achim Nogli, Ami Noyman, Patrick O'Donnell, John O'Keefe, Dan Ohlhaut, Omar Padilla, Jim Pendergast, Rosa Peral, Ralf Pfiszter, Enrico Piccinin, Oliver Picot, Guenter Pindhofer, Rene Plourde, Greg Plummer, Bob Poulton, Steve Reeves, Brian Remedios, James Rendell, Scott Rich, Cameron Roy, Jouko Ruuskanen, Jari Saari, Craig Setera, Dan Shaver, Ed Shirk, Allen Smith, Christine Smith, Craig Smith, David Smith, Larry Smith, Daniel Stainhauser, Jim Stewart, Jeff Stratford, Jean Talbott, Steve Tang, John Tobin, Mark Tompkin, Mike Toohey, Rick Trotter, David Twyerould, Timo Ullrich, Harold Wadler, Jim Wason, Christopher Webster, Tony Weddle, Ronny Weisz, David Whiteman, Mark Wilkes, Joe Winchester, Rory Woodward, Cindy Wotus, Glorious Wright, Alfred Wu, Barry Young, Ric Zapanta, Sherwood Zern, and Slavik Zorin, for their numerous contributions, questions or answers, hints and tips.
Many thanks go to Alexis Scott, Nancy Lewis, Paul Braun, and Shawn Walsh at the ITSO Raleigh Center, for their great administrative support, and to Pat Donleycott, ITSO Raleigh Center Manager, for hosting the residency.

Thanks also to Shirley Hentzell and Maggie Cutler for their outstanding editing of this book, to Liz Rice for her editorial assistance, and to Geoff Nicholls, without whose advice this book would not have a decent index.

## Comments Welcome

**Your comments are important to us!**

We want our redbooks to be as helpful as possible. Please send us your comments about this or other redbooks in one of the following ways:

* Fax the evaluation form found in "ITSO Redbook Evaluation" to the fax number shown on the form.

* Use the electronic evaluation form found on the Redbooks Home Pages at the following URLs:

For Internet users http://www.redbooks.ibm.com

For IBM Intranet users http://w3.itso.ibm.com

* Send us a note at the following address:

redbook@vnet.ibm.com
# Chapter 1. What Is VisualAge for Smalltalk?

## Description of VisualAge for Smalltalk

**Question**

What is VisualAge for Smalltalk?

**Answer**

VisualAge for Smalltalk is a client/server rapid application builder for constructing state-of-the-art, flexible, scalable business applications. With extensive libraries of classes, a rich set of preexisting parts from IBM and other vendors, wrapping of existing COBOL, C, IMS transactions or VBX controls, and multimedia authoring support, VisualAge enables rapid assembly of applications with minimal new code. VisualAge for Smalltalk supports development on Windows, OS/2, or AIX, with full portability of applications across these target platforms. It combines the power of a pure object-oriented environment with the ease of visual programming. Users can connect prefabricated, reusable components or extend these components with user-created code. VisualAge for Smalltalk eases the learning and implementation of object-oriented technologies. VisualAge for Smalltalk supports multiple client/server models, GUI construction, popular communications and transaction protocols, access to industry-leading databases, the CORBA standard for object interoperability, and multiple legacy interfaces. VisualAge for Smalltalk Standard is the entry-level product for individual programmers. The Professional product, for individuals or teams, includes version control and configuration management. The Professional Server product includes a LAN repository for team development. Add-on components include support for native ORACLE data access, communications and transactions, reports, AS/400, IMS, and distributed objects.

## VisualAge for Smalltalk Technology

**Question**

What type of technology does VisualAge use?

**Answer**

Application developers use a construction-from-components or construction-from-parts paradigm when using VisualAge. VisualAge is based on IBM Smalltalk, which embodies the principles of object-oriented (OO) technology to build applications, providing all of the benefits of reuse and rapid application development. With VisualAge's GUI-based development platform, proficiency in OO is not a prerequisite, thus easing a developer's entry into OO.
## Description of Smalltalk

**Question** What is Smalltalk?

**Answer** Smalltalk is a popular OO language. Often referred to as a 5GL, Smalltalk is a very powerful, high level language that offers exceptional capabilities for rapid prototyping and delivery of applications. It is an emerging language in the programming environment.

Smalltalk has been around since 1971. It was developed in Xerox PARC, and it was the first system in the history of computers featuring a GUI with windows, mice, and other properties of the modern graphical operating systems. IBM Smalltalk is a portable, robust, standards compliant, integrated Smalltalk language and development environment embedded as a component of VisualAge. IBM Smalltalk adheres to industry standards such as OSF Motif and POSIX and is based on the proposed common-base Smalltalk specification submitted to the X3J20 committee for making Smalltalk recommendations to ANSI.

## Description of ENVY

**Question** What is ENVY?

**Answer** ENVY is an incredibly powerful Smalltalk development environment from OTI, having features that no other Smalltalk development environment has. Originally, ENVY was an environment, to be based on top of other basic Smalltalk implementations. But now, in IBM Smalltalk, you have a full from-scratch integration between the language and the environment.

## Stability and Maturity

**Question** How stable and mature is VisualAge for Smalltalk?

**Answer** VisualAge for Smalltalk was in development for several years before it became generally available in the first quarter of 1994. According to Eric Ostrom, a consultant for IS International, "VisualAge [for Smalltalk] is the most solid release 1 development tool I have ever used. Each release is faster and offers more features. Version 3.0 with distributed Smalltalk is outstanding." Standards-conforming IBM Smalltalk (and therefore VisualAge for Smalltalk) is based on the proposed common-base Smalltalk specification submitted to the X3J20 committee for making Smalltalk
recommendations to ANSI. Both the chairman and secretary of the ANSI Smalltalk committee work for IBM in Smalltalk development. In addition, IBM Smalltalk adheres to industry standards of OSF Motif, X-Windows, POSIX, and IBM's CORBA implementation (SOM).

## Openness

**Question**

In what respect is VisualAge for Smalltalk open?

**Answer**

It is portable among platforms— Windows, OS/2, AIX, Sun, and HP. VisualAge for Smalltalk supports IBM and non-IBM databases and a variety of communication protocols, including TCP/IP, for operation in heterogeneous environments. VisualAge for Smalltalk is built on a nonproprietary standards base (Smalltalk) that can be extended and modified by customers and third party vendors.

## Team or Professional Version

**Question**

Does VisualAge have a team or pro edition?

**Answer**

Yes. VisualAge for Smalltalk actually has two base versions—Standard and Professional. VisualAge for Smalltalk Standard is for the individual programmer. VisualAge for Smalltalk Professional is for individuals or teams and can support a LAN-based library of classes and parts, version control, configuration management and other functions that support collaborative team development. Additionally, a Professional Server product is available for VisualAge for Smalltalk and IBM Smalltalk. The Professional Server extends the box product by providing multiple user access and a central LAN-based library of classes and parts that developers can access concurrently.

## Advantages of VisualAge

**Question**

What are the key advantages of VisualAge?

**Answer**

VisualAge for Smalltalk is the only tool of its class that offers full integration of visual programming, object-oriented environment, and best-of-breed team support. Programmers never need to leave one tool to go to another to build and test a complete application. Teams of programmers can easily manage complex object-oriented development projects. VisualAge for Smalltalk permits programmers to extend their applications and the
VisualAge for Smalltalk tool itself. Where other tools require programmers to work within the limits of the tool, VisualAge allows programmers to build new extensions to the VisualAge product that become reusable components and part of the complete Smalltalk environment. VisualAge implements "class-based" programming, such that new parts become Smalltalk classes, which can be part of the class hierarchy system and can be located with the Smalltalk browsers. VisualAge for Smalltalk includes state-of-the art multimedia authoring support, which allows developers to build exciting kiosk-style applications. VisualAge for Smalltalk also provides a report writer, which provides the ability to lay out reports using the facilities of the VisualAge construction-from-parts paradigm

## Advantages of Smalltalk

**Question**

What are the key advantages of IBM Smalltalk?

**Answer**

IBM Smalltalk is a very robust Smalltalk that is based on industry standards such as POSIX for filing systems and Motif for GUI. It is also based on the proposed common Smalltalk standard that was submitted to the X3J20 committee for making Smalltalk recommendations to ANSI in 1993. IBM Smalltalk contains a wide range of functions spanning more than 1100 classes in IBM Smalltalk and more than 2500 classes in VisualAge for Smalltalk. IBM Smalltalk enables robust portability. Unlike other portable implementations that emulate objects on various platforms, IBM Smalltalk applications automatically take on the look and feel of target platforms by using the native platform widgets. Unlike simple check-in and check-out library systems, IBM Smalltalk team support includes an object repository, true version control, and configuration management capabilities. Do you have a vendor program similar to Digitalk's and Powersoft's that encourages third party vendors to build parts that can be utilized with VisualAge? We have published a Construction from Parts architecture that teaches vendors and end-users how to create their own parts. IBM's Object Connection program for VisualAge encourages other companies to build components that enhance the applicability and value of VisualAge. We are currently working with more than 100 corporate members who are marketing more than 50 products.
## VisualAge for Smalltalk and VisualAge Generator

**Question**

How would you compare VisualAge for Smalltalk and VisualAge Generator as client-server application development tools?

**Answer**

VisualAge Generator provides a highly productive workstation development environment for traditional host-based COBOL developers that exploit new object-oriented technologies while not requiring an investment in additional skills training. VisualAge Generator uses a 4GL COBOL-like scripting language along with visual programming for developing line-of-business client/server solutions. VisualAge Generator provides facilities for building both client and server components, interactive test at the source level, and generation of both client and server. VisualAge for Smalltalk is a fully object-oriented tool providing a visual programming construction-from-parts paradigm and uses IBM Smalltalk as the scripting language. VisualAge for Smalltalk focuses on building client/server solutions while providing extensive database access, communications support, and support for reusing existing enterprise data and code. The products are complementary. Each has its own strengths. In some customer situations, one of the products may provide the right solution, whereas in others the entire solution may dictate that both products provide the ultimate benefit. For users wanting to explore the world of object-oriented programming while maintaining a 4GL development environment, VisualAge for Smalltalk should be a very attractive addition.

## VisualAge for Smalltalk and C++

**Question**

How would you compare VisualAge for Smalltalk and VisualAge for C++?

**Answer**

C++ is the language of choice for the professional C or C++ programmer building high-performance, small-footprint, or real-time applications, for "close to the metal" application development. Smalltalk is the language of choice for the professional programmer who wants a rapid application development environment for solving enterprise business problems, for "business logic" application development. C++ and Smalltalk are equivalent in capability, for well-trained and skilled developers.
## Visualizer

**Question** How does Visualizer compare with VisualAge for Smalltalk?

**Answer** Visualizer is a powerful decision support tool that allows end users to visually construct database queries and generate reports. It also features add-on components up to and including a GUI builder. VisualAge is targeted for professional developers rather than end users.

## Team Connection

**Question** Does VisualAge for Smalltalk support Team Connection?

**Answer** VisualAge provides team support, using an object repository that is tightly integrated in the product and that provides a high-level of support for Smalltalk-based development. Our direction is to expand this excellent object repository with bridges to other technologies such as TeamConnection.

## Supported Platforms

**Question** On which platforms is VisualAge for Smalltalk offered?

**Answer** VisualAge is available on:

* OS/2 Warp Version 3 or Version 4

* Windows 3.11

* Windows 95

* Windows NT 3.51 or 4.0

* AIX 4.1.4 or 4.2

* Sun Solaris 2.5.1

* HP-UX 10.10
## Smalltalk Strategy

**Question** Is Smalltalk strategic?

**Answer** Smalltalk is a strategic language for IBM and will be developed as a standards compliant, open, multiplatform language. Smalltalk is an important and emerging object-oriented language in the industry. Its use in business and commercial application development is growing rapidly. IBM is chairing the effort to develop ANSI standards for Smalltalk, and a full range of third party consultants, tool vendors, and service providers are available to complement the offerings of Smalltalk vendors. IBM recognizes the value of Smalltalk and is delivering a full range of tools, education, consulting, and service offerings to address this important market.

## Smalltalk and Java

**Question** Will Java overpower Smalltalk?

**Answer** While not disregarding the strength of Java, we must note that Smalltalk is superior to Java in many ways. The main strength of Smalltalk is its maturity. Smalltalk has been around for 25 years. By contrast, Java is in its very infancy. Smalltalk's maturity has some important effects:

* Code quality. Smalltalk systems have been refined by several generations of programmers and have proved to be free of both coding bugs and, more importantly, ideological bugs.

* Legacy code. There is a huge estate of existing Smalltalk applications.

* Performance. Smalltalk is quite fast, thanks to the concerted efforts of many programmers during the last 25 years. Java needs an investment of similar effort to reach a comparable level of performance.

## Configuration Management

**Question** How does VisualAge for Smalltalk support configuration management?

**Answer** OTI's ENVY configuration management and version control system is included in the VisualAge for Smalltalk Professional and Professional Server products, precluding the need to order a separate product and managing compatability between VisualAge and ENVY. The October 9, 1995 issue of *InfoWorld*, states that: "IBM did a superb job weaving Object Technology
Inc.'s Envy Developer into VisualAge, resulting in unmatched team
development facilities."

Packaging Support

**Question** How does VisualAge for Smalltalk support packaging?

**Answer** One of the enhancements to Envy found in VisualAge for Smalltalk is the one-button packager, which automatically excludes unnecessary classes from the application executable. The developer can also customize what is stripped out of the image to provide an even smaller executable.

Database Support

**Question** Which databases does VisualAge for Smalltalk support?

**Answer** VisualAge for Smalltalk supports a wide variety of database systems including the DB2 family, for example, DB2/2 for OS/2, DB2/6000 for AIX, and on Windows using CAE client support. Through connectivity services of DDCS, VisualAge for Smalltalk can access the DB2 family (including DB2 and SQL/DS and access to the AS/400). Oracle ODBC (with industry standard drivers such as Sybase, SQL Server, Informix) IBM intends to respond to additional customer needs for native support for other databases. In addition to any database driver supported by ODBC, the capability always exists within VisualAge to drop into the Smalltalk development environment to build any type of unique class library and parts you need.

Communication Protocol Support

**Question** Which communications protocols does VisualAge for Smalltalk support?

**Answer** Communications protocols are supplied in the VisualAge for Smalltalk Communications/Transactions feature and include TCP/IP, APPC, CPI-C, NetBIOS, CICS ECI, EHLLAPI, MQSeries, and RPC.
## Legacy Code

**Question**

How does VisualAge for Smalltalk handle legacy code?

**Answer**

You can wrapper legacy COBOL, C, or C++ applications into parts by using the COBOL, C, and C++ support included with the base product. The IMS Connection feature enables you to wrap existing IMS transactions to be used as parts within the VisualAge for Smalltalk environment. IBM SOM and DSOM support enables you to reuse existing SOM and DSOM objects as VisualAge for Smalltalk parts.

## Runtime Distribution Fees

**Question**

Are there any run-time distribution fees for VisualAge or IBM Smalltalk?

**Answer**

No. In contrast to many contemporary application development tools, the VisualAge and IBM Smalltalk license agreements allow you to freely distribute the run-time environment for the applications you write with VisualAge.

## Distributing Smalltalk Compiler

**Question**

Can the Smalltalk compiler be distributed with a run-time application?

**Answer**

No. Redistribution of the Smalltalk compiler is not permitted. The compiler is a key component of the VisualAge application development environment itself. You must purchase one license for each compiler distributed. However, you can distribute the run-time without a fee.

## Source Code Availability

**Question**

How much of the Smalltalk source is available with the VisualAge for Smalltalk product?

**Answer**

99% of the source code is available. Some methods remain proprietary and are still hidden; however, those methods are typically used because they are required for application development (for example, method code in the Smalltalk compiler.)
## Upward Compatibility

**Question** Is an application written for one version of VisualAge for Smalltalk compatible with the environment of a higher version of the product?

**Answer** One of the features of the IBM VisualAge development environment is the ability to easily port existing VisualAge applications to other platforms and to easily upgrade the run-time environment for a new release of VisualAge. All you have to do is repackage the application with the new run-times and DLLs.

## Common User Access Compliance

**Question** Does VisualAge for Smalltalk force Common User Access (CUA) compliance?

**Answer** CUA compliance is up to the programmer. However, with VisualAge it is a simple task to produce fully CUA-compliant applications.

## Multiple Inheritance

**Question** Does Smalltalk support multiple inheritance?

**Answer** No. Multiple inheritance is a property that has been confused as a characteristic of the OO paradigm. It is not. It is only mildly useful in certain situations; invariably it causes objects to carry more attributes than necessary.

## Porting Smalltalk Applications

**Question** How do I port a Smalltalk application to VisualAge?

**Answer** The recommended approach is to import (through a DAT file) or file in (through an ST file) the model code. The GUI code should be rebuilt in VisualAge because the effort to port may exceed the effort to rebuild.
Sources of Support

**Question** Once I purchased VisualAge for Smalltalk, what kind of support can I expect?

**Answer** A variety of support is available, including:

* Sixty days of free IBM direct telephone support

* TalkLink forums

* CompuServe forums

* Web (for DAP members)

* Technical support, consulting, education, training, and more—from third parties

TalkLink

**Question** Which forums are available on TalkLink?

**Answer** Talklink's public forums for VisualAge for Smalltalk are:

* IBMPARTS IBM Parts for Visualage for Smalltalk

* VADIST Distributed feature

* VAIMS CICS/IMS feature

* VAINSTAL Install questions

* VACOMLNG Communications and Language features

* VA400 AS/400 Connection feature

* VAOTHER Other topics not covered

* VAHOWTO How-to questions

* VADB Database questions

* VABUGS Bug reports
## CompuServe

**Question**

Which forums are available on CompuServe?

**Answer**

The CompuServe forums for VisualAge for Smalltalk are:

* Free-for-all

* Install/Begin

* Communications/Languages

* Database

* AS/400 Feature

* How-to

* Everything Else

* Bug Reports

* Third Party

* IBM Smalltalk

* Classifieds

## Usenet

**Question**

Is there a Usenet group dedicated to Smalltalk?

**Answer**

Yes: COMP.LANG SMALLTALK.

## Resource Catalog

**Question**

How can I get the resource catalog about vendors of components for VisualAge for Smalltalk?

**Answer**

The document number of the Resource Catalog is G325-0813. If you work for IBM, you can order it through Puborder. The catalog is also accessible from the VisualAge home page on the World Wide Web:

http://www.software.ibm.com/software/ad/vastub.html

Be sure you are getting the latest catalog if you order a hard copy.
## Learning Courses

**Question**

Where can I find out about a suggested sequence of courses for application programming with VisualAge and IBM Smalltalk?

**Answer**

The Object Technology University (OTU) offers a curriculum for VisualAge for Smalltalk. For more information visit their Web site at:

http://www.training.ibm.com/ibmedu/roadmaps/client/ot/

## New Features in Version 3

**Question**

What are the new features in VisualAge for Smalltalk Version 3?

**Answer**

The functions of Version 2 plus:

* Development and run-time support for AIX Version 4.1.3.

* Open Database Connectivity (ODBC) support. This feature enables you to access data from a variety of databases and file systems which support the ODBC interface.

* Performance improvements through tuning and enhancements to the underlying virtual machine (VM): up to 5 times faster execution; machine code execution for Intel platforms

* Usability improvements through improved startup, consistency in dialogs, settings, font usage, additional parts, improved help, better and more complete examples.

* Enhanced database parts for greater usability and performance

* Upgraded IBM Database support for DB2/2 V2.1 with support for user-defined functions (UDFs), user-defined types (UDTs) and binary large objects (BLOBs).

* New portable controls (notebook, container, slider, and spin button) for multiplatform support and portability

* Portable drag-and-drop support

* VBX support (Windows only). This feature enables you to wrapper existing VBX controls and use them on the VisualAge for Smalltalk palette.

* Multimedia enhancements, including kiosk authoring enablement (OS/2 and Windows only), which includes support for hot spots and scene-to-scene navigation.
* VisualAge for Smalltalk, Distributed, enables you to develop a VisualAge for Smalltalk application on a single development platform and split the logic of the application to run on multiple execution platforms. Facilities are provided for remote debugging, performance profiling for optimal distribution, and other features that complement the development environment.

* VisualAge for Smalltalk, Database for Oracle for OS/2, for AIX, and for Windows, V3.0 provides access to Oracle data through native APIs. (Access to Oracle and other databases through ODBC is also provided in the base products.)

* VisualAge for Smalltalk, Reports for OS/2 and for Windows, V3.0 enables you to lay out reports, using the facilities of the VisualAge for Smalltalk construction-from-parts paradigm.

* Message Queue Series (MQSeries) support and remote procedure call (RPC) support as part of VisualAge for Smalltalk, Communications/Transactions for OS/2, for AIX, and for Windows V3.0.

* System Object Model (SOM) and Distributed SOM (DSOM) 2.1 Client support (OS/2 and AIX only).

* VisualAge for Smalltalk, AS/400 Connection for OS/2 and for Windows, V3.0 enables you to access additional AS/400 services, objects, and data, along with additional parts for VisualAge for Smalltalk.

* VisualAge for Smalltalk, IMS Connection for OS/2, for AIX, and for Windows, V3.0 enables you to wrap existing IMS transactions to be used as parts within the VisualAge for Smalltalk environment.

## New Features in Version 4

**Question** What are the new features in VisualAge for Smalltalk Version 4?

**Answer** VisualAge for Smalltalk is IBM's award winning enterprise application development tool that is the cornerstone of IBM's VisualAge family of development products. VisualAge for Smalltalk allows software developers to create highly portable, scalable, multitier business applications that take advantage of emerging technologies such as the World Wide Web, ActiveX, OLE, and OLE controls (OCX) as well as seamlessly integrate existing legacy C, COBOL, CICS, DB2, IMS, and Tivoli systems. Version 4.0 takes the next step in enabling global enterprises to quickly construct line of business applications that are portable, highly scalable, and simple to maintain and fit easily into existing IT infrastructures.
VisualAge for Smalltalk is now available on more UNIX, Windows and OS/2 platforms than ever before. In addition to the existing OS/2 Warp V3.0, AIX V4.1.4/4.2, Windows 3.11, Windows 95, and Windows NT 3.51, new platforms supported are HP-UX V10.10, Sun Solaris V2.5, S/390 MVS, OS/2 Warp V4.0, and Windows NT 4.0. On Windows 95 and NT, OLE and ActiveX are now supported as well as new native user interface controls. Version 4.0 is now registered and certified for the "Designed for Microsoft Windows NT and Windows 95" logo.

Version 4.0 brings further performance enhancements, usability improvements, tool enhancements, and enhanced packaging support. Performance has been improved through the introduction of image components (ICs), which allow developers to create dynamically loadable modules that partition a Smalltalk application into smaller components that can be loaded and unloaded during program execution. ICs enable a more fine-grained packaging system and allow multiple applications to "share" the client's run-time image, which improves performance and footprint and further promotes reuse. Performance of database applications will improve under Version 4.0, and DB2 applications can now be improved substantially by using static SQL. Tool enhancements include a more robust debugger, allowing for static and conditional breakpoints, and profiler enhancements that provide for easier fine tuning of an application's performance. VisualAge for Smalltalk has also improved its external callout and callback support, allowing non-Smalltalk applications to communicate more easily with Smalltalk applications. Several Version 3.0 optional features have been moved into the base, including native Oracle support, Connection for Lotus Notes, Reports, a leading-edge object visualization tool, and Pro Server, providing the best value in the industry. Management of applications is improved by including parts that allow your application to interact with the Tivoli system management products. Also included with each copy of Version 4.0 is AppletAuthor, which allows you to create eye-popping Java applets that lead to dynamic, visually appealing Web sites without the need to know Java programming.

## Additional Platforms and Windows Platform Exploitation

Platform choice has been a hallmark of VisualAge for Smalltalk, and Version 4.0 increases that choice fivefold. New UNIX platforms HP-UX (V10.10) and Sun Solaris (V2.5) have been added, and additional versions of PC operating systems are now supported: OS/2 Warp V4.0 and Windows NT 4.0. Finally, Smalltalk applications can be written for the S/390 MVS platform by using the new VisualAge Smalltalk Server for MVS product in conjunction with VisualAge for Smalltalk Version 4.0. With Smalltalk on the S/390 MVS system, mainframe programmers can achieve the same level of productivity and capability as those using Smalltalk on a PC or workstation. Using
Server Smalltalk for MVS, you can quickly build business logic in true object-oriented form on the MVS operating system. Support for IMS, CICS, DB2, native file system access, and batch programming are just a few of the features included. State-of-the-art cross-development tools allow you to develop the bulk of the application on a PC and later deploy it to MVS for the robust run-time performance we all expect from that platform. You can now create end-to-end enterprise objects, from client to mid-tier server to third-tier server, using a single language and development environment. For more information, please see the white paper titled "Introducing VisualAge Smalltalk Server for MVS."

For those of you who use the Windows platform, Version 4.0 adds additional power and function. A new OLE application framework provides support for incorporating OLE (OCX) and ActiveX controls in your application and makes it easy for you to write OLE clients in VisualAge for Smalltalk. Off-the-shelf OLE and ActiveX controls can be placed on the VisualAge palette, dropped on the application design surface, and visually connected to other parts, using the award winning construction-from-parts technology. If you want to write OLE clients, the framework provides high-level abstractions for the OLE container concepts, allowing you to focus on your Smalltalk application and not on the low-level OLE programming interfaces. Using the framework, you can write OLE container applications that support embedding, linking, in-place activation, drag-and-drop, and structured storage. You can also write OLE automation controllers in Smalltalk that can control third party OLE automation servers, such as Microsoft Word or Lotus 1-2-3 for Windows.

Windows 95 and NT 4.0 support many new or visually redesigned user interface controls, and so does VisualAge for Smalltalk Version 4.0. You will find support for the new system slider, progress bar, tab strip, toolbar, tree view and status bar. These are included in a new palette category in the VisualAge application builder for easy visual application construction, as well as in the widget class library.

## Image Components

Developers of Smalltalk code are very familiar with the concept of an image. An image is a file that contains all of the user's objects, and it is loaded and executed by the Smalltalk run-time system. In VisualAge for Smalltalk Version 3.0, single, stand-alone image files are the norm. Typically these image files are quite large, and copying and storing them requires a lot of resources because these images are not shareable, code that is common between applications must be duplicated in the image files that represent each application and in memory when each application is running. Although techniques have been developed to apply fixes to application programs in an image, the process is time consuming and difficult, especially when only a few applications, classes, or methods must be replaced in a large system.
In Version 4.0, ICs enable you to overcome these and other difficulties. ICs promote reuse, reduce memory requirements, make application maintenance easier, and promote porting. In Version 4.0, you can divide an image into separate IC files, which can be reused among independent applications. ICs reduce the memory required when multiple applications are running because the ICs are shared among applications using the shared memory facilities of the underlying operating system. Also, ICs use a compact format which results in smaller images that load and run faster. An additional benefit of the compact format is shorter time spent in garbage collection. Because ICs are replaceable, they make it easier to maintain and enhance applications. replaceable. You can update an IC with bug fixes or patches and replace the existing IC, not the entire image file. Provided the Smalltalk code in an IC is platform independent, an IC is portable, because the same IC file will load and execute on all platforms supported by VisualAge for Smalltalk Version 4.0.

## Smalltalk Language and Tool Enhancements

Support for ICs is just one of several improvements that have been made to the Smalltalk language and tools in Version 4.0. Breakpoints have been added to the debugger, enabling you to more easily find, isolate, and remove bugs from your code. You can set a breakpoint on any line of Smalltalk code, and you will see a red dot in the margin of the browser indicating that a breakpoint is set. The executing program stops when the breakpoint is reached, and you can begin debugging at that point by stepping through the code, inspecting objects, and so forth. A conditional expression can be associated with a breakpoint, and the execution will stop only when the condition is true. Thus you can isolate those hard-to-find bugs that occur when the state or content of an object becomes incorrect, by setting a breakpoint that will only trip when that occurs. You can also set the number of iterations a breakpoint must be reached before the execution will be stopped, so that you can debug pieces of code that are executed repeatedly without stepping through each iteration manually. From the development environment you can display a list of all methods in which breakpoints are set and browse the method code from the list.

Namespaces have been added to the language, which give you control over the scope of globals in your application. Namespaces allow you to use a language construct that logically groups globals and assigns them a name. You can later selectively gain access to and include the collection of globals in the scope of your application by referring to its name. Thus namespaces provide the same type of scoping control for globals as application prerequisites provide for class references. They also provide an easier to use and more robust technique than was provided by "toBeLoadedCode" and "wasRemovedCode" in previous releases. A new query tool has been
added to the development environment that lets you display all references to objects, methods, and globals that are outside the scope of your application, its namespace references, and its prerequisite applications. This tool helps you find and correct scoping and namespace problems and correctly prepare your application for packaging, especially when using ICs.

The performance analysis and tuning tools now monitor and collect more memory allocation information and enable you to easily create, run and compare the results of performance benchmarks. The memory monitor in Version 4.0 now shows individual pieces of allocated memory segments. You can quickly identify the portions of your application that are using a lot of memory, making it much easier for you to tune and improve that code. The benchmarking workshop now lets you collect and store performance benchmark test cases. You can make performance test runs using any and all of these test cases. Results can be graphically displayed and compared with previous runs so that you can quickly see the impact of your performance tuning efforts.

Better callback support from C to Smalltalk has greatly improved the interoperability between C and Smalltalk. This entry point can be passed to an external program when calling-out to it from Smalltalk. It gives that program an entry point to the Smalltalk object and selector it represents. In C you can map the entry point to a function pointer, making it very easy and natural to callback from C to Smalltalk. When combined with ICs, you now have powerful new options for packaging and delivering Smalltalk dynamically loadable application code that must call to and be called from programs written in other languages.

## Database Performance Improvements and Enhancements

Major performance and database security improvements are in store when you use DB2 static SQL support, a new addition to VisualAge for Smalltalk in Version 4.0. Other database improvements include unified fields and samples, "headless" server support, and improved performance in applications using dynamic SQL.

In Version 3.0, dynamic SQL was used for all database access. IBM's DB2 static SQL essentially allows you to compile your SQL statements and store them in the database. What is stored is called a *plan*, which contains optimized database access and manipulation code to execute your SQL statements. Comparing static SQL and dynamic SQL is very similar to comparing compiled and interpreted programming languages. Static SQL gives you compiled, optimized, high performance database access, while dynamic SQL is in some cases slower to execute but more flexible and easier to change. The Version 4.0 database support enables you to create, test, and debug your DB2-based Smalltalk application, using dynamic SQL,
and then flip a switch and convert it to static SQL. Thus, you have the rapid
application development style of an interpreted environment early in the
development cycle, and the speed of a compiled environment when you roll
your database application out into production. Dynamic and static SQL can
be used in combination in the same application, allowing you to stage or
phase in your cutover to static.

The performance gains you will realize when switching to static SQL vary
and are application dependent. Database security for any application that
uses static SQL is vastly improved over dynamic SQL. For users to execute
dynamic SQL, he must have complete authority to the tables and data
affected by the query. This can present an exposure if, for example, one of
the tables contains sensitive data not included in the SQL SELECT
statement. Users can use interactive query tools to view the sensitive data
and bypass the SELECT statement in the application program, because they
must have access to the entire table in order to run the SQL statement
dynamically. This is an even greater exposure for other SQL statements, like
UPDATE and DELETE. Not so with static SQL. User authorization may be
given only to specific plans (compiled SQL statements), thus preventing the
user from viewing or changing any data not included under the scope of the
plan. Static SQL is one of the strongest features of IBM's DB2 family, and
now VisualAge for Smalltalk allows you to exploit that strength.

Unified fields now allow you to create applications that are largely database
neutral. In Version 3.0, the database field classes, which represent data
types in the database, are database vendor specific. The DB2 field classes
differ from the ODBC field classes, both of which differ from those
supporting native Oracle. The field classes have been refactored and
unified, allowing you to easily switch the underlying database system
without changing your Smalltalk application code. The database samples
have been redesigned to exploit this, yielding a unified, database-neutral set
of samples. A migration tool is included that will help you convert your
application from using the old database specific field classes to the new
unified field classes.

A "headless" application is one that typically runs on a server and does not
have a GUI or an operator console. Headless application support has been
added to the Version 4.0 database support so that you can package an
unattended database server application that does not require a GUI or a
console window. Concurrency has also been added to the database support.
You can now develop unattended database server applications that
simultaneously serve multiple clients.

Runtime performance of dynamic SQL applications has been improved up to
70% over the same applications running on Version 3.0. In Version 4.0,
many database access related computations have been moved to
application development time from run time. This change in Smalltalk has
yielded significant performance improvements in overall database
application run time. Run time performance improvements of 70% in
SELECT, 30% in DELETE, and 25% in UPDATE statements have been
realized by some applications.

## Web Connection

With the Web Connection feature you can use VisualAge for Smalltalk to
build applications that are accessible through the World Wide Web. You use
the composition editor to build dynamic Web pages that provide the user
interface for your application. You implement the program logic by making
connections to visual and nonvisual parts and writing Smalltalk scripts, just
as you would with any VisualAge application. Thus you can quickly add a
Web client interface to your existing VisualAge for Smalltalk applications, or
rapidly develop a new Web client from scratch that leverages your existing
relational data and transactions. To the Web client support, Version 4.0 adds
a grid visual part, ActiveX controls, and JPEG images. The server now
supports DLL or shared library based interfaces for improved performance.

The new grid visual part enables you to build HTML tables. The tables can
contain an arbitrary number of rows and columns, and cells of the table can
contain other visual parts such as text, buttons, list boxes, and forms. Using
the grid you can create clean, well-organized, visually appealing Web pages
that provide table-based user interface layouts. You can easily embed
ActiveX controls on a page, using the object tag. JPEG images are also
supported. When these Version 4.0 enhancements are taken in combination
with the existing Web client development capabilities, you can create
dynamic, visually attractive Web clients.

In Version 4.0, server application performance is greatly improved over the
CGI using DLL or shared library interfaces. These interfaces streamline the
startup of the server application because an operating system process does
not have to be created for each request made of the server, as it does with
CGI. The DLL or shared library interfaces are available in Web server
products supporting IBM's ICAPI, Netscape's NSAPI, and Microsoft's ISAPI
on any platform that is supported by both the Web server product and
VisualAge for Smalltalk. The CGI interface continues to be supported.

## Usability

Drag-and-drop or direct manipulation of objects in a GUI is one of the most
intuitive and efficient methods for interacting with a software application.
Version 4.0 adds platform drag-and-drop, which allows you to drag objects
between applications written in Smalltalk and any other drag-and-drop
enabled application or any desktop object, on any platform. You can now let
the users of your VisualAge for Smalltalk applications avail themselves of
the improved usability and efficiency of drag-and-drop. Enabling
drag-and-drop for visual parts is as simple as changing a property (setting)
on the part.

Speaking of property changes, the most obvious and pervasive usability
improvement in Version 4.0 is the new property view for parts. This view
appears whenever you want to display or change the properties or settings
for a part, typically by double-clicking on the part. Gone is the tedium of
flipping notebook pages to find and change various properties and their
values. Instead you use a scrollable two column table, which displays the
property name on the left and its value on the right. Your productivity is
improved greatly when changing several properties for a part as the table is
easy to use.

## Optional Features

Several Version 3.0 optional features have been moved into the base,
including native Oracle support, Connection for Lotus Notes, Reports, two of
the tools from the Distributed feature, and Pro Server, providing the best
value in the industry. Management of applications is improved by including
Tivoli Connection parts in the base that enable your application to interact
with the Tivoli system management products.

The two tools from the Distributed feature that are now included in the base
enable you to analyze your application's performance. The Object Visualizer
helps you analyze object activity and interaction in your application. You can
see how many instances of a class exist at any time, watch a visual
representation of message traffic between objects, identify which objects are
most and least busy, and determine which clusters of objects should be
local to each other based on the amount of message traffic between them.
The cluster view dynamically displays the objects and clusters as they form
and re-form, so you can see graphically the cohesion between your objects.
The Event Profiler is a browser that shows all of the events (method calls)
sent among selected objects. You can use it to browse each event and trace
the method call stack that led up to it. Using these tools you can better
understand the message traffic and interaction between the objects in your
application and then tune your application for peak performance.

IBM's Tivoli family of system management products helps you deploy,
monitor, update, and manage software applications in your enterprise. Tivoli
Connection, provided in the base, includes two facilities for enabling the
development of VisualAge for Smalltalk applications that are
management-ready for Tivoli. The first is a set of parts that enable you to
easily build an application that generates events and sends them to the
Tivoli/Enterprise Console. The new parts are available on the parts palette
when you install Tivoli Connection. The parts allow you to instrument your
application with events that communicate information about the status and
health of your application. For example, you can send events that identify
the startup and shutdown of tasks and the occurrence of error conditions.
These events are sent to the Tivoli/Enterprise Console, which provides
centralized monitoring and management of system information and events.

The second facility is a stand-alone program, the Tivoli Developer Kit, that
enables you to define the management characteristics of your application to
the Tivoli Management Environment. The Developer Kit assists you in
defining management information about your application by using Tivoli's
Application Management Specification. You can specify your application's
components, dependencies, distribution and installation details, and
operational tasks that are needed by the Tivoli Management Environment.

For developers of VisualAge applications in a complex, network computing
environment, Tivoli Connection provides the support for building
management-ready applications.

AppletAuthor

AppletAuthor is included with each copy of VisualAge for Smalltalk Version
4.0. AppletAuthor is a Java authoring tool that lets you create applets
without writing a line of Java code. By combining components (Java beans)
from a palette using simple mouse movements, Web site authors can bring
to life their site. Once you create your applets, you can include them in a
Web site created with any number of Web page or site creation tools,
including the Web Connection feature of VisualAge for Smalltalk.
# Chapter 2. General Information

It seems that every Smalltalk programmer looks for tips on good Smalltalk image maintenance. This chapter covers questions and answers about the image and general housekeeping.

## Cleaning Up the Image

**Question**

How do I clean up my image?

**Answer**

The never-fail approach to reducing your image size is to rebuild it. Export all of your stuff from the old image. Then get a virgin image (you may need to get one from the installation CD) and load all of your applications. It's good practice to keep a base image around that has all of the IBM and third-party applications already loaded. When you need to rebuild, simply load your applications to the base and save under another name. Be sure to keep your base image updated with any fixes.

## Creating a New Image

**Question**

How do I create a new image?

**Answer**

* With the Standard Edition of VisualAge for Smalltalk, if you have backup copies of the files sources.es, changes.log, abtdev.pom and image, then you can copy these files into your VisualAge for Smalltalk subdirectory and launch. If you do not have backup copies of these files, then it will probably be best to reinstall to get a new image. To avoid reinstalling in the future, make backup copies of these four files and keep them where you can access them. Be careful to file-out applications you would like to keep!

* If using VisualAge for Smalltalk Team Version 2, change into your VISUALAG directory on the server. From there, change into either the OS2 or WIN subdirectory, depending on whether you are using OS/2 or Windows. Then change into the client subdirectory. Within this subdirectory, there is an image file that you can copy into your client VisualAge subdirectory. You can either rename your old copy or delete it, depending on whether you want it backed up or not.

* VisualAge for Smalltalk Professional Version 3.0 no longer supports two-step centralized installation, so you must ensure that you always
have a backup copy of the virgin image (or of the image with only the features installed).

## Reducing Image Size

<figure><img src="image_6.png" /></figure>

**Question** My image has grown significantly in size, yet I have added little to it. At the same time, performance seems to degrade. Why is this happening, and can I fix this?

<figure><img src="image_7.png" /></figure>

**Answer** Close all VisualAge windows except the Transcript. Type

Smalltalk

Dependents

in your Transcript, select, and inspect it. If more than *self* and *Behavior* is in the leftmost window pane, type

Smalltalk

Object abeReinitializeDependents

in your Transcript, select, and execute it. Then save your image. The size of your image should reduce back to what it was initially.

*Object abeReinitializeDependents* frees up the resources associated with any existing dependents. When you use a part that is not subclassed from *AbtObservableObject*, and you establish connections to this part (so that other parts are notified when this part changes), you create dependents.

Here's something else to check. From the Transcript, select **Smalltalk Tools → Open Debugger**. Then, from the debugger, select **Processes → Debug Other**. Typically, there are two. If there are many more, select and terminate them.

If you try these things and your image is still quite large, try this from the Transcript (save parts and close all windows first!):

Smalltalk

EmSystemConfiguration new abtScrubImage
This reinitializes dependents, removes and terminates active processes, and reinitializes common widgets. It closes all VisualAge windows and returns the System Transcript window back to its default message.

## Preventing Image Growth

**Question**

What should I look for if my image size is increasing over time?

**Answer**

Execute *System abtScrubImage*. Does your image size shrink considerably? If so, it is time to figure out where you are hanging onto resources. There are several possibilities here. Check the following:

* Open a debugger. You can open a debugger from the Transcript by selecting **Smalltalk Tools → Open Debugger**, or from the VisualAge Organizer, **Tools → Debugger**. To see the Debugger item in the Tools pulldown menu, select **Options → Full Menus** in the Organizer. From the Debugger's pull-down menu, select **Processes → Debug other**. There should be only two processes, the `CwAsyncIOProcess` process and the Idle process. If there are others, you should attempt to figure out what objects are suspending them and holding onto them.

* With no windows but the Transcript and VisualAge Organizer open, inspect the `AbtEventDependents` classVariable of `AbtCLDTAdditions`. There should be only two entries. If there are more, then you have dependencies that are not being released. This most often occurs when sending `closeWidget` as opposed to performing the action `closeWidget`. The selector corresponding to the `closeWidget` action is `closeWidgetCommand`. Sending `closeWidget` will prevent dependencies from being freed.

## AbtScrubImage

**Question**

I've heard many times about *abtScrubImage*, that it helps me reduce my image size. What does it do, actually?

**Answer**

First of all, it clears out the dependents dictionaries. Then, it terminates all the running processes except the currently active process. It then resets the Organizer applications view, and restarts it. And, finally it does *CommonWidgets reinitialize*.
## Ghosts

**Question**

How do I get rid of unwanted ghosts (multiple instances of my parts hanging around).

**Answer**

I don't know what you are doing to cause them to hang around (do you save your view instances in a global or class variable?), but you can scrub VisualAge with

Smalltalk

System abtScrubImage.

It clears out the dependents' dictionaries and a few other things that can get messed up after lots of walkbacks. Look at `EmSystemConfiguration>>#abtPrimScrubImage: for details`. If you still have instances after running the scrub, check who is referencing them with `#allReferences`. In addition, make sure that, if you are closing your views programatically, you are sending `closeWidgetCommand` and **not** `closeWidget`.

## Image Growth after Packaging

**Tip**

I would bet that your image size has grown as the result of saving your image after doing the packaging. I've noticed that something created by the packager gets a global reference and is therefore never garbage collected. To avoid this, I would advise saving your image immediately before packaging, then package and exit without saving the image.

## Keeping Multiple Versions on the Same System

**Question**

Can I keep both VisualAge for Smalltalk 2.0 and 3.0 on the same machine?

**Answer**

Yes, they can coexist on the same machine. You did not say whether you were on OS/2 or Windows. However, since Version 2 and 3 do not share DLLs of the same names, keeping both is fairly easy. Just put the ".;" (period and semicolon) in your path (or libpath) as the first thing so that files are picked up from your current subdirectory. This may mean consolidating some of the files in the same directory. Also watch the `abtpath`, it can
reference several subdirectories as well. Libraries can be kept on the same machine, just make sure you are pointing the clients to the right one.

## Replacing the Default Icon

**Question** How do I replace the default VisualAge icon with my own?

**Answer** If you do not want a splash screen everywhere `abt.exe` is mentioned, replace it with `nodialog.exe`. Abt.exe can be found in your VISUALAGE subdirectory while nodialog.exe can be found in your VISUALAGE\DIALOG subdirectory. Copy the abt.rc, abtrc.h, and the abt.exe (or nodialog.exe) files to your run-time application directory from the dialog directory. Do an edit of your abt.rc and change the following line

```
POINTER ID ICONRESOURCE visAge.ico
to
POINTER ID ICONRESOURCE iconName.ico
```

* If you *do not* want a splash screen, you can erase the rest of the abt.rc file. (The rest of it pertains to the splash screen.)

* If you *do* want the VisualAge splash screen, leave the rest as is.

Once you have saved the changes to your abt.rc, compile your resource script file and merge this into your abt.exe (or nodialog.exe) with the following command:

```
rc abt.rc abt.exe
or
rc abt.rc nodialog.exe
```

You can find a resource compiler in the OS/2 toolkit. Once this is done, you can run your application against your image.

## Escaping an Infinite Loop

**Question** How do I find a way out of an infinite loop? Does VisualAge have something like CTRL-C?
**Answer**

VisualAge allows you to hit Alt+SysReq. Hold this until you hear a low beep. A debugger will appear, signaling that the process has been terminated or interrupted, with the error string *"User Break."*

## File-In and File-Out

**Question**

How do I file-in and file-out code programmatically?

**Answer**

You can write Smalltalk scripts that will file-out code for you. Doing this, you can make the scripts as sophisticated as you want. Use class CfsWriteFileStream to create your file. Examine the class EmFileOutInterface. This class has several methods which you will find useful, such as *fileOutOn:*, *fileOutSourceOn:from:*, and so on. Do not forget to generate archival code when you save the part.

## Separate Threads

**Question**

Can I run VisualAge for Smalltalk from separate operating system threads?

**Answer**

True multithreading has been tested in AIX, but no specific release plans are available. OS/2 and Windows releases do not support true multithreading. OS/2 and Win95/NT may support multithreading in a future release, but I have been unable to find out specifics so far. The only ways to do parallel processing today are:

* Launch multiple copies of VisualAge for Smalltalk on the same or different machines

* Use the VisualAge Distributed feature along with launching multiple copies.

Distributed would be much easier to coordinate and is quite elegant, but does require a larger image and adds complexities such as TCP/IP setup if you don't already have it.

## Capturing Stack Information

**Question**

How can I capture the stack information when I have a walkback?
**Answer**

In the debugger window, use the *Write Stack Trace Text To File* option from the Stack pull-down. This writes the information to a file of your choice.

## Renaming a Class

**Question**

How do I rename a class ?

**Answer**

The *VisualAge for Smalltalk User's Guide* discusses this a little bit. Filing out and filing in classes to rename them works fine.

Another way to rename classes is this:

* Change to the Script Editor for the class.

* Change the class name in the class definition in the bottom window of the Script Editor to the desired name.

* Save the change. A new class with the desired name will be added to the application browser. It is an empty class for now.

* Select all methods showing in your method window, choose **Move Methods → To a new Class** from the **Methods** pull-down menu. Type in the new class name when prompted.

* Be sure to move all class and instance methods—both public and private—over to the new class.

* Test your new class to make sure it behaves as the other one did.

* When you are positive that your new class works, you may delete the old one if it is not needed anymore.

## Environment Variable

**Question**

How do I get the value of an environment variable defined in `config.sys`?

**Answer**

There is a private method called `abtScanEnv` in `EsString` that should do what you desire. To use it, try executing the following code:

```
Smalltalk
PATH' abtScanEnv
```
## Registered Connection

**Question**

How do I remove a registered event-to-script connection?

**Answer**

Try sending *destroyPart* to the connection you dynamically created.

## Loading Different Image

**Question**

How do I specify a different image from a command line?

**Answer**

You can use the -i parameter, for example:

```
abt.exe -id:\va30\image
```

## Deferred Update Part

**Question**

How do I use the Deferred Update Part?

**Answer**

**Opinion One**

Deferred update parts exist only to buffer editing of control widget values. Although there is sufficient demand for things like buffering, the practical use of the deferred update part is rather limited. The limitations are twofold.

First, the part assumes that your objects are just objects that contain data attributes. That is, assume you have the object `RightAngleTriangle` with attributes `a`, `b`, and `c`, where `c` is calculated based on `a` and `b`. Using a deferred update part, you will never see attribute `c` calculated until the user hits the apply button, whereas without the deferred update part, the attribute `c` will be updated as either `a` or `b` changes.

Second, if you allow your users to open different views on the same object, they may have made some changes on a view and not applied them. When they then open a second view on this object, it comes up without the changes they have just made on the first view, and things look inconsistent.

In my opinion, you have a couple of strategies depending on your application, but the best is to have the view ask for a copy of the object (this may even be a specific copy for this view). Have the view be a view of the real objects and then you get all the behavior right away that the object should exhibit. If the user cancels, it is the view's responsibility to set the object back into its original state.
## Opinion Two

To the naked eye, the deferred update parts can be of little use once your objects consist of a bit more than primitive attributes. But, believe it or not, we found ways around the problem. You just have to look closely at the AbtDeferredUpdatedManager and what it does. Your domain object can implement two different class methods which the Manager sends to the class during the creation of the deferred update part instance. These methods respond with a class name which the Manager uses to instantiate the deferred part, and there you could implement some of the behavior such as changing attribute b when a attribute changes. The object you will be dealing with at that time is the update operation whose target is your object which is undergoing a change. Hence, you can ask your object to recalculate some other value based on the attribute changed.

My recommendation would be to attempt to use deferred update parts, and enhance them when needed. The benefit is that there is so much infrastructure there. The Command or the Momento pattern is nice, but not as easy to implement from scratch. Also, if one uses VisualAge correctly—that is, having a form work with a single object that includes nested forms which in turn edit other complex attributes of your object—deferred update parts work great.

As for seeing noncommitted object changes when a different editor is opened on the object currently being edited, I say it is up to your personal preference. One must have a pretty smart application-based transaction framework to support such behavior. What about different views editing the same object? Getting the transient state of an object is wonderful, as long as you are willing to pay the price for the added complexity.

## Renaming a Visual Part

**Question**

How do I rename a visual part?

**Answer**

The current implementation of VisualAge for Smalltalk provides no mechanism for renaming a part once it has been created. The copy facility is flawed, in that certain connections retain a reference to the previous class name.

In Smalltalk, you can rename a class by filing it out, exchanging the names in an editor, and filing it back in. A little more work must be done in VisualAge (even Smalltalk classes with a public interface will not work using the file-out, file-in technique).
**Solution 1**

Open the Composition Editor for your class and select **Generate Archival Code** from the file menu. File out your class and in an editor find and replace occurrences of the old class name with the new class name. Save the file and then file it into your image.

An unfortunate side effect of this technique is that the archival code will stay connected to your class forever. Whenever you save the part in the Composition Editor, you will be asked if you want to regenerate archival code.

**Solution 2**

Create a new visual part. In the new part dialog, change the superclass to the name of your existing class.

When the Composition Editor editor opens, make a small change (move some widget a bit to enable the **Save** menu item) and save the part. This generates the magic *abtBuildInternals* method and all the invisible stuff needed. Change to the Script Editor. In the class definition, change the superclass from the name of your old part to *AbtAppBldrView* and save the definition.

Just to be safe, whenever you change the superclass of a visual part, close the editor and reopen it.

## Hover Help for Buttons

**Question**

How do I customize hover help for my push buttons?

**Answer**

Push buttons with a graphical label don't contain textual information. This textual information is what is displayed by hover help and, in the absence of textual information, it displays the part name. The part name, unfortunately, cannot contain special characters, such as accented characters for French language.

When defining the push button, specify both the label text and the graphics descriptor. In the settings editor for the push button, first define the label type as text and enter the text you want to see for hover help. then, define the label type as graphical and specify the bitmap you want to display.
## Customizing Connection Menu

**Question**

Can I customize the connection pop-up menu for a visual part?

**Answer**

Yes. You must specify which options should be shown on the context menu and which can be accessed using more. The `preferredConnectionFeatures` class method for the specific part that needs this menu adjusted must be modified as follows: (using a, b, c, d as the list of connections)

Smalltalk

`preferredConnectionFeatures`

`^#(a,b,c,d)` "this shows a,b,c,d and More on the menu"

## Live Updating of Images

**Question**

I am creating a settings page that features a form in the center that will be used to display a GIF file. Right above the form is a file picker that returns the path and file name of the graphic the user picked. (It is basically a recreation of the background image selector on the form part in Web Connection). The system fails to update the graphic properly however. I have torn off the backgroundDescriptor from the form and tied its module name attribute to the output of the file picker. When I open the page for the first time the image is correct, (whatever the user selected last time) but I am unable to get the image to update live. Any ideas? How can I get the `updateOperation` to fire before the user actually clicks the OK button?

I tried to examine the logic, but I am stymied by what look like incomplete connection diagrams in the settings view parts. The edges are just floating with no apparent sources or targets. What can be done to get around this?

**Answer**

You cannot see the form in the settings page view because the bottom and right edge attachment offsets are zero. To fix this, do the following:

Edit the part in question, for example, `AbtIntegerDatatypeSettingsView`. Normally you would select the form and open its settings page to change the offsets. However, as you cannot see the form, you cannot select it, forcing you to change the offsets manually.

First, open an inspector on the `partBuilder` as follows. Press Alt-Shift-Mouse button 1 anywhere on the Composition Editor. Then inspect the `partBuilder`,
then the *subPartBuilders*, then the entry named *Form1* in the *AbtOrderedDictionary*. This should lead to an *AbtInternalSubpartBuilder*. Inspect the attribute settings and then the *framingSpec* entry. Open inspectors on the *bottomEdge* and *rightEdge*. The *AbtEdgeConstraint* should have an offset of 0. Change it to something like 100.

After closing all the inspectors save the part. This requires tricking VisualAge into thinking that you have changed something, so you will need to do something innocent like move the center of a connection slightly or move the *updateOperation* variable a pixel or two. After saving, exiting, and reentering the part, the form should now be visible allowing you to work with it.

The problem with the stale image may be related to the fact that the *updateOperation* variable is just a deferred part. Deferred parts are not instances of the class they are deferring and are just a buffer for public interface attribute values. Thus, any behavior you may have imposed on your part to respond to a method such as image will never affect your object. The solution is to add your own variable and code as though the settings page were a normal Composition Editor.

## Passing Parameters Between Windows

**Tip**

Your VisualAge design should use the dependency mechanism. For example, you could have an attribute-to-attribute connection from a nonvisual (model) object attribute, using its public interface, to the list in the first GUI window. The second window could have a variable promoted to its public interface that receives the model object from the first window. It is this object that is receiving the edits in the second window. When the changes occur (as when an OK button is clicked), the model object state changes and its dependents are notified (including those in the first window). The refresh will then occur after the changes to the model object state.

## Generating Archival Code

**Question**

What application should you specify when generating archival code ?
**Answer**

Create a new application, such as `MyArchivalApplication`, and generate archival code to it. You don't want to generate archival code to the application that you plan to package and distribute to your customers (it will be larger than it needs to be). You can always delete the generated methods if necessary.

To create your archival application, do the following:

1. From an application manager, create the archival application. Change its prerequisites to include `AbtBuildViewsApp`, plus the application you are generating code for.

2. Open the part in the Composition Editor or Public Interface Editor.

3. Select **Generate archival code** from the **File** pull-down menu.

4. Select your archive application's name as the target for the generated code.

**Note:** We recommend a one-to-one correspondence (an archival application for each one of your applications).

**Remember**

If you want to share code, you will have to file out *both* applications— the original and the archival.

## Deleting Parts with Instances

**Question**

How do I delete a class or part that still has instances?

**Answer**

To remove instances of a class, execute:

**Smalltalk**

`<MyClass> allInstances do: [ :anInstance | anInstance become: nil ].`

Although this method of removing instances does work, and all of us have resorted to it at some time or another, we should warn you that it is dangerous. You will usually get away with this, but it can also cause walkbacks and even system crashes or meltdowns. Use it at your own risk.
## Change Table Format

**Question**

How can I change the dashes on a table to a line?

**Answer**

You can use the following code:

```
Smalltalk
  setGridLineStyleAndColor
    "Set the line style and color appropriate for the grid"

  self foreground: self clrGrid.
  lineStyle == AbtTWLineStyleGrid
    ifTrue: [^self]. "already done"

  self gc setLineAttributes: 1 "line width"
    lineStyle: (self useDashedLines
                ifTrue: [ LineOnOffDash ]
                ifFalse: [ LineSolid ])
    capStyle: CapButt
    joinStyle: JoinMiter.
  lineStyle := AbtTWLineStyleGrid.
```

The table defaults to having solid lines. To change the table to have dashed lines, `true` needs to be sent to the `useDashedLines` method. This can be accomplished by connecting the `aboutToOpenWidget` event of the table to a script connection with similar code:

```
Smalltalk
  dashedLines
    (self subpartNamed: 'Table') useDashedLines: true.
```

## Error Messages

**Question**

How do I find information on fatal errors?
**Answer**

From the System Transcript, display the following code:

Smalltalk

SystemPrimitiveErrors keyAtValue: errorNumber

Example: SystemPrimitiveErrors keyAtValue: 33

If you highlight this code and choose Display, the following is returned:
'PrimErrImageFileOpenError'.

## Removing Archival Code

**Question**

How do I remove archival code from my base application if I generated it here instead of to an archival application?

**Answer**

Generating archival code to a new application will not move methods to the new application if they have previously been generated to a different application. This is important, especially when packaging your application to an image. You should not package archival code to a run-time image.

You may either delete the methods below from all classes in your application, or move them to the new archival application. If you delete them, be sure to generate archival code to your new archival application after deletion.

To move the archival methods, select the **Move methods** choice from the **Classes** pull-down menu of an Application Browser or Classes Browser. When prompted where to move the method, type the name of the target application and class. The following methods are archival:

* Public Class Method

- `calculateInterfaceSpec`

- `calculatePartBuilder`

* Private Class Methods

- `add...PartBuilder:`

- `codeGenerationParameters:`

- `connect...`

- `converter...PartBuilder:`

- `test`
## Apply Push Button

**Question**

There are unlisted actions for both an okay and cancel push button on a part's custom settings view, but how do you handle an apply push button?

**Answer**

If you are creating a VisualAge part, and want the custom settings view to have an apply push button, add an event-to-script connection from the push button * clicked event to the following script:

Smalltalk

apply

| op newOp |

op := ((self subpartNamed: 'updateOperation') value) execute.

newOp := op target customSettingsOperation

stackHolder: op stackHolder;

defaultValuesSource: op defaultValuesSource;

target: op target.

(self subpartNamed: 'updateOperation') value: newOp.

## Inspector

**Question**

How can I quickly open an inspector on a part in the Composition Editor?

**Answer**

Do Alt-Shift-Click1 on a part in the Composition Editor.

## Multimedia

**Question**

Where do I find examples of using multimedia in VisualAge?

**Answer**

There are multimedia applications on the VisualAge CD. Also, when you load the Multimedia and Multimedia Samples features, you will get an application named AbtMultimediaSamplesApp in your Organizer window. In this application, you will find multiple sample parts that you can run. For example, you can run MtTravelAgencyMainView. There are also parts for browsing videos (look for .AVI files in the VISUALAG\SAMPLES directory), and browsing sounds (look for .WAV files in the same SAMPLES directory).
## Default Memory

**Question** Is there a way to change how much memory gets allocated by VisualAge? It appears that 2 MB is the default.

**Answer** The following will work for Version 2 (see page 38/39 of the Smalltalk User's Guide for memory options in Version 3). When you call the packaged image *abt.exe -iMyImage*, add the following parameters:

- **-mi500000** This gives the memory an increment of 0.5 MB at a time, and is what was defaulting to 2 MB.

- **-mo5500000** This gives the initial memory allocation to the image. As a rough guide, take the previous *mi* figure away from the initial size of the image, for example, 5.5 MB.

The full call would then be: *abt.exe -iMyImage -mo5500000 -mi500000*

## Storing Settings

**Question** I want to be able to store current settings into a file just prior to closing an application. The goal is so that next time the same VisualAge application is opened, it will provide the user with the same settings as the last access by first reading the file with the settings. How would I do this?

**Answer** One way to do this is by using the objectDumper and objectLoader. Create a class called *settings* which contains all the settings attributes you will store persistent in the file. To save the settings in the file, use:

Smalltalk

ObjectDumper new
load: <settingsInstance> intoFile: <aFile>

To load the settings from the file use:

Smalltalk

settings := ObjectLoader new loadFromFile: <aFile>

Connect the *save* action with *aboutToCloseWidget*, the *load* action with *aboutToOpenWidget*. The objectDumper unloads the complete instance into
the file in a noneditable format. For redistributing, you also need the ABTSWP30.DLL.

Extending Classes

**Question** Why do I get a prompter asking me to create a scratch edition of the base VisualAge application when I want to extend an existing method?

**Answer** Extensions can only add behavior to an existing class (for instance, adding new methods to add functionality). You cannot alter existing methods as an extension. The only way to alter existing behavior (alter existing methods) is to subclass and alter the methods you want to do something different in your subclass.

Running VisualAge from External SCSI Drive

**Question** How can I copy the entire VisualAge installation to an external SCSI drive and run it from there?

**Answer** Just copy the whole VISUALAG directory structure to the new drive and use a command file to setup VisualAge to run from a directory (so you don't have to mess with CONFIG.SYS), for example

```
@echo off
SET BEGINLIBPATH=x:\VISUALAG\DLL
PATH=x:\VISUALAG;%PATH%
SET HELP=x:\VISUALAG\HELP;%HELP%
SET ABTPATH=x:\VISUALAG\ABT
```

In addition, you'll need to update ABT.CNF and NLS.CNF (I make the path references relative to the current directory).

Damaged Classes

**Question** How do I get rid of damaged classes?

**Answer** Version and release your classes, applications, and configuration maps. Then, get a fresh image and reload your stuff.
Extending Classes

Question

How do I extend classes in the Organizer?

Answer

You can extend classes in the Organizer in one of two ways. Both ways require you to be using full menus. To get full menus, click **Full Menus** from the **Options** pull-down menu.

* Option 1:

Select the application you want to extend the class into. From the **Parts** menu, click on **New → Extension** and enter the name of the class you want to extend.

* Option 2:

Select the class (part) you want to extend. From the **Parts** menu, click on **Extend** and enter the name of the application you want to extend the class into.

Modifying the System Menu

Question

I would like to modify the System Menu, the menu you get when you click on the VisualAge icon at the upper left corner of a window, for an application. The problem I have is how to connect an appropriate action to the new menu items.

Answer

Here's an example that shows how you can change the system menu. Make sure to add `PlatformWidgetsConstants` and the `CwConstants` pool dictionary to your class definition first. Note that the second parameter of `hook:with:` is the method that will run when the menu item is selected, and it must take one parameter (even though you do nothing with it). The example also highlights the use of an accelerator key.
```Smalltalk
| menuItem key |
menuItem := (self subpartNamed: 'Window1') yourself
primaryWidget
osWidget
systemMenu
createMenuItem.
menuItem label: 'my item';
owner: self;
accelText: 'Alt+F2';
hook: OSxSelect with: #myAction:;
yourself.
key := VkToKeySym
keyAtValue: XKF2
ifAbsent: [nil].
menuItem
alt: true
shift: false
control: false
virtual: true
key: key.
```

## Organizer Views

**Tip**

You can switch to different views in the Organizer. For example, it can look like this:

<figure><img src="image_8.png" /></figure>
File in Use

Question

What might cause a "File In Use" error when trying to read (only) a file in
VisualAge?

Answer

Normally, this is caused by an access rights problem outside the VisualAge
domain. Make sure the server access allows concurrent read-only rights to
clients. Check this out by making sure you can see the files and file
contents from any program on the client system. In VisualAge, make sure
the code uses the ORDONLY access mode. Do not use any of the following:
OWRONLY, ORDWR, OCREAT, OAPPEND, OTRUNC, or OEXCL.

OS/2 Shutdown

Question

Why doesn't OS/2 shut down until all running applications have terminated?

Answer

In general, OS/2 won't shut down until all running applications have
terminated to prevent the user from possibly losing data. This is an OS/2
behavior for any application, and is not unique to VisualAge.

BRW Format Generator

Question

Is there a generator that produces a .BRW format for help?

Answer

Use an ASCII editor—or Smalltalk Workspace—to develop a .BRW file. We gave the source files the extension .BRW for browser to distinguish the files from other types of files). The BROWSER.BRW file describes the tags used to specify fonts, lay out a page, display a graphic, and so on. To see how we used the tags, open an ASCII editor on BROWSER.BRW or VAXAMPLS.BRW. To see the formatted text (or view your own file), test AbtHelpBrowserView and load the file. AbtExamplesHelpBrowserSubApp contains the Smalltalk code that parses the tags. We'll probably change our code so it reads HTML tags, and you might consider doing something similar for your own browser.
## Loaded Method

**Question**

Is an application's `loaded` method invoked when it is run as an executable? Do you need to do anything special if you want to ensure that it will be run?

**Answer**

The `loaded` method is a class method called only when the class is loaded into the image. Its usual purpose is to complete the task of hooking the class into the environment and setting up class variables and such. It is not called at execution time.

## Missing Character Set

**Question**

What should I do if I get a "missing characterSet translation table, ibm-NNN" error?

**Answer**

You need to customize the `ABTRULES.NLS` file to include the 862 code page. Do this by copying and pasting all 862 code page table definitions from `ABTRULES.All` file to `ABTRULES.NLS`. This is a null table that doesn't really do anything. Eventually, you will need a table with the proper values if you really want code page translation to work for your system.

## Event Triggering

**Question**

I created a Smalltalk class and defined in it an event in its public interface. In this class, I have only one method that signals this event under a certain condition. However, when running the code, this event is being fired and I am pretty sure I didn't fire it. Tracing the code in the debugger reveals that `VisualAge` has a collection of `Abt***Spec` and it is firing the event from this collection. Is it the design of `VisualAge` or am I not defining the event correctly? I do not want the event to be triggered unless I use the `signalEvent`: method.

**Answer**

Since this is a Smalltalk class (that is, a subcass of `Object` as opposed to `AbtObservableObject` or `AbtPart`), you may want to look at the method `featuresAffectedByAction:`. In order to handle classes that normally don't signal events in all cases, this method defaults to signal all events for any action. To change this behavior, override the method to indicate exactly which attributes should be signaled for a given action.
## Part not Visible

**Question**

What does it mean for a part to not be visible from an application?

**Answer**

If you get a message about some class not being visible, it means that you are either trying to extend or subclass it in an application that does not prerequisite the application containing that class.

## Removed Class

**Question**

I got the following debug message from a script: "Removed Class:ClassName does not understand method." What did I do wrong and how can I solve this problem?

**Answer**

This problem in VisualAge is caused by deleting a class without removing all method references to it. You should be able to do "Browse References..." and find all the references to the class that no longer exists (if you deleted, then recreated the class, simply recompile the methods referencing it).

If this does not work for you and if you are in the Team environment, it is probably best to get a new image and reload your application. We have seen this before, and that is the fastest and best way to get rid of it.

## Synchronizing Attributes

**Question**

I have two classes, A and B, and I make an attribute-to-attribute connection of one attribute in class A to another attribute in class B.

Suppose I have methods in both classes that reference these two attributes. When the attribute of A or B changes, do these methods get executed simply because they reference (by using the `getSelector`) these two attributes?

**Answer**

With an attribute-to-attribute connection, class A will signal in a method that its attribute has changed using the `changeSymbol` defined for the attribute:

Smalltalk

`(self signalEvent: #attributeOfAChanged)`
This signaling of the event will cause the *AbtAttributeToAttributeConnection* to get the value of class A's attribute (using the *getSelector* defined for it) and set the value in the instance of class B (using the *setSelector* defined for class B's attribute).

## Keeping the Packaged Image Small

**Tip**

Image size is a fundamental problem when it comes to running on restricted resources. Keep in mind that VisualAge uses substantial amounts of DLL code— most probably more than the image size.

Anyway the packager will do its best to get rid of any superfluous classes and methods, but you can do a few things that might be helpful:

* Have a small image to run packaging from, containing only the absolute minimum classes and methods (no other applications, no samples, no unnecessary infrastructural support).

* Do not use "standard" method names, as the packager seems to determine class and method exclusion by name, disregarding the class context for method names. For example, calling a packaged and needed method *doSomething* will package every method called *doSomething* that is found in your entire development image, which will include every class.

* Get the prerequisites right; having unnecessary or wrong prerequisites can be fatal, possibly resulting in an 8 MB package instead of the normal 2 MB.

## Including Classes in a Package

**Question**

We create a complex object outside of our application and dump the object to disk using the *ObjectDumper* class. This dumped object contains a collection of *Catalog* objects, and each *Catalog* object contains a collection of *Part* objects and collections of *Vehicle* objects. After dumping this object to disk, the object remains static, so our application can use it.

I discovered that when we packaged our application, objects such as *Catalog*, *Part* and *Vehicle* are not included in the package. To get around this, I am creating an instance of these classes, and finally letting them be collected as garbage. Not doing this results in an error after using the *ObjectLoader*, saying the "Class definition was missing."
To me this looks like a dirty solution, is there a better way to force classes to be included in the package?

**Answer** Implementing the method *packagerIncludeClasses* (on your applications) to answer a collection of classes that you want to force the packager to package will solve this problem. Browse implementors of *packagerIncludeClasses* for more details.

## Packaging for AIX from OS/2

**Question** We are using VisualAge for Smalltalk for OS/2 V3.0. We need to distribute both OS/2 and AIX clients of the application. Can we package the AIX version of the client from our OS/2 development environment? Or do we need to export from OS/2 and then import into VisualAge for AIX, and then package the AIX version from VisualAge for AIX.

**Answer** You must package in the target environment. By the way, to access a single manager on an AIX machine, you can use TCP/IP and the EMSRV support for all environments. If you do that, no import/export is necessary, just a load and package.

## Loading Application in a Run-time Image

**Question** Is it possible to load .APP files into a runtime image, not a stock image, if the ApplicationLoader and Swapper are included in it? It seems that the reduced runtime image (AbtEpStandardRuntimeSpecification) that comes with VisualAge includes both.

**Answer** The reduced runtime image does not have the ApplicationLoader and Swapper applications that you will need to bind .APP files to it. The stock image does.

Why did it seem that the reduced run-time image had these applications? It is likely that you reviewed the applications in the Packaged Image Browser associated with the reduced run-time image specification. If this is true, you should note that these applications were not *base* applications, and as such, may not be completely added to the run-time image.
## Packaging an Application for Windows

**Question**

Is it possible to package an application that should run under Windows with VisualAge under OS/2?

**Answer**

You cannot run the OS/2-packaged application under Windows regardless of whether that's native Windows or a Win-OS/2 session. In order to package your application for execution on a Windows platform, you must have a copy of VisualAge for Windows from which to create the run-time.

## Icons and DLLs

**Tip**

The VisualAge run-time does not use ABTICONS.DLL for any of its resources. In fact, the edittime doesn't either. Only the SampleParts and VisualAge Examples Help use the resources contained in this DLL. The DLL is provided simply to provide some common images for you to use in your application. Now, when shipping your packaged application you have to include the .BMP files and not the ABTICONS.DLL.

## Packaging a Workspace

**Question**

Is it possible to package an EtWorkspace with an application?

**Answer**

You cannot package an EtWorkspace because it is part of the edit-time development environment (see the \visualag\install\visualag api file for a list of redistributable classes and methods); this is partly because those workspaces have menu options for evaluating code using the compiler, which is definitely not packageable. If you are looking to simply reproduce an editor window, just drop a multiline edit part in a window. .

## Image Reduction

**Question**

How do I strip down my development image?

**Answer**

The VisualAge for Smalltalk packager is functionally equivalent to the third party and OEM strippers that are available for other Smalltalks. They all analyze your image, and remove unneeded classes and methods. The major difference is that some of the better third party strippers can dynamically analyze the running system, where the VisualAge packager does only a
static analysis. Even so, the packager does a pretty good job of getting the image size down.

## Ensuring that Needed Classes are Packaged

**Question** How can I make sure that all classes and methods I need for an application are packaged, given that the classes are spread over various applications? Would it be sufficient to include two private methods: `packagerInclude Selectors` and `packagerIncludeClassName`s?

**Answer** The packager excludes all applications that are not part of the prerequisite list, even if you implement one of the methods (`packagerIncludeSelectors`, `packagerIncludeClassName`s). By using one of these methods, you are telling the packager to include the selector, class, and so on from the application no matter whether the packager thinks it should be included or not. However, you still need to tell the packager what application to draw from.

## Class Modifications and Packaging

**Question** Suppose you extend a class, such that you need to create a new edition of the application to which that class belongs, will there be anything special you need to do when you package your application?

**Answer** No, if you have your changes loaded in the image when you package, then the changes will be picked up by the packager. For what it is worth, if you extend a class you only add methods and do not directly modify the existing code so you should not have to modify the owning application. You can create a new extention of that class in your own application by selecting **New → Extension** from the **Parts** menu in the **Organizer**.

## Merging Application Files into Run-time Image

**Question** The VisualAge 3.0 on-line manuals state that it is possible to merge APP files into run-time images, even if the image is not the stock image, but a reduced one. How do I enable the reduced image to load the APP files?
**Answer**

A stock image is no longer shipped since Version 3. You can either generate it using the Packaged Images Browser and appropriate packaging specification (AbtEaRuntimeSpecification) and use the ABTAPP.CNF approach as with Version 2, or you must add the appropriate logic within your own application which supports this type of behavior (that is, uses ApplicationLoader to bind .APP files under certain conditions). If you add the logic yourself, it is your responsibility to ensure that the reduced run-time image contains all the necessary methods to support the methods required by your application modules (.APP files).

## Missing Icons

**Question**

Why do I have missing icons after packaging the application?

**Answer**

VisualAge caches the window handles of the icons used in the message prompter. The cache is cleared when the image is saved. If you package your application before saving your image, the current window handles of the icons get packaged into the run-time image. When you run the packaged image, these window handles are no longer valid and, as a result, you get missing icons or a trap. A quick fix to the problem is to save your image and then package your application (don't test it after saving the image). A more appropriate solution is to implement a private class method in AbtPromptersAppWithUI called `packagingRulesFor:` which will clear the cache prior to packaging. Underneath you find the code for this method:

Smalltalk

```
packagingRulesFor: aPackagedImage
"Define rules for the given packaged image."
aPackagedImage initializeToNilClassVariable: 'AbtIconPixmaps'
inClass: AbtExtendedMessagePrompter.
```

## Required .CAT Files

**Question**

How do I find out what .CAT files are required for my run-time image?

**Answer**

There's a little script to scan the messages during packaging and show you catalogs your code referenced. That's the minimum set of *.cat files you need to distribute. By the way, most nonerror items are bound to the image using the CAT entries from the development environment (English). These files are needed if the locale changes because it is on a non-US machine or a run-time error occurs. See EsPoolDictionary>>indexedMsg: for details.
```
| stream tokens file |

file := (CwFileSelectionPrompter new)
    title: 'Packaging Messages'; prompt.
(file isNil) ifTrue: [ ^nil ].
stream := CfsReadFilmStream
    open: file.
[stream atEnd] whileFalse: [
    tokens := stream nextLine subStrings.
    ((tokens size > 0) and: [((tokens at: 1)
        indexOfSubCollection: 'NlsCat' startingAt: 1) > 0]) ifTrue: [
        Transcript cr; show: 'References messages in: ',
        ((Smalltalk at: (tokens at: 1) asGlobalKey)
        at: 'CATALOGNAME')]].
stream close.
```

## Packaging Pool Dictionaries

**Question**

How can I tell the packager not to change my pool dictionaries when
creating a run-time image?

**Answer**

To prevent the packager from changing your pool dictionaries, add the
following class method to your class application:

```
packagingRulesFor: aPackagedImage
"Pack the NLS pool"

aPackagedImage includeGlobal: #MyClassPool.
```

**Question**

I'm having difficulty getting the simple packaging process to include all keys and values of two application specific pool dictionaries that are used in one of the classes in my application. The packager seems to be excluding all keys/values in these pools unless I code a rather ugly method which explicitly refers to all keys/values in these two pools. What do I do?
**Answer**

Are you referring to your pool dictionary entries by name (for example, are you using #at: to look them up)? If you are, you'll need to inform the packager not to reduce the pool. By default, the packager will remove any entries that are not directly referenced. To prevent this, add a packaging rules class method to your application class like the one below. The packager will not do pool reduction if a rule has been explicitly set.

Smalltalk

aPackagedImage includeGlobal: #MyPoolDictionary.

## Application Prerequisites

**Tip**

Of the problems we have encountered with packaging, 90% have been problems with prerequisites. With the team version of VisualAge, it is possible to partition your deliverable across multiple applications.

Each application has certain requirements that must be met for an image to make sense. For example, if an application introduces a new class, the superclass must be available, either in the same application or in a prerequisite application. It can be said that one application needs others to be in memory to work.

It is also worth mentioning that when an application is listed as a prerequisite for another, no mention of the appropriate version is made. Before packaging, ensure that the appropriate versions of all applications have been loaded. The packager uses the prerequisites when building a runtime image.

## Missing Classes in the Run-time Image

**Tip**

The packager starts with the collection of all classes in the application and all prerequisite applications. From that starting point, it extracts all classes and methods which are not explicitly referenced in code.

If you use any metaclass tricks, like asking a class for its subclasses, those subclasses would not be explicitly referenced, and would therefore be excluded.

The packager can be coerced into including certain classes by adding a new class method to the class with the same name as your application.
Smalltalk

packagerIncludeClassNames: aString

"Answers a collection containing the names of the
classes which must be included when packaging."

#(MyFirstClass MySecondClass)

The class with the same name as your application can hold behavior that is specific to your application (in its class methods). This class is a subclass of the class called Application, which is itself a subclass of SubApplication. In the class SubApplication, you find similar methods that force specific methods or classes to be included, or excluded when packaging.

## Missing Method in Package

**Question**

I try to package a reduced run-time image. After the packaging process has finished it seems that the package is missing the method `convertToCodePage:` of `EsString` even though it is referenced several times. Is there a way to force a method to be packaged?

**Answer**

You can force the method to be included by the packager by adding a class method called `includedMethods` to the class with the same name as your application. This method returns an array of methods to be included in the packaged image. An example of this method is listed below:

Smalltalk

includedMethods

"Return a list of methods to be included in the packaged image"

^Array with: ToDoListView >> #test
## Run-time Image Packaging Problem

**Tip**

Messages about OS2.INI not being able to be saved have usually been the result of insufficient disk space (which would also lead to slow execution since the swapper cannot grow), so check that first. Another cause of slow execution is not having ABTbytes.DLL in the LIBPATH (or PATH under Windows).

As for the run-time image itself, more than 5 MB is way too large (unless you have a truly huge application). This is typically caused by having the wrong prerequisites for your application. A common example is when your application requires AbtBuildViewsApp (part of the application builder development environment). This usually happens if you generate archival code into your application rather than having a separate archival application (which is strongly recommended). If this is the case, you should create the separate archival application, move all archival code into that application, and update your prerequisites so that they do not include any of the development-time applications.

To determine which methods are archival, just regenerate again and note the messages in the Transcript. An API document is shipped in softcopy form with the product, which details what applications are considered part of the runtime and thus redistributable.

## Generating Getters and Setters

**Tip**

You can use the TrailBlazer browser to generate getters and setters for an application. Select a class, navigate to instance variables (or class variables), select a variable, pop up the menu, and select **Generate Accessors**.

## High Performance Trace Logging

**Tip**

For complex systems, often trace logging must be built in. Unfortunately, you can incur a high performance penalty if you do not build in trace logging properly. One way of avoiding this penalty is to send blocks rather than strings to your logging subsystem. For example:
Smalltalk

self traceShow: "I am entering method #blah for ", self printString,
" with: ", myArg printString.

Using a string can be expensive because you have to build the entire string even if tracing is not active. Therefore use a block:

Smalltalk

self traceShowBlock: ["I am entering method #blah for ", self printString,
" with: ", myArg printString.].

Then in the trace block code, do this:

Smalltalk

traceShowBlock: aBlock

self isTracing ifTrue: [
  traceLog cr ^ show: aBlock value ].

In this way, you can leave your trace code in the system without paying a steep performance penalty. The string is only built when tracing is active.

Closing a DLL from Smalltalk

Tip

If you are developing a Smalltalk application that calls C or COBOL functions in a DLL, when you initially call the DLL function, Smalltalk opens the DLL and leaves it open. If you need to change the DLL code, the DLL must be closed. To avoid having to shut down Smalltalk, execute the following:

Smalltalk

(PlatformLibrary logicalName: 'myDIName') close"
## Unloading When Instances Exist

**Tip**

To unload an application when instances exist, execute the following:

**Smalltalk**

```
MyClass basicAllInstances do: [ :each |
    each become: Object new ].
```

Using *basicAllInstances* is faster than using *allInstances* because a garbage collection is not performed.

## Testing When Looping Walkbacks Occur

**Tip**

When testing while a looping walkback occurs (such as in the midst of a losingFocus callback), use the following:

**Smalltalk**

```
GloballsTesting ifTrue: [
    GloballsTesting := false.
    self halt. ]
```

Then execute this before each test:

**Smalltalk**

```
Smalltalk at: #GloballsTesting put: true.
```

A walkback will occur only the first time the halt is encountered rather than every time.

## Quickly Disabling Methods

**Tip**

To quickly make a method do nothing, add this line:

**Smalltalk**

```
true ifTrue: [ ^nil ].
```
To quickly make a method forward its behavior to its superclass use this line:

Smalltalk

true ifTrue: [ ^super myMethodName ].

In this way you do not have to delete or significantly modify a method when
you want to change its behavior or bypass an unfinished portion.

Specifying Public or Private with TrailBlazer

Tip

To quickly specify the public or private policy for a class, select the class and in the lower area (the properties area) select the instance interface (or class interface). You can then easily make public or private assignments.

Browse and Find in the Pop-Up Menu

Tip

Here is a little tool that extends the development environment. The tool
adds two extra items to the pop-up menu: *Browse* and *Find*.

*Browse* is an intelligent browse; you select the code in the pane and then
make your choice. The code you have marked is evaluated, and the
resulting class is determined. If the class is a part, the *editPart* message is
sent and the VisualAge for Smalltalk editor is opened. If the class is not a
part, the ordinary Smalltalk browser is opened.

*Find* brings the marked text into the Find window (of VisualAge for Smalltalk) and opens it. If the Organizer is not minimized, the resulting class (if you search for a class) is marked.

Here is the code for filing into your image. When the application NhaTool is
loaded, you have the extension.
Application create: #NhaTools with:
(#( AbtViewApplication EtTools)
  collect: [:each | Smalltalk at: each ifAbsent: [
    Application errorPrerequisite: #NhaTools missing: each]))!

NhaTools becomeDefault!
AbtViewApplicationAbtPackage subclass: #NhaToolsAbtPackage
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''!

NhaTools becomeDefault!
Application subclass: #NhaTools
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''!

NhaTools becomeDefault!

!EtBrowser publicMethods !

defaultTextMenu
"Answer the modified textMenu"

^super defaultTextMenu
addLine;
add: #menuBrowse label: 'Browse';
add: #menuFind label: 'Find';
yourself! !

EtDebugger description: 'Developer: Niclas Havrup

Date: 96-06-07

APAR:

Description:
Menu items add to the debugger' in: NhaTools!
```
!EtDebugger privateMethods !
```

```
defaultTextMenu
  "Answer the modified textMenu"
```

```
^super defaultTextMenu
  addLine;
  add: #menuBrowse      label: 'Browse';
  add: #menuFind        label: 'Find';
  yourself! !
```

```
!EtInspector publicMethods !
```

```
defaultTextMenu
  "Answer the modified textMenu"
```

```
^super defaultTextMenu
  addLine;
  add: #menuBrowse      label: 'Browse';
  add: #menuFind        label: 'Find';
  yourself! !
```

```
!EtWindow publicMethods !
```

```
menuBrowse
  "Browse the class for the selection"
```

```
| selection classname |
selection := self targetTextWidget getSelection trimBlanks.
className := (Smalltalk classAt: selection
  ifAbsent: [(self evaluateSelectionIn: targetTextWidget
    ifFail: [ ^self ])
    class.]).
```

```
(className inheritsFrom: AbtPart)
ifTrue: [ classname editPart.]
ifFalse: [ ((EtTools browser: #class) on: classname) open ].
!
```
menuFind

"The Find window"

| selection classname |

selection := self targetTextWidget getSelection.

selection isNil

ifFalse: [selection := selection trimBlanks].

(AbtApplicationsOrganizerView current find

secondaryViews at: #find ifAbsent: [nil]) findText: selection.

!!

!EtWorkspace publicMethods !

defaultTextMenu

"Answer the modified textMenu"

^super defaultTextMenu

addLine;

add: #menuBrowse label: 'Browse';

add: #menuFind label: 'Find';

yourself! !

!NhaTools class privateMethods !

runtimeStartUp

self abtViewApplicationPackage runtimeStartUp! !

NhaToolsAbtPackage initializeAfterLoad!

NhaTools initializeAfterLoad!

NhaTools loaded!
## Versioning Applications Not Owned

**Tip**

If you make changes to a class that is in an application you do not own, it can be difficult to version and release the application.

Here's the incantation (which assumes that you do not have password control of user IDs or know the passwords):

1. Open the Application Manager.

2. Select the troublesome application.

3. Select the open editions of the class or classes. The owner of that change will be highlighted in the user list in the Application Manager.

4. Double-click on the highlighted name to change the user to that person.

5. Click the right mouse button over the class list and select **Version → Name each, One name, or Use defaults**. This will version the classes. Now you need to release them.

6. Double-click on the name list to change the user to the manager of the application (name with the > next to it).

7. Click the right mouse button over the class list and select **Version/Release All →**, select **Name each, One name, or Use defaults**. This will version and release all the classes, some of which may already have been versioned. Another way to do this is to just select the classes that have not been released yet (marked with a >), click with the right mouse button to open the menu, and select **Release**.

8. When all classes in the application are versioned and released, change the user to the manager and version the application.

## Client Not Supported

**Tip**

If your connectivity is through Microsoft Windows for Workgroups (3.11) or any other protocol that is not supported by the client, be aware that the CA/400 DOS Extended client is not supported for use with either MSDLC or VisualAge AS/400 Connection (see AS/400 Connection User's Guide SC34-4544-0 under Chap. 1, "Getting Started..." section on "Prerequisites for Windows") in this case, you must use the Client Access/400 for Windows 3.1 client.
## AbtRecord

**Question**

How do I use AbtRecords?

**Answer**

There are some references to AbtRecord in the online *Communications/Transactions Guide and Reference*. One way to create an AbtRecord instance is by sending the message #newRecord to an AbtCompoundType. Here is an example I found:

**Smalltalk**

```Smalltalk
| ctype rec |
ctype := ( AbtCompoundType new
    addField: (AbtCOBOLDisplayField new name: 'string1'; length: 8 ) ;
    addField: (AbtCOBOLDisplayField new name: 'string2'; length: 8 ) ;
    yourself ).
rec := ctype newRecord.
rec at: 'string1' put: 'abcde'.
rec at: 'string2' put: 'dddddd'.
Transcript cr ; show: (rec at: 'string1');
    cr; show: (rec at: 'string2').
```

## Indexed Message Editor

**Tip**

I find that, whenever I made changes in the Indexed Message Editor, I need to

1. Save the changes.

2. Execute application `abtGenerateExternalizedStringsIfNecessary`.

3. Execute `AbtNLSCoordinator forceRelocalizationOfSeparatedConstants`.

After I do this, all my messages are immediately available. I never have to unload or reload the application.
## Corrupted MRI File

**Question**

The messages in my MRI user message file appear corrupted or have bad data. What can be wrong?

**Answer**

The MRI file in VisualAge for Smalltalk, Version 1.0 has a limit of 64 KB, so messages above this limit may appear corrupted. To get past the limit, in application AbtNLSSubApp, change class AbtMRIGroupHeader, method offsetSize as follows:

Smalltalk

offsetSize

"Public - answer size of file offset used in header.

^offsetSize isNil

ifTrue: [ offsetSize := 4 ]

ifFalse: [ offsetSize ]

The only change in this method is to change the number 2 to 4. For VisualAge for Smalltalk, Version 2.0, the changes have already been made. In the method above, the offsetSize now defaults to 4 instead of having to change it to 2. So, corruption should no longer be a problem in Version 2.0

## Class Naming Convention

**Question**

What naming convention should I use?

**Answer**

Our naming convention complements existing literature¹ on the subject to facilitate code reuse and to provide a layered architecture for the development environment.

A naming convention in your development environment greatly helps reusing existing classes because it allows searching by class name based on a filter.

<footnote>1</footnote>

<footnote>* VisualAge for Smalltalk, Programmer's Guide to Building Parts for Fun and Profit, IBM</footnote>

<footnote>* Smalltalk with Style, David Thomas et al, Prentice Hall</footnote>

<footnote>* Smalltalk Best Practice Patterns, Kent Beck, Prentice Hall</footnote>
## Class Name Prefix

The prefix is arbitrarily defined with the following three characters:

1. The first letter stands for the company name.

2. The second letter describes the type of components:

A Application

C Class

M Configuration map

3. The third letter is used to categorize the component within a layered architecture:

A Defines classes of the top layer, which is the application layer. All classes are visual, representing the screens of the application. At the application layer, the primary part of a class is always a window (for example, an instance of AbtShellView) rather than a form (an instance of AbtFormView).

F This optional layer contains reusable visual classes. The main difference between this layer and the application layer is the fact that the primary part of a class is always a form rather than a window.

M The model layer contains the implementation of the object model reflecting the business domain of the enterprise.

G As part of the infrastructure, the GUI layer contains classes that provide additional features to the base product, such as converters, security defined at the widget level, controller services common to any instances of Model-View-Controller (MVC), or a window manager that keeps track of the view that owns the current unit of work.

E As part of the infrastructure, this layer contains class extensions made to the base product.

T As part of the infrastructure, this layer contains in-house development tools for developers. These classes are never packaged with the end-user application.

S As part of the infrastructure, this layer contains common services defined in the Common Object Request Broker Architecture (CORBA), for example, the persistence object service, concurrency, and transaction service.
### Class Name Suffix

For a class, the category of component is defined with the third letter of its prefix and the use of a suffix.

### Model Class

Model classes (for example, business domain classes) do not need a suffix.

### Reusable Visual Classes

Reusable visual classes are derived from model classes. There is a one-to-many relationship between one model class and its reusable visual classes, and that is why we always use the name of the model class as the name of the reusable visual class. Its suffix consists of two parts:

* The first part characterizes the information being displayed. Use a name that characterizes the reusable visual class based on the attributes displayed from its model class. Consider using terms like the following:

- Summary

- Detail

* The second portion is the word *View*.

### Visual Classes

Visual classes are task oriented and should reflect in their name their main task. Use *View* for suffix.

### Facade Classes

Structuring a system into subsystems helps reduce complexity. A common design goal is to minimize the communication and dependencies among subsystems. The Facade class provides a single and simplified interface to the more general facilities of a subsystem<fnref n="2" />. Use *Facade* for suffix.

### Controller Classes

Controller classes handle the sequence of events found in a use case. They deal with user interface logic or business processes. Jacobson defines them as control objects<fnref n="3" />. Use *Controller* as suffix.

### Agent Classes

Agent classes are used to encapsulate the physical implementation of a portion of or whole service by using one or more service objects. One agent class plays an intermediate role between one or more model classes, which

<footnote n="2">² *Design Patterns*, Erich Gamma et al, Addison-Wesley</footnote>

<footnote n="3">³ *Object-Oriented Software Engineering*, Ivar Jacobson, Addison-Wesley</footnote>
do not know anything about the outside world of a Smalltalk run-time image, and the service object, which in turn does not know anything about the business domain<fnref n="4" />.

Use the word *Agent* followed by the kind of service object used. Here are some examples:

* AgentDB2: Classes implementing service, using DB2/2 service objects

* AgentMQ: Classes implementing service, using MQSeries service objects

* AgentTCPIP: Classes implementing service, using TCP/IP service objects

## Manager Classes

Manager classes keep track of all instances of a specific class or a subset of a class. They are also used to select some instances of one specific class based on some criteria<fnref n="5" />. Use *Manager* as suffix.

## Category Naming

How should I group methods within a class in order to improve readability?

Category names have to be explicitly created. We propose category names for instance and class methods.

**Question**

### Categories for Instance Methods

* Get and set selectors

**Answer**

Contains all accessor methods for instance variables

* Extensions

Used when an extension is made to an existing class of the development tool

* Initializations

Contains initialization methods

* User interface logic

Used for validation or navigation logic

<footnote n="4">⁴ VisualAge and Transaction Processing in a Client/Server Environment, Andreas Bitterer et al, Prentice Hall PTR</footnote>

<footnote n="5">⁵ Enhancing the Object Design Process Using Stereotypes, paper presented by Rebecca Wirfs-Brock at the Smalltalk User's Conference in New York, 1996</footnote>
* ResponsibilityName

A category is created for each responsibility (for example, contract) taken by the object.

* Services

Contains methods having a general purpose such as boolean or copy methods

We do not recommend defining a method to more than one category even if the tool allows it.

## Categories for Class Methods

Some categories for class methods are the same as those described for instance methods.

* Get and set selectors

Contains all accessor methods for class variables

* Creations

Contains methods returning one instance of the class

* Constants

Contains constant methods

* Example

Contains methods explaining how to use the class. A common usage is showing how to create an instance of the receiver.

* Extensions

Used when an extension is made to an existing class of the development tool.

* Initializations

Contains initialization methods

* ResponsibilityName

A category name is created for each responsibility (for example, contract) taken by the object.

* Services

Contains methods having a general purpose such as boolean or copy methods.

* Tests

Contains unit testing methods
## Archival Code is Missing

**Question**

I had an application on VisualAge for Smalltalk on OS/2 2.11. Now I installed VisualAge for Smalltalk on a Warp system and filed in my application and the archive file. I get all parts, but the view wrapper parts are empty (the Composition Editor shows only an empty window). Has anyone an idea what could be wrong?

**Answer**

The problem you are experiencing (for example, no visual parts in any of the windows) is usually an indication that the archival code is missing. Open a Composition Editor on one of your visual parts and then switch to the Script Editor. Check and see if you have any class methods. If you generated and then filed in your archival code, you should see the following class public methods:

* `calculateInterfaceSpec`

* `calculatePartBuilder`

You should also have some class private builder methods. Do you see any of these methods? Open a browser on the archival application. Do you see class names for all your visual parts? When you generate archival code for your visual parts, the class gets extended in the archival application. The class extensions are the archival code methods.

If you don't have the archival code methods, I suggest you go back and regenerate the archival code, file it out, and then file it back in.

## Meaning of Application Errors

**Question**

Where or how can I find an explanation of the fatal application errors?

**Answer**

From the System Transcript, display the following code:

Smalltalk

SystemPrimitiveErrors keyAtValue: errorNumber

If, for example, you highlight and display this statement with argument: 33, you get the following result: 'PrimErrImageFileOpenError'.
## Error: 'Undefined Object does not understand messageString'

**Question**

I get the following error every time I try to save a part: 'Undefined Object does not understand messageString' How can I correct this?

**Answer**

Inspect AbtShellView (the class). You can do this by executing

Smalltalk

(AbtShellView inspect).

From the inspector, double click on the entry 'classPool' This should open a Dictionary Inspector with two entries: 'AbtInImageRestore' and 'InLongOperation'. Select the entry called 'InLongOperation'.

If it says true then change it to false and save (using the pop-up menu) the change.

If false appears in the right pane, then you have a different problem.

## Error on Saving a Part

**Question**

When I try to save a part, I get an error that states that there is no primary part, why?

**Answer**

This can happen assuming the following order of actions:

1. Open a new part (the default window is the primary part)

2. Add, for example, a notebook (the default window is still the primary part).

3. Delete the window (no primary part)

From here, an attempt to save will generate a warning until you specify which part is to be the primary one.

However, if the order is the following, the result is different:

1. Open a new part (the default window is the primary part).

2. Delete the window (no primary part).

3. Add the notebook (the notebook becomes the primary part).

From here, saves works fine.
In summary, if the primary part is deleted, VisualAge makes no assumptions about which part should now become the primary one. If, however, you add a new part when no primary part is currently defined, the newly added part becomes the primary part. It must be a visual part when editing a view class, otherwise the primary part will stay undefined. The rationale for automatically setting a primary part when one is not currently set is to simplify the typical scenario where one wants to substitute the window for an embeddable window (Form).

## Inappropriate VisualAge Icon

**Question**

In Windows, I click on the VisualAge icon and nothing happens or my VisualAge icon has DOS in it instead of the eye, or I receive "cannot run in DOS mode." What should I do?

**Answer**

You have probably not installed Win32s support needed for Windows or do not have the correct version of Win32s. VisualAge for Smalltalk requires level 1.15.111.0. You can tell what version you have by looking at the Win32s.ini file in the \windows\system subdirectory. Refer to the readme.txt file in the \wradcdw1\vaprodn1\readme subdirectory on the VisualAge for Smalltalk CD and search for Win32s instructions on installing Win32s support.

## Double Execution of Script

**Answer**

Why does my script get executed twice when a user hits the enter key and I use the defaultActionRequested event?

**Answer**

This is a known problem. You'll need to change the method AbtTextView->>#postCreationInitialization. Locate the following piece of code in the method and remove it:

### Smalltalk

```
widget addCallback: XmNactivateCallback
receiver: self
selector: #defaultAction:clientData:callData:
clientData: nil.
```
## Error 203

**Question**

When trying to start VisualAge for Windows, I get Error 203. Why?

**Answer**

Older versions of VisualAge for Smalltalk did not run on Windows 95 or NT. You need to upgrade to at least version 3.0a if you want to run VisualAge for Smalltalk under Windows 95 or Windows NT.

## Removing Elements from a View

**Question**

How do I remove elements from a tree view?

**Answer**

We opened APAR PN82758 on a problem that sounds very similar to this problem. Here is a workaround or fix: In EwHierarchy>#refreshItems:childrenBlock: Change the lines that read:

Smalltalk

oldExpandedItems add: (self items at: index).

oldExpandedNodes add: node!.

To the following:

Smalltalk

(index between: 1 and: self items size)

ifTrue:

oldExpandedItems add: (self items at: index).

oldExpandedNodes add: node!!.

## Class EmLibraryStatistics

**Question**

Where is the class EmLibraryStatistics that was in IBM Library Tools configuration map?

**Answer**

It was left out of the Version 3.0a refresh manager. You can import the configuration map from your Version 3.0 manager into your Version 3.0a manager. The code hasn't changed between the two.
Error: rc=12

**Question**

What does a rc=12 for abt.exe mean?

**Answer**

Try executing the following code:

Smalltalk

Object primitiveErrorStringFor: 12 → "Not enough memory"

Error: SYS317x

**Question**

Can I avoid SYS317x in ESVM30.DLL, PMMERGE.DLL, or xxx.DLL on OS/2?

**Answer**

OTI believes that many of the SYS317x messages our customers are seeing are due to stack overflow. When the stack overflows, some reasonably important data is trashed in ABT.EXE. The effect of trashing this data can be immediate or delayed (depending on how much is trashed and what the trash looks like). Also, according to OTI, there is no way for customers to either protect against a stack overflow or know when one has occurred. Many of our customers run quite successfully with the original stack size of 32 KB. However, as VisualAge for Smalltalk applications have become more complex, stack usage has increased. Therefore, before the Version 3.0a refresh, ABT.EXE was rebuilt with a 64 KB stack.

It has been noted that a 64 KB stack is not always enough either. So, I have developed a version of ABT.EXE that runs Smalltalk on a thread. This allows customers to set any stack size they need. It also keeps Smalltalk-called DLLs from writing past the end of the stack (based on the different mechanism used for managing thread stacks vs. the main thread stack).

When you get a report of a SYS317x on IBM Smalltalk or VisualAge for Smalltalk that occurred while running the product (not during install, for example), here are some steps to diagnose and correct the problem:

1. Does the trap occur when the user is doing lots of user interface interaction? If so, suggest that users update their video drivers to the newest level and retry. In the past, we've seen this kind of problem on Windows, but it is also beginning to show up on OS/2. It seems to be most prevalent with S3-based video cards, but has been seen with others. Diamond Stealth drivers seem to be particularly notorious for causing this problem.
2. Is the user still on Version 3.0? If so, suggest that they upgrade to Version 3.0a. In the meantime, you could send them a replacement for ABT.EXE to bring it up to the Version 3.0a level.

3. Does the trap occur when bring up a Version 3.0a image with database features loaded? Have the customers saved their image with a database connection open? If so, suggest that they reload into a clean image and not save with open database connections. There is a problem in database with finalization code that is trying to free operating system objects that have bogus memory pointers at startup.

If these don't help, and if the SYS317x occurs based on a repeatable scenario, then we can turn the problem over to OTI support (after verifying that it can be recreated) if the customer supplies: a) a scenario for recreating the failure, b) the failing image, and c) any associated files, DLLs, and the like needed to recreate the failure.

## Error: Primitive Error Codes 52 through 55

**Tip**

Primitive error codes 52 through 55 indicate a general protection fault or trap. They are described in the table at the end of Chapter 11 in the *IBM Smalltalk Programmer's Reference*. These error codes were introduced in Version 3.0a. The specific meanings are:

52 - General Protection Fault

53 - General Protection Fault - read from invalid memory location

54 - General Protection Fault - write to invalid memory location

55 - General Protection Fault - invalid instruction executed

If the primitive error is associated with a *callWith: type* method, then the general production fault occurred in the DLL being called (or in a function that it called). If the primitive error is associated with a *xxxAt:* or *xxxAt:put:* type method, then an invalid address was supplied to the method.

## Error: Does Not Understand Format

**Question**

After filing in code from Version 2 Standard to Version 3 Team, I get a debugger with "AbtlbmDate384Field does not understand format:" when generating runtime code for an access set.
**Answer**

Implement a `format:` instance method for `AbtlbmDate383Field` that does nothing.

## Menu on Windows NT 4.0

**Question**

VisualAge for Smalltalk Version 3.0a for Windows has a small menu problem when run on Windows NT 4.0. The context menu for text fields appears after a default windows menu. What do I do?

**Answer**

This behavior can be easily fixed by executing the following code:

Smalltalk

```perl
OSWidget eventTableAt: 16r7B "WmContextmenu"
put: #wmContextmenu:with:
```

## Back-tabbing in Container Details Views

**Tip**

On some UNIX platforms (HP-UX and Hummingbird Exceed X server, for example) shift-Tab is mapped to key symbols other than back tab. The container details view expects shift-Tab to back tab (or tab to the left). Therefore, when running VisualAge on these platforms, you may need the following workaround in order to use Shift-Tab to back tab through container cells. Edit the key mappings for your X server. If you are using X server software on a Windows or OS/2 workstation, the X server software may provide dialogs to edit the keyboard mappings. Use these dialogs to change the setting for `"Shift" + "Tab"` to generate the `keysym "Tab."` For X servers running under UNIX, you can run X command `xmodmap` to change the mappings. For example, to correct the mapping on an HP-UX workstation, run the following command:

```
xmodmap -e "keysym Tab = Tab Tab"
```

You can run this command from your `.profile` or other startup or logon script, but it must be run after your display is specified. If you are already running `xmodmap`, you may have a resource file, possibly called `.xmodmaprc`, to which you can add the above `keysym` expression.
## Properties Views and Notebook Settings Views

**Tip**

To switch from Properties views to Notebook settings views, do the following:

1. From either the System Transcript or the Organizer, bring up the Load/Unload dialog.

2. Choose to load VisualAge Notebook Style Settings Views.

3. In the VisualAge Organizer Preferences, make sure Notebook Style is selected for the Preferred Settings View.

## Code Page Conversion Errors

**Tip**

If you are receiving errors related to code page conversion, select **Tools → NLS → Rebind Image Strings** from your Transcript.

## Determining Required ICs

**Tip**

The following script can be run to determine the ICs that are needed at run time. It will show a list of all IC packaging instructions that are currently loaded. When you select a packaging instruction, the required run-time ICs will be listed on the Transcript.
```
| icCollection instructionNames instructionName instructionClass work |
 instructionNames := (EpAbstractPackagingInstructions
 withAllSubclasses collect:
  [ :ea | ea name asString])
 asSortedCollection asArray.
 instructionName := CwListPrompter new
 title: 'Find IC files required by the selected IC';
 items: instructionNames;
 prompt.
 instructionName size = 0 ifTrue: [^self ].
 instructionClass := Smalltalk classAt: instructionName
 ifAbsent: [^self ].
 icCollection := Set new.
 icCollection add: instructionClass dumperOptions imageFileName.
 instructionClass prerequisiteICs do: [:eachICInstructionClass|
  icCollection add: (eachICInstructionClass asClass)
   dumperOptions imageFileName].
 work := Transcript bringToFront.
 work cr;
 nextPutAll: '******** The required ic files for ',
 instructionClass name, ' ********';
 cr;
 cr.
 icCollection empty
 ifTrue: [work tab; nextPutAll: 'No IC files needed.'; cr]
 ifFalse: [icCollection asSortedCollection do: [:each| work tab;
 nextPutAll: each; cr]].
```

## Required CAT and MPR Files for an IC Run-time Image

<figure><img src="image_9.png" /></figure>

**Tip** The following script can be run to determine the `.cat` and `.mrp` message files that are needed by an IC image at run time. It will show a list of all IC packaging instructions that are currently loaded. When you select a packaging instruction, the required run-time message files will be listed on the Transcript.
| appCollection catFiles mprFiles instructionNames
instructionName instructionClass work |

instructionNames := (EpAbstractPackagingInstructions
withAllSubclasses collect:

[ :ea | ea name asString])

asSortedCollection asArray.

instructionName := CwListPrompter new

title: 'Find .cat and .mpr files required by the selected IC';

items: instructionNames;

prompt.

instructionName size = 0 ifTrue: [ ^self ].

instructionClass := Smalltalk classAt: instructionName

ifAbsent: [^self].

appCollection := Set new.

catFiles := Set new.

mprFiles := Set new.

instructionClass actualIncludedSubApplicationNames do: [:eachApp|

appCollection add: (eachApp asClass rootApplication)].

instructionClass prerequisiteICs do: [:eachICInstructionClass|

(eachICInstructionClass asClass)

actualIncludedSubApplicationNames do:

[:eachApp|

appCollection add: (eachApp asClass rootApplication)].

appCollection do: [:eachApp | |poolNames mprName|

poolNames := eachApp definedPoolNames.

poolNames do: [ :eachPoolName | |pool catName|

(pool := (Smalltalk at: eachPoolName ifAbsent:[]))

epIsPoolDictionary

ifTrue: [(catName := (pool at: '!CATALOGNAME'

ifAbsent: [])) isNil

ifFalse: [catFiles add: (catName,'.cat')]]].

(mprName := eachApp abtNIsRawFilename) empty

ifFalse: [mprFiles add:

(AbtNLSCoordinator resolveLanguageMappingCharacter:

mprName)].
work := Transcript bringToFront.
work cr,
    nextPutAll: '******* The required message files for ',
               instructionClass name, ' ********';
    cr;
    cr;
    nextPutAll: 'Cat files:';
    cr.
catFiles empty
    ifTrue: [work tab; nextPutAll: 'No .cat files needed'; cr]
    ifFalse: [catFiles asSortedCollection do:
               [:each| work tab; nextPutAll: each; cr]].
work cr;
    nextPutAll: 'Mpr files:';
    cr.
mprFiles empty
    ifTrue: [work tab; nextPutAll: 'No .mpr files needed'; cr]
    ifFalse: [mprFiles asSortedCollection do:
               [:each| work tab; nextPutAll: each; cr]].

## Required CAT and MPR Files for a Reduced Run-time Image

Tip

The following script can be run to determine the .cat and .mpr message files that are needed by a reduced image at run time. It reads the spusage.es file produced by packaging, so you should run the script right after your packaging run so that you have the correct spusage.es file available. The required run-time message files will be listed on the Transcript.
```
| spusageFile fileStream class classCollection
appCollection catFiles mprFiles work icxFileName |

classCollection := Set new.
appCollection := Set new.
catFiles := Set new.
mprFiles := Set new.
spusageFile := 'spusage.es' asFileSpec.
fileStream := spusageFile cfsStreamReadOnlyIfError:
    [ :aCfsErr| aCfsErr printString].
(fileStream skipToAll: 'Output statistics for: '
    ifTrue: [icxFileName := (fileStream nextLine)].
(fileStream skipToAll: '# Size # Size # Size') ifTrue: [
    fileStream nextLine; nextLine.
    [fileStream atEnd] whileFalse: [
        (class := fileStream upTo: $ )empty
        ifTrue: [fileStream setToEnd]
        ifFalse: [
            classCollection add: (class asClass).
            fileStream nextLine]]].
fileStream close.
classCollection do: [:eachClass | |app|
    app := eachClass controller.
    appCollection add: app rootApplication].
appCollection do: [:eachApp | |poolNames mprName|
    poolNames := eachApp definedPoolNames.
poolNames do: [ :eachPoolName| |pool catName|
    (pool := (Smalltalk at: eachPoolName
        ifAbsent:[]) eplspoolDictionary
        ifTrue:[(catName := (pool at: '!CATALOGNAME'
                                ifAbsent: [])) isNil
        ifFalse: [catFiles add: (catName,'.cat')]]].
(mprName := eachApp abtNIsRawFilename) empty
        ifFalse: [mprFiles add: (AbtNLSCoordinator
                                resolveLanguageMappingCharacter: mprName)]].
```
Smalltalk (continued)

work := Transcript bringToFront.
work cr,
    nextPutAll: '******** The required message files for ',
    icxFileName, '********';
    cr;
    cr;
    nextPutAll: 'Cat files:';
    cr.
catFiles empty
    ifTrue: [work tab; nextPutAll: 'No .cat files needed']
    ifFalse: [catFiles asSortedCollection do:
        [:each| work tab; nextPutAll: each; cr]].
work cr;
    nextPutAll: 'Mpr files:';
    cr.
mprFiles empty
    ifTrue: [work tab; nextPutAll: 'No .mpr files needed']
    ifFalse: [mprFiles asSortedCollection do:
        [:each| work tab; nextPutAll: each; cr]].

Format Change for CTLs

Tip

The format of the .CTL files used during feature load and unload has changed between Version 3 and Version 4. This change will affect you if you create .CTL files for your components.

Sample V3 CTL File Format

Smalltalk

SOMsupport "AbtCommonProductInstallerApp products: #('va')
platforms: #( 'aix' 'os2' 'win95' 'winnt' ) sys: 'es'"
'SOMsupport' 'V 3.0a' abtesm30.dat
'AbtSOMsupport' 'V 3.0a' abttsm30.dat

Sample V4 CTL File Format
Smalltalk

SOMsupport, Base "AbtCommonProductInstallerApp
productId: 'sdcs00000023'
platforms: #('win95' 'winnt' 'os2' 'unix')"
include=abttvv40.ctl
include=abtesm40.ctl
'AbtSOMsupport Run' 'ts=3032438045' 'abttsm40.dat'
'AbtSOMsupport Run V4.0'
'AbtSOMsupport Edit' 'ts=3032437984' 'abttsm40.dat'
'AbtSOMsupport Edit V4.0'

Here is what has changed:

* Feature identification

- Text up to the first double-quote forms the feature name that will display in the Feature load and unload dialog

- The products: and sys: parameters are no longer used.

- The new productId: parameter is used to determine whether a feature is for evaluation or for production. If you use sdcs00000023 for the value of this parameter, your evaluation status will track with the evaluation status of the base VisualAge product. If you use an unrecognized string for this parameter, your component will always be treated as for evaluation.

- For the platforms: parameter, aix has been replaced with unix.

* Prerequisite loading

Prerequisite features are indicated with the include statement referencing the .ctl file of the prerequisite. There is one include statement for each direct prerequisite feature. In this example, SOMsupport, Base for IBM Smalltalk, and VisualAge Base are the direct prerequisite features of SOMsupport, Base for VisualAge. These two lines are equivalent to the second line in the Version 3 example.

* Feature loading

The final two lines in the example identify the configuration maps comprising the feature. Each line is composed of four parts:

- Name of the configuration map to be loaded

- Time stamp of the configuration map to be loaded

- Name of the .DAT file containing the code to be loaded
- A comment (typically the name and version of the configuration map to be loaded)

These two lines are equivalent to the third line in the Version 3 example.

To have your component listed in the VisualAge section of the load and unload dialog, make the fourth letter of your DAT file name a **t**. To have your component listed in the IBM Smalltalk section of the load/unload dialog, make the fourth letter of your DAT file name an **e**.

## Unloading the Visualization Feature

**Tip**

To unload the Visualization feature, first execute the following code from a workspace:

Smalltalk

DtEventProfilerApplication eventQueueProcessor.

Then unload the Visualization feature.

## Manager Access

**Tip**

Watch out for the following manager access issues:

### Solaris Server

- Error 1212 "Transaction terminated prematurely" message

When running EMSRV on Sun Solaris 2.5.1, you may get an Error 1212 "Transaction terminated prematurely" message when loading a large config map. This is an access denied error due to an incorrect return value from one of the Solaris lock checking functions. Temporary patches from Sun are available to fix this problem. You can download these patches from Sun's FTP site:
ftp://sunsolve1.sun.com//pub/patches/T103640-06.tar.Z.

- Starting EMSRV

EMSRV for Solaris does not determine the device number correctly. In most cases, images that talk to it fail to connect with the message "File resides on unsupported device." This error also prevents the use of the EMCOPY command.
To resolve the problem, start EMSRV with all the options you normally
would use in addition to option -xd0. For instance, if your normal EMSRV
startup options are:

emsrv -v -b50 -lt240

then you should use:

emsrv -v -b50 -lt240 -xd0

Note that when you use -xd0, you lose the protection mechanism that
prevents you from starting EMSRV on an NFS drive. To avoid corruption,
take extra care to ensure that you run EMSRV from a local hard drive
when you start with this option.

Windows 95 Client

From a Windows 95 client, you must use Novell's Client32 for Windows 95
requesters and associated patches. If you use the wrong requesters, library
corruption is possible.

The Client32 for Windows 95 requester and the required patches can be
obtained from Novell's Web site.

From the Core OS Updates section, select landr9.exe; from the Client Kits &
Updates section, select cltdr2.exe. Because fixes may be updated or files
renamed over time, you may find that these files are no longer available. In
this case, follow the instructions at the top of the page for accessing
Novell's Product Support area.

If these two patches are not used, users may experience severe
performance problems when reading from attached servers and may also
find that locks are not correctly released if more than one image is running
concurrently on the same machine. The two patches should correct both of
these problems.

The Client32 for Windows 95 requester has many parameters that may be
changed in the Advanced Settings dialog. The default settings provided on
installation have been tested; in most cases there is a trade-off between
data integrity and performance (for example, True Commit set to off).
Although other settings have not been tested, changing any of the settings
in the Performance - Cache parameter group to less optimistic values
should not present any problems.
When using this configuration, set ENVY/Manager's release lock mode parameter to *true*.

**Windows NT Client**

Windows NT clients must only use the Microsoft Client Services for Netware (CSNW) that is provided with Windows NT 3.51. The Novell Netware Client for Windows NT should not be used as it has not been tested with VisualAge for Smalltalk.

When using this configuration, set ENVY/Manager's release lock mode parameter to *true*.

**OS/2 Warp 3 Client**

From an OS/2 Warp 3 client, use Novell's OS/2 2.11 requester for library access.

**OS/2 Warp 4 Client**

Direct access to Novell Netware servers from Warp 4 is not currently supported. OS/2 Warp 4 customers should use EMSRV for library access.

## Opening Multimedia Devices

**Tip**

Open only one multimedia device (for example, Digital Video Player) at a time. Make sure you close one device before opening another, otherwise unexpected results may occur. This is an OS/2 Warp limitation.

## Using Digital Video Player on OS/2

**Tip**

To use the Digital Video Player, move the MMOS2 directory to the beginning of your LIBPATH and PATH statements in your CONFIG.SYS file on OS/2 before starting VisualAge. This is an OS/2 Warp limitation.

## Video Disk Player

**Tip**

The wrap function does not work for the video disk player.
## Crystal Wave and MWave Audio Cards

**Tip**

When running video or audio under OS/2 on a Crystal Wave Audio or MWave audio card, the video or audio might not terminate and thereby lock up VisualAge. Installing more recent audio drivers might help solve this problem. Using a different audio card, such as SoundBlaster, will solve the problem.

## AVA Playback Windows

**Tip**

An AVA Playback Window in a scene of a story enables the user to use Ctrl+Esc to escape that scene in a full screen presentation even if the *Prevent user exit* option is on. This is an Ultimedia Builder limitation.

## Lotus Notes

**Tip**

On DBCS systems, a Notes database title might be truncated when displayed in a Notes database icon. You can view the entire title in the database properties dialog. This problem occurs when the database name is longer than 32 bytes which can occur with as few as 11 Lotus multibyte characters (LMBCS). Depending on the type of characters in the database title, such truncation might lead to an unviewable character at the end of the title.
# Chapter 3. Graphical User Interface

In this chapter we cover issues related to graphical user interface (GUI).

## GUI Architecture

**Question**

What GUI architecture does IBM Smalltalk use?

**Answer**

IBM Smalltalk has many advantages in its GUI implementation.

ParcPlace VisualWorks Smalltalk emulates all the supported operating systems GUIs in Smalltalk—that is, it opens a window, and does all the bit manipulation itself. This makes it very flexible for cross-system development but there is a performance overhead. Digitalk (now ParcPlace) Visual Smalltalk uses more of the underlying operating system GUI, for better performance but at the price of only supporting a common subset of GUI controls; it's better with Version 3, but complex controllers still require quite a lot of work.

IBM Smalltalk maps the Motif GUI widgets onto the underlying operating system widgets. This means you get a very rich kit to build your GUI, but the widgets operate at near native speed. You have the best of both worlds.

## MappingWidgets Across Systems

**Question**

How do I map Motif widgets to Smalltalk widgets?

**Answer**

Each Smalltalk widget that maps to a Motif widget class must implement two class methods:

* `platformWidgetClass`

* `platformWidgetGadget`

The XPlatformAdministration class>>#initializeWidgetClasses method sets up global variables in PlatformGlobs used by each of these methods (for example, `XmPkgeButtonWidgetClass`). These map a Motif widget class (an address) using the `CwWidgetClassMappings` variable of `CwBasicWidget` into a Smalltalk widget class (see `CwBasicWidget` class>>#widgetFor:).

As a result, you can map only one Motif widget class into a single Smalltalk class. (Note: Multiple Motif widget classes can be handled by the same
Smalltalk class. Several classes do that, see implementors of `platformWidgetClass`.)

One possible particular scenario is: You create a subclass of `CwPushButton`, and when the class `#initialize` method is run (`CwBasicWidget`), the `CwWidgetClassMappings` table is rebuilt. This causes all Motif push button widget class instances (an address) to be mapped into the new subclass. The new `CwPushButton` subclass could add `#platformWidgetClass` and `#platformWidgetGadget` methods to make them unique (not inherit from `CwPushButton`), although I don't know what address they could specify, since it is truly a Motif push button.

Despite all this verbose explanation, I cannot explain why this particular walkback occurs, but I argue it is largely academic because even if there wasn't a walkback, simple subclassing of a `CwBasicWidget` would not work. Instead, subclass a `CwExtendedWidget` where the primary widget is a push button.

## Motif Documentation

**Question**

Is there any formal documentation as to which `Xm...` entries are available?

**Answer**

VisualAge for Smalltalk does not use any application-specific X resources, but it does inherit the standard Motif/Xt/X11 resources by virtue of being an X client and using the native widgets. For a reference on available resources, check out the standard Motif/Xt/X11 manuals, such as those from O'Reilly and Prentice Hall.

## Interface to Windows 95

**Question**

Will VisualAge for Smalltalk provide an interface to Windows 95 integration features?

**Answer**

VisualAge for Smalltalk is meant primarily as a standard-compliance-oriented tool. For example, even though you have the Windows 95 control support in Version 4, I strongly suggest that you abandon Windows 95-specific controls in the interest of portability through Common User Access (CUA) 91 standard compliance.
## Applications with Multiple Windows

**Question**

How do I create applications with multiple windows?

**Answer**

View Wrappers can be extremely useful when building complex applications with many windows because of the ability to conserve screen real estate in the Composition Editor. The View Wrapper performs better than the variable approach because the reusable part is not constructed by VisualAge for Smalltalk until the openWidget connection executes.

The View Wrapper is essentially an icon that represents another view that you have created. Instead of taking up valuable Composition Editor space, you can place this icon on the free-form surface and make connections to and from it. After adding a View Wrapper part to the Composition Editor, change its type to the class name of a view that you have already created. Since the View Wrapper is a place holder for a view, you make connections to it as if it were the actual view class.

## Exit Dialog Message Box

**Question**

I am attempting to create an exit dialog message box that prompts the user to respond to the question "Are you sure you want to exit?" when they either select **Close** from the system menu or double click on the system menu.

**Answer**

Create an event-to-script connection from closeWidgetRequest (of the window) to the following new script:

Smalltalk

okayToClose: aDoit

aDoit doit: (true == (System confirm:

'Are you sure you want to exit?')).
Window Location

Question

How do I specify where my window will appear on the screen when open?

Answer

There are two ways to do this if your window is a visual part.

* Think of the free-form surface of the Composition Editor as your display; if your window is at the top left of the free-form surface, it will be at the top left of your display.

* Assuming that you want to place it specifically at test or run time (and not affect its position in the Composition Editor), you could connect from *aboutToOpenWidget* of the window to a script like the following:

Smalltalk

(self subpartNamed: 'Window') yourself primaryWidget
x: 200;
y: 400.

Also, you could use the view's *finalInitialize* method to do something like the following:

Smalltalk

finalInitialize

self initWidgetSize: self computeSomeSizeAndPosition.
^super finalInitialize

Positioning Window at Cursor

Question

How do I initially position the window where the cursor is?

Answer

Look at the following code:
finalInitialize

| rootXReturn rootYReturn |

CgDisplay default

queryPointer: CgWindow default

rootReturn: (ReturnParameter null)

childReturn: (ReturnParameter null)

rootXReturn: (rootXReturn := ReturnParameter new)

rootYReturn: (rootYReturn := ReturnParameter new)

winXReturn: (ReturnParameter null)

winYReturn: (ReturnParameter null)

maskReturn: (ReturnParameter null).

self initWidgetSize:

(Rectangle origin: rootXReturn value @ rootYReturn value extent: 300 @ 200).

^super finalInitialize

## Maximizing a Window

**Question**

Is there a way to maximize a window programmatically?

**Answer**

There are platform-specific ways to maximize and minimize a window:

* In Windows:

Smalltalk

"Code for maximizing a window:"
self primaryWidget osWidget handle
showWindow: SwShowmaximized

"Code for minimizing a window:"
self primaryWidget osWidget handle
showWindow: SwShowminimized

* In OS/2:
### Smalltalk

```
"Code for maximizing a window:"
(self primaryWidget osWidget handle winQueryWindow: QwParent)
winSetWindowPos: nil x: 0 y: 0 cx: 0 cy: 0 fl: SwpMaximize
```

```
"Code for minimizing a window:"
(self primaryWidget osWidget handle winQueryWindow: QwParent)
winSetWindowPos: nil x: 0 y: 0 cx: 0 cy: 0 fl: SwpMinimize
```

## Opening Window Maximized

**Question**

How can I cause a window to be opened maximized?

**Answer**

Let's apply what we just learned. Create a script like the following:

### Smalltalk

```
maximizeWindow
"Maximize window in OS/2"
```

```
(self primaryWidget osWidget handle winQueryWindow: QwParent)
winSetWindowPos: nil x: 0 y: 0 cx: 0 cy: 0 fl: SwpMaximize
```

Then, create an event-to-script connection from the #openedWidget event of the window to the script you just wrote, and enjoy.

## Display Resolution

**Question**

How can I retrieve the display resolution?

**Answer**

The following code snippet buys you the height and width of the screen:

### Smalltalk

```
screenHeight := CgScreen default width.
screenWidth := CgScreen default height.
```
## Opening Window Centered

**Question** How do I open a window centered on the screen depending upon its resolution?

**Answer** Connect the `aboutToOpenWidget` event of your window to a `setPosition` method which determines window position based on screen size:

Smalltalk

```perl
setPosition
| w |
w := self primaryWidget.
w
x: ((CgScreen default width - w width) / 2) asInteger;
y: ((CgScreen default height - w height) / 2) asInteger.
```

## Window Space Planning

**Question** How do I calculate the space taken up by the window border, title bar, and so on?

**Answer** In OS/2, you can query the title bar height, menu bar height, and border width using `OSCall>>#winQuerySysValue:`, for example,

Smalltalk

```
(PlatformGlobs at: 'HndDeskTop')
winQuerySysValue: (PlatformConstants at: 'SvCytitlebar')
```

should return you the title bar height.
Iterating over Widgets

**Question** How do I iterate over all widgets in a window?

**Answer** Use #recursiveViewsDo: instead of #components do: against the main window. This will ensure all widgets are touched; it is necessary when adding callbacks to a window in Windows.

Modal Dialog

**Question** How can I get my modal dialog to return a value?

**Answer** I suggest adding an instance variable called *result* to your view, and implementing a *prompt* method:

Smalltalk

prompt

result := nil.

self suspendExecutionUntilRemoved.

^result

You would open the view like this:

Smalltalk

(view := MyView new) openApplicationModalWidget

myResult := view prompt.

Capturing the Minimize Request

**Question** Is there a way to capture the minimize request similar to the CloseWidgetRequest? I do not want a window to minimize to the desktop, I would like to create a pseudo desktop within my application and minimize to it.
**Answer**

You get notified, but cannot disallow it.

Window Synchronization

**Question**

How do I open a window from one method and wait on a return from the window in the method?

**Answer**

Try the following code snippet:

Smalltalk

myWindow openWidget

"or use any other message, such as openOwnedWidget"

myWindow suspendExecutionUntilRemoved.

"code to be executed, when the window is closed goes here"

Closing a Window

**Question**

What is the difference between closeWidget and destroyPart for a window?

**Answer**

The *closeWidget* action will destroy the widget. The *destroyPart* action will destroy the widget and release all connections. You want to destroy the part when closing the owning window to be sure that all connections are freed; otherwise dependencies will be left around and your image size will grow.

Resolution-Independent Screen

**Question**

When I change the screen resolution, say from 800*600 to 1280*1024, the text does not seem to scale properly. If there is a text label before an input field, the text ends up overlapping the input field. Is there a platform independent solution to fix this?

**Answer**

The best way to do this is by using widget attachments. Using the widget attachments, attach the right edge of the label field with either no attachment or attach it to its own left edge with 9 to 11 offset points per character of text in the label. Then, attach the left edge of the text field to the right edge of the label field with an offset of 2 or 3 pixels. To be safe, attach the top and bottom of the text field to the top and bottom of the label field with an offset of zero. If you want to get really fancy, group controls on
a form part or in a group box and offset the controls from each other and
the sides of the form or group and then offset the forms and group boxes.

Setting Minimum Window Size

**Question** How can you set or specify the minimum size for a window?

**Answer** The following script checks, after each window resize, whether it has exceeded a predefined minimum size. If so, it sets it to the predefined minimum size. Do not forget to connect the *resized* event of the window to this script.

Smalltalk

checkResize
| tempWidget minimumWidgetSize |
minimumWidgetSize := #(400, 200).
tempWidget := self primaryWidget.
( tempWidget width < minimumWidgetSize first ) ifTrue: [
tempWidget width:minimumWidgetSize first].
( tempWidget height < minimumWidgetSize last ) ifTrue: [
tempWidget height:minimumWidgetSize last]

Closing a Widget from a Script

**Question** I have created a view in which I show some customer information from an ordered collection that I dropped on the free form. I also dropped a button and connected it to the following script:

Smalltalk

return
"Close the widget and return."
self closeWidget.

When testing the script, the widget closes, but a dependent of ordered
collection remains in the Dependent dictionary. Is this not the proper way of
closing a view? I have noticed that if you close the view by using ALT-F4
from the system menu, the Dependent dictionary does not contain the ordered collection.

**Answer** You are leaving dependents lying around because you are using the private `closeWidget` method. You should use the `closeWidgetCommand` method instead. You could use the Script Editor to paste the proper action `closeWidgetCommand` into your method.

## Removing the Close Menu Option

**Question** How do I disable or remove the Close menu option on the system menu for a window?

**Answer** You can't, but you can add a `closeWidgetRequest` callback. That is a callback that is invoked before a shell is closed. If you set the `doit:` to `false`, the window is not closed. Normally this is used to display an "Are you sure?" message before closing the window. See `AbtApplicationsOrganizer->#confirmCloseRequest:` for an example. It hooks the `closeWidgetRequest` event to a script.

## Widget Warning: Circular Reference

**Question** I am getting a warning in the Transcript: "CwForm circular reference ..." My application works fine, but I would like to get rid of the warning. What should I look for?

**Answer** This means that you have one widget whose attachments are dependent on another widget, and the other widget's attachments are dependent eventually (if not immediately) on the first widget.

Here's an example of circularity. Widget A's bottom edge is attached to Widget B's bottom edge, while Widget B's left edge is attached to Widget A's right edge.
<figure><img src="image_10.png" /></figure>

The nonobvious restriction with attachments is that in order for Widget B to successfully attach to Widget A, Widget A's edges must be fully resolved. That is, they can't be directly or indirectly (by additional widgets) based on any of the edges of Widget B.

## Always-on-Top Window

**Question**

We have built a tool bar for our application. We would like the tool bar window to always stay on top. Is there a way in VisualAge for Smalltalk to set a window to always stay on top? I know there is a windows application programming interface (API) that will keep a window on top, but I do not know how to get it if from VisualAge.

**Answer**

An easy way to do this is to use `CwOverrideShell` rather than `CwTopLevelShell` as the shell class for the window. This will cause it to float on top of all other windows. If you want the tool bar to float on top of a specific window, then make the tool bar a child of the other window (by setting its parent to be the other window). Either of the above methods requires digging into IBM Smalltalk a bit.

## Changing the Mouse Pointer

**Question**

When the mouse pointer enters into the scope of an editable field, the pointer changes from the arrow to the I-beam. Is it possible to accomplish a similar behavior while crossing over some arbitrary other control, like a form or button?
Answer

To change the shape of the pointer when moving over a button, do the following:

1. Create a new visual part.

2. Put a push button in the window.

3. Go to the Script Editor. In the class definition for your part, add an instance variable named *cursor* and save the class definition.

4. Implement the following instance methods:

Smalltalk

changeCursor
"Change cursor for Push Button1."
| display |

display := (self subpartNamed: 'Window') yourself
primaryWidget display.

self freeCursor.

self cursor: (display createFontCursor: (CgConstants at: 'XCGumby')).

(self subpartNamed: 'Push Button1') yourself
primaryWidget window
defineCursor: self cursor.

Smalltalk

cursor
"Answer the currently selected CgCursor, or nil."

^cursor

Smalltalk

cursor: aCgCursorOrNil
"Set or clear the currently selected CgCursor."

cursor := aCgCursorOrNil

Smalltalk

freeCursor
"Free the cursor if one is allocated."

self cursor notNil
ifTrue: [ self cursor freeCursor ]