═══ About this Information ═══ The How Do I... information provides solutions to common tasks that you would perform with the various components of VisualAge C++. Before you begin to use this information, it would be helpful to understand how to navigate through it:  Use the Contents and Index facilities to locate topics.  Use the Search facility to search the text of this document.  Use hypertext links to acquire related information on the current topic. Hypertext links appear in a different color (which you can customize using the OS/2 Scheme Palette). For example, below there are two lists of hypertext links. By double-clicking on the text of the link or by pressing Enter on a highlighted link, you will open a panel of related information. To shift the focus to other links using the keyboard, use the Tab key. For more information on using this help facility, see:  How to Use the Contents  How to Obtain Additional Information  How to Access and Use IPF Facilities For more information, see:  Other Information You Might Find Helpful  Communicating Your Comments to IBM  Notices  Trademarks ═══ How to Use the Contents ═══ The Contents window is the first to appear. Some topics have a plus ( ) icon beside them. This icon indicates that additional topics are available. To expand the Contents if you are using a mouse, click on the plus ( ) icon. If you are using the keyboard, use the Up or Down Arrow key to highlight the topic, and press the plus (+) key. To see additional topics for a heading with a plus ( ) icon, click on the icon or highlight that topic and press the plus (+) key. To view a topic, double-click on the topic (or press the Up or Down Arrow key to highlight the topic, and then press the Enter key). ═══ How to Obtain Additional Information ═══ After you select a topic, the information for that topic appears in a window. Highlighted words or phrases indicate that additional information is available. Certain words and phrases are highlighted in a different color from the surrounding text. These are called hypertext terms. If you are using a mouse, double-click on the highlighted word. If you are using a keyboard, press the Tab key to move to the highlighted word, and then press the Enter key. Additional information then appears in a window. ═══ How to Access and Use IPF Facilities ═══ Several choices are available for managing the information presented in this document. There are three PullDown menus: the Services menu, the Options menu, and the Help menu. The actions that are selectable from the Services menu operate on the active window currently displayed on the screen. These actions include the following: Placing Bookmarks You can set a placeholder so you can retrieve information of interest to you. Searching for Information You can find occurrences of a word or phrase in the current topic, selected topics, or all topics. Printing Information You can print one or more topics. You can also print a set of topics by first marking the topics in the Contents list. Copying Information to a File You can copy a topic that you are viewing to the System Clipboard or to a file that you can edit. This method is particularly useful for copying syntax definitions and program samples into the application that you are developing. Using the actions that are selectable from the Options menu, you can change the way your Contents list is displayed. To expand the Contents and show all levels for all topics, choose Expand all from the Options PullDown menu. You can also press the Ctrl, Shift and * keys together. The actions that are selectable from the Help menu allow you to select different types of help information. For information about any of the menu choices, highlight the choice in the menu and press F1. ═══ Placing Bookmarks ═══ When you place a bookmark on a topic, it is added to a list of bookmarks you have previously set. You can view the list, and you can remove one or all bookmarks from the list. If you have not set any bookmarks, the list is empty. To set a bookmark, do the following: 1. Select a topic from the Contents. 2. When that topic appears, select the Bookmark option from the Services menu. 3. If you want to change the name used for the bookmark, type the new name in the field. 4. Click on the Place radio button (or press the Up or Down Arrow key to select it). 5. Click on OK (or select it and press Enter). The bookmark is then added to the bookmark list. ═══ Searching for Information ═══ You can specify a word or phrase to be searched. You can also limit the search to a set of topics by first marking the topics in the Contents list. To search for a word or phrase in all topics, do the following: 1. Select the Search option from the Services menu. 2. Type the word or words to be searched for. 3. Click on All sections (or press the Up or Down Arrow keys to select it). 4. Click on Search (or select it and press Enter) to begin the search. 5. The list of topics where the word or phrase appears is displayed. ═══ Printing Information ═══ You can print one or more topics, the index, or the table of contents. Make sure that your printer is connected to the serial port, configured correctly, and ready for input. To print: 1. Select Print from the Services menu. 2. Select what you want to print. Note that the This section and Marked sections choices are only available if you are viewing a topic or if you have marked topics, respectively. To mark topics in the table of contents, press the Ctrl key and click on the topics, or use the arrow keys. 3. Select Print to print what you've chosen on your printer. ═══ Copying Information to a File ═══ You can copy a topic that you are viewing in two ways:  Copy copies the topic that you are viewing into the System Clipboard. If you are using a Presentation Manager (PM) editor (for example, the Enhanced Editor) that copies or cuts (or both) to the System Clipboard, and pastes to the System Clipboard, you can easily add the copied information to your program source module.  Copy to file copies the topic that you are viewing into a temporary file named TEXT.TMP. You can later edit that file by using any editor. TEXT.TMP is placed in the directory where your viewable document resides. To copy a topic, do the following: 1. Expand the Contents list and select a topic. 2. When the topic appears, select Copy to file from the Services menu. 3. The system puts the text pertaining to that topic into the temporary file TEXT.TMP. ═══ Other Information You Might Find Helpful ═══ The VisualAge C++ provides a number of online guides and references that we hope you'll find helpful as you develop applications. This information includes:  User's Guide information provides conceptual and usage information,  Reference information is organized for quick access, and  How Do I... information gives you specific instructions for performing common tasks. You can get to this online information from the Information folder inside the main product folder. You can also get to it from the Help menu in any of the components of the product. ═══ Communicating Your Comments to IBM ═══ If there is something you like, or dislike, about this document, please let us know. You can use one of the methods listed below to send your comments to IBM. Please be sure to include the complete title of the publication that you are commenting on. For example, you would refer to the How Do I... information for the Browser as: VisualAge C++ Browser: How Do I... for OS/2. The comments you send should only pertain to the information in this document and its presentation. To request additional publications or to ask questions or make comments about the functions of IBM products or systems, you should talk to your IBM representative or your authorized IBM remarketer. When you send comments to IBM, you grant IBM a nonexclusive right to use or distribute your comments in any way it believes appropriate without incurring any obligation to you. You can send your comments to IBM in the following ways:  By mail to the following address: IBM Canada Ltd. Laboratory Information Development 2G/345/1150/TOR 1150 EGLINTON AVENUE EAST NORTH YORK, ONTARIO CANADA M3C 1H7  By FAX to the following number: - United States and Canada: (416) 448-6161 - Other countries (+1) 416-448-6161  By electronic mail to one of the following IDs. Be sure to include your entire network address if you wish to get a reply. - Internet: torrcf@vnet.ibm.com - IBMLink: toribm(torrcf) - IBM/PROFS: torolab4(torrcf) - IBMMAIL: ibmmail(caibmwt9) ═══ Notices ═══ Copyright International Business Machines Corporation, 1995. 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. This edition applies to Version 3.0 of IBM VisualAge C++ for OS/2 (30H1664, 30H1665, 30H1666) and to all subsequent releases and modifications until otherwise indicated in new editions. Make sure you are using the correct edition for the level of the product. This publication could include technical inaccuracies or typographical errors. Changes are periodically made to the information herein; any such changes will be reported in subsequent revisions. Requests for publications and for technical information about IBM products should be made to your IBM Authorized Dealer or your IBM Marketing Representative. When you send information to IBM, you grant IBM a nonexclusive right to use or distribute the information in any ways it believes appropriate without incurring any obligation to you. Any reference to an IBM licensed program in this publication is not intended to state or imply that only IBM's licensed program may be used. Any functionally equivalent product, program, or service that does not infringe any of IBM's intellectual property rights may be used instead of the IBM product, program, or service. Evaluation and verification of operation in conjunction with other products, except those expressly designated by IBM, is the user's responsibility. IBM may have patents or pending patent applications covering subject matter in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to the IBM Director of Licensing. IBM Corporation, 500 Columbus Avenue, Thornwood, NY, 10594, USA. This publication contains examples of data and reports used in daily business operations. To illustrate them as completely as possible, the examples include the names of individuals, companies, brands, and products. All of these names are fictitious and any similarity to the names and addresses used by an actual business enterprise is entirely coincidental. ═══ Trademarks and Service Marks ═══ The following terms used in this publication are trademarks or service marks of IBM Corporation in the United States or other countries: C/2 C Set/2 C Set ++ Common User Access CUA IBM Operating System/2 OS/2 Personal System/2 Presentation Manager PS/2 VisualAge WorkFrame/2 Other company, product, and service names, which may be denoted by a double asterisk(**), may be trademarks or service marks of others. ═══ 1. ...Create a simple Visual Builder application ═══ Creating the To-Do List application consists of the following steps:  Starting Visual Builder for the To-Do List application  Creating a new visual part for the To-Do List application  Placing parts in the application window  Resizing and aligning the parts  Connecting the parts  Generating the C++ code for your application  Building the application  Running the application  Exiting the Composition Editor and Visual Builder ═══ 1.1. Start Visual Builder for the To-Do List application ═══ Before you create the To-Do List application, start Visual Builder. For this sample application, start Visual Builder from the Tools folder, as follows: 1. Double-click on the VisualAge C++ folder icon on your desktop. The VisualAge C++ folder opens. 2. Double-click on the Tools folder icon. The Tools folder opens. 3. Double-click on the Visual Builder icon. Visual Builder displays the Visual Builder window, as shown in the following figure. Now it is time to create a new visual part for the To-Do List application. ═══ 1.2. Create a new visual part for the To-Do List application ═══ The next thing to do when creating the To-Do List application is to create the main part, a new visual part, as follows: 1. Select PartNew. Visual Builder displays the Part - New window, as shown in the following figure: The Part - New window provides the following fields in which you can enter information about your part:  The Class name field, where you enter the name of your part. Each composite part must have a name. For the To-Do List application, enter the following: ToDoList  The Description field, where you enter a description of your part. For this example, enter the following: The To-Do List application  The File name field, where you enter the name of the .vbb file in which you want Visual Builder to store your part. For this example, you can either leave this field blank or enter the following: ToDoList.vbb This causes Visual Builder to store the ToDoList part in a file named todolist.vbb. If you leave this field blank, Visual Builder uses the part name as the name of the .vbb file by default, so the result is the same.  The Part type field, where you indicate the type of part. This field initially contains Visual part. However, you can specify a different type of part to create by selecting one from the field's drop-down list box. For this example, do not select a different part type because you want to create a visual part for the To-Do List application.  The Base class field, where you specify the class that you want to be the base class of the part that you are creating. The base class is the part that part you are creating inherits attributes, events, and actions from. The Base class field contains the default base class name of IFrameWindow, which Visual Builder uses when you specify that you want to create a new visual part. For this example, leave IFrameWindow as the base class. 2. Select the Open push button to create a visual part named ToDoList whose parent is IFrameWindow. This causes Visual Builder to display the Composition Editor. If you look back at the Visual Builder window, you see that the file todolist.vbb is now included in the list of loaded files. This file was created for you when you selected the Open push button in the Part - New window. Before you place any parts in the application window, first edit its title. Changing the title of the To-Do List application window The new visual part that you just created contains an IFrameWindow* part. This will be the To-Do List application window. Change the title of this window by doing the following: 1. Hold down the Alt key. 2. Click on the title bar with mouse button 1. 3. Type the new title text, such as To-Do List. 4. Press Shift+Enter after you have changed the window title. ═══ 1.3. Place parts in the application window ═══ Now that you have created your new visual part and edited the title of the application window, it is time to place the other parts of the To-Do List application in the application window. Placing a static text part in the window The To-Do List application needs two static text parts. Follow these steps to place the first static text part in the To-Do List application window: 1. Select , the Data entry category, from the row of icons on the left-hand side of the parts palette. 2. Select , the IStaticText* icon, from the row of icons on the right-hand side of the parts palette. When you move the mouse pointer over the free-form surface, you see that it has changed to crosshairs. This means the mouse pointer is loaded with the IStaticText* part. 3. Place the crosshairs in the upper-left corner of the To-Do List application window's client area and click mouse button 1. A static text part is placed in the window. 4. Change the text of the static text part to To-do item. Use the same method for changing text that you learned previously when you changed the title of the To-Do List application window. Placing an entry field in the window The To-Do List application needs an entry field part. Follow these steps to place an entry field part in the To-Do List application window: 1. Select , the Data entry category, from the row of icons on the left-hand side of the parts palette. 2. Select , the IEntryField* icon, from the row of icons on the right-hand side of the parts palette. 3. Place the crosshairs beneath the first static text part and click mouse button 1. The entry field part is placed beneath the static text part. Placing another static text part in the window The To-Do List application needs another static text part. Follow these steps to place and modify this part: 1. Place the second static text part in the To-Do List application window. Use the same method for placing a static text part that you learned previously when you placed the first static text part in the To-Do List application window. 2. Change the text of the static text part to To-do list. Use the same method for changing text that you learned when you changed the title of the To-Do List application window. Placing a list box in the window Because the to-do list is to consist of a list of text strings, you want to store that list in an IListBox* part. Follow these steps to place a list box part in the To-Do List application window: 1. Select , the Lists category, from the row of icons on the left-hand side of the parts palette. 2. Select , the IListBox* icon, from the row of icons that Visual Builder displays on the right-hand side of the parts palette. 3. Place the crosshairs below the second static text part and click mouse button 1. The list box part is placed beneath the second static text part. Placing the push buttons in the window The To-Do List application needs two push buttons, one for adding items to the list and one for removing items from the list. Follow these steps to place two push button parts in the To-Do List application window: 1. Select , the Buttons category, from the row of icons on the left-hand side of the parts palette. 2. Select , the IPushButton* icon, from the row of icons on the right-hand side of the parts palette. 3. Place the crosshairs below the lower-left corner of the list box and click mouse button 1. The first push button part is placed in the window. 4. Select the IPushButton* icon again. 5. Place the crosshairs to the right of the first push button and click mouse button 1. The second push button is placed in the window. 6. Change the text of the first push button to Add. Use the same method you used to change the text in the title bar. 7. Change the text of the second push button to Remove. ═══ 1.4. Size and align the parts ═══ Now that you have placed all of the parts you need in the application window, it is time to resize and align them. When you have finished, your application window should look like the following figure: Matching the width of the list box to the width of the entry field Follow these steps to match the width of the list box to the width of the entry field: 1. Move the mouse pointer over the list box. 2. Press and hold mouse button 1. The selection handles appear at the four corners of the list box. 3. While holding down mouse button 1, move the mouse pointer to the entry field. The selection handles on the list box become hollow and black selection handles appear on the four corners of the entry field. This means that both parts are selected, but the entry field is the anchor part. Therefore, any sizing actions performed using the tool bar cause the list box to match the size of its anchor part, the entry field. 4. Select , the Match Width tool, from the row of icons on the tool bar, located beneath the menu bar. The width of the list box changes to match that of the entry field. Matching the width of the Add push button to that of the Remove push button Using the techniques you learned in the preceding steps, match the width of the Add push button to that of the Remove push button. Dragging and dropping parts in the application window Before you align the parts, you might want to drag and drop some of them to put them in closer proximity to each other. For example, you might want the static text parts to be closer to the parts that they label. Follow these steps to drag and drop the parts in the application window: Note: The following instructions are written for dragging and dropping multiple parts simultaneously. If you just want to drag and drop one part at a time, you can skip the first step. 1. Select all of the parts you want to drag using the technique you learned previously when matching the width of the list box to the width of the entry field. 2. Move the mouse pointer over one of the parts that you selected to drag. 3. Press and hold mouse button 2 and move the mouse cursor. Visual Builder displays an outline of the parts that you are dragging. 4. Move the outline to the place where you want to drop the parts and release mouse button 2. The parts are moved to their new location. Resizing the application window At this point, the parts in the application window are closer to the left window border than to the right window border. Follow these steps to resize the application window: 1. Select the application window by clicking mouse button 1 on the title bar. 2. Move the mouse pointer over the selection handle on the lower-right corner of the application window. 3. Press and hold mouse button 1. 4. Resize the application window by dragging the mouse pointer towards the left until the right border of the application window is approximately the same distance from the entry field and list box as the left border is. To size the window in only one direction, either horizontally or vertically, hold down the Shift key while dragging the mouse pointer. Centering the entry field and list box within the application window The entry field and list box need to be centered within the application window. Follow these steps to center them: 1. Select the entry field. 2. Select , the Distribute Horizontally tool, from the row of icons on the tool bar. Visual Builder centers the entry field between the left and right borders of the application window. 3. Select the list box and then the entry field, making the entry field the anchor part. Use the multiple part selection technique you learned previously. 4. Select , the Align Center tool, from the row of icons on the tool bar. The list box is centered beneath the entry field. Aligning the static text, entry field, and list box parts so their left edges are even The static parts need to be aligned evenly with the left edges of the entry field and list box. Follow these steps to align them: 1. Select the first static text part and then select the entry field, making the entry field the anchor part. Use the multiple part selection technique you learned previously. 2. Select , the Align Left tool, from the row of icons on the tool bar. The first static text part is aligned even with the left edge of the entry field. 3. Repeat steps 1 and 2 for the second static text part and the list box. The second static text part is aligned even with the left edge of the list box. Aligning the top edges of the push buttons The push buttons need to be aligned so that their top edges are even. Follow these steps to align them: 1. Select the Add push button and then select the Remove push button. Use the multiple part selection technique you learned previously. 2. Select , the Align Top tool. Visual Builder aligns the Add push button even with the top of the Remove push button. Spacing the push buttons evenly across the application window The push buttons need to be evenly spaced across the width of the application window. Follow these steps to space them: 1. Select both push buttons. You can make either push button the anchor part. Use the multiple part selection technique you learned previously. 2. Select , the Distribute Horizontally tool. Visual Builder spaces both push buttons evenly across the application window. Centering the push buttons between the bottom edge of the list box and the bottom border of the application window The push buttons need to be centered between the bottom edge of the list box and the bottom border of the application window. Follow these steps to center them: 1. Select both push buttons. You can make either push button the anchor part. Use the multiple part selection technique you learned previously. 2. Move the mouse pointer over either push button. 3. Press and hold mouse button 2, and position the push buttons midway between the bottom edge of the list box and the bottom window border. 4. When the push buttons are in place, release mouse button 2. Your application should now look like the one shown in the following figure: ═══ 1.4.1. Connect the parts ═══ Now it is time for you to connect the parts so that your application can add items to and remove items from the to-do list. You need to connect the push buttons to the list box and entry field. The following steps show you how to do this. Before you start connecting parts, it is a good idea to make sure none of your parts is selected. Otherwise, the correct pop-up menus may not appear. To do this, hold down the Ctrl key, point to each item that is selected, and press mouse button 1. When the selection handles disappear, you know that the part is no longer selected. Connecting the Add push button to the list box The connection between the Add push button and the list box provides the information your application needs to add items to the list box. 1. With the mouse pointer over the Add push button, click mouse button 2. A pop-up menu is displayed. 2. Select Connect. A cascaded menu, called the connection menu, of the Add push button is displayed. 3. Select the buttonClickEvent feature. Selecting the buttonClickEvent feature means that you want something to happen whenever a user clicks this push button. The mouse pointer changes to look like a spider, indicating that it is ready for you to select another feature. 4. Move the mouse pointer to the list box and click mouse button 1. A pop-up menu is displayed showing the connection menu of the list box. 5. Select the addAsLast action. Selecting the addAsLast action means that you want new items to be added to the end of the to-do list whenever a user clicks the Add push button. The connection is shown in the following figure: The line connecting the Add push button to the list box is dark green. It points from the push button to the list box, showing that the event that occurs when the push button is selected will cause the list box to perform an action. Notice that the connection line is dashed instead of solid. A dashed line means that the connection is incomplete. The connection is supposed to add something to the list box when the Add push button is clicked, but you have not yet supplied what needs to be added. The next step does that. 6. Move the mouse pointer to the dashed connection line between the Add push button and the list box. 7. To take a shortcut to display connection menus, hold down the Alt key and click mouse button 2. The pop-up menu for the connection is displayed. 8. Select the text parameter. The text parameter is the reason the connection line is dashed. You need to give this parameter a value. 9. Move the mouse pointer over the entry field, and click mouse button 1. Visual Builder displays the connection menu for the list box. 10. Select the text attribute. Selecting the text attribute here means that you want to pass the text that a user enters in the entry field to the text parameter of the addAsLast action. This text string is added to the end of the to-do list whenever the addAsLast action is called, which occurs whenever the Add push button is clicked. The completed connection is shown in the following figure: The line connecting the entry field to the connection between the Add push button and the list box is violet. The solid arrow head points to the entry field, showing that the text attribute is the target of the connection. The hollow arrow head points to the connection line, indicating that the text parameter of the addAsLast action is the source of the connection. When the text parameter needs a value, which occurs when a user clicks on the Add push button, the connection invokes the get member function of the entry field's text attribute. The value of that attribute (the text in the entry field) is returned to the text parameter and the addAsLast action puts the text string in the list box. Notice that both of the connection lines are solid. This means that the connection between the Add push button and the list box now has the information it needs to perform its function, so the connection is complete. Connecting the Remove push button to the list box The connection between the Remove push button and the list box provides the information your application needs to remove items from the list box. 1. With the mouse pointer over the Remove push button, hold down the Alt key and click mouse button 2. Visual Builder displays the connection menu for the Remove push button. 2. Select the buttonClickEvent feature. 3. Move the mouse pointer to the list box and click mouse button 1. Visual Builder displays the connection menu for the list box. 4. Select the remove action. Selecting the remove action means that you want your application to remove the selected item in the to-do list whenever a user clicks the Remove push button. Once again, the connection is incomplete. 5. Move the mouse pointer to the connection between the Remove push button and the list box. 6. Hold down the Alt key and click mouse button 2. Visual Builder displays the connection menu for the connection. 7. Select the index parameter. The index parameter is the reason the connection line is dashed. You need to give this parameter a value. 8. Move the mouse pointer over the list box and click mouse button 1. Visual Builder displays the connection menu for the list box. 9. Select the selection attribute. Selecting the selection attribute means that you want to pass the index of the selected item in the list box to the index parameter of the remove action. The remove action uses this index to determine which item to remove whenever the Remove push button is clicked. Making this connection completes your application. It should now look like the one shown in the following figure: Note: In the preceding figure, we changed the shape of the connection between the Remove push button and the list box to make it easier for you to see. You can do this by selecting the connection and dragging the middle selection handle. Now that you have made all of the connections, the next step is to generate your C++ source code. ═══ 1.5. Generate the C++ code for my application ═══ The first thing you must do to get your application ready to build is to generate the C++ code. This is a two-part process that consists of generating the source code for your new visual part and then generating the source code for your main procedure. Generating the source code for your visual part To generate the C++ source code for your visual part, select FileSave and GeneratePart source. Another way to generate part code is to select , the Part Code Generation tool, on the tool bar. The results are the same. Visual Builder generates the following files in the working directory: todolist.cpp The C++ code for your ToDoList part. todolist.hpp The C++ header file for your ToDoList part. todolist.h The resource header file for your todolist.cpp file. todolist.rc The resource file for your todolist.cpp file. Generating the source code for your main() function To generate the source code for your main() procedure, select FileSave and Generatemain() for part. Visual Builder generates the following files in the working directory: todolist.app The main function for your application. Note: If you start Visual Builder from a WorkFrame project, the name of this file is vbmain.cpp. todolist.mak The make file that you specify when you build your application. You have now generated the C++ code for your application. The next step is to build the application. ═══ 1.6. Build the application ═══ Building your application consists of compiling and linking it. To build your application, do the following: 1. Open an OS/2 window. 2. Change to your Visual Builder working directory. 3. Enter the following command: nmake todolist.mak This command produces the following files: todolist.exe The executable file for your application. todolist.map The application configuration map. todolist.o The object file for your application. Note: If you start Visual Builder from a WorkFrame project, the name of this file is vbmain.obj. todolist.obj The object file for your part. Visual Builder provides a separate object module for your part that is used when compiling this part with other parts. todolist.res The binary resource file that is bound to todolist.exe. You have now built your application; the next step is to run your application. ═══ 1.7. Run the application ═══ To run your application from the same OS/2 command prompt from which you entered the nmake command, enter the following: todolist Once your application is running, experiment with it to make sure it works as you designed it. That is all there is to it! You can add a finishing touch to your application by creating an OS/2 program object. Create a program object from the OS/2 Templates folder, specifying the name todolist.exe as the program name and the directory that contains todolist.exe as the working directory. Once you have done this, you can run your application by simply double-clicking on the program object you just created. ═══ 1.8. Exit the Composition Editor and Visual Builder ═══ To exit either the Composition Editor or Visual Builder, do either of the following. Note: When you exit Visual Builder, any changes you have made to the selections in the Options menu are saved. Therefore, if you want certain options to be selected or deselected the next time you start Visual Builder, be sure to select or deselect them before exiting Visual Builder.  Select FileExit.  Double-click on the system menu icon in the window. If you try to exit Visual Builder while one or more editor windows is open, Visual Builder displays a message asking if you want to close the editors and Visual Builder. You can select either of the following:  The OK push button to exit the windows.  The Cancel push button to cancel the exit request. If you select the OK push button with this message displayed or try to exit an editor and the open editor window contains unsaved changes, Visual Builder displays a message asking if you want to save the changes for each open editor before exiting. You can select either of the following:  The Yes push button to save the changes and exit.  The No push button to exit without saving the changes.  The Cancel push button to cancel the exit request. ═══ 2. ...Set up and starting Visual Builder ═══ This chapter tells you how to do the following:  Set up your WorkFrame project to use Visual Builder  Start Visual Builder ═══ 2.1. Set up my WorkFrame project to use Visual Builder ═══ If you have created a WorkFrame project and will be running Visual Builder from the project folder, you should set up the project as follows before starting Visual Builder. Note: We recommend that you use a Project Smarts Visual Builder template in your WorkFrame project. Refer to the VisualAge C++ User's Guide for information on how to do this. 1. Open the settings notebook for the project folder by doing the following: a. Click on the project folder with mouse button 2. b. Select OpenSettings. The settings notebook appears. 2. Set the names of the executable file and the make file by doing the following: a. On the Target page, type the name that you want your executable file to have in the Name field. b. Type the name that you want your make file to have in the Makefile field. 3. Set the directory in which your project files will be stored by doing the following: a. Select the tab for the Location OS/2 Files page. b. Type the full path for the directory in which you want to store your project files in the multiline edit field on this page. This is the directory in which Visual Builder puts the files for your application when you generate your source code. 4. Inherit the settings of a C++ project by doing the following: a. Select the tab for the Inheritance page. b. Select the Add push button. A dialog is displayed in which you select the project whose settings you want to inherit. c. Double-click on the Desktop directory in the Directory list box. d. Double-click on the VisualAge C++ 3.0 directory, also in the Directory list box. e. Select the C Set ++ Project file in the File list box. f. Select the Inherit push button. This puts all of the WorkFrame tools, including Visual Builder, that you need for a C++ project in the project's pop-up menu, giving you easier access to them. 5. Close the settings notebook. start Visual Builder. ═══ 2.2. Start Visual Builder ═══ You can start Visual Builder in the following ways:  From the C/C++ window  From the Tools folder icon  From a WorkFrame Project folder Starting Visual Builder from the C/C++ window To start Visual Builder from the C/C++ window, do the following: 1. Double-click on the icon for the VisualAge C++ folder. The folder opens. 2. Double-click on the C/C++ Window icon. The C/C++ window opens. 3. Type the following: icsvb 4. Press the Enter key. Visual Builder displays the Visual Builder window, as shown in the following figure. Starting Visual Builder from the Tools folder To start Visual Builder from the Tools folder, do the following: 1. Double-click on the icon for the VisualAge C++ folder. The folder opens. 2. Double-click on the Tools folder icon. The folder opens. 3. Double-click on the Visual Builder icon. Visual Builder displays the Visual Builder window, as shown in the preceding figure. Starting Visual Builder from a WorkFrame Project folder You can start Visual Builder from a WorkFrame Project folder in the following ways. Note: The following steps assume that your project inherits the settings of a C Set ++ project or that it was created using a Project Smarts template.  If the WorkFrame Project folder is closed, you can click on the folder with mouse button 2 and select Visual from the pop-up menu.  If the WorkFrame Project folder is open, you can do any one of the following: - Double-click on the name of the .vbb file - Click on the name of the .vbb file with mouse button 2 and select Visual from the pop-up menu. - Click on the white space in the project folder with mouse button 2 and select Visual from the pop-up menu. Visual Builder displays the Visual Builder window, as shown in the preceding figure. If you double-clicked on a .vbb file to open Visual Builder, that file and all other .vbb files that you selected are preloaded. ═══ 3. ...Load part files ═══ To give Visual Builder access to parts, you must load the contents of the part files that contain those parts by doing the following: 1. Select FileLoad file in the Visual Builder window. Visual Builder displays the window shown below: 2. Select the file or files that you want to load. 3. Select the OK push button. When you are just loading one file, it is quicker to double-click on the file name instead of selecting the file name and the OK push button. The file name or names are displayed in the Loaded Part Files list box in the Visual Builder window. The following figure shows the Visual Builder window with multiple .vbb files loaded. ═══ 4. ...Unload part files ═══ If a part file appears in the Loaded Part Files list box in the Visual Builder window, Visual Builder has access to the parts that the part file contains. If you do not want Visual Builder to have access to those parts, you can unload the part file, with the exception of vbbase.vbb. To unload one or more part files, do the following: 1. Select one or more files in the Loaded Part Files list box. To select multiple files, hold down the Ctrl key while clicking on a file name with mouse button 1. 2. Select FileUnload file. The following window is displayed showing the files you selected to unload: At this point, you can review the files that you selected and make any changes by deselecting any file or files that you want to remain loaded. 3. Select the Unload push button. The window disappears and the file names are removed from the Loaded Part Files list box. ═══ 5. ...Select all part files ═══ To select all of the part files, select EditSelect all files. Visual Builder highlights all of the part files listed in the Loaded Part Files list box. At this point, you can review the list to see if you want to deselect any of the files. ═══ 6. ...Deselect all part files ═══ To deselect all of the part files, select EditDeselect all files. Visual Builder removes the highlighting from all of the selected part files listed in the Loaded Part Files list box. At this point, you can review the list to see if you want to select any of the files. ═══ 7. ...Customize the information area ═══ The following options allow you to specify the kind of information that Visual Builder displays in the information area for a selected part in the Visual Builder window. To use these options, select OptionsInformation area and then select one of the following options: Show base class Displays the C++ notation for a class and its base class. For example, if you select IVBContainerControl when this option is selected, Visual Builder displays the following in the information area to show that IControl is IVBContainerControl's base class: IVBContainerControl::IControl Show description Displays a brief description of the selected part. For example, if you select IVBContainerControl when this option is selected, Visual Builder displays the following description in the information area: IBM container control, any view Show full file names Displays the name of the part file in which the part is stored. For example, if you select IVBContainerControl when this option is selected, Visual Builder displays the following file name in the information area to show that VBBase.vbb contains the IVBContainerControl part. VBBase.vbb ═══ 8. ...See the base files ═══ Select OptionsShow base files to see the names of the parts in the .vbb files that Visual Builder provides, as follows: VBBase.vbb Contains the base parts that Visual Builder provides. VBCC.vbb Contains sample parts based on the IBM Collection Class Library. VBMM.vbb Contains sample multimedia parts. ═══ 9. ...See where part files are located ═══ Select OptionsShow full file names to see the drive and directory where each of your part files is stored. ═══ 10. ...See the type list ═══ To display a type list, do the following: 1. Select the part file or files for which you want to see defined types. 2. Select OptionsShow type list. A list box titled Loaded Type Information is displayed at the bottom of the Visual Builder window, as shown in the following figure. ═══ 11. ...Use File Allocation Table (FAT) file names ═══ Select Default to FAT file names if your system uses the File Allocation Table (FAT) file system instead of the High Performance File System (HPFS). This option is selected by default when you first install VisualAge C++. The FAT file system limits file names to a maximum of eight characters and file name extensions to a maximum of three characters. ═══ 12. ...Generate make files ═══ Select Generate make files if you want Visual Builder to generate a make file for you when you generate the default source code for the main() function of your application. ═══ 13. ...Set the working directory ═══ Select OptionsSet working directory if you want to store files created with Visual Builder in a different working directory. The default working directory is the directory in which you installed Visual Builder. When you select this option, Visual Builder displays the following window: To change the working directory, do the following: 1. Type the complete path to the directory in which you want to store Visual Builder files that you create. The path consists of all directories that must be opened to get to the working directory. 2. Select the OK push button. If the path you enter in the Working Directory window is invalid, Visual Builder displays an error message and resets the path to the last valid path that was entered. ═══ 14. ...Refresh the display ═══ You might want to ensure that the information displayed in the Visual Builder window is current, for example, when you have loaded and unloaded several part files or moved parts from one part file to another. If such a situation occurs, you can cause the display to show the latest updates by selecting EditRefresh. ═══ 15. ...Work with the Class Editor ═══  Entering a description of a part  Moving a part to a different .vbb file  Seeing the base class of a part  Modifying a part's constructor  Specifying your own constructor code  Specifying your own destructor code  Specifying a library file  Specifying a starting resource ID  Specifying a unique icon for your part  Specifying the names of your code generation files  Specifying files to include when you build your application ═══ 15.1. Enter a description of a part ═══ The Description field in the Class Editor is an entry field in which you can enter a description of your part. This description is used in the following places:  If you add your part to the parts palette, the description appears in the information area at the bottom of the Composition Editor when you select the part.  If you export your part information into a .vbe file, the description is included in the first line. In the following example, the text shown in quotation marks was taken from the Description field for the ToDoList part. //VBBeginPartInfo: ToDoList,"To-Do List sample application" ═══ 15.2. ...Move a part to a different .vbb file from the Class Editor ═══ The Part file specification field in the Class Editor shows the name of the .vbb file that contains this part. If you want to move this part to another .vbb file while using the Class Editor, do the following: 1. Replace the name of the current .vbb file with the name of another .vbb file in which you want to store the part. 2. Select FileSave to apply the change. Visual Builder moves the part from the former .vbb file to the one you just specified. If the .vbb file you specified does not exist, Visual Builder creates it for you. ═══ 15.3. ...See the base class of a part ═══ The Base class - access level field in the Class Editor shows the name of the base class for your part. This is the class name that you specified as the base class when you created the part. This field also shows you the current access level to the base class: public, protected, or private. You cannot modify the base class name or the access level. ═══ 15.4. ...Modify a part's constructor ═══ The Constructor field in the Class Editor initially contains a default constructor that Visual Builder inserts for you. If the default constructor does not do exactly what you want it to do, you can modify it by typing over the text in this field. If you want your class to have multiple constructors, we recommend putting them in the .hpv and .cpv files that contain your default feature code and then including them when you generate your code. Otherwise, if you modify your code after generating it, your changes will be lost the next time you generate your code. For information about including files, see Specifying Files for Visual Builder to Include When You Build Your Application. ═══ 15.5. ...Specify my own constructor code ═══ Use the User constructor code field in the Class Editor to enter your own constructor code for the part that you are editing. If you enter code in this field, it is added at the end of the default constructor that Visual Builder provides for you. If you have more than one line of code, put your code into a function and put the function name in this field. Put the code for this function in the files that Visual Builder creates when you generate your default feature code. These file names are specified in the User .hpv file and User .cpv file fields. ═══ 15.6. ...Specify my own destructor code ═══ Use the User destructor code field in the Class Editor to enter your own destructor code for the part that you are editing. If you enter code in this field, it is added at the beginning of the default destructor that Visual Builder provides for you. If you have more than one line of code, put your code into a function and put the function name in this field. Put the code for this function in the files that Visual Builder creates when you generate your default feature code. These file names are specified in the User .hpv file and User .cpv file fields. ═══ 15.7. ...Specify a library file ═══ Use the .LIB file name field in the Class Editor to specify the name of a library file (partname.lib) that you want to to be included when you generate the source code for your part. The library file points to a .dll file that contains information about a subpart in your application that was compiled separately. When you generate the source code for your part, Visual Builder includes a #pragma statement to include the library file. When Visual Builder generates make files for other parts that use this part, the .lib file is specified in the make file as a dependency. ═══ 15.8. ...Specify a starting resource ID ═══ Use the Starting resource id field in the Class Editor to specify the number that Visual Builder is to use as a starting point for generating resource IDs for your part. The resource IDs that Visual Builder generates are written into a file named partname.h, which Visual Builder creates when you generate code for your part. The check box next to the field enables the starting resource ID. The first time you select this check box, Visual Builder inserts a default starting resource ID. You can change this number. If you deselect the check box, the field is disabled. The number in the field is included in the partname.h file when you generate your code, but it is not referenced. Generating resource IDs is useful if the text in your application is being translated into another language. See Enabling National Language Support for an Application for more information about using starting resource IDs. ═══ 15.9. ...Specify a unique icon for my part ═══ Fill in the fields in the Icon group box in the Class Editor before you add your part to the parts palette so that you can use an icon other than the default icon provided by Visual Builder to represent your part. The default icon is . The Icon group box contains the following fields: DLL name An entry field in which you enter the name of the resource DLL that contains the icon you want to use. Enter just the file name, not the extension. Resource Id The resource ID number of the icon in the DLL whose name you entered in the DLL name field. When you enter both the DLL name and a valid resource ID number, Visual Builder displays the icon that matches the resource ID number in the area below the Resource Id field. This occurs when you click on another field. This allows you to verify that you entered the correct resource ID number. ═══ 15.10. ...Specify the names of my code generation files ═══ The Code generation files group box in the Class Editor contains the following fields:  A C++ header file (.hpp) field  A C++ code file (.cpp) field The file names displayed in these fields are the files into which your C++ header file code and source code are written. This occurs when you generate default code from the Visual Builder window or from any of the editors by selecting FileSave and GeneratePart source. For complete information about generating default source code, see Generating Source Code for Parts and Applications. The fields in the group box initially contain .hpp and .cpp file names that are based on the name of the part you are editing. To change the file names in these fields, select FileSave so that Visual Builder uses the new file names. Warning: If the files already exist, Visual Builder replaces their contents with the code currently being generated. Visual Builder writes both files to the current directory. ═══ 15.11. ...Specify files to include when I build my application ═══ The User files included in generation group box in the Class Editor allows you to specify files that you want to be included when you build your application. These fields are typically used to contain the names of the files that hold user code that Visual Builder is to use when you generate default feature code for your part's features. The .hpv and .cpv file extensions are used because the WorkFrame Build tool tries to compile every .cpp file that it finds into an object module (.obj file). Since these files are not meant to be compiled by themselves, we selected a different file extension for you to use to prevent this from happening. ═══ 16. ...Add an attribute ═══ To add an attribute in the Part Interface Editor, do one of the following:  If you want to add the attribute using the default attribute type, get member function, set member function, and event identification that Visual Builder provides, enter a name in the Attribute name field and select the Add with defaults push button. Visual Builder adds the attribute to the part interface.  If you want to see the default attribute type, get member function, set member function, and event identification that Visual Builder provides before you add the attribute, select the Defaults push button.  If you want to add the attribute after seeing or modifying its default information or after entering your own information, select the Add push button. Visual Builder adds the attribute to the part interface. ═══ 17. ...Change an attribute ═══ To change, or update, an attribute in the Part Interface Editor, do the following. Note: You can change anything about an attribute except its name. To change an attribute's name, you must create a new attribute with the name you want to use. 1. Select the attribute that you want to change or type its name in the Attribute name field. 2. Make the changes that you want to make in the fields on the right side of the Attribute page. 3. Select the Update push button. Visual Builder saves the changes you made. ═══ 18. ...Delete an attribute ═══ To delete an attribute in the Part Interface Editor, do the following: 1. Select the attribute that you want to delete or type its name in the Attribute name field. 2. Select the Delete push button. Visual Builder deletes the attribute. Note: If you added the attribute that you just deleted to the preferred features list, you must go to the Preferred page and delete it there, too. ═══ 19. ...Set defaults for an attribute ═══ To set defaults for an attribute in the Part Interface Editor, do the following: 1. Select the attribute that you want to set defaults for or type its name in the Attribute name field. 2. Change the attribute type in the Attribute type field. 3. Select the Defaults push button. Visual Builder changes all occurrences of the former attribute type to the new attribute type in the fields on the right side of the Attribute page. ═══ 20. ...Clear the Attribute page fields ═══ To clear the fields on the Attribute page, select the Clear push button. Visual Builder clears all of the fields on the Attribute page. ═══ 21. ...Add an event ═══ To add an event in the Part Interface Editor, do one of the following:  If you want to add the event using the default event identification that Visual Builder provides, enter a name in the Event name field and select the Add with defaults push button. Visual Builder adds the event to the part interface.  If you want to see the default event identification that Visual Builder provides before you add the event, select the Defaults push button. To add a parameter and its type to this table, do the following. Note: You can add only one parameter and type for each event. 1. Move the mouse pointer over the table and click mouse button 2. Visual Builder displays a pop-up menu. 2. Select either Add before or Add after. Visual Builder adds a row to the table with a default parameter name and type. 3. If you want to change the defaults, do the following: a. Click on the parameter name with mouse button 1. b. Type the parameter name you want to use. c. Click on the parameter type with mouse button 1. d. Type the parameter type you want to use. e. Select the Update push button. ═══ 22. ...Change an event ═══ To change, or update, an event, do the following. Note: You can change anything about an event except its name. To change an event's name, you must create a new event with the name you want to use. 1. Select the event that you want to change or type its name in the Event name field. 2. Make the changes that you want to make in the fields on the right side of the Event page. 3. Select the Update push button. Visual Builder saves the changes you made. ═══ 23. ...Delete an event ═══ To delete an event, do the following: 1. Select the event that you want to delete or type its name in the Event name field. 2. Select the Delete push button. Visual Builder deletes the event. Note: If you added the event that you just deleted to the preferred features list, you must go to the Preferred page and delete it there, too. ═══ 24. ...Set defaults for an event ═══ To set defaults for an event, do the following: 1. Select the event that you want to set defaults for or type its name in the Event name field. 2. Select the Defaults push button. Visual Builder changes the former event identification to the default event identification in the Event identification field. ═══ 25. ...Clear the Event page fields ═══ To clear the fields on the Event page, select the Clear push button. Visual Builder clears all of the fields on the Event page. ═══ 26. ...Add an action ═══ To add an action in the Part Interface Editor, do one of the following:  If you want to add the action using the part you are editing as the default return type, enter a name in the Action name field and select the Add with defaults push button. Visual Builder adds the action to the part interface.  If you want to see the default return type before you add the action, select the Defaults push button. ═══ 27. ...Change an action ═══ To change, or update, an action in the Part Interface Editor, do the following. Note: You can change anything about an action except its name. To change an action's name, you must create a new action with the name you want to use. 1. Select the action that you want to change or type its name in the Action name field. 2. Make the changes that you want to make in the fields on the right side of the Action page. 3. Select the Update push button. Visual Builder saves the changes you made. ═══ 28. ...Delete an action ═══ To delete an action in the Part Interface Editor, do the following: 1. Select the action that you want to delete or type its name in the Action name field. 2. Select the Delete push button. Visual Builder deletes the action. Note: If you added the action that you just deleted to the preferred features list, you must go to the Preferred page and delete it there, too. ═══ 29. ...Set defaults for an action ═══ To set defaults for an action in the Part Interface Editor, do the following: 1. Select the action that you want to set defaults for or type its name in the Action name field. 2. Select the Defaults push button. Visual Builder changes the former return type to the default return type in both the Action member function and the Return type fields. ═══ 30. ...Clear the Action page fields ═══ To clear the fields on the Action page, select the Clear push button. Visual Builder clears all of the fields on the Action page. ═══ 31. ...Promote a feature ═══ To promote a feature in the Part Interface Editor for a subpart, do the following: 1. Select a subpart name from the list box beneath the Subpart name field or type the name in the field. Visual Builder displays the name of the subpart that you select in the Subpart name field. 2. Select a feature type from the list box beneath the Feature type field or type the name in the field. Visual Builder displays the type that you select (attribute, event, or action) in the the Feature type field. 3. Select the feature that you want to promote from the list box beneath the Promotable feature field or type the name in the field. Visual Builder displays the feature that you select in the Promotable feature field. 4. Do one of the following:  If you want to promote the feature using the default name that Visual Builder provides, select the Add with defaults push button. Visual Builder promotes the feature and displays the feature name in both the Promote feature name field and in the list box below this field.  If you want to see the default feature name that Visual Builder provides before you promote the feature, select the Defaults push button. Visual Builder displays the default name for the feature in the Promote feature name field.  If you want to promote a feature after seeing its default name or typing another name that you prefer, select the Add push button. Visual Builder promotes the feature using the name in the Promote feature name field and displays the name in the list box below this field. ═══ 32. ...Change a promoted feature ═══ To update a feature that you have already promoted, do the following: 1. Select the promoted feature that you want to update. 2. Select those aspects of the promoted feature that you want to update in the fields on the right side of the Promote page. You can select any or all of the following:  Subpart name  Feature type  Promotable feature 3. Select the Update push button. Visual Builder updates those aspects of the feature that you selected. ═══ 33. ...Delete a promoted feature ═══ To delete a promoted feature, do the following: 1. Select the promoted feature that you want to delete. 2. Select the Delete push button. Visual Builder deletes the promoted feature from the list box beneath the Promote feature name field. Note: If you added the promoted feature that you just deleted to the preferred features list, you must go to the Preferred page and delete it there, too. ═══ 34. ...Clearing the Promote Page Fields ═══ To clear the fields on the Promote page, select the Clear push button. Visual Builder removes the information from all of the fields on the page. ═══ 35. ...Add a preferred feature ═══ To add a preferred feature to the connection menu for a part, do the following: 1. Select a feature name from one of the list boxes on the left side of the page. 2. Do either of the following:  Select the Add push button at the bottom of the page.  With the mouse pointer still over the list box in which you selected the feature name, do the following: a. Click mouse button 2. A pop-up menu with the Add choice appears. b. Select Add to add the feature. The feature name that you selected is inserted into the Preferred Features list box in alphabetical order. ═══ 36. ...Remove a preferred feature ═══ You can remove a preferred feature name from the connection menu for a part. Doing this removes the feature from the menu only; it does not delete the feature. To remove a preferred feature from the connection menu for a part, do the following: 1. Select the name that you want to remove from the Preferred Features list box. 2. Do either of the following:  Select the Remove push button at the bottom of the page.  With the mouse pointer still over the feature name in the Preferred Features list box, do the following: a. Click mouse button 2. A pop-up menu appears. b. Select Remove to remove the selected feature. A message box is displayed to make sure you want to remove the name of this preferred feature. 3. Select Yes to remove the feature name from the list. The feature name that you selected is removed from the list. ═══ 37. ...Remove all preferred features ═══ You can remove all of the feature names from the connection menu for a part. Doing this removes the features from the menu only; it does not delete the features. Once you remove all preferred features from the connection menu, you must select More to use the features in a connection. To remove all of the preferred features from the connection menu for a part, do either of the following:  Select the Remove all push button at the bottom of the page.  With the mouse pointer over the Preferred Features list box, do the following: 1. Click mouse button 2. A pop-up menu appears. 2. Select Remove all to remove all of the selected features. A message box is displayed to make sure you want to remove all of the preferred features. Select Yes to remove all of the feature names from the list. All of the feature names are removed from the list. ═══ 38. ...Show inherited preferred features only ═══ To show only the preferred features that your part inherits from other parts, select the Default push button. A message box is displayed. Select Yes to display only the inherited preferred features. ═══ 39. ...Create nonvisual parts ═══  Defining the part interface  Adding code to your part ═══ 39.1. Steps for creating nonvisual parts ═══ You create a part by doing the following: 1. Design the part. 2. Define the part interface, either through the Part Interface Editor or by importing a part information file. 3. Add code to your part. You can use C++ code written outside of Visual Builder, or you can generate default feature code in Visual Builder and modify it. ═══ 39.2. Define the part interface ═══ When you are satisfied with your part's design, you are ready to define the part interface to Visual Builder. 1. Define the attributes of your part. A part's attributes typically correlate to the class' data members and can additionally include derived attributes, or attributes that are determined based on the value of other attributes. 2. Define the member functions that get or set the value of those attributes. 3. Define any actions that you want the part to be able to do. A part's actions correlate to the class' public member functions. 4. Specify the event notification identifier used to signal a change in the value of each attribute. You can define the part interface in either of the following ways:  Use the Part Interface Editor. With this method, you create the part from the Visual Builder window and then enter each feature of the part interface individually using the pages of the Part Interface Editor.  Use a part information file. With this method, you encode part information in a file and then create the part and its interface by importing the information into Visual Builder. This method might be more efficient if C++ code already exists for your part. See and refer to Building VisualAge C++ Parts for Fun and Profit for information about creating part information files. ═══ 39.2.1. Define the part interface using the Part Interface Editor ═══ Open a new nonvisual part called OAContractor. The Part Interface Editor appears. On the Attribute page, do the following: 1. Type lastName in the Attribute name text-entry field and select the Add with defaults push button. 2. Change any of the default values, if needed. For this example, change the default attribute type to IString. You can do this by typing the value directly into the entry field or by selecting the drop-down list box arrow to the right of the entry field and selecting IString from the list. Also, edit the Get member function and Set member function fields, changing IStandardNotifier to IString. This causes these member functions to accept IString as a parameter instead of IStandardNotifier. 3. Select the Update push button to save the changes you just made. 4. Select the Clear push button to clear the fields before adding the next attribute. 5. Repeat the previous steps for the contractor's firstName, middleInitial, homeStreet, homeCity, homeState, homeZip, startDate, endDate, currentContract, and phoneNumber attributes. For these attributes, specify the IString attribute type before selecting the Add with defaults push button in the first step. This prevents you from having to change IStandardNotifier* to IString as you did previously. 6. Define the contractorID attribute as IString, with the following get member function: OAContractor & getContractorID (); This attribute is derived from other attributes; we will add the code for this later. You do not want users to set this attribute directly, so do not include a setContractorID member function. 7. Define the activeStatus attribute as Boolean. Note that the default get member function and set member function follow a different format than the ones for IString attributes. 8. To define the actions for OAContractor, select the Action page. 9. Type putContractor in the Action name field and the following into the Action member function field: OAContractor & putContractor(); 10. Select the Add push button; then select Clear. 11. Repeat for the getContractor and parseName actions. At this point, the Action page appears as shown in the following figure: 12. Select Save from the File pull-down menu to save your work. ═══ 39.3. Add code to my part ═══ Once you have specified the part interface for your part, you are ready to add the code to make the part work. Adding code involves the following tasks: 1. Generating default feature code. If you already have C++ code for your part and have imported the part information, this step is not necessary. 2. Modifying the feature code. 3. Adding code created outside Visual Builder if it already exists. ═══ 39.3.1. Generate default feature code ═══ To generate default feature code for the OAContractor part, follow these steps. Note: This example is a continuation of the example in the preceding section using the OAContractor part, which should be open in the Part Interface Editor. 1. Switch to the Class Editor by selecting the icon in the lower-right corner of the window. 2. Specify the .hpv and .cpv files for Visual Builder to use for the default feature code for the OAContractor part's attributes and actions by filling in the following fields: User .hpv file contrctr.hpv User .cpv file contrctr.cpv 3. Select FileSave and GenerateFeature source. 4. Generate the default feature code using one of the following methods:  Select the Generate all push button to generate default feature code for member functions and data members.  Select the appropriate member functions and data members from the Member functions, Attribute data members, or Event data members list boxes. Then, select the Generate selected push button. For this example, select the Generate all push button. The default feature code is stored in the files you specified in the Class Editor, contrctr.hpv and contrctr.cpv. If these files already exist, the code you just generated is appended to the ends of these files. For most parts, you must modify the default code to make your part fully functional. ═══ 39.4. Modify the generated feature code ═══ After you have Visual Builder generate the feature code, review it. Does it do what you need it to do? If not, modify the code. The OAContractor part needs the following changes:  Modified code for the getContractor action  Modified code for the putContractor action  Modified code for the parseName action  Added code to set the activeStatus attribute  Added code to set the contractorID attribute ═══ 39.4.1. Modify code for the getContractor action ═══ This version of our contractor application uses an IProfile-based database to store information about the contractors. For our OAContractor part to use this database, we must complete the getContractor and putContractor actions and modify the activeStatus attribute. The following example shows the default code generated for the two actions: OAContractor & OAContractor::getContractor() { return *this; } OAContractor & OAContractor::putContractor() { return *this; } To modify default feature code, edit the code files using the syntax text editor provided by VisualAge C++ or your favorite editor. Code for our getContractor action follows: OAContractor & OAContractor::getContractor() { // Start data access code IProfile *p = new IProfile("contrctr.ini"); // Test for missing name information // Necessary for proper derivation of the contractorID attribute if ((!iLastName) || (!iFirstName) || (!iMiddleInitial)) { throw IException("The contractor's name is incomplete. Complete all name fields and try again."); return *this; } // Refresh the value of contractor ID setContractorID(); // Check for this contractor ID in the profile collection if (!p->containsKeyName("contractorID", iContractorID)) { throw IException("A record was not found for this contractor."); return *this; } // If other data exists for this contractor, // set the corresponding contractor attributes if (p->containsKeyName("lastName", iContractorID)) setLastName(p->elementWithKey("lastName", iContractorID)); if (p->containsKeyName("firstName", iContractorID)) setFirstName(p->elementWithKey("firstName", iContractorID)); if (p->containsKeyName("middleInitial", iContractorID)) setMiddleInitial(p->elementWithKey("middleInitial", iContractorID)); if (p->containsKeyName("homeStreet", iContractorID)) setHomeStreet(p->elementWithKey("homeStreet", iContractorID)); if (p->containsKeyName("homeCity", iContractorID)) setHomeCity(p->elementWithKey("homeCity", iContractorID)); if (p->containsKeyName("homeState", iContractorID)) setHomeState(p->elementWithKey("homeState", iContractorID)); if (p->containsKeyName("homeZip", iContractorID)) setHomeZip(p->elementWithKey("homeZip", iContractorID)); if (p->containsKeyName("phoneNumber", iContractorID)) setPhoneNumber(p->elementWithKey("phoneNumber", iContractorID)); if (p->containsKeyName("startDate", iContractorID)) setStartDate(p->elementWithKey("startDate", iContractorID)); if (p->containsKeyName("endDate", iContractorID)) setEndDate(p->elementWithKey("endDate", iContractorID)); if (p->containsKeyName("currentContract", iContractorID)) setCurrentContract(p->elementWithKey("currentContract", iContractorID)); // Call overloaded set member function using string parameter if (p->containsKeyName("activeStatus", iContractorID)) enableActiveStatus(p->elementWithKey("activeStatus", iContractorID)); delete p; // End data access code return *this; } The getContractor action checks for one possible error condition. If it occurs, the action throws an exception. Otherwise, the action retrieves data by contractor identifier from the contrctr.ini file. In response to these exceptions, the OAContractorView part shows a message box. Constructing the User Interface. Passing Exceptions to Message Boxes. ═══ 39.4.2. Modify code for the putContractor action ═══ Code the putContractor action as follows: OAContractor & OAContractor::putContractor() { // Start data entry code IProfile *p = new IProfile("contrctr.ini"); // Test for missing name information // Necessary for proper derivation of the contractorID attribute if ((!iLastName) || (!iFirstName) || (!iMiddleInitial)) { throw IException("The contractor's name is incomplete. Complete all name fields and try again."); return *this; } // Refresh the value of contractor ID setContractorID(); p->addOrReplaceElementWithKey("contractorID", contractorID(), iContractorID)); // If other data about this contractor exists, update it in the database if (lastName) p->addOrReplaceElementWithKey("lastName", lastName(), iContractorID)); if (firstName) p->addOrReplaceElementWithKey("firstName", firstName(), iContractorID)); if (middleInitial) p->addOrReplaceElementWithKey("middleInitial", middleInitial(), iContractorID)); if (homeStreet) p->addOrReplaceElementWithKey("homeStreet", homeStreet(), iContractorID)); if (homeCity) p->addOrReplaceElementWithKey("homeCity", homeCity(), iContractorID)); if (homeState) p->addOrReplaceElementWithKey("homeState", homeState(), iContractorID)); if (homeZip) p->addOrReplaceElementWithKey("homeZip", homeZip(), iContractorID)); if (telephoneNumber) p->addOrReplaceElementWithKey("telephoneNumber", telephoneNumber(), iContractorID)); if (startDate) p->addOrReplaceElementWithKey("startDate", startDate(), iContractorID)); if (endDate) p->addOrReplaceElementWithKey("endDate", endDate(), iContractorID)); if (currentContract) p->addOrReplaceElementWithKey("currentContract", currentContract(), iContractorID)); if (iActiveStatus) { p->addOrReplaceElementWithKey("activeStatus", "yes", iContractorID)); } else { p->addOrReplaceElementWithKey("activeStatus", "no", iContractorID)); } delete p; // End data entry code return *this; } The putContractor action checks for one possible error condition. If it occurs, the action throws an exception. Otherwise, the action stores data by contractor identifier in the contrctr.ini file. In response to these exceptions, the OAContractorView part shows a message box. Constructing Containers and Notebooks. Passing Exceptions to Message Boxes. ═══ 39.4.3. Modify code for the parseName action ═══ The parseName action parses input text from the Request for Contractor Information window and sets the contractor's firstName, middleInitial, and lastName attributes. Add code as follows: OAContractor & OAContractor::parseName(const IString & aName) { // aName is supplied by user in OAQueryContractor // Test for missing information in newly entered name if (aName.numWords()!= 3) { throw IException("The name you entered is incomplete. Enter first name, middle initial, and last name."); return *this; } // Set name attributes and derive contractorID attribute setFirstName(aName.word(1)); setMiddleInitial(aName.word(2)); setLastName(aName.word(3)); setContractorID; // End added code return *this; } ═══ 39.4.4. Add code to set the activeStatus attribute ═══ You must add a member function to pass string data to the one Boolean attribute, activeStatus. All data in our simple database is stored as strings, but the set member function for the activeStatus attribute takes a Boolean as a parameter. Because only OAContractor's two actions use this member function, it is not necessary to add this to the part interface for OAContractor. However, you must add the member function prototype to the contrctr.hpv file. The following example shows both the default feature code and the added code in contrctr.cpv: Boolean OAContractor::isActiveStatus() const { return iActiveStatus; } OAContractor & OAContractor::enableActiveStatus(const Boolean enable) { if (iActiveStatus != enable) { iActiveStatus = enable; notifyObservers(INotificationEvent(OAContractor::activeStatusId, *this)); } // endif return *this; } // Start Boolean string enabler OAContractor & OAContractor::enableActiveStatus(const IString & status) { Boolean tempBoolean = iActiveStatus; if (status = "yes") iActiveStatus = true; if (status = "no") iActiveStatus = false; if (tempBoolean != iActiveStatus) { notifyObservers(INotificationEvent(OAContractor::activeStatusId, *this)); } return *this; } // End Boolean string enabler iActiveStatus is the private data member that corresponds to the activeStatus attribute. The notifyObservers function signals that the value of the activeStatus attribute has changed. For more information about notification, see Building VisualAge C++ Parts for Fun and Profit. ═══ 39.4.5. Add code to set the contractorID attribute ═══ Now, add code to derive the value of the contractorID attribute. The following example shows the code as modified in contrctr.cpv: OAContractor & OAContractor::setContractorID() { IString tempString = iFirstName+iMiddleInitial+iLastName; if (iContractorID != tempString) { iContractorID = tempString; notifyObservers(INotificationEvent(OAContractor::contractorIDId, *this)); } // endif return *this; } ═══ 39.5. Add code created outside Visual Builder ═══ To include previously existing member function code with generated class declarations, do the following: 1. Change the file extension of .cpp files to .cpv. 2. Change the file extension of .hpp files to .hpv. 3. Change the file extension of any .rc files to .rcv. 4. Add these files to the Class Editor for the appropriate part. If you prefer not to use Visual Builder to develop the code for a nonvisual part but you want to be able to use it in the Composition Editor, you can do the following:  Write the code.  Compile it into a .lib file.  Define the part interface using a part information file.  Import the part information file. ═══ 40. ...Work with parts in the Visual Builder window ═══  Displaying part names  Selecting all parts  Deselecting all parts  Importing part information  Exporting part information  Creating a new part  Opening parts  Copying parts from one .vbb file to another  Moving parts to a different .vbb file  Deleting parts from a .vbb file  Renaming parts in .vbb files ═══ 40.1. Display part names ═══ To display the names of the parts in a .vbb file, in the Loaded Files list box in the Visual Builder window select the .vbb file whose parts you want to see. The names of the parts contained in the .vbb file that you selected are displayed in the Visual Builder window. Visual parts are displayed in the Visual Parts list box; nonvisual parts and class interface parts are displayed in the Nonvisual Parts list box. ═══ 40.2. Select all parts ═══ To select all of the parts in the selected .vbb files, select EditSelect all parts. At this point, you can review the list to see if you want to deselect any of the parts. You can do so by pressing the Ctrl key and clicking on the part name with mouse button 1. ═══ 40.3. Deselect all parts ═══ To deselect all of the parts in the selected .vbb files, select EditDeselect all parts. ═══ 40.4. Import part information ═══ To import part information, do the following: 1. Select FileImport part information. 2. Select the part information file that you want to import. 3. Select the OK push button. The part information in the part information file is imported. Any visual parts that the part information file contains are displayed in the Visual Parts list box, and any nonvisual parts and class interface parts it contains are displayed in the Nonvisual Parts list box. In addition, one or more .vbb files may be created. ═══ 40.5. Export part information ═══ To export part information, do the following: 1. Select the part or parts whose information you want to export in either the Visual Parts list box, the Nonvisual Parts list box, or both. 2. Select PartExport interface. 3. Type the name of the .vbe file in which you want the part information to be stored in the Open filename field. If you do not enter a file name, Visual Builder uses exported.vbe as the default file name. 4. Select the OK push button. The part information maintained by Visual Builder is exported to the file name you specified in the Open filename field. ═══ 40.6. Create a new part ═══ To create a new part, do the following: 1. Select PartNew. 2. Enter the name that you want to give to your part in the Class name field. 3. Enter a description of your part in the Description field. 4. Enter the name of the .vbb file in which you want Visual Builder to store the part in the File name field. 5. Select the type of part that you want to create in the Part type field. You can select one of the following:  Visual part  Nonvisual part  Class interface 6. Either keep the default class name provided by Visual Builder in the Base class field, change it, or delete it. 7. Select Open. One of the following occurs:  If you are creating a visual part, the Composition Editor is displayed.  If you are creating a nonvisual part or a class interface part, the Part Interface Editor is displayed. 8. Use the displayed editor to create your part. ═══ 40.7. Open parts ═══ The following instructions tell you how to open one part at a time or multiple parts simultaneously. Opening one part To open one part, do the following: 1. Find the name of the part that you want to open by scrolling through the appropriate list box in the Visual Builder window. Note: If the list boxes in the Visual Builder window are empty or if you cannot find the part, the .vbb file that contains the part you want to open is not selected or not loaded. See Loading .vbb Files if you need help loading .vbb files. 2. Select the part you want to open. 3. Select Part on the menu bar. 4. Select Open in the pull-down menu. One of the following occurs:  If you are opening a visual part, Visual Builder displays the Composition Editor.  If you are opening a nonvisual part, Visual Builder displays the Part Interface Editor. A quicker way to open an existing part is to double-click on the part name within the Visual Parts or Nonvisual Parts list box. Opening multiple parts To open multiple parts, do the following: 1. Find the name of the first part that you want to open by scrolling through the Nonvisual Parts and Visual Parts list boxes shown in the Visual Builder window. Note: If the list boxes in the Visual Builder window are empty, see Loading .vbb Files if you need help loading .vbb files. 2. Select the first part you want to open. 3. Find the next part you want to open and press the Ctrl key while selecting that part. 4. Continue finding and selecting parts in this manner, pressing the Ctrl key while selecting each part, until you have selected all the parts you want to open. 5. Select Part on the menu bar. 6. Select Open in the pull-down menu. Visual Builder displays a separate window for each part that you selected. The window displayed is the Composition Editor for visual parts or the Part Interface Editor for nonvisual parts. ═══ 40.8. Copy parts from one .vbb file to another ═══ To copy a part, do the following: 1. Select the part that you want to copy in the Visual Parts or Nonvisual Parts list box. If you select more than one part or if you do not select a part, the Copy function is not available. 2. Select PartCopy. The Source part name field shows the name of the part that you selected to copy. 3. In the Target part name field, enter the name you want the part to have when you copy it. 4. In the Target file name field, enter the name of the .vbb file to which you want to copy the part. If you leave this field blank, the part's current file name is used. 5. Select the Copy push button. The part is copied under the new name and stored in the designated .vbb file. ═══ 40.9. Move parts to different .vbb files ═══ To move one or more parts from one .vbb file to another, do the following: 1. Select the part or parts that you want to move. If you do not select at least one part, the Move function is not available. 2. Select PartMove. 3. Use the following instructions for moving one part or multiple parts: Moving one part If you selected one part, the following window is displayed: The Part name field of this window shows the name of the part that you selected to move. The File name field displays the complete path of the .vbb file that contains the part you want to move. Do the following: a. In the New file name field, enter the path and name of the .vbb file to which you want to move the part. b. Select the Move push button. The part is moved to the .vbb file specified in the New file name field. Moving multiple parts If you selected more than one part, the following window is displayed: The text in the window specifies the names of the parts you selected. Do the following: a. In the entry field, enter the name of the .vbb file to which you want to move the parts. If the .vbb file is not in your current directory, specify the complete path for the .vbb file. b. Select the OK push button. The parts are moved to the .vbb file specified in the entry field. ═══ 40.10. Delete parts from a .vbb file ═══ To delete a part, do the following: 1. Select the part or parts that you want to delete in the Visual Parts list box, Nonvisual Parts list box, or both. If you do not select at least one part, the Delete function is not available. 2. Select PartDelete. Deselect any parts that you do not want to delete. Once you delete a part from a .vbb file, you cannot recover it unless you have another copy stored in another .vbb file. 3. Select the Delete push button. The selected parts are deleted. ═══ 40.11. Rename parts in .vbb files ═══ To rename a part in a .vbb file, do the following: 1. Select the part that you want to rename in the Visual Parts or Nonvisual Parts list box. If you select more than one part or if you do not select a part, the Rename function is not available. 2. Select PartRename. The Part name field shows the name of the part that you selected to rename. 3. In the New part name field, enter the new name that you want to give the part. 4. Select the Rename push button. The part is renamed under the new name. ═══ 41. ...Work with parts on the free-form surface ═══  Placing parts on the free-form surface  Selecting and deselecting parts  Manipulating parts, which includes: - Displaying pop-up menus - Copying parts - Deleting parts - Editing text strings - Renaming parts  Arranging parts, which includes: - Moving parts - Positioning parts on the grid - Sizing parts - Matching part sizes - Aligning parts - Spacing parts within Composer parts - Spacing parts within a bounding box  Changing settings for a part  Tearing off an attribute ═══ 41.1. Place parts on the free-form surface ═══ In the Composition Editor, you place visual, nonvisual, and class interface parts on the free-form surface. This section explains how to place parts there that appear on the parts palette, as well as parts that do not appear on the parts palette. Placing a part that appears on the parts palette 1. From the left column of the parts palette, select the appropriate category. Then, from the right column, select the part you want to add. When the mouse pointer is moved over a place where the part can be placed, it changes to a crosshair, indicating that it is loaded with the part. 2. Move the mouse pointer to where you want to add the part. 3. Click mouse button 1. If you hold down mouse button 1 instead of clicking it, an outline of the part is displayed under the pointer to help you position the part. After the part is in position, release mouse button 1. To unload the mouse pointer at any time, do either of the following:  Select , the Selection tool, on the tool bar.  Select ToolsSelection Tool on the menu bar. To add several copies of the same part, select Sticky on the parts palette. When Sticky is selected, the mouse pointer remains loaded with the part you last selected. When Sticky is not selected, the mouse pointer becomes unloaded after you add a part. Placing a part that is not on the parts palette You can place on the free-form surface any part whose .vbb file is loaded by doing the following: 1. Select Add part from the Options pull-down menu. 2. Type the part's class name in the Part class field. 3. Type a name for the part in the Name field. 4. Select the Add push button to add the part. 5. Move the crosshairs to the place where you want to add the part and click mouse button 1. ═══ 41.2. Select and deselect parts ═══ The following sections describe how to select and deselect a single part and multiple parts. Selecting a single part To select a part that you have placed on the free-form surface, click on the part with mouse button 1. If other parts are already selected, they are deselected automatically. Selecting multiple parts Selecting multiple parts enables you to perform the same operation on several parts at once. To select multiple parts, do one of the following:  Hold down the Ctrl key and click mouse button 1 on each additional part you want to select.  Hold down mouse button 1 instead of clicking it; then move the mouse pointer over each additional part you want to select. After you select the parts, release mouse button 1. Note: Depending on the operation you want to perform, remember to consider which part you want to be the anchor part because that is the part you want to select last. For example, if you select two parts because you want to match the width of one part to the width of the other, the part you select last is the anchor part, the part whose width is used for the operation. Deselecting parts To deselect a part after you have selected it, do the following: 1. Hold down the Ctrl key. 2. Click on the selected part with mouse button 1. To deselect multiple parts, do the following: 1. Hold down the Ctrl key. 2. Click on a selected part with mouse button 1. 3. Without releasing either the Ctrl key or mouse button 1, move the mouse pointer to another selected part. 4. Repeat the previous step until all parts that you want to deselect have been deselected. ═══ 41.3. Manipulate parts ═══ Once a part is added to the free-form surface, you can manipulate it in a number of different ways. The following sections explain each of those ways.  Displaying pop-up menus  Copying parts  Deleting parts  Editing text strings  Renaming parts on the free-form surface ═══ 41.3.1. Display pop-up menus ═══ To display the pop-up menu of a part, click on the part with mouse button 2. The pop-up menu displays the operations you can perform on that part. A part does not have to be selected for you to display its pop-up menu. The pop-up menu that is displayed is for the part the mouse pointer is over when mouse button 2 is clicked, even if another part is selected. ═══ 41.3.2. Copy parts ═══ To copy parts by dragging them, do the following: 1. Select all the parts you want to copy. If you only want to copy one part, you do not have to select it. 2. Move the mouse pointer over the part you want to copy or one of the selected parts. 3. Hold down the Ctrl key and mouse button 2. 4. Drag a copy of the part or parts by moving the mouse pointer to a new position. An outline of the part or parts is displayed to help you with positioning. When you are copying multiple parts, the outlines of each part move together as a group. 5. Release the Ctrl key and mouse button 2 when the part or parts are where you want them to be. A copy of the part or parts appears where you positioned the outline or outlines. Copying parts using the clipboard To copy parts by using the clipboard, do the following: 1. Select all the parts you want to copy. 2. From the Edit pull-down menu, select Copy. A copy of each selected part is placed on the clipboard. 3. Select Paste from the Edit pull-down menu when you are ready to use the parts. The mouse pointer turns to crosshairs to show that it is loaded with the copied parts. 4. Position the mouse pointer where you want the parts to be copied. 5. Click mouse button 1. Copies of the parts are pasted at the position of the mouse pointer. Parts that you copy remain on the clipboard until you copy something else. Therefore, you can continue to paste copies of those parts by selecting Paste, positioning the mouse pointer, and clicking mouse button 1. If you select Paste and then decide against pasting the parts, you can unload the mouse pointer by either selecting the Selection Tool on the tool bar or by selecting ToolsSelection Tool on the menu bar. ═══ 41.3.3. Delete parts ═══ To delete one or more parts, do the following: 1. Select all of the parts you want to delete. If you are deleting just one part, you do not have to select it. 2. Position the mouse pointer over the part you want to delete or one of the selected parts. 3. Click mouse button 2. 4. From the part pop-up menu, select Delete. The part or parts are deleted. Any connections between the part that you are deleting and other parts are also deleted. Visual Builder displays a message to alert you to this. However, the EditUndo function also restores any connections that were removed when you deleted the part. ═══ 41.3.4. Edit text strings ═══ Some visual parts, such as push buttons and menus, have text strings. To directly edit a part's text string, do the following: 1. Hold down the Alt key. 2. Click mouse button 1 on the text string. 3. Edit the text string. 4. When you have finished, do either of the following:  Click mouse button 1 anywhere outside of the text string.  Press Shift+Enter. You can also use this direct editing technique to edit the names of nonvisual parts. The name of a nonvisual part is displayed directly below its icon. ═══ 41.3.5. Rename parts on the free-form surface ═══ If you want to give parts names that are more descriptive or meaningful to your application, you can do so as follows: 1. Move the mouse pointer over the part whose name you want to change. 2. Click mouse button 2 to display the pop-up menu for the part. 3. Select Change Name. A Name Change Request window is displayed. 4. Type a new name in the entry field. 5. Select OK. Visual Builder changes the name of the part to the name that you typed in the entry field. You can also change a part's name by opening the part's settings notebook and changing the name in the Subpart name field. ═══ 41.4. Arrange parts ═══ You can arrange parts on the free-form surface in a number of different ways. The following sections explain each of those ways.  Moving parts  Positioning parts on the grid  Specifying grid spacing  Showing and hiding the grid  Sizing parts  Matching part sizes  Aligning parts  Spacing subparts within Composers parts ═══ 41.4.1. Move parts ═══ To move a part, move the mouse pointer over the part, hold down mouse button 2, and move the mouse pointer to drag the part to the new position. You can move several parts at once by first selecting all the parts you want to move and then dragging one of the parts as described. All of the selected parts will move together, maintaining their position relative to each other. ═══ 41.4.2. Position parts on the grid ═══ To position the top-left corner of parts to the nearest grid coordinate, do the following: 1. Select all the parts you want to position to the grid. Note: If the parts you select are subparts, they are positioned to the grid set up inside the Composers part, not the grid for the free-form surface. 2. Select , the Snap To Grid tool. You can automatically position a part to the nearest grid coordinate when it is added to the free-form surface or a Composers part by selecting Snap On Drop from the Options pull-down menu. ═══ 41.4.3. Specify grid spacing ═══ To specify the grid spacing, do the following: 1. From the pop-up menu of a Composers part or the free-form surface, select Set Grid Spacing. 2. Specify the horizontal and vertical distance between the lines of the grid in pixels. ═══ 41.4.4. Show and hide the grid ═══ To toggle between showing and hiding the grid for the free-form surface, do one of the following:  If no parts are selected, you can select , the Toggle Grid tool to toggle the grid for the free-form surface.  If a Composers part is selected, selecting the Toggle Grid tool toggles the grid for the Composers part instead of the free-form surface. Toggling between showing and hiding the grid for a Composers part To toggle between showing and hiding the grid for a Composers part, do one of the following:  Select the Composers part and the select , the Toggle Grid tool.  From the Composers part's pop-up menu, select Toggle Grid. ═══ 41.4.5. Size parts ═══ To change the size of a part, select it and use mouse button 1 to drag one of the selection handles to the new position. An outline of the part is displayed under the mouse pointer to show you the new size of the part. You can size several parts at once by first selecting all the parts you want to size. To size a part in only one direction, press and hold the Shift key while using mouse button 1 to size the part. Holding down the Shift key prevents one dimension of the part from changing while you resize the other dimension. For example, to change the width of a part but prevent its height from changing, hold down the Shift key while changing the width. You can also size a part to the grid coordinates by selecting Snap On Size from the Options pull-down menu. ═══ 41.4.6. Match part sizes ═══ To size parts to the same width or height of another part, do the following: 1. Select all the parts you want to size, making sure the last part you select is the part whose size you want the others to match. 2. Select one of the following sizing tools from the tool bar: Match Width Match Height The size of all the parts you selected, with the exception of the last part, changes to match the size of the last part selected. ═══ 41.4.7. Align parts ═══ To align parts to the same position as another part, do the following: 1. Select all the parts you want to align, and then select the part you want the others to be aligned with. 2. Select one of the following alignment tools from the tool bar: Align Left Align Top Align Center Align Middle Align Right Align Bottom ═══ 41.4.8. Space subparts within Composers parts ═══ To evenly space subparts within their Composers part, do the following: 1. Select all the parts you want to evenly space. 2. Select one the following spacing tools from the tool bar: Distribute Horizontally Distribute Vertically ═══ 41.4.9. Space parts within a bounding box ═══ To evenly space parts within the unseen bounding box that contains the selected parts, do the following: 1. Select all the parts you want to evenly space. You must select a minimum of three parts. 2. From the pop-up menu of one of the selected parts, select LayoutDistribute, and then one of the following: Horizontally In Bounding Box Evenly distributes the selected parts within the region bounded by the leftmost edge and rightmost edge of the selected parts. Vertically In Bounding Box Evenly distributes the selected parts within the region bounded by the topmost edge and bottommost edge of the selected parts. ═══ 41.5. Change settings for a part ═══ The settings notebook of a part provides a way to display and set attributes and options for the part. Opening the settings notebook for one part To open the settings notebook for a part, move the mouse pointer over the part and do one of the following:  Double-click mouse button 1.  Click mouse button 2 and select Open settings from the part's pop-up menu. Opening settings notebooks for multiple parts You can open the settings notebooks for multiple parts by doing the following: 1. Select the parts whose settings you want to change. 2. Move the mouse pointer over one of the selected parts. 3. Click mouse button 2. 4. Select Open settings from the pop-up menu. Visual Builder opens a settings notebook for each of the selected parts. Navigating through a settings notebook You can navigate through the notebook pages in the following ways:  To turn the pages of a notebook, use the small left- and right-arrow push buttons at the bottom right corner of each page.  To move to a different settings category, select one of the tabs to the right of the pages. Note: When a category has more than one page, the page number and total number of pages within the category are displayed at the bottom of the page.  If all the category tabs cannot fit below the pages of the notebook, small double left- and right-arrow push buttons are displayed to the left and right of the category tabs. Use these buttons to move through the available category tabs. Adding a handler To add a handler, do the following: 1. Enter the name of the handler class in the Handler Name field, along with the list of parameters that you want to send to the handler's constructor. If you use any part names as parameters, be sure to use the default name that Visual Builder has assigned unless you have changed the name. Also, put a lower case "i" before those parameters because Visual Builder prefixes the part name with an "i" when it generates the code files. For example, if you are using the first entry field that you placed in a frame window as a parameter and have not changed the default name that Visual Builder assigns, the parameter name would be iEntryField1. 2. If the Handler List list box contains other handlers, select the handler that you want your new handler to either precede or follow. 3. Select either the Add after or Add before push button. If you did not import the handler class from a .vbe file, Visual Builder displays a message saying that the name you entered is not a valid part and asks if you want to continue. 4. Select the Yes push button. The message disappears and the handler is added either after or before the handler that is selected in the Handler List list box, depending on which push button you select. 5. Select the OK push button to save the new handler in the handler list and close the settings notebook. We recommend that you put your handler class declaration and code in separate user .hpv and .cpv files rather than modifying the files that Visual Builder generates. This way, if you need to regenerate the files, you do not have to recreate your handler code. Be sure to include the names of the files that contain the handler code in the User .hpv file and User .cpv file fields in the Class Editor. For information about implementing handlers, refer to the IBM Open Class Library User's Guide and the IBM Open Class Library Reference. Moving a handler To move a handler to a different position in the list, do the following: 1. Select the handler that you want to move. 2. Select the Move push button. 3. In the dialog that is displayed, select the handler that is to precede or follow the handler being moved. 4. Select the Move after push button to move the handler after the selected handler, or select the Move before push button to move the handler before the selected handler. The dialog disappears and the handler is moved. Removing a handler To remove a handler from the list, do the following: 1. Select the handler you want to remove from the list. 2. Select the Remove push button. The selected handler is removed from the list. Changing the color To change the color, do the following: 1. In the Color Area group box, select the area, such as foreground or background, whose color you want to change. 2. Do one of the following:  If you want to specify red-green-blue values, select the RGB check box and specify values in the fields in the RGB Values group box.  If you want to select a color by its name, deselect the RGB check box and select a color from the Colors drop-down list box. 3. Select either the Apply push button to see how this color looks for your part without saving the change or the OK push button to close the settings notebook and save the color change. Specifying the size and position of a part To specify the size and position of a part, do the following: 1. In the x and y fields, specify the initial x/y coordinates for the part. These coordinates determine the position of the part's upper left corner. 2. In the width and height fields, specify the number of pixels for the width and height of the part. 3. Optionally, you can also specify the smallest size the part can have by using the Minimum Size group box to do either of the following:  If you want the minimum size to be calculated for you, select the Calculate at execution time radio button.  If you want to specify the minimum size for the part, select the Set value here radio button and then enter the width and height in pixels in the corresponding fields. Changing the font for a part To change the font for a part, do one of the following:  If you know the name and size of the font you want to use, you can enter them in their respective fields.  If you do not know the name and size of the font you want to use or if you want to change the style or emphasis, select the Edit push button. Visual Builder displays a standard font dialog on which you can select the name, size, style, and emphasis you want to use for the part's font. Using code strings to supply initial field values Many settings pages provide fields in which you can specify initial values for part settings. For example, the General page of the IEntryField* settings notebook contains a Text field and a Limit field. In the Text field, you can enter a text string that you want Visual Builder to initially display in the entry field. The Limit field contains a default value of 32, which represents the maximum number of characters a user can type in the entry field, and you can change this number. To facilitate National Language Support (NLS) translation and code changes in providing settings values, you can enter a code string to provide those values. You must precede the code string with a number sign (#). If the first character of your code string is a #, be sure to enter two #s-the first one to signify that a code string follows and the second one to begin your code string. For example, suppose you want the initial text in an entry field to be Enter a name here. Further, suppose that you want the limit for this entry field to be 18 characters. In a user header file (.hpv or .h), you could insert the following #define statements: #define NAME_PROMPT "Enter a name here" #define NAME_LENGTH 18 Be sure to enter the name of the file that contains these #define statements in the Required include files field in the Class Editor. Otherwise, this file is not included when you generate the code for this part. Then, on the General page of the IEntryField* settings notebook you could enter the following in the Text and Limit fields, respectively: #NAME_PROMPT #NAME_LENGTH By doing this, the values that you defined for NAME_PROMPT and NAME_LENGTH are used when you generate the source code for the part being edited. For an example that uses a code string to specify an icon to represent items in a container, see the subsection titled "Specifying the container type and layout" in Adding Container Parts. Activating settings changes After you make changes to the settings, you can activate them in the following ways:  Select the OK push button to immediately activate and save the settings changes you have made, and close the settings notebook.  Select the Apply push button to apply the settings changes you have made and keep the settings notebook open. This allows you to see whether you need to modify any of the changes you have made. The changes remain applied until you change them again. Select the Cancel push button to remove the settings notebook. If you made changes and selected the Apply push button, the changes are saved. Select the Help push button for more help with using the settings notebook. For information about the settings of a particular part, refer to the settings section of the part in the Visual Builder Parts Reference. ═══ 41.6. Use the generic settings notebook ═══ To view the settings notebook for your part, do one of the following:  To set values for an instance of your part that you are using in a composite part, do the following: 1. Place the part in the Composition Editor. 2. Move the mouse pointer over the part and click mouse button 2. 3. Select Open settings from the pop-up menu. Visual Builder displays the settings notebook for the part.  To set attribute values for your part that will be available each time your part is used, do the following: 1. Open the part. 2. If the part is a nonvisual or class interface part, switch to the Composition Editor. You will already be in the Composition Editor if your part is a visual part. 3. Move the mouse pointer over the free-form surface and click mouse button 2. 4. Select Open settings from the pop-up menu. A quicker way to open the generic settings notebook is to double-click on the part. Visual Builder displays the settings notebook for the part. ═══ 41.7. Set the tabbing order ═══ Displaying the tabbing order list To display the tabbing order list, do the following: 1. Move the mouse pointer to the Composers part whose tab order you want to change. 2. Click mouse button 2. Visual Builder displays the pop-up menu for the Composers part. 3. Select Tabbing And Depth Order. A list of the current tabbing order is displayed. When the tabbing order is displayed, you can do the following:  Change the positions of parts in the tabbing order list.  Set groups and tab stops.  Perform operations on parts in the tabbing order list. ═══ 41.7.1. Change the positions of parts in the tabbing order ═══ To change the position of a part within the tabbing order list, do the following: 1. Move the mouse pointer to the part whose position you want to change. 2. Press and hold mouse button 2. 3. Drag the part to a new position in the list. 4. Release mouse button 2. You can change the position of several parts within the tabbing order at the same time by first selecting all the parts you want to move. You select multiple parts by holding down the Ctrl key and clicking on the parts with mouse button 1. You cannot move a subpart to a new Composers part by changing the tabbing order. You must do this in the Composition Editor. ═══ 41.7.2. Set groups and tab stops ═══ If you want the user to be able to move the input focus to a part using the Tab and Backtab keys, select the Tab stop check box to the left of the part in the tabbing order list. If you want the user to be able to move the input focus to a part with the keyboard arrow keys, select the Group check box to the left of the first part in the group. All other parts listed below the part that has Group selected are included in the group. To start another group, select the Group check box for the part that you want to be the first part in that group. If a part has both Group and Tab stop selected, a user can tab to the first part in the group and then use the arrow keys to move to the other parts in the group. ═══ 41.7.3. Perform operations on parts in the tabbing order list ═══ To perform an operation on a part in the tabbing order list, do the following: 1. Move the mouse pointer over the part. 2. Click mouse button 2. Visual Builder displays the pop-up menu for the part. 3. Select the operation you want to perform. ═══ 41.8. Edit parts placed on the free-form surface ═══ If you need to edit a part that was added to the part you are currently editing, do the following: 1. If you have not already done so, load the .vbb file that contains the part you want to edit. 2. Move the mouse pointer over the part you want to edit. 3. Click mouse button 2. The part's pop-up menu appears. 4. Select Edit Part. Visual Builder displays the appropriate editor for the part, as follows:  If you are editing a visual part, Visual Builder displays the Composition Editor  If you are editing a nonvisual or class interface part, Visual Builder displays the Part Interface Editor. 5. Edit the part. If you want to promote any of the features of the parts used to create the composite part you are editing, doing so now keeps you from having to edit this part again later. See Promoting a Part's Features if you need more information about doing this. 6. Select FileSave to save the part. 7. Close the editor by doing one of the following:  Double-click on the system menu icon.  Select FileExit. The editor you are using disappears and you are returned to the Composition Editor you were using previously. However, Visual Builder has not applied the changes you made to the part you just edited, so those changes are not visible yet. 8. Select FileSave to save the original part. 9. Close the Composition Editor for the original part that you were editing, as described above. 10. Reopen the original part you were editing by double-clicking on the part's name in the Visual Builder window. You should now be able to see the changes you made to the part that you edited. ═══ 41.9. Promote a part's features ═══ The following steps show you how to promote a part's features from the Composition Editor. To promote features of several subparts, we recommend using Promote page of the Part Interface Editor. 1. If you have not already done so, load the .vbb file that contains the composite part whose features you want to promote. 2. If you have not already done so, open the composite part or edit the subpart, whichever is necessary. Visual Builder displays the Composition Editor with the part that you are opening or the subpart that you are editing on the free-form surface. 3. Move the mouse pointer over a part whose features you want to promote. 4. Click mouse button 2 to display the part's pop-up menu. 5. Select Promote Part Feature. 6. Select a feature. The name of the feature you selected is displayed in the Promote feature name entry field prefixed with the name of the part. This is how the feature name will appear in the connections menu unless you change it before performing the next step. 7. Select the Promote push button. The feature name is added to the Previously promoted list box, as shown inthe following figure: 8. Repeat the previous two steps until you have promoted all of the features you need to make the necessary connections. 9. Close the window for promoting features. 10. Select FileSave to save the features you just promoted. 11. Close the Composition Editor. You can now use the feature or features that you promoted to make connections. ═══ 41.10. Tear off an attribute ═══ Select Tear-Off Attribute from a part's pop-up menu to work with an attribute as if it were a standalone part. The torn-off attribute is not actually a separate part but a variable that either represents the attribute itself or points to it. When you select Tear-Off Attribute, Visual Builder displays the list of attributes for the part that you are tearing from. After you select an attribute from the list, you can drop the torn-off attribute on the free-form surface. Visual Builder creates an ═══ 41.11. Undo changes in the Composition Editor ═══ If you change something in the Composition Editor and then decide that you should have left things as they were, select Undo from the Edit pull-down menu to restore the part to its previous state. You can undo as many operations as you want, all the way back to when you opened the Composition Editor. If you undo an operation and then decide that you did the right thing in the first place, select Redo from the Edit pull-down menu. Redo restores the part to the state it was in before the last Undo, including any connections that were deleted. If you are not sure which operations you want to undo or redo, select Undo/Redo list from the Edit pull-down menu to display two lists of operations, one for undoing and one for redoing. From these lists, you can select an operation and then select the Undo or Redo push button. The operation that you select and all of the operations listed below it are undone or redone. Note: Undo, Redo, and Undo/Redo list only affect operations you perform on the free-form surface and parts palette in the Composition Editor. They have no affect on any of the functions in the File pull-down menu, such as Save, Save As, and Save and Generate, which you cannot undo. ═══ 42. ...Construct a GUI using the OASearch application ═══  Adding basic visual parts - Adding the parts - Changing the settings  Adding a variable to a composite part - Changing the variable's type - Adding the variable to the part interface ═══ 42.1. Add basic visual parts ═══ The purpose of this section is to guide you through constructing a version of the Opportunities Abound Contract Information window for the OASearch sample application. You construct this part (ContractView) in the Composition Editor using the basic visual parts. When finished, the Opportunities Abound Contract Information window looks like the following figure: To see the finished part, open contract.vbb. Begin with adding the parts. ═══ 42.1.1. Add the parts ═══ Before starting this new visual part, make sure that oanonvis.vbb is loaded into Visual Builder. Adding the parts 1. Because you are constructing a new user interface, begin by creating a visual part. Call it ContractView. When you create a visual part, the Composition Editor opens a part that inherits from IFrameWindow*. By default, the client area of the IFrameWindow* appears as a canvas. 2. Change the title of the window. 3. Add the following parts to the window part:  Static text and entry field parts for Account Number, Company Name, Project Manager, and Department.  A group-box part for the Position Details group. Resize the group box.  Static-text and entry-field parts for the items inside the group box.  Push-button parts. See the figure below to see how the window should look after the parts are added. Changing the Labels Directly edit the static text so that the text matches the previous figure. Arranging the Parts Arrange the parts on the frame window part so they are aligned and positioned as shown the previous figure. Now that all the parts have been added, continue on with changing the settings. ═══ 42.1.2. Change the settings ═══ Now that the parts have been added for the user interface, customize the parts by modifying their settings. Specifying a push button label with mnemonic On the General settings page for the middle push button, type ~Save in the Text field. Select the OK push button. The middle push button of your window now reads Save, with a mnemonic of S. This means the user can select the push button by pressing Alt+S. Repeat this procedure for the push button to the right of the Save push button, specifying Cl~ear as the push button label. This push button now reads Clear, with a mnemonic of E. For the rightmost push button, specify ~Cancel as the label. This push button now reads Cancel, with a mnemonic of C. Specifying the default push button On the General settings page for the leftmost push button, type ~Refresh in the Text field. Select the Apply push button. The leftmost push button of your window now reads Refresh, with a mnemonic of R. On the Styles settings page, select the On radio button for the defaultButton style. Select the OK push button. The Refresh push button is now the default button for the window. This means the user can select the push button by pressing the Enter key. For details on the settings of a particular part, refer to the Visual Builder Parts Reference. For more information on how to perform these operations, see Changing Settings. Now that the settings have been specified, the next step is making connections between the parts. ═══ 42.2. Add a variable to a composite part ═══ Begin by opening the ContractView part (found in contract.vbb) in the Composition Editor. If you prefer to use the OAContractView part, you can find this part in oawin.vbb. At this point, the ContractView part appears as shown in the following figure: We are using a variable instead of an OAContract* part because the contract data varies with the information entered from the OAQueryContract* part. To add a variable to the free-form surface, select , the Models category, from the parts palette; then add , an IVBVariable* part, to the free-form surface. Change its name to Contract. The ContractView with a variable added appears as shown in the following figure: Notice the square bracket symbols around the variable part. You can always identify a variable by these symbols. Also note that tear-off attributes also have square brackets and are in fact variables with a special connection. The next step is changing the variable's type. ═══ 42.2.1. Change the variable's type ═══ 1. First, make sure the the .vbb file holding the OAContract part (oanonvis.vbb) is loaded into Visual Builder. 2. Select Change Type on the variable's pop-up menu; then type OAContract* The next step is adding the variable to the part interface. ═══ 42.2.2. Add the variable to the Part Interface ═══ So far, the Contract variable is empty. To make the variable available for passing values from the main view (or any part outside ContractView), we must add the variable to the part interface of ContractView), Do this by selecting Promote Part Feature from the variable's pop-up menu. See Promoting a Part's Features if you need information about doing this. The next step is connecting the variable. ═══ 43. ...Learn to use connections ═══  Making the connections  Connecting features to member functions  Connecting exception events to actions and member functions  Manipulating connections  Rearranging connections  Making connections for the OASearch application shows the results of connecting attributes that have different behavior types. See ═══ 43.1. Make the connections ═══ In this section, you learn how to make attribute-to-attribute, event-to-attribute, event-to-action, and attribute-to-action connections. This section provides the following information:  Determining the source and target  Browsing a part's features  Connecting features to features  Satisfying parameters for incomplete connections Member function connections are discussed in Connecting Features to Member Functions. Custom logic connections are discussed in Adding a Custom Logic Connection. ═══ 43.1.1. Determine the source and target ═══ Here are the source and target rules:  With an attribute-to-action, event-to-action, or event-to-attribute connection, the event is always the source and the action or attribute is always the target. If you try to make an action-to-attribute, action-to-event, or attribute-to-event connection, Visual Builder automatically reverses it for you.  For attribute-to-attribute connections, if only one of the attributes has a set member function Visual Builder makes that attribute the target. This is done so that the attribute that has the set member function can be initialized when the application starts.  When you make attribute-to-attribute connections, the order in which you choose the source and target is important. The source and target attribute values are probably different when your view is first initialized. If they are, Visual Builder resolves the difference by changing the target end of the connection to match the source. Thereafter, if both attributes have set member functions, the connection updates either attribute if the other changes. Refer to the attributes, actions, and events sections of the particular part in the Visual Builder Parts Reference for information that is specific to a part's features. ═══ 43.1.2. Browse a part's features ═══ To browse the features of a part, do the following: 1. Move the mouse pointer over the part and click mouse button 2. Visual Builder displays the part's pop-up menu. 2. Select Browse Part Features. Visual Builder displays a browse window that contains three columns: one for actions, one for attributes, and one for events. 3. Select the feature you want to browse. Visual Builder displays information about the feature that you select in the entry fields below the feature columns. 4. If the information about a part's features should change, you can select the Refresh push button to see those changes reflected in the browse window. 5. When you have finished browsing the features, select the Close push button to close the browse window. ═══ 43.1.3. Connect features to features ═══ When you connect features to features, you can use any of the following source-target combinations: ┌───────────────────┬────────────────────────┐ │If source is a... │The target can be a... │ │part │part or connection │ │connection │part │ └───────────────────┴────────────────────────┘ Follow these steps to connect features: 1. Position the mouse pointer over the source, the part or connection that you want to connect from, click mouse button 2, and select Connect from its pop-up menu. To display the connection pop-up menu more quickly, hold down the Alt key while clicking mouse button 2. A menu appears showing the names of the most commonly used attributes, actions, and events, called the preferred features. If the source is a part, there is usually a More selection at the bottom of the list. If the More selection is not there, this means the list contains all of the available features, not just the preferred ones, and there are no more from which to select. 2. Do one of the following:  If the feature you want appears in the list, select it.  If the feature you want does not appear in the list, but the More selection is available, select More and then select the feature you want from the complete list of features.  If the feature you want does not appear in either the preferred list or the expanded list that is displayed when you select More, you can edit the part to add the feature you need. For more information about this, see Editing Parts Placed on the Free-form Surface. If, at this point, you decide not to complete the connection, do one of the following: - If a pop-up menu is displayed, move the mouse pointer away from the connection menu and click mouse button 1. - If a window showing all of the features is displayed, select the Cancel push button at the bottom of the window. The menu or window disappears and the connection is not completed. 3. Position the mouse pointer over the part or connection that you want to connect to. While moving the mouse, notice that a dashed line trails from the mouse pointer to the source of the connection. 4. Click mouse button 1 and a pop-up menu appears, again showing a list of features. 5. Select a name from the pop-up menu or from the More list. The same instructions regarding the presence of More apply as described previously. ═══ 43.1.4. Satisfy parameters for incomplete connections ═══ Satisfying a parameter using a connection To supply a parameter value, do the following: 1. Start a new connection using the dashed connection line that requires the parameter as the source. 2. For the target, select the attribute, action, member function, or custom logic that is to provide the value that the parameter needs. While making a connection, when the mouse pointer is directly over the connection line, you see a small box as a visual cue that the pointer is positioned correctly. Satisfying a parameter using a constant value When connections need parameters whose input values are constant, you provide these values by using the settings window of the incomplete connection, as follows: 1. Select Open settings from the incomplete (dashed) connection's pop-up menu. A quicker way to open the settings window is to double-click on the connection line. The settings window of the incomplete connection is displayed. 2. Select the Set parameters push button. The Constant Parameter Value Settings notebook is displayed showing the parameters for which you can set constant values. 3. Enter the constant parameter values you want to use. 4. Do one of the following:  Select the OK push button to apply the values and save them.  Select the Apply push button if you want to see what effect these values have before saving them.  Select the Cancel push button to remove the notebook without saving any of the parameter values you entered. You can select Help for additional information about entering parameter values. Specifying defaults for parameters There are two places in Visual Builder in which you can specify defaults for the parameters of actions in the declaration of the action's member function:  In the part's .vbe file  On the Action page of the Part Interface Editor Either of these allows a default value to be passed in an event-to-action connection, thus avoiding the need to satisfy a parameter. For example, suppose you want to connect the buttonClickEvent feature of a Remove push button to a removeSelected action that you created for an IListBox* part. Normally, you would also need to connect the selection attribute of the subclassed IListBox* part to the index attribute of the connection between buttonClickEvent and removeSelected. This connection would be required to get the index of the selected item in the list box. However, in the .vbe file of the IListBox* part, you can specify the following default parameter value for the removeSelected action: //VBAction: removeSelected, "removeSelected",, //VB: removeSelected(unsigned long index=selection()) This means that if no attribute of the IListBox* part is connected to the index attribute, the selection member function (the get member function of the selection attribute) is called by default to provide the index of the selected item. You could do the same thing by creating a removeSelected action on the Action page of the Part Interface Editor for the IListBox* part. You would specify the default parameter in the declaration of the removeSelected member function in the Action member function field, as follows: virtual unsigned long removeSelected(unsigned long index=selection()) Missing or invalid parameters When an action connection requires arguments, be sure that you make the correct number of parameter connections. Also be sure that you make the parameter connections before you generate the default code for your part. See Manipulating Connections to learn how to re-order connections. ═══ 43.2. Connect features to member function connections ═══  Adding an event-to-member function connection  Using Browser information ═══ 43.2.1. Add an event-to-member function connection ═══ The following figure shows the OAContractorView part used in the OASearch sample application in this book. The steps for adding an event-to-member function connection, which follow the figure, are based on this part. For information about how to construct this part, see Adding Notebook Parts. 1. With the mouse pointer over the Clear push button, hold down the Alt key and click mouse button 2. Visual Builder displays the connection menu for the Clear push button. 2. From this menu, select the buttonClickEvent choice, an event. 3. Move the mouse pointer to a point on the free-form surface outside the OAContractorView notebook part and click mouse button 1. 4. Select More. Visual Builder displays a window that contains three list boxes. For this example, the For class field should contain OAContractorView, the part that you are editing. For this example, the Access field should contain public. 5. Type the member function to which the buttonClickEvent feature is to be connected in the entry field below the Access field. Be sure to type the full declaration of the member function, including return type and parameters. For this example, enter the following member function to clear all of the fields in OAContractorView: void resetFields(); You must also create an .hpv file that contains this member function declaration and a .cpv file that contains the code for this member function. The member function declaration that you enter in this field must be identical to the declaration that you put in the .hpv file. For information about .hpv and .cpv files, see Specifying Files for Visual Builder to Include When You Build Your Application In addition, before you generate the code for your part, you must switch to the Class Editor and enter the names of these files so that Visual Builder will include them in the code for your part. For more information about including these files, see Specifying Files for Visual Builder to Include When You Build Your Application. 6. Select the OK push button. The connection window disappears and a light green connection arrow is drawn from the Clear push button toward the edge of the free-form surface. It looks like this: ═══ 43.2.2. Use Browser information ═══ The cascaded menu that Visual Builder displays when you select FileBrowser contains the following selections: Quick browse Causes Visual Builder to retrieve a list of the classes that the part you are editing inherits from, as well as a list of the member functions that your part and the part it inherits from contains. If you select one of the classes in the list, Visual Builder retrieves a list of the member functions that the class contains. This function is available only if you start Visual Builder from a WorkFrame project. It gives you access to browser information before you compile your application. Open browser data Works the same as Quick browse except you must compile your application with the -Fb+ option before using this function. Also, you do not have to start Visual Builder from a WorkFrame project to use this function. Refresh browser data Refreshes the list of the classes that the part you are editing inherits from, as well as the list that is displayed in the member function list box for the current class. If you reparse a part or recompile your application, use this function afterwards to ensure the data in the list boxes is current. Close browser data Removes the list of the classes that the part you are editing inherits from, as well as the member functions those classes contain. ═══ 43.3. Add a custom logic connection ═══ The requirements for connecting an event or attribute to custom logic are a visual part that has at least one event or attribute specified for it. Following are the steps to follow for adding a custom logic connection. The following figure shows the History page of the OAContractorView part used in the OASearch sample application in this book. The example used in the following steps is based on this part. 1. Select the right arrow in the lower right corner of the notebook to display the History page. 2. With the mouse pointer over the Clear push button, hold down the Alt key and click mouse button 2. Visual Builder displays the connection menu for the Clear push button. 3. From this menu, select the buttonClickEvent choice, an event. 4. Move the mouse pointer to a point on the free-form surface outside the OAContractorView part and click mouse button 1. Doing this indicates to Visual Builder that you want to connect the event to the OAContractorView part instead of one of its subparts. Visual Builder displays the connection menu with the preferred features that have been defined for the OAContractorView part. 5. Select Custom logic. Visual Builder displays the following window: 6. Enter the following in the Description field: Custom logic code to clear all entry fields 7. The buttonClickEvent feature is the event you want to connect to your custom logic, so do not change the Event name field for this example. 8. The default return type of void is the return type you want to use, so do not change the Return type field for this example. 9. Select the Target push button. Visual Builder inserts target-> in the Custom logic field. In the generated code, the entry fields that we want to clear are created using the new operator. For the StartEF part, the resulting pointer is called iStartEF. 10. Type the following to the right of target->: iStartEF->removeAll(); This code calls the removeAll member function for the StartEF part, the entry field labeled OA Start Date. 11. Press the Enter key to move the cursor to a new line. 12. Select the Target push button again. 13. Type the following to the right of target->: iEndEF->removeAll(); This code calls the removeAll member function for the EndEF part, the entry field labeled OA End Date. 14. Press the Enter key to move the cursor to a new line. 15. Select the Target push button again. 16. Type the following to the right of target->: iContractEF->removeAll(); and put the following line beneath it: return; This code calls the removeAll member function for the ContractEF part, the entry field labeled Current Contract. The connection window should now look like the following figure: 17. Select the Add push button. The connection window disappears and a blue connection arrow is drawn from the Clear push button toward the edge of the free-form surface. It should look like this: ═══ 43.4. Connect exception events to actions and member functions ═══ To connect an exception event, do the following: 1. Use your favorite text editor to create an action or member function that throws an exception. The easiest way to do this is to include the following in your action or member function source code: throw IException("Error message."); where the text of the error message that you want to display in the message box is the only parameter given for the IException constructor. 2. Connect an event to the action or member function you just created. 3. Drop an IMessageBox* part on the free-form surface. This message box is used to display the error message. 4. Move the mouse pointer to the connection you just made. 5. While holding down the Alt key, press mouse button 2. 6. Select the exceptionOccurred event from the connection menu. 7. Move the mouse pointer to the IMessageBox* part. 8. Click mouse button 1. 9. Select the show action from the connection menu. This connection causes the application to show a message box that contains the exception error message whenever the exception is thrown. For an example using the OAContractorView part from the OASearch application, see Passing Exceptions to Message Boxes. ═══ 43.5. Manipulate connections ═══ Once a connection is made, you can manipulate it by doing the following:  Changing settings for a connection  Reordering connections  Deleting connections  Showing and hiding connections ═══ 43.5.1. Change settings for a connection ═══ To open the settings window for a connection, move the mouse pointer over the connection and do one of the following:  Double-click mouse button 1.  Click mouse button 2 and select Open settings from the connection's pop-up menu. ═══ 43.5.2. Reorder connections ═══ If you make several connections from the same part, they run in the order in which you made the connections. To ensure the correct flow of control when you generate the source code, you may need to reorder the connections. If so, do the following: 1. Select the source part. 2. From the source part's pop-up menu, select Reorder Connections From. Visual Builder displays the Reorder Connections window showing a list of your connections. 3. With the mouse pointer over the connection you want to reorder, press and hold mouse button 2. 4. Drag the connection to the place in the list where you want the connection to occur. 5. Release mouse button 2. 6. Repeat these steps until the connections are listed in the order in which you want them to occur. 7. Close the window. ═══ 43.5.3. Delete connections ═══ You can delete a connection in either of the following ways:  From the connection's pop-up menu. Note: You do not have to select a connection to delete it using this method. To delete a connection from its pop-up menu, do the following: 1. Click on the connection with mouse button 2 to display its pop-up menu. 2. Select Delete.  From the connection's settings window To delete a connection from its settings window, do the following: 1. Open the settings window for the connection by doing one of the following: - Double-clicking on the connection - Clicking on the connection with mouse button 2 to display its pop-up menu and selecting Open Settings 2. Select the Delete push button. ═══ 43.5.4. Show and hide connections ═══ You can show and hide connections by using , the Hide Connections tool, and , the Show Connections tool on the Tool bar. These tools show or hide all connections that have the selected part or parts as their source or target. If no parts are selected, these tools show or hide all of the connections. If you hide connections, the Composition Editor free-form surface is drawn faster and is less cluttered, making it easier for you to work. If no parts are selected, these tools show and hide all of the connections in the view. If a part or parts are selected, these tools show and hide the connections between the selected part or parts. Another way to show and hide connections is to move the mouse pointer over a part, click mouse button 2, and select the Browse Connections choice from the part's pop-up menu, which displays a cascaded menu. The choices in the menu affect only connections going to and from the part the mouse pointer was over when you displayed the pop-up menu. ═══ 43.6. Rearrange connections ═══ You can rearrange a connection by doing the following:  Selecting connections  Deselecting connections  Changing the source and target of connections ═══ 43.6.1. Select connections ═══ You select connections in the same way that you select parts. When you select a connection, three boxes called selection handles appear on it to show that it is selected: one at each end and one in the middle. You can use these boxes to change either of the following:  The end points of the connection, as described in Changing the Source and Target of Connections.  The shape of the connection arrow by dragging the middle box to another location. This helps you distinguish among several connection lines that are close together. Selecting a single connection 1. Move the mouse pointer over the connection you want to select. 2. Click mouse button 1 to select the connection. The connection is selected. Selecting multiple connections If you want to select several connections, do one of the following:  To select multiple connections using just the mouse, do the following: 1. Move the mouse pointer over one of the connections you want to select. 2. Hold down mouse button 1 instead of clicking it. 3. Move the mouse pointer over each connection that you want to select. The selection boxes appear on each connection that the mouse pointer passes over to show they are selected. 4. After the connections are selected, release mouse button 1.  To select multiple connections using both the mouse and the keyboard, do the following: 1. Hold down the Ctrl key. 2. Move the mouse pointer over a connection. 3. Click mouse button 1 while the mouse pointer is over the connection line. 4. Without releasing the Ctrl key, repeat the preceding steps until all connections that you want to select are selected. ═══ 43.6.2. Deselect connections ═══ If you want to deselect a connection without selecting another part or connection, do the following: 1. Move the mouse pointer over the connection line. 2. Hold down the Ctrl key. 3. Click mouse button 1. ═══ 43.6.3. Change the source and target of connections ═══ Visual Builder gives you the ability to change what a connection is pointing to (the target) or pointing from (the source). Of course, you could always just delete the connection and create a new one. However, the following steps show you a quicker way to do this. To move either end of a connection, do the following: 1. Select the connection. 2. Move the mouse pointer over either selection handle that appears on the ends of the connection. 3. Press and hold mouse button 2. 4. Move the mouse pointer to the new part or connection. 5. Release the mouse button. Depending on the connection type, you may get a pop-up menu asking you for new information for the connection. What you can change You can change the source and target of either end of any connection. However, depending on the feature that you connect to when you make the change, you might get a different type of connection than the one you started with. The following table gives you a closer look at the connection types and what you can change without changing the connection type: ┌──────────────────────────────┬─────────────────┬─────────────────┬─────────────────┐ │Connection type │Move either end │Move source end │Move target end │ │attribute-to-attribute │x │ │ │ │attribute-to-member function │ │x │ │ │attribute-to-action │x │ │ │ │event-to-action │x │ │ │ │event-to-attribute │x │ │ │ │event-to-member function │ │x │ │ │custom logic │x │ │ │ │parameter connection │x │ │ │ └──────────────────────────────┴─────────────────┴─────────────────┴─────────────────┘ ═══ 43.7. Make the connections for the OASearch application ═══ The following sections show you how to connect the parts that were used to create a GUI for the OAContractView part in Constructing a GUI: the OASearch Application  Enabling push buttons when an entry field contains a value  Enabling a window to be cleared of all entry values  Connecting the variable part  Passing exceptions to message boxes ═══ 43.7.1. Enable push buttons when an entry field contains a value ═══ This section shows you how to make the connections that enable the Refresh and Save push buttons in the OAContractView window. When you have made these connections, the window appears as shown in the following figure: Follow these steps to enable the push buttons: 1. From the Account Number pop-up menu, select Connect. 2. Select text from the list. 3. Click on the Refresh push button. 4. Select enabled from the pop-up menu. 5. Follow the same procedure to connect the text attribute of the Account Number text part to the enabled attribute of the Save push button part. ═══ 43.7.2. Enable a window to be cleared of all entry values ═══ You can enable the Clear push button to empty all entry fields of their contents using more than one method. For this example, assume that the member function has been written. Make the connection as follows: 1. From the Composition Editor, use Alt-mouse button 2 to select the buttonClickEvent of the Clear push button. The connection spider appears. 2. Use Alt-mouse button 2 to select an empty section of the free-form surface. 3. Select More from the pop-up menu. 4. Enter the member function declaration in the entry field as shown in the following figure: 5. Select the OK push button. 6. Switch to the Class Editor. Include the files containing the member function code. For this example, the file names are oafwclr.cpv and oafwclr.hpv. a. In the User .hpv file field, type the name of the header file, oafwclr.hpv b. In the User .cpv file field, type the name of the code file, oafwclr.cpv For details on the attributes, actions, or events of a particular part, refer to the Visual Builder Parts Reference. For more information on how to perform these operations, see Making the Connections. ═══ 43.7.3. Connect the variable part ═══ Once you have added the variable to the free-form surface and set its name and type, you need to connect it to the OAContractView composite part. Making the attribute-to-attribute connections So that recruiters can display and update contract information held by the Contract variable, you must make attribute-to-attribute connections between the composite visual part and the Contract variable as follows: From part, feature To part, feature Contract,#accountNum EntryField1,#text Contract,#companyName EntryField2,#text Contract,#projectMgr EntryField3,#text Contract,#deptName EntryField4,#text Contract,#positionTitle EntryField5,#text Contract,#startDate EntryField6,#text Contract,#endDate EntryField7,#text Contract,#currContractor EntryField8,#text So far, the connections appear as shown in the following figure: Making the event-to-action connections To enable push buttons on the composite visual part, you must make event-to-action connections. This is a two-step process, because you specified an input parameter for each of the data access actions. First, connect each push button to the Contract variable. The connection line appears dashed, indicating an incomplete connection. Next, connect the attribute that represents the input parameter to the event-to-action connection itself. For this example, make the following connections: From part, feature To part, feature PushButton1,#buttonClickEvent Contract,#getContract EntryField1,#text (Account Number text) The anAccountNum parameter of the PushButton1,#buttonClickEvent--> Contract,#getContract connection. Visual Builder draws the parameter connection in the opposite direction. PushButton2,#buttonClickEvent Contract,#putContract EntryField1,#text (Account Number text) The anAccountNum parameter of the PushButton2,#buttonClickEvent--> Contract,#putContract connection. Visual Builder draws the parameter connection in the opposite direction. The connections now appear as shown in the following figure: The putContract and getContract actions throw exceptions when the account number is not found in the database. The next step is passing the exception to a message box. ═══ 43.7.4. Pass exceptions to message boxes ═══ You can trigger the display of a message box when an exception is thrown. Although a message box is a user-interface element, Visual Builder treats message boxes as nonvisual parts. Adding the message box To add a message box to the free-form surface, select , the Other category, from the parts palette; then add , an IMessageBox* part, to the free-form surface. Making the connections Now, connect the exceptionOccurred event of each event-to-action connection to the showException action of the message box. The connections appear as shown in the following figure. Save and close your visual part. ═══ 44. ...Display objects in a list box ═══ The following steps show you how to modify the original To-Do List application to use objects instead of text strings. If you have not already done so, please complete the original application, shown in Creating a Simple Visual Builder Application, before continuing with this example.  Copying the ToDoList part  Creating the ToDoItem nonvisual part  Replacing and modifying the list box  Placing and modifying an IVBFactory* part  Placing and modifying an IVSequence* part  Making the new connections  Generating the source code for your visual part and main() procedure  Building and running the modified application ═══ 44.1. Copy the ToDoList part ═══ First, you must copy the ToDoList part, as follows: 1. Select todolist.vbb. Visual Builder displays the name of the ToDoList part in the Visual Parts list box. 2. Select the ToDoList part. 3. Select PartCopy. Visual Builder displays the Copy Part window. 4. Enter ToDoLst2 in the Target part name field. 5. Enter todolst2.vbb in the Target file name field. 6. Select the Copy push button. Visual Builder creates a copy of the ToDoList part, gives it the name ToDoLst2, and stores it in the todolst2.vbb file. ═══ 44.2. Create the ToDoItem nonvisual part ═══ The next step is to create a nonvisual part called ToDoItem, as follows: 1. Open a new nonvisual part by doing the following: a. In the Visual Builder window, select PartNew. Visual Builder displays the Part - New window. b. Fill in the fields in this window as follows. Class name ToDoItem Description Type of objects in To-Do List File name ToDoLst2.vbb Part type Nonvisual part Base class IStandardNotifier c. Select the Open push button. Visual Builder displays the Part Interface Editor. 2. Create a new attribute called toDoItemName by doing the following: a. On the Attribute page, fill in the following fields: Attribute name toDoItemName Attribute type IString b. Select the Add with defaults push button. Visual Builder adds the toDoItemName attribute to the ToDoItem part. You can add the toDoItemName attribute to the preferred features list so that it will be readily available for making connections by doing the following: a. Switch to the Part Interface Editor. b. Select the Preferred page. c. Scroll down the list of attributes until you find the toDoItemName attribute and select it. d. Select the Add>> push button. Visual Builder adds the toDoItemName attribute to the list of preferred features so that it will appear in the pop-up connection menu. 3. Specify the .hpv and .cpv files for Visual Builder to use for the default feature code for the toDoItemName attribute by doing the following: a. Switch to the Class Editor if you followed the steps in the preceding hint. b. Fill in the following fields: User .hpv file ToDoItem.hpv User .cpv file ToDoItem.cpv 4. Generate the default source and feature code for the ToDoItem part by doing the following: a. Select FileSave and generatePart source. Visual Builder generates the code for the ToDoItem part and stores it in files named ToDoItem.hpp and ToDoItem.cpp. These files contain the appropriate include statements for the ToDoItem.hpv and ToDoItem.cpv files. b. Select FileSave and generateFeature source Visual Builder generates the default code for the toDoItemName attribute and stores it in the ToDoItem.hpv and ToDoItem.cpv files. 5. Override the asString member function in the IVBase* part by doing the following: a. Using your favorite text editor, edit the ToDoItem.hpv file and insert the following at the bottom of the public section: IString ToDoItem :: asString () const; b. Save the file. c. Edit the ToDoItem.cpv file and insert the following at the bottom of the file: IString ToDoItem :: asString () const { return toDoItemName(); } d. Save the file and close the text editor. 6. Close the Part Interface Editor. The ToDoItem part is now completed. ═══ 44.3. Replace and modify the list box ═══ You need a list box that can display objects instead of just text strings, so next you must replace the IListBox* part with an ICollectionViewListBox* part, and then modify the ICollectionViewListBox* part to specify the type of objects it can display. Replacing IListBox* with ICollectionViewListBox* 1. Open the ToDoLst2 part. 2. Delete the IListBox* part. The IListBox* part only accepts strings. You want a part that accepts objects. Visual Builder displays a message warning you that it will delete the connections as well as the list box if you continue. You want to delete the connections because you need different connections for this example. 3. Select the OK push button. Visual Builder deletes the list box and the connections. 4. Select , the Lists category, from the row of icons on the left-hand side of the parts palette. 5. Select , the ICollectionViewListBox* icon, from the row of icons that Visual Builder displays on the right-hand side of the parts palette. 6. Place the crosshairs below the bottom left corner of the second static text part and click mouse button 1. A list box part that displays the items in a collection is placed beneath the second static text part. Specifying the type of items the list box can contain 1. Move the mouse pointer to the list box, click mouse button 2, and select Open Settings. Visual Builder displays the settings notebook for the list box. 2. Enter ToDoItem* in the Class name of items field. 3. Select the OK push button. The list box can now accept only ToDoItem* objects. ═══ 44.4. Place and modify an IVBFactory* part ═══ You need an IVBFactory* part to create the objects to be displayed in the list box. In addition, you must specify the type of objects the IVBFactory* part can create. Placing an IVBFactory* part on the free-form surface 1. Select , the Models category, from the row of icons on the left-hand side of the parts palette. 2. Select , the IVBFactory* icon, from the row of icons that Visual Builder displays on the right-hand side of the parts palette. 3. Place an object factory part on the free-form surface to the right of the To-Do List window adjacent to the entry field. 4. Change the text beneath the object factory icon to ItemFactory. Specifying the type of objects the object factory can create 1. Move the mouse pointer to the object factory, click mouse button 2, and select Change Type. Visual Builder displays a window in which you are to enter the type of objects that the object factory is to create. 2. Enter ToDoItem* in the entry field in this window. 3. Select the OK push button. The object factory can now create only ToDoItem objects. ═══ 44.5. Place and modify an IVSequence* part ═══ You also need to place an IVSequence* part to put the objects that the IVBFactory* part creates into a sequence; you must also specify the type of objects the sequence can contain. Placing an IVSequence* part on the free-form surface 1. Select OptionsAdd part. Visual Builder displays the Add part window. 2. Enter ItemSequence in the Name field. 3. Enter IVSequence* in the Part class field. 4. Select the Add push button. 5. Place an IVSequence* part on the free-form surface surface to the right of the To-Do List window adjacent to the list box. Specifying the type of objects in the sequence 1. Move the mouse pointer to the sequence, click mouse button 2, and select Open Settings. Visual Builder displays the settings notebook for the sequence. 2. Enter ToDoItem* in the Class name of items field. 3. Select the OK push button. The sequence can now accept only ToDoItem objects. ═══ 44.6. Make the new connections ═══ The following steps describe the connections that this example requires to add objects to and remove objects from the list box. To review the instructions for connecting features, see Making the Connections. 1. Connect the buttonClickEvent feature of the Add push button to the new action of the object factory. This connection causes the object factory to create a new ToDoItem object whenever a user clicks the Add push button. 2. Connect the toDoItemName attribute of the object factory to the text attribute of the entry field. This connection causes text in the entry field to be used as the name of ToDoItem objects that the object factory creates. Notice that the connection line is violet, the color of a parameter connection, instead of cyan, which is the color of an attribute-to-attribute connection. The connection line is violet because the text attribute of the entry field supplies a value for the toDoItemName attribute only when the object factory creates a new object, just as if it were satisfying a parameter of the new action. 3. Connect the newEvent attribute of the object factory to the addAsLast action of the sequence. This connection causes each new ToDoItem object to be added as the last object in the sequence. 4. Connect the this attribute of the sequence to the items attribute of the list box. This connection causes the list box to display all of the ToDoItem objects that the sequence contains. 5. Connect the buttonClickEvent feature of the Remove push button to the removeAtPosition action of the sequence. This connection causes the object at a specified position in the sequence to be removed. This connection is incomplete because the removeAtPosition action's position parameter must be satisfied. 6. Connect the position parameter of the previous connection to the selectedCollectionPosition attribute of the list box. This connection provides the position of the selected item in the collection of objects, which is required by the previous connection in order to remove an object. ═══ 44.7. Generate the source code for my visual part and main() procedure ═══ To generate the C++ source code for your visual part, select FileSave and GeneratePart source. Visual Builder generates the following files in the working directory: todolst2.cpp The C++ code for your todolst2 part. todolst2.hpp The C++ header file for your todolst2 part. todolst2.h The resource header file for your todolst2.cpp file. todolst2.rc The resource file for your todolst2.cpp file. Generating the source code for your main() procedure To generate the source code for your main() procedure, select FileSave and Generatemain() for part. Visual Builder generates the following files in the working directory: todolst2.app The main function for your application. Note: If you start Visual Builder from a WorkFrame project, the name of this file is vbmain.cpp. todolst2.mak The make file that you specify when you build your application. Note: You must select OptionsGenerate make files in the Visual Builder window to generate this file. ═══ 44.8. Build and run the modified application ═══ You should now be ready to build and run your modified To-Do List application, as follows: Building the new To-Do List application 1. Open an OS/2 window. 2. Change to your Visual Builder working directory. 3. Enter the following command: nmake todolst2.mak This command produces the following files: todolst2.exe The executable file for your application. todolst2.map The application configuration map. todolst2.o The object file for your application. Note: If you start Visual Builder from a WorkFrame project, the name of this file is vbmain.obj. todolst2.obj The object file for your part. Visual Builder provides a separate object module for your part that is used when compiling this part with other parts. todolst2.res The binary resource file that is bound to todolst2.exe. Running the new To-Do List application To run your application from the same OS/2 command prompt from which you entered the nmake command, enter the following: todolst2 Once your application is running, experiment with it to make sure it works as you designed it. That is all there is to it! You can add a finishing touch to your application by creating an OS/2 program object. Create a program object from the OS/2 Templates folder, specifying the name todolst2.exe as the program name and the directory that contains todolst2.exe as the working directory. Once you have done this, you can run your application by simply double-clicking on the program object you just created. ═══ 45. ...Create resizable windows ═══  Adding a multicell canvas  Adding parts to the multicell canvas  Changing the multicell canvas grid  Extending a part to span more than one cell  Adding a group box  Changing the settings for a multicell canvas ═══ 45.1. Add a multicell canvas ═══ This example is based on OAContractView, found in oawin.vbb. 1. Because you are constructing a new user interface, begin by creating a visual part. Call it contractView. When you create a visual part, the Composition Editor opens and an IFrameWindow* part is automatically added for you. By default, the client area of the IFrameWindow* part appears as a canvas. 2. Delete the default canvas client. 3. Select , the Composers category, from the left side of the parts palette. 4. Select , the IMultiCellCanvas* part, from the right side of the parts palette and drop it on the IFrameWindow* part. Your visual part now looks like the following figure: The next step is adding parts to the multicell canvas. ═══ 45.2. Add parts to the multicell canvas ═══ When you first drop a multicell canvas, the cell grid appears at its default size in the upper-left corner of the client area. You can now drop parts into the canvas. For the contractView example, do the following: 1. Select , the Data Entry category, from the left side of the parts palette. 2. Select , the IStaticText* part, from the right side of the parts palette. When you move the mouse pointer over the free-form surface, the pointer changes to crosshairs. 3. Drop the part at cell (2,2) of the multicell canvas. Row 1 was left as a spacer between the top of the multicell canvas and the window border. When you drop the IStaticText* part, cell (2,2) expands to contain the dropped part. The multicell canvas now looks like the following figure: 4. Drop another IStaticText* part at cell (4,2), leaving row 3 as a spacer. The multicell canvas now looks like the following figure: 5. Drop two more IStaticText* parts into the expansion area below the StaticText2 part. Each time you drop a part into the expansion area, a new row is created for you. 6. Drop three more IStaticText* parts in column 3 as shown in the following figure: No spacer rows exist yet between these new rows. We will add these in Adding Rows or Columns. Now add some IEntryField* parts. 7. Select , the Data Entry category, from the left side of the parts palette. 8. Select , the IEntryField* part, from the right side of the parts palette. 9. Drop IEntryField* parts in the expansion area to the right of the IStaticText* parts, starting at row 2. A new column 6 is created, as shown in the following figure: ═══ 45.3. Change the multicell canvas grid ═══ You can add or delete rows or columns from a multicell canvas as follows:  To add rows or columns from the expansion area, you can just drop parts into it, as discussed in Adding Parts to the Multicell Canvas.  To add several rows or columns at a time, you might find it easiest to change the grid using the multicell canvas's settings notebook. This method is discussed in Changing the Multicell Canvas Grid Using the Settings Notebook.  With the multicell canvas selected, you can press mouse button 2 and use the contextual menu. For more information on this method, see the following: - Adding Rows or Columns Using the Contextual Menu - Deleting Rows or Columns Using the Contextual Menu ═══ 45.3.1. Add rows or columns using the contextual menu ═══ You can add rows or columns anywhere on the multicell canvas as follows: 1. Select a cell next to where you want to add the row or column. Note: No selection handles are shown on the cell if it is empty. Also, you can only open the contextual menu for an empty cell. 2. Press mouse button 2 to open the contextual menu. 3. To add a row, select Rows. To add a column, select Columns. A cascade menu appears. 4. If you want to insert the row above the cell you selected, select Add row before from the cascade menu. If you want to insert the row below the cell you selected, select Add row after from the cascade menu. For columns, Add column before inserts a column to the right of the selected cell. Add column after inserts a column to the left of the selected cell. For practice, add spacer rows to the contractView example as follows: 1. Select the empty cell to the left of StaticText3. Add a row after it. 2. Add one row each after StaticText4 through StaticText7. At this point, the contractView window looks like the following figure: ═══ 45.3.2. Delete rows or columns using the contextual menu ═══ You can delete rows or columns from anywhere on the multicell canvas as follows: 1. Select a cell in the row or column you want to delete. 2. Press mouse button 2 to open the contextual menu. 3. To delete the row, select Rows. Then select Delete row. To delete the column, select Columns. Then select Delete column. ═══ 45.4. Extend a part to span more than one cell ═══ Build a deck of push buttons using an ISetCanvas* part as a base, as follows: 1. Drop an ISetCanvas* part in the bottom expansion area of column 2. 2. Extend the span of the ISetCanvas* as follows: a. Select the ISetCanvas* part. b. Holding the Alt key with one hand, drag either right-hand part handle over to the column that contains the IEntryField* parts. c. Release the mouse. 3. Add three IPushButton* parts to the ISetCanvas* part. The ISetCanvas* and multicell canvas parts expand to contain the newly dropped IPushButton* parts. To change the way minimum size is calculated for the IPushButton* parts, edit Pack Type settings for the ISetCanvas* part. 4. Edit the IStaticText* parts so that they appear as shown in the following figure: Extend each column 2 IStaticText* part into column 3. ═══ 45.5. Add a group box ═══ In the contractView sample, the column 3 IStaticText* parts and their entry fields belong to the Position Details group shown in the following figure: The group box will extend from cell (10,2) to cell (18,8). Adding the extra rows and columns to hold the group box Extra cells are necessary to hold the group box and provide space between the group box and the parts within it. 1. Add 2 rows above Title. 2. Add 2 rows after Contractor. 3. Add 2 columns after the corresponding IEntryField* parts. The sample window now looks like the following figure: Dropping and extending the group box 1. Select , the Data Entry category, from the left side of the parts palette. 2. Select , the IGroupBox* part, from the right side of the parts palette. 3. Drop the IGroupBox* part into cell (10,2). This temporarily distorts the multicell canvas. Resize the IFrameWindow* part to see the extra columns on the right. 4. Select the IGroupBox* part. Holding the Alt key with 1 hand, drag the lower right part handle to cell (18,8) as shown in the following figure: If necessary, press Alt-Backspace to undo and retry. Edit the IGroupBox* text to read Position Details. Remember to move the IGroupBox* part up in the tabbing and depth order. ═══ 45.6. Change the settings for a multicell canvas ═══ You can use the General page of the multicell canvas settings notebook to do the following:  Move a dropped part  Change the default minimum size for rows or columns  Add rows or columns  Delete rows or columns  Make fixed rows and columns expandable This page consists of a series of directly editable tables. ═══ 45.6.1. Move dropped parts ═══ From the free-form surface, you can move dropped parts by selecting and dragging them to their new locations. You can also move dropped parts between cells in a multicell canvas using the settings notebook as follows: 1. Open settings for the multicell canvas. 2. At the top of the General page is a scrollable list of all parts contained in the multicell canvas as shown in the following figure: 3. Select the table entry you want to change and edit the highlighted value. Row and column numbering starts from (1,1) in the upper-left corner of the multicell canvas. 4. Select the OK push button to close settings. Use this table for reference whenever you edit row and column settings. ═══ 45.6.2. Change default minimum size for rows or columns ═══ You can change the minimum size of a row or column when it is empty. As stated previously, the default minimum size is 10 pixels wide (columns) and 10 pixels high (rows), but you can change the default minimum size for individual rows and columns as follows: 1. Open settings for the multicell canvas. 2. The second table on the General settings page is called Rows, as shown in the following figure: 3. The default height appears as nil. To change the minimum height for row 1, select the Row 1 table entry under Height. Change this to the new default value in pixels. For example, the minimum height of row 1 in most views of the OASearch sample application is 20. 4. Scroll down the General page a little more to see the third table on the page, called Columns. You can edit values in this table in the same way you edited the Rows table. 5. Select the OK push button to close settings. ═══ 45.6.3. Add rows or columns using the settings notebook ═══ To save time when adding more than one row or column at a time, use the settings notebook. The methods for adding rows and columns are similar, as follows: 1. Open settings for the multicell canvas. The tables on the General page are described in Moving Dropped Parts and Changing Default Minimum Size for Rows or Columns 2. If necessary, scroll down to the Rows table. For a complex layout, consider resizing the window so that the Controls table is also displayed. 3. Select the number of a row next to the insertion point. Select the Add push button. 4. Select either Add before or Add after.  Add before inserts the new row above the selected row.  Add after inserts the new row below the selected row. 5. Select the OK push button to close settings. ═══ 45.6.4. Delete rows or columns using the settings notebook ═══ To save time when deleting more than one row or column at a time, use the settings notebook. The methods for deleting rows and columns are similar, as follows: 1. Open settings for the multicell canvas. The tables on the General page are described in Moving Dropped Parts and Changing Default Minimum Size for Rows or Columns 2. If necessary, scroll down to the Rows table. For a complex layout, consider resizing the window so that the Controls table is also displayed. 3. Select the number of the row you want deleted. Select the Delete push button. 4. Select the OK push button to close settings. ═══ 45.6.5. Make rows or columns expandable ═══ The methods for making rows and columns expandable are similar, as follows: 1. Open settings for the multicell canvas. The tables on the General page are described in Moving Dropped Parts and Changing Default Minimum Size for Rows or Columns 2. If necessary, scroll down to the Rows table. For a complex layout, consider resizing the window so that the Controls table is also displayed. 3. The default expansion value appears as nil. Select the appropriate entry from the Rows table under Expand. For the contractView example, select the row 19 entry. 4. The value d is highlighted. Change it to y and select the Apply push button. 5. Move the settings notebook window over so you can see the result of your work, as shown in the following figure: The expansion area is now hidden. All extra vertical space becomes part of row 19. 6. When you are finished adjusting row and column expansion settings, select the OK push button. To make this row fixed later, enter n in the Expand column. ═══ 46. ...Construct containers and notebooks ═══  Adding container parts - Setting up the container - Adding container columns - Filling the container  Adding notebook parts - Adding the notebook - Adding notebook pages ═══ 46.1. Add container parts ═══ In this section, you set up a container in the OASkillView part to hold the OASkill* objects returned as a result of a user's skill query. The completed window looks like the following figure: This example is based on the OASkillView* part, found in oawin.vbb. Before constructing this new visual part, make sure that oanonvis.vbb is loaded into Visual Builder. 1. Create a new visual part and name it OASkillView. A frame window and default canvas appear. 2. Select , the Lists category, from the left side of the parts palette. 3. Select , the IVBContainerControl* part, from the right side of the parts palette and drop the part onto the default canvas. 4. Change the container's name to SkillCnr. 5. Resize the container part as needed. The next step is Setting Up the Container. ═══ 46.1.1. Set up the container ═══ You set some container values in the container part and some in the container column part. Set the following values in the container part:  Title and title format  View style  Type of contained objects Set the following values in the container column parts:  Column title and width  Attribute to appear in the column  Vertical and horizontal separators  Whether contents can be changed by the user Adding Container Columns. Setting the container titles 1. Open the settings notebook for SkillCnr. 2. Specify the general settings. In the Title Attributes group, type Contractors Holding This Skill into the Title field. 3. Select both Show title and Show title separator. 4. Select the Left radio button for left title alignment. Specifying the container type and layout 1. Select showDetailsView from the View type list box. 2. Scroll down on the General page. In the Container Item Attributes group, type OASkill into the Part type field. 3. Select contractorID from the Text drop-down combination box. The Text field specifies which OASkill attribute would appear as text in the container's icon view. 4. The Icon field specifies the icon to be used for each item in the container. Type the following into the Icon field: #IDynamicLinkLibrary("cppov33r").loadIcon(803) cppov33r.dll is the resource DLL containing the icons for this application, and 803 is the resource ID for the skill icon that would appear in the container's icon view. 5. Select the Refresh container after changes check box. 6. Select the OK push button to save and close the settings notebook. ═══ 46.1.2. Add container columns ═══ Once you have added a container, add container columns. This is a good idea even if you intend for the container to be used mainly as an icon view. 1. Select , the Lists category, from the parts palette. 2. Select the Sticky check box. 3. Select , the IContainerColumn* part, from the parts palette. 4. Drop two IContainerColumn* parts on the SkillCnr part. Setting up the container columns 1. Open up the settings notebook for the first container column. 2. On the General settings page, type Contractor ID in the Heading text field. 3. Specify the column's width (in pixels) in the Width field. For this example, enter 200. 4. Specify the OASkill attribute to appear in this column. Select the Use the Text attribute set in the container radio button because you want to display the same information in this container column that the container displays as text on the icon view. 5. Set the container so that its elements cannot be changed by the user. Select the following from the Styles settings page:  For the readOnlyHeading style, select the On radio button.  For the readOnly style, select the On radio button. 6. Set a vertical separator for container column 1 only. For the verticalSeparator style, select the On radio button. 7. Select the OK push button to close the settings notebook. Repeat this procedure for the second container column, adjusting the width of the column to fit. The second column is supposed to display the number of years of experience each contractor has for a certain skill, so use the following settings:  Select the Use an attribute from the part radio button  Choose yearsExp to populate the container column.  Do not add a vertical separator. The next step is Filling the Container. ═══ 46.1.3. Fill the container ═══ The easiest way to fill the container is to use a collection part. The OASkillView part uses an IVSequence* part named SkillList. Adding the nonvisual parts The OASearch application uses static parts that are actually found in OAMain part. All nonvisual parts in this view except SkillList are variables that will be connected later to the actual parts. 1. Add an OASkill* part as a variable. Name it Skill. For help on how to do this, see Adding a Variable to a Composite Part. 2. Add an OASkillBase* part as a variable. Name it SkillBase. 3. Add an IVSequence* part. Name it SkillList. 4. Add an IMessageBox* part to handle exceptions. Populating the collection The SkillBase part contains the action (getSkills) needed to populate the skill list. The getSkills action takes two parameters, a skill description and a sequence. Make the following connections: From To Skill,#skillName EntryField1,#text PushButton1,#buttonClickEvent SkillBase,#getSkills Skill,#skillName The aSkillName parameter of the PushButton1,#buttonClickEvent--> SkillBase#getSkills connection SkillList,#this The aList parameter of the PushButton1,#buttonClickEvent--> SkillBase#getSkills connection To handle exceptions, connect the exceptionOccurred feature of the getSkills connection to the showException feature of the message box part. Connecting parts to fill the container To fill the container, connect the this attribute of the SkillList part to the items attribute of the container. ═══ 46.2. Add notebook parts ═══ The purpose of this section is to guide you through using a notebook part to create the OAContractorView part. The completed window looks like the following figure: The steps in creating a notebook are as follows:  Add the notebook and set it up.  Add notebook pages and set them up. Begin by adding the notebook. ═══ 46.2.1. Add the notebook ═══ Before constructing this new visual part, make sure that oanonvis.vbb is loaded into Visual Builder. 1. Create a new visual part. Call it OAContractorView. A frame window and default canvas appear. 2. Delete the default canvas part from the frame window and resize the window as necessary. 3. Select , the Composers category, from the left side of the parts palette. 4. Select , the INotebook* part, from the right side of the parts palette and drop the part onto the frame window. Specifying the notebook layout You change the notebook's appearance using its settings notebook. As you make selections, notice that the Preview area changes to reflect your choices. 1. Open the settings notebook for the notebook part. 2. On the General settings page, select the icon that represents the orientation that you want for the notebook. For this example, select from the Layout group. 3. From the Binding group, select the Spiral radio button. 4. From the Tab Shape group, select the Round radio button. 5. From the Justification group, select the two Center radio buttons. 6. Select the OK push button to close the settings notebook. The next step is adding notebook pages. ═══ 46.2.2. Add notebook pages ═══ You add notebook pages using the notebook part's Composition Editor contextual menu. 1. To add the first page of the notebook, select Add initial page. 2. To add each additional page, select Add page before or Add page after. For this example, add one page after the initial page. Setting up the notebook page and tab 1. Open the settings notebook for the first notebook page. To open the settings for the notebook page instead of the canvas that is on the notebook page, move the mouse pointer to the small area around the canvas before opening the settings. 2. On the General page, type ContactPage into the Subpart name field. 3. Type Contact into the Tab text field. This text is what appears on the notebook tab. 4. Type Vital statistics into the Status text field. This text is what appears in the status area at the bottom of the notebook page. 5. On the Style page, select the On radio button for the following styles:  The autoPageSize style, to enable automatic sizing of the notebook page  The statusText style, to enable display of the status text that you entered in the previous step to be displayed  The majorTab style, to give the notebook page a major tab Adding parts to a notebook page Each notebook page initially contains an ICanvas* part. If you want to use a different part, delete the ICanvas* part and select another part from the Composers category, such as IMultiCellCanvas*. Note: A notebook page allows only one subpart, which should be a part from the Composers category. You can, of course, add other subparts to the Composers part. The ContactPage subpart contains the primitive parts shown in the following figure: To see the other notebook pages, open the OAContractView part in oawin.vbb. ═══ 47. ...Add menus to my application ═══  Adding a menu bar  Connecting the menu bar to the window  Adding menu choices  Adding menu separators  Connecting menu choices to actions Begin with adding a menu bar to the window. ═══ 47.1. Add a menu bar ═══ Begin by opening the visual part that contains the OASearch welcome window, the OAMain part. 1. Select , the Frame Extensions category, from the left side of the parts palette. 2. Select , the IMenu* part, from the right side of the parts palette and drop it on the free-form surface next to the window, as shown in the following figure: 3. To add two of the menu choices to the menu bar, add two menu parts on top of the menu part for the menu bar. As you add each menu part, a cascade button part is added to the menu bar and a connection is made between the cascade button part and the menu part you added. This connection causes the menu part to be displayed when the user selects the cascade button part. See the following figure: 4. Edit the text of the menu choices as shown in the following figure: To do this, select each one and press Alt-mouse button 1. ═══ 47.2. Connect the menu bar to the window ═══ To make the menu a menu bar, connect the this attribute of the IMenu* part to the menu attribute of the window part. Although the menu continues to appear vertically on the free-form surface, this connection defines the menu part as a menu bar. Since the menu bar is shown outside the frame window, be sure to leave enough space for it below the window title. Making this same connection to a part other than a window part, such as a list part, makes the menu part a pop-up menu instead of a menu bar. Now that the menu bar has been added, the next step is adding the menu choices. ═══ 47.3. Add menu choices ═══ Once the menu structure is complete, you need to add menu choices that do something other than open other menus. 1. Select , the Frame Extensions category, from the left side of the parts palette. 2. Select , the IMenuItem* part, from the right side of the parts palette. 3. The position at which you click the mouse is where the part is added within the menu. Drop menu items as follows:  One part as the last item in the Menu1 part  Four items in the Menu2 part  Two items in the Menu3 part You can change the position of a menu choice part within the menu part by using mouse button 2 to drag each item to a new position. Position these parts and change their text as shown in the following figure: The next step is connecting menu choices to actions. ═══ 47.4. Add menu separators ═══ Once you have added and edited the OAMain menu items, add a separator bar to Menu2 between Skill and General Information as follows: 1. Select , the Frame Extensions category, from the left side of the parts palette. 2. Select , the IMenuSeparator* part, from the right side of the parts palette. ═══ 47.5. Connect menu choices to actions ═══ Once you have added menu choices, you can connect them to actions in this or other parts. As an example, connect the Exit menu bar item so that when the item is selected, the main window closes, as follows: From part, feature To part, feature ExitMI,#commandEvent FrameWindow,#close Command events occur when a user selects a menu item, push button, or accelerator key. In this case, the user' selection of Exit generates a command event to perform the close action on the Frame Window. Note: You cannot promote menu item events to the part interface. The other menu choices, shown in the following figure, connect to other parts that are not on this free-form surface. These connections are completed in Completing the Menu Bar. ═══ 48. ...Add help to Visual Builder applications ═══  Creating the help file  Providing context-sensitive help  Providing general help  Providing the application help window  Providing help for factory-generated frame windows  Providing a Help push button  Displaying fly-over help when the mouse pointer is over a part  Displaying help in an information area ═══ 48.1. Create the help file ═══ Before we can connect the help, we must first create the help file. Writing the help For convenience sake, we have provided the help source so you do not have to retype it. Double-click here to see the help source and select Copy from the Services pull-down menu to copy the panel text to the system clipboard. Using your favorite editor, create a new file and paste this text into the file. When creating your own help files, try using a Project Smarts IPF template, which provides the basic tags for creating online help using the OS/2 Information Presentation Facility. For more information on writing online help, refer to the OS/2 Information Presentation Facility Guide and Reference. Save this file with a name similar to cppov33.ipf.ipf. Building the help file Ensure that you have the IPF compiler installed on your system and that your environment variables are set up to run the IPF compiler. The IPF compiler comes with the OS/2 2.1 Toolkit and the OS/2 Warp Toolkit. To build the help file, simply run the Information Presentation Facility (IPF) compiler. For example, if you saved your help file with the name cppov33.ipf, you would enter the following command in the directory where you saved your file: ipfc cppov33.ipf This command generates a file called cppov33.hlp. You have now built your help file. The next step is to provide context-sensitive help in your application. ═══ 48.2. Sample Help Source Code ═══ :userdoc. :title.Opportunities Abound Databases Help :docprof toc=1 ctrlarea=page. :ctrl ctrlid=buttons controls='ESC SEARCH PRINT' page. :h1 res=9998. General Help for the Opportunities Abound Databases :i1.general help :p.Text goes here. :h1 res=9999. Request for Skill Information Help :i1.requesting skill information, help for :p.Text goes here. :h1 id=10000. Skill Information Help :i1.skill information, help for :p.Text goes here. :h1 res=10001. Request for Contract Information Help :i1.requesting contract information, help for :p.Text goes here. :h1 res=10002. Contract Information Help :i1.contract information, help for :p.Text goes here. :h1 res=10003. Request for Contractor Information Help :i1.requesting contractor information, help for :p.Text goes here. :h1 res=10004. Contractor Information Help :i1.contractor information, help for :p.Text goes here. :euserdoc. ═══ 48.3. Provide context-sensitive help ═══ This section tells you how to provide context-sensitive help for subparts in your application. For this example, we use the graphic push buttons on the window. To provide context-sensitive help for a subpart, do the following: 1. Open the cppov33.ipf file in your text editor and find the "Request for Skill Information Help" heading. Above this heading is the heading tag, :h1, with a res attribute. This attribute contains the resource number for the help panel for the Skills push button. 2. Open the settings notebook for the subpart, in this case the Skill push button. 3. Select the Control page. It looks like the following figure: 4. Enter the resource number for the Skills push button help panel in the Help panel id field. When you generate the code for your application, Visual Builder creates a help table in the resource (.rc) file that it generates and inserts this number into the help table. 5. If the Enable check box is not checked, select it. 6. Select the OK push button. 7. Repeat steps 2 through 6 for the Contract push button and the Contractor push button. Use the resource numbers for the "Request for Contract Information Help" and "Request for Contractor Information Help", respectively. You have now provided context-sensitive help for the push buttons. The next step is to provide general help in your application. ═══ 48.4. Provide general help ═══ This section tells you how to provide general help for your application. For this example, we use the frame window. To provide context-sensitive help for your application, do the following: 1. Open the cppov33.ipf file in your text editor and find the "General Help for the Opportunities Abound Databases" heading. Above this heading is the heading tag, :h1, with a res attribute. This attribute contains the resource number for the general information help panel. 2. Open the settings notebook for the subpart, in this case the frame window. 3. Select the Control page. It looks like the following figure: 4. Enter the resource number for the general information help panel in the Help panel id field. When you generate the code for your application, Visual Builder creates a help table in the resource (.rc) file that it generates and inserts this number into the help table. 5. If the Enable check box is not checked, select it. 6. Select the OK push button. You have now provided general help for the main window. The next step is to provide a help window to display the help panels in. ═══ 48.5. Provide the application help window ═══ Now that you have added the context-sensitive help and the general help for the main window, you need a help window to display the help panels in. You must place an IHelpWindow* part on the free-form surface to give Visual Builder a window in which to display the help information. The default owner of the IHelpWindow* part is the primary part for your application. Therefore, no connections are required. To add a help window to your application, do the following: 1. Select , the Other category, on the parts palette. 2. Select , the IHelpWindow* part, and place it on the free-form surface. 3. Open the settings notebook for the IHelpWindow* part. It looks like the following figure: 4. In the Title field, enter the title of the help window. This must be the same title that you entered on the :title tag in your .ipf file. 5. In the Help libraries field, enter the name of the help file that you compiled, such as oasearch.hlp. If you had created multiple help files for your application, you would enter all of their names in this field. 6. We recommend that you leave the Help table id field empty and let Visual Builder generate it for you unless you need a specific help table ID. Otherwise, you could have conflicts in your resource (.rc) file. 7. Select the OK push button. ═══ 48.6. Provide help for factory-generated frame windows ═══ You can associate a help window with a part that is generated by an object factory if the base class of that part is IFrameWindow*. To do this, you can do either of the following:  Edit the part that the object factory generates, place an IHelpWindow* part on the free-form surface next to it, and do all the things described in the preceding sections to use the help window properly. Repeat this step for each IFrameWindow*-based part that is generated by an object factory. You should use this method if you have created multiple help library (.hlp) files for your library instead of putting all of your help panels in one library file.  Place an IHelpWindow* part on the free-form surface in the same view with the object factory if you have created only one help library file for all of your help panels. Then, do the following: 1. Open the settings notebook for the IHelpWindow* part. 2. Enter the help window title and the name of the library (.hlp) file. 3. Close the settings notebook by selecting the OK push button. 4. Connect the newEvent feature of the object factory to the setAssociatedWindow action of the help window. 5. Repeat step 4 for each object factory in the view. 6. Edit each IFrameWindow*-based part that an object factory generates and specify the appropriate help panel IDs for the subparts that you want to provide help for. Each help panel ID must be a resource ID in the library file that you specified in step 2. ═══ 48.7. Provide a Help push button ═══ To provide a Help push button in your application, do the following: 1. Select , the Buttons category, in the left-hand column on the parts palette. 2. Select , the IPushButton* part, and place it where you want it to be. 3. Change the text on the push button to Help. 4. Open the settings notebook for the push button. 5. Select the Styles tab. 6. Find help on the Styles page and select the On radio button. This style turns a regular push button into a help push button. 7. On the same page, find noPointerFocus and select the On radio button. 8. Select the OK push button to close the settings notebook. You now have a Help push button. If you have followed the steps in the preceding sections, clicking this button causes the contextual help panel for the part that currently has the input focus to be displayed. If no part has the focus, the main help panel for the window is displayed. The behavior of the Help push button is identical to that of the F1 key. To provide a help panel for the Help push button itself, follow the instructions in ═══ 48.8. Display fly-over help when the mouse pointer is over a part ═══ Your application can provide the following types of fly-over help:  A short text string that your application displays next to the subpart that the mouse pointer is over  A longer text string that your application displays in a text control Providing fly-over help for a subpart To provide fly-over help for a subpart, do the following: 1. Place an IVBFlyText* part on the free-form surface by doing the following: a. Select , the Other category, on the parts palette. b. Select , the IVBFlyText* part, and place it on the free-form surface. 2. Add fly-over help text to one or more subparts by doing the following: a. Open the settings notebook for a subpart, such as an entry field or push button. b. Select the Control notebook tab. c. Enter fly-over text strings in the Fly over short text field, the Fly over long text field, or both. d. Select the OK push button to save the text strings that you just entered. That is all you need to do. There are no connections to make. ═══ 48.9. Display help in an information area ═══ The following sections provide specific information about displaying help in an information area:  Adding an information area to a frame window  Displaying help for menu choices in an information area  Displaying information about successful actions ═══ 48.9.1. Add an information area to a frame window ═══ To add an information area to a frame window, do the following: 1. Select , the Frame Extensions category, on the parts palette. 2. Select , the IInfoArea* part. 3. Move the mouse pointer over the title bar or window border of the frame window and click mouse button 1. Visual Builder places an information area at the bottom of the frame window. 4. Open the settings notebook for the information area. 5. Enter text that you want your application to display in the following fields: Disabled text Text to display when the selected menu choice is disabled. Inactive text Text to display when no menu choice is selected. Missing text Text to display when the information area cannot find and display specific help for a menu choice. ═══ 48.9.2. Display help for menu choices in an information area ═══ To display help text for menu choices in an information area, do the following: 1. Create the menu bar and pull-down menus for your application. 2. Open the settings notebook for each menu choice. 3. Enter a description of the menu choice in the Info area text field. 4. Select the OK push button to save the description you just entered. ═══ 48.9.3. Display long fly-over text in an information area ═══ To display a long fly-over text string in an information area, do the following. Note: The following steps assume that you have already added an IVBFlyText* part and an IInfoArea* part to a frame window. If you have not, you should complete the steps in the following sections and then return here.  Displaying Fly-over Help When the Mouse Pointer Is Over a Part When following these steps, make sure you enter a text string in the Fly over long text field in the settings notebook for a subpart, such as an entry field or push button.  Adding an Information Area to a Frame Window 1. Display the connection menu for the information area. 2. Select the this attribute. 3. Display the connection menu for the fly-over text part. 4. Select the longTextControl attribute. That is all you have to do. ═══ 48.9.4. Display information about successful actions ═══ To display information in an information area when an action or member function completes successfully, do the following: 1. Create an event-to-attribute connection using the text attribute of the IInfoArea* part as the target. The source event can be one of the following:  The same event that triggered the action or member function  The actionResult event of the connection that triggered the action or member function 2. Double-click on the connection you just made to open the settings window for the connection. 3. Select the Set parameters push button to open the Constant Parameter Value Settings window. 4. In the text field, enter the text string that you want to assign to the text attribute. Your application will display this text string in the information area each time the action or member function completes successfully. 5. Select the OK push button to close the Constant Parameter Value Settings window. 6. Select the Cancel push button to close the connection settings window. ═══ 49. ...Integrate visual parts into a single application ═══  Adding nonvisual support parts to the primary part  Adding static visual parts  Adding visual parts as dynamic instances - Adding and setting Object Factory parts - Adding variable parts - Connecting to the Object Factory parts - Connecting the Object Factory parts to their corresponding variable parts  Making the final connections - Connecting the nonvisual parts to the variables that represent them - Completing the menu bar ═══ 49.1. Add nonvisual support parts to the primary part ═══ For this example, refer to the primary view, OAMain, in oawin.vbb, shown in the following figure: 1. Begin by building the primary part as you would any IFrameWindow*-based part. For information about building the menu bar, see Adding Menus to Your Application. 2. The OASearch application starts up with a small number of static nonvisual instances to support the visual parts. Add the following parts:  OAContractor*. Name it Contractor.  OAContract*. Name it Contract.  OASkill*. Name it Skill.  OASkillBase*. Name it SkillBase. You must connect these part instances to the variables that represent them in the other visual parts. First, you must add the visual parts. ═══ 49.2. Add static parts ═══ One visual part, OAGenInfo, exists statically in the OASearch application as a modal window. The disadvantage of using static visual parts is that once the user closes the window, the part is destroyed and cannot be instantiated again in the same session. Add the OAGenInfo* part. Name it VBDevelopment. You must also connect OAGEnInfo* to the menu item that causes it to display. For details, see Completing the Menu Bar. ═══ 49.3. Add visual parts as dynamic instances ═══ Implementing dynamic parts involves the following tasks:  Adding and setting Object Factory parts  Adding variable parts  Connecting to the Object Factory parts  Connecting the Object Factory parts to the corresponding variable parts The first step is adding and setting Object Factory parts. ═══ 49.3.1. Add and set object factory parts ═══ Before you can use Object Factory parts, you must have created the part classes to be represented. Before you start, be sure to load the .vbb files that contain those parts into Visual Builder. Adding the Object Factory parts 1. Select , the Models category, from the left side of the parts palette. 2. Select the Sticky check box. 3. Select , the Object Factory part, from the right side of the parts palette. 4. Drop six Object Factory parts on the free-form surface. 5. Unload the mouse pointer by selecting , the Selection tool, from the Visual Builder tool bar. Setting an Object Factory part 1. Change the part name using the Composition Editor contextual menu. In the OASearch example, the Object Factory parts are named as follows: ConQFac Request for Contract Information window ConVFac Contract Information window CtrQFac Request for Contractor Information window CtrVFac Contractor Information window SklQFac Request for Skill Information window SklVFac Skill Information window 2. Change the part type from the default (IStandardNotifier*) using the Composition Editor contextual menu. In the OASearch example, the Object Factory parts have the following types: ConQFac OAQueryContract* ConVFac OAContractView* CtrQFac OAQueryContractor* CtrVFac OAContractorView* SklQFac OAQuerySkill* SklVFac OASkillView* 3. Set the Object Factory part to automatically delete each instance, as follows: a. Open the settings notebook for the part. b. Switch to the General page. c. Select the AutoDelete check box. ═══ 49.3.2. Add variable parts ═══ When used with Object Factory parts, variable parts represent the newly created part instance. Add and set variable parts as follows: ContractQ Set the type to OAQueryContract*. ContractorQ Set the type to OAQueryContractor*. SkillQ Set the type to OAQuerySkill*. ContractV Set the type to OAContractView*. ContractorV Set the type to OAContractorView*. SkillV Set the type to OASkillView*. For more information on variables, see Adding a Variable to a Composite Part. ═══ 49.3.3. Connect to the object factory parts ═══ Once you have added and set both the Object Factory and variable parts, connect the IGraphicPushButton* parts on the welcome window to the Object Factory parts representing the query windows, as follows: From part, feature To part, feature ContractGB, #buttonClickEvent ConQFac, #new ContractorGB, # CtrQFac, #new buttonClickEvent SkillGB, #buttonClickEvent SklQFac, #new Next, connect promoted button actions in the query windows to the Object Factory parts representing the information windows, as follows: From part, feature To part, feature ContractQ, #okPB ConVFac, #new ButtonClickEvent ContractorQ, #okPB CtrVFac, #new ButtonClickEvent SkillQ, #okPBButtonClickEvent SklVFac, #new ═══ 49.3.4. Connect the object factory parts to their corresponding variable parts ═══ Once you have set both Object Factory and variable parts, you must connect them. In OAMain, the connections vary depending on whether the window is modal. Modal windows retain focus until they are closed; the user cannot switch focus to another window without closing the modal window. In OAMain, OAGenInfo and the query windows are modal; the other windows are modeless. Connections for modal windows Make the following connections for the query window parts. The connections for OAGenInfo* are listed in Completing the Menu Bar. From part, feature To part, feature ConQFac, #newEvent ContractQ, #this ConQFac, #newEvent ContractQ, #setFocus ConQFac, #newEvent ContractQ, #showModally CtrQFac, #newEvent ContractorQ, #this CtrQFac, #newEvent ContractorQ, #setFocus CtrQFac, #newEvent ContractorQ, #showModally SklQFac, #newEvent SkillQ, #this SklQFac, #newEvent SkillQ, #setFocus SklQFac, #newEvent SkillQ, #showModally Connections for modeless windows Now make the following connections for the modeless information windows: From part, feature To part, feature ConVFac, #newEvent ContractV, #this ConVFac, #newEvent ContractV, #setFocus ConVFac, #newEvent ContractV, #visible CtrVFac, #newEvent ContractorV, #this CtrVFac, #newEvent ContractorV, #setFocus CtrVFac, #newEvent ContractorV, #visible SklVFac, #newEvent SkillV, #this SklVFac, #newEvent SkillV, #setFocus SklVFac, #newEvent SkillV, #visible ═══ 49.4. Make the final connections ═══ With all parts represented in the primary part, you have only to make the final connections. This includes the following:  Connecting the nonvisual parts to their corresponding variable parts  Completing the menu bar ═══ 49.4.1. Connect the nonvisual parts to the variables that represent them ═══ Each visual part contains promoted variables as placeholders for the static nonvisual parts dropped in OAMain. Now, connect the static parts to the variables that represent them as follows: From part, feature To part, feature Contract, #this ConQFac, #contract Contract, #this ConVFac, #contract Contract, #this CtrVFac, #contract Contractor, #this CtrQFac, #contractor Contractor, #this CtrVFac, #contractor Skill, #this SklQFac, #skill Skill, #this SklVFac*, #skill SkillBase, #this SklQFac, #skillBase SkillBase, #this SklVFac, #skillBase SkillBase, #this CtrQFac, #skillBase SkillBase, #this CtrVFac, #skillBase ═══ 49.4.2. Complete the menu bar ═══ Now that all parts appear on the free-form surface, you can complete the menu bar. The connections echo those made in Connecting to the Object Factory Parts. Connections from the View submenu From part, feature To part, feature ContractMI, #commandEvent ConQFac, #new ContractorMI, #commandEvent CtrQFac, #new SkillMI, #commandEvent SklQFac, #new GenInfoMI, #commandEvent VBDevelopment, #setFocus GenInfoMI, #commandEvent VBDevelopment, #showModally Connections from the Edit submenu From part, feature To part, feature ContractMI, #commandEvent ConVFac, #new ContractorMI #commandEvent CtrVFac, #new Once all connections are complete, you are ready to generate code. Make sure to save your work. ═══ 50. ...Generate source code for parts and applications ═══  Preparing for source code generation: - Setting up Visual Builder to generate make files - Setting up Visual Builder projects to use WorkFrame's makemake program  Generating C++ source code for individual parts  Source files created during part code generation  Generating C++ source code for your application's main() function  Source files created during generation of main() function code  Preparing generated files for compilation - Specifying additional libraries in the make file - Specifying debug options for the compiler and linker programs  Compiling and linking your application ═══ 50.1. Prepare for source code generation ═══ Before getting started, decide how you want to build your application's make file. You can create make files in either of the following ways:  From Visual Builder  Using WorkFrame's makemake program Both options require the following advance preparation. ═══ 50.1.1. Set up Visual Builder to generate make files ═══ If you want Visual Builder to generate make files with the C++ source code, follow these steps from the Visual Builder window: 1. From the menu bar, select Options. 2. Select Preferences; then select Generate make files. The next step is generating C++ source code for individual parts. ═══ 50.1.2. Set up Visual Builder projects to use WorkFrame's makemake program ═══ If you prefer to build your application's make file using WorkFrame, make sure your Visual Builder project has the correct compile and link options set. Follow these steps from the desktop: 1. Open the Settings notebook for your Visual Builder project. 2. Select the Target notebook tab. Type an appropriate name in the Make file name field. 3. Select the Actions notebook tab. 4. Select the link action; then select the Options push button. 5. Select the Templates notebook tab. 6. Select the Templates used radio button; then select the compile action to associate with the link action. 7. Select the OK push button. 8. Select the File Names notebook tab. 9. Under Libraries to use, type in: cppoov3i.lib os2386.lib 10. Under Definition (.DEF) file name, type the appropriate module definition file name. 11. Select the OK push button. 12. Close the Settings notebook. The next step is generating C++ source code for individual parts. ═══ 50.2. Generate C++ source code for individual parts ═══ After you finish constructing a part, you must generate source code. If the part is an application in itself or if you want to test a part individually, you must also generate the code as described in Generating C++ Source Code for Your Application's main() Function. You can generate source code for the part being edited from any of the Visual Builder editors. 1. From the editor's menu bar, select File. 2. Select Save and generate; then select Part source. In addition, if you are using the Composition Editor, you can select , the icon for the Generate Part Code tool, on the tool bar. There is no difference between selecting this icon and using the menu item described previously. One of the most common causes of code generation errors is changing the names of features that are connected to other features. For example, suppose feature A is connected to feature B. If you change the name of feature A and then regenerate the source code for your part, Visual Builder displays an error. This can also occur if you change the name of a promoted feature. To correct the error, double-click on the connection arrow and replace the incorrect feature name with the correct one. For more information about the files generated, see Source Files Created during Part Code Generation. The next step is generating C++ source code for your application's main() function. ═══ 50.2.1. Know which source files are created during part code generation ═══ For each part processed, Visual Builder generates several source code files. As an example, the following files are created for the OAContractView part: contractg.cpp A C++ code file. contractg.hpp The header file for contractg.cpp. contractg.h A resource header file for the .cpp file. This file contains the resource IDs for your part. contractg.rc A resource file that contains any text strings used in the part for entry field labels, push buttons, menus, and so forth. If you selected Default to FAT file names under the Options pull-down menu of the Visual Builder window and your part name has more than eight characters, Visual Builder creates an eight-character name for the part when it is created. Note: If you are using the File Allocation Table (FAT) file system, we recommend that you always use part names and file names that have eight characters or less, even if you have selected the Default to FAT file names option. Otherwise, Visual Builder might use a file name for a .vbb file that is the same as one that already exists and write over the existing file. For information about how the .h and .rc files are used for translation, see Enabling National Language Support for an Application. The next step is generating C++ source code for your application's main() function. ═══ 50.3. Generate C++ source code for my application's main() function ═══ To create an executable application, you must generate code for the standard C++ main() function. You can do this for parts that you want to test individually or for your entire application. If you want to compile your entire application, generate the function using the part that represents your application's primary view. You must first generate the C++ code for all parts that you intend to compile in your application. Load into Visual Builder the .vbb files that represent all parts that will appear in the compiled application. Then, generate the main() function from the part that you want to appear first when your application is started (the main part). You can generate application source code for the main() function if the main part is displayed in any of the Visual Builder editors. 1. From the editor's menu bar, select File. 2. Select Save and generate; then select main() for part. For more information about the files generated, see Source Files Created during Generation of main() Function Code. The next step is preparing generated files for compilation. ═══ 50.3.1. Know which source files are created during generation of main() ═══ function code For each main part processed, Visual Builder creates several files. For the OAMain part, the following files are created: oamain.app The C++ code file containing the main() function declaration. Note: If you start Visual Builder from a WorkFrame project, a file named vbmain.cpp is generated instead of a file named oamain.app. oamain.mak A make file, if you opted to generate make files using Visual Builder. If you selected Default to FAT file names as a preference under the Options pull-down menu of the Visual Builder window and your part name has more than eight characters, Visual Builder creates an eight-character name for the generated files. Note: If you are using the File Allocation Table (FAT) file system, we recommend that you always use part names and file names that have eight characters or less, even if you have selected the Default to FAT file names option. Otherwise, Visual Builder might use a file name for a .vbb file that is the same as one that already exists and write over the existing file. The next step is preparing generated files for compilation. ═══ 50.4. Prepare generated files for compilation ═══ Before compiling your application, be sure you have the following files:  Header files for all parts  .cpp files for all parts  A make file  An .app file for the main part Note: If you start Visual Builder from a WorkFrame project, you should have a file named vbmain.cpp instead of an .app file. Final preparations for compilation and linking include the following:  Specifying additional libraries (C++ libraries and DLLs) in the make file  Specifying debug options for the compiler and linker programs ═══ 50.4.1. Specify additional libraries in the make file ═══ Review the list of libraries specified in the make file, particularly libraries for parts that you compiled separately. If your application uses DLLs, add the DLL names as dependent files in the description blocks used to keep the object files up to date. The order in which you list object files is significant. Files with external references must occur after the referred-to files. ═══ 50.4.2. Specify the option to generate Browser information ═══ If your want the VisualAge C++ compiler to generate Browser information, you must include the -Fb+ option when you compile your application. This option causes the compiler to generate a file with an extension of .pdb. Once this file is generated, you can use the Browser data when connecting features to member functions and for other purposes. For more information, see Using Browser Information. ═══ 50.4.3. Specify debug options for the compiler and linker programs ═══ If you prefer to compile and link your application using WorkFrame, you should have already specified debug options in your Visual Builder project file. For more information about the options you need to set, see the WorkFrame documentation. If you opted to let Visual Builder generate your make file, Visual Builder adds debug options to the make file by default. If you do not want your application compiled with debugging turned on, remove the /Ti+ option. For more information, refer to the VisualAge C++ Language Reference. To make Visual Builder connections easier to debug, set up a trace by following these steps: 1. In your config.sys file, add this line: SET ICLUI TRACETO=STDOUT 2. In your make file, add this phrase at the end of the GCPPFLAGS statement, but before the back slash (\): -DIC_TRACE_DEVELOP 3. When you run your compiled application, redirect the output to a file. For example, run myapp.exe as follows: myapp > myapp.out Browse the output file (myapp.out) to see what connections were fired and in what order. ═══ 50.5. Compile and link my application ═══ You can compile your application from the OS/2 command line or from WorkFrame. To call both the complier and linker programs, you can run the Toolkit's nmake program. Regardless of how you choose to compile and link your Visual Builder application, use the following compile and link options: B"/DE /pmtype:pm" Passes the string /DE /pmtype:pm to the linker as parameters. C Compiles and links. Fb+ Generates Browser information in a file with a .pdb extension. Ft(dir) Generates files for template resolution and puts them in the dir directory. Gd+ Dynamically links to the runtime library. Gm+ Builds an .exe file. I Searches the directory of the source file for include files; then, searches paths specified in config.sys include variable. Q Displays the compiler logo when invoking the compiler. Ti+ Generates debugger information. This is optional but recommended. Tdp Compiles all source files as C++ files and ensures that template functions are resolved. For more information on compiling and linking, refer to the VisualAge C++ Programming Guide. ═══ 51. ...Use existing C and C++ code with Visual Builder ═══  Defining the part interface using part information files  Creating a part information file  Importing the part ═══ 51.1. Define the part interface using part information files ═══ If C++ code already exists for your Visual Builder application, you can more efficiently define the part interface using part information files. This involves the following steps: 1. Determine the part's features. 2. Create a part information file using your favorite editor. This file can include information for as many parts as you need. 3. In Visual Builder, import the part. ═══ 51.1.1. Create a part information file ═══ To create a part information file, add information about your part's part interface to a file using your preferred editor. The following example shows how you could specify part information for the OAContractor part: //VBBeginPartInfo: OAContractor,"Contractor part for OASearch sample" //VBParent: IStandardNotifier //VBIncludes: "Cntrctor.hpp" _OACONTRACTOR_,"iprofile.hpp","istring.hpp","iexcbase.hpp" //VBPartDataFile: OANONVIS.VBB //VBConstructor: OAContractor() //VBComposerInfo: nonvisual,802,cppov33r //VBEvent: ready, "ready", readyId //VBAction: getContractor, //VB: "Get contractor data from database", //VB: OAContractor&, //VB: OAContractor& getContractor() //VBAction: putContractor, //VB: "Add or update contractor data in database", //VB: OAContractor&, //VB: OAContractor& putContractor() //VBAction: parseName, //VB: "Parse user input to get contractor's name", //VB: OAContractor&, //VB OAContractor& parseName(const IString& aName) //VBAttribute: contractorID, //VB: "Contractor's employee identifier", //VB: IString, //VB: IString contractorID() const,, //VB: contractorIDId //VBAttribute: lastName, //VB: "Contractor's last name", //VB: IString, //VB: IString lastName() const, //VB: OAContractor& setLastName(const IString& aLastName), //VB: lastNameId //VBAttribute: firstName, //VB: "Contractor's first name", //VB: IString, //VB: IString firstName() const, //VB: OAContractor& setFirstName(const IString& aFirstName), //VB: firstNameId //VBAttribute: middleInitial, //VB: "Contractor's middle initial", //VB: IString, //VB: IString middleInitial() const, //VB: OAContractor& setMiddleInitial(const IString& aMiddleInitial), //VB: middleInitialId //VBAttribute: homeStreet, //VB: "Contractor's home street address", //VB: IString, //VB: IString homeStreet() const, //VB: OAContractor& setHomeStreet(const IString& aHomeStreet), //VB: homeStreetId //VBAttribute: homeCity, //VB: "Contractor's home city", //VB: IString, //VB: IString homeCity() const, //VB: OAContractor& setHomeCity(const IString& aHomeCity), //VB: homeCityId //VBAttribute: homeState, //VB: "Contractor's home state or province", //VB: IString, //VB: IString homeState() const, //VB: OAContractor& setHomeState(const IString& aHomeState), //VB: homeStateId //VBAttribute: homeZip, //VB: "Contractor's home postal code", //VB: IString, //VB: IString homeZip() const, //VB: OAContractor& setHomeZip(const IString& aHomeZip), //VB: homeZipId //VBAttribute: phoneNumber, //VB: "Contractor's daytime phone number", //VB: IString, //VB: IString phoneNumber() const, //VB: OAContractor& setPhoneNumber(const IString& aPhoneNumber), //VB: phoneNumberId //VBAttribute: startDate, //VB: "Contractor's starting date with OA", //VB: IString, //VB: IString startDate() const, //VB: OAContractor& setStartDate(const IString& aStartDate), //VB: startDateId //VBAttribute: endDate, //VB: "Contractor's last day with OA (empty if active)", //VB: IString, //VB: IString endDate() const, //VB: OAContractor& setEndDate(const IString& aEndDate), //VB: endDateId //VBAttribute: activeStatus, //VB: "Whether contractor actively seeks contract work", //VB: Boolean, //VB: Boolean isActiveStatus() const, //VB: OAContractor& enableActiveStatus(Boolean enable = true), //VB: activeStatusId //VBAttribute: currentContract, //VB: "Contractor's current assignment, if any", //VB: IString, //VB: IString currentContract() const, //VB: OAContractor& setCurrentContract(const IString& aCurrentContract), //VB: currentContractId //VBPreferredFeatures: enabledForNotification, getContractor, putContractor, this //VBEndPartInfo: OAContractor Note the following syntax:  The VBBeginPartInfo and VBEndPartInfo statements delimit the part information for OAContractor.  The VBPart statement specifies the base class for OAContractor, IStandardNotifier*.  The VBIncludes statement specifies a header file to be added in an #include directive when the code is generated.  The VBPartDataFile statement specifies the .vbb file that holds the information for OAContractor.  The VBComposerInfo statement indicates that this is a nonvisual part. The absence of the abstract keyword indicates that this is a concrete part that can be dropped on the free-form surface.  The VBEvent, VBAction, and VBAttribute statements define features for this part. For information about part definition syntax, refer to Building VisualAge C++ Parts for Fun and Profit. The next step is importing the part. ═══ 51.1.2. Import the part ═══ Before importing the part, you must create a part information file. To import the part, follow these steps from the Visual Builder window: 1. From the menu bar, select File. Select Import part information. The Enter Name for Part Information File window appears. 2. Specify the path and name of the part information file that contains the information that you want to import. When the import is finished, the name of the part appears in in the Visual Builder window. If C++ code for your part already exists, your part is finished. If you want to change the part interface later, do either of the following:  Use the Part Interface Editor to edit feature specifications. You must use this method to delete features.  Edit your part information file and re-import the part information. If C++ code for your part does not exist, the next step is adding code to your part. ═══ 52. ...Add categories and parts to the parts palette ═══  Preparing icons for the parts palette  Adding a category to the parts palette  Specifying a unique icon for a part you add to the parts palette  Adding a part to the parts palette  Deleting a category or part from the parts palette  Saving parts palette changes ═══ 52.1. Prepare icons for the parts palette ═══ This example uses for the OAModels category and for the OAContractor part, which are stored in the cppov33r.dll file as resource numbers 800 and 802, respectively. To prepare icons for use with Visual Builder, do the following: 1. Create your icons. One way to do this is to use your operating system toolkit icon editor. For VGA displays on OS/2, use the Independent VGA form (32x32). For higher display resolutions on OS/2, use the 8514-16 colors form (40x40). 2. Create a resource DLL that contains your icons. Use files similar to the following:  userpal.c empty() { }  userpal.rc icon 800 oamodels.ico icon 801 oacontractor.ico  userpal.def library userpal description 'Icons for user-extended palette'  userpal.mak userpal.dll: userpal.obj userpal.def userpal.res icc userpal.obj /Feuserpal.dll userpal.def rc userpal.res userpal.dll userpal.obj: userpal.c icc /C+ userpal.c userpal.res: userpal.rc rc -r userpal.rc Once you have the files ready, type the following to build the resource DLL: nmake userpal.mak 3. Place the resource DLL in a directory in your LIBPATH. Your icons are now ready for use with Visual Builder. The next step is adding a category to the parts palette. ═══ 52.2. Add a category to the parts palette ═══ Now that you have your icons prepared in a resource DLL, you are ready to extend the parts palette. To add a category to the parts palette, do the following: 1. In the Composition Editor, select Modify PaletteAdd New Category from the Options pull-down menu. The Add palette category window is displayed as follows: Notice that the default category icon, , is specified. It is stored as resource ID 150 in the dde4vr30.dll resource file provided with Visual Builder. 2. Type OAModels or the name that you want for your category in the Category name field. 3. Type cppov33r or the name of your resource DLL in the Module name field. Note: Do not type the .dll file extension in the Module name field. 4. Type 800 or the resource ID of the icon in your resource DLL in the ID field. Note: After you enter the resource ID number, move the cursor to another component in the window, such as the Module name field, if you want to see the graphic that will be used before continuing. 5. Select the OK push button. Your category with the icon specified is added to the parts palette. The next step is specifying a unique icon for your part. ═══ 52.3. Specify a unique icon for a part I add to the parts palette ═══ You can specify a unique icon for a part that you add to the parts palette, but you must do so before you add it to the parts palette. To give your part a unique icon, do the following: 1. Open the part. 2. Switch to the Class Editor. 3. Enter the name of the DLL file that contains the icon you want to use in the DLL Name field. 4. Enter the resource ID number for the icon in the Resource Id field. If you enter a valid DLL file name and resource ID number, Visual Builder displays the icon below the Resource Id field. This allows you to verify the icon before adding it to the parts palette. 5. Select FileSave to save the resource DLL and resource ID information in the Class Editor. The next step is adding a part to the parts palette. ═══ 52.4. Add a part to the parts palette ═══ You can add a part to any category on the parts palette using any of the following methods:  Adding a part that is selected in the Visual Builder window  Adding the part that you are currently editing  Adding any part whose .vbb file is loaded ═══ 52.4.1. Add a part that is selected in the Visual Builder window ═══ To add a part to the parts palette from the Visual Builder window, do the following: 1. Load the .vbb file that contains the part you want to add to the parts palette if it is not already loaded. 2. Select the .vbb file. For this example, select oanonvis.vbb. 3. Select the part you want to add. For this example, select OAContractor. Note: You can add multiple parts by holding down the Ctrl key and clicking on each part that you want to add. 4. Select PartAdd to palette. Visual Builder displays the Add to Palette window, as shown in the following figure: 5. Select the part that you want to add. For this example, select OAContractor. 6. Select the category that you want to add the part to. For this example, select OAModels. 7. Select the Add push button. Visual Builder adds the OAContractor part to the parts palette in the OAModels category. ═══ 52.4.2. Add the part that I am currently editing ═══ You can add the part that you are currently editing to the parts palette from either the Composition Editor, the Class Editor, or the Part Interface Editor. To add the part that you are currently editing to the parts palette, do the following: 1. Double-click on the OAContractor part in the Visual Builder window. Visual Builder opens the OAContractor part in the Part Interface Editor. 2. Select FileAdd to palette. Visual Builder displays the Add to Palette window, as shown in the following figure: The Part name field shows the name of the part that you are editing. This is the part that is to be added to the parts palette. You cannot change the name of the part displayed in this field. In this example, OAContractor is displayed in this field. 3. Select the category that you want to add the part to. For this example, select OAModels. 4. Select the Add push button. The OAContractor part is added to the OAModels category on the parts palette. To see this, switch to the Composition Editor and select the OAModels category. The icon for the OAContractor part is displayed in the parts column. ═══ 52.4.3. Add any part whose .vbb file is loaded ═══ You can add any part to the parts palette as long as its .vbb file is loaded in the Visual Builder window. The following steps explain how to do this: 1. In the Composition Editor, select Modify PaletteAdd New Part from the Options pull-down menu. The Add to Palette window is displayed as follows: To add a part to the parts palette, do the following: a. Type OAContractor in the Part name field or the class name of the part you want to add. b. Select OAModels in the Category list or the name of the category to which you want to add your part. c. Select the Add push button. Your part is added to the parts palette in the specified category. Notice that the part you just added uses the same icon as the part it inherits from. If you inherit from a part whose icon does not appear on the parts palette, such as IStandardNotifier*, or for which you have not provided a resource DLL, Visual Builder uses the default part icon, . The next section tells you how to delete a category or part from the parts palette ═══ 52.5. Delete a category or part from the parts palette ═══ To delete a part from the parts palette, do the following: 1. Select the part on the parts palette. 2. Select Modify PaletteDelete Part from the Options pull-down menu. The selected part is deleted from the parts palette. To delete a category from the parts palette, do the following: 1. Select the category on the parts palette. 2. Select Modify PaletteDelete Category from the Options pull-down menu. The selected category and all of the parts in it are deleted from the parts palette. ═══ 52.6. Save parts palette changes ═══ Visual Builder automatically saves all parts palette changes for you. When you create a new category or part, Visual Builder stores information about that category or part in a file named vbpalet.dat, which is stored in your current directory. This file is written automatically. Removing a category or part that you just added The vbpalet.dat file also allows you to undo and redo any changes you make to the parts palette, but only during the current Composition Editor session. For example, after adding a category or part, you can select EditUndo to remove the part or category you just added. Selecting EditRedo would put the part or category back on the parts palette, again. Once you close the Composition Editor, you can no longer undo or redo any changes. However, you can still add categories and add parts, as well as delete categories and parts. ═══ 53. ...Enable national language support for an application ═══  Using resource files for translation  Using canvases to adjust size for translated text  Specifying parts with country-sensitive formatting  Providing double-byte character support for Asian languages ═══ 53.1. Use resource files for translation ═══ In Generating Source Code for Parts and Applications, you learned that Visual Builder generates the following resource files for you:  A resource file (partname.rc), which contains the text strings used in your part  A resource header file (partname.h), which contains the resource IDs for your application The resource (partname.rc) file The .rc file groups resources into two categories:window resources and nonwindow resources. The window resources are the text strings that are associated with window IDs for information area text and fly-over text. The nonwindow resources are the text strings that are displayed in your composite part. Examples are window titles, static text used to label entry fields and list boxes, and the text on push buttons and menu items. These text strings are delimited by quotation marks (") and can be translated into another language. Here is the todolist.rc file that we generated for the To-Do List application shown in Creating a Simple Visual Builder Application: //************************************************************* // Resource file for: ToDoList.cpp //************************************************************* #include "ToDoList.h" #include #ifndef MAIN_RESOURCES_INCLUDED #define MAIN_RESOURCES_INCLUDED HELPTABLE WND_ToDoList BEGIN HELPITEM WND_ToDoList_FrameWindow, WND_ToDoList_FrameWindow, 0 END #define ToDoList_WINDOWRESOURCES #define ToDoList_NONWINDOWRESOURCES STRINGTABLE BEGIN 1, "Visual Builder 3.0" END #endif #ifdef ToDoList_NONWINDOWRESOURCES #ifndef ToDoList_NONWINDOWRESOURCES_INCLUDED #define ToDoList_NONWINDOWRESOURCES_INCLUDED STRINGTABLE BEGIN STRRC_ToDoList_FrameWindow_title, "To-Do List" STRRC_ToDoList_StaticText1_text, "To-do item" STRRC_ToDoList_EntryField1_text, "" STRRC_ToDoList_StaticText2_text, "To-do list" STRRC_ToDoList_PushButton1_text, "Add" STRRC_ToDoList_PushButton2_text, "Remove" END #endif #endif #ifdef ToDoList_WINDOWRESOURCES HELPSUBTABLE (WND_ToDoList_FrameWindow) BEGIN END #endif #ifdef ToDoList_HELPITEMRESOURCES HELPITEM WND_ToDoList_FrameWindow, WND_ToDoList_FrameWindow, 0 #endif #ifdef ToDoList_HELPSUBITEMRESOURCES #endif The window resources and nonwindow resources are grouped into separate string tables so that translators can easily find the text that is to be translated. You may have text strings in your part, such as the application name, that you do not want translated. If that is the case, you can prevent those text strings from being inserted in the .rc file by inserting a number sign (#) at the beginning of the text and enclosing the text in quotation marks ("). This change must be made in the settings notebook for the part, not in the Composition Editor. For example, suppose you do not want the text in the window title, To-Do List, to be translated. To prevent Visual Builder from inserting this text string in the .rc file, you would open the settings notebook for the ToDoList part, find the entry field on the General page that contains the title text, and change it to the following: #"To-Do List" Notice that each text string that Visual Builder inserts in the .rc file is preceded by a #define statement that begins with STRRC. These #define statements represent the resource ID of each text string. Visual Builder generates these #define statements and defines them in the partname.h file. By inserting and defining these #define statements, Visual Builder relieves you from the task of having to specify resource IDs for each text string. To help Visual Builder generate these #define statements properly, you must enter the starting resource ID for your part. The following section explains how to do this. The resource header (partname.h) file The .h file contains a list of #define statements. Visual Builder uses these #define statements in the .rc file to assign unique resource IDs to each of the text strings that you use to create your composite part and a unique window ID to all primitive visual parts. The only resource ID that you need to specify is the starting resource ID for the part. Here is the todolist.h file that we generated for the To-Do List application shown in Creating a Simple Visual Builder Application: //************************************************************* // Resource header file for: ToDoList.cpp //************************************************************* #ifndef _ICCONST_ #include #endif #ifndef _IVBDEFS_ #include #endif #ifndef RC_ToDoList #define RC_ToDoList 10000 #endif #ifndef WND_ToDoList #define WND_ToDoList VBBASEWINDOWID #endif #define WNDOFFSET_ToDoList_FrameWindow 0 #define WND_ToDoList_FrameWindow WND_ToDoList #define STRRC_ToDoList_FrameWindow_title RC_ToDoList+0 #define WNDOFFSET_ToDoList_Canvas 1 #define WND_ToDoList_Canvas WND_ToDoList + WNDOFFSET_ToDoList_Canvas #define WNDOFFSET_ToDoList_StaticText1 2 #define WND_ToDoList_StaticText1 WND_ToDoList + WNDOFFSET_ToDoList_StaticText1 #define STRRC_ToDoList_StaticText1_text RC_ToDoList+1 #define WNDOFFSET_ToDoList_EntryField1 3 #define WND_ToDoList_EntryField1 WND_ToDoList + WNDOFFSET_ToDoList_EntryField1 #define STRRC_ToDoList_EntryField1_text RC_ToDoList+2 #define WNDOFFSET_ToDoList_StaticText2 4 #define WND_ToDoList_StaticText2 WND_ToDoList + WNDOFFSET_ToDoList_StaticText2 #define STRRC_ToDoList_StaticText2_text RC_ToDoList+3 #define WNDOFFSET_ToDoList_PushButton1 5 #define WND_ToDoList_PushButton1 WND_ToDoList + WNDOFFSET_ToDoList_PushButton1 #define STRRC_ToDoList_PushButton1_text RC_ToDoList+4 #define WNDOFFSET_ToDoList_PushButton2 6 #define WND_ToDoList_PushButton2 WND_ToDoList + WNDOFFSET_ToDoList_PushButton2 #define STRRC_ToDoList_PushButton2_text RC_ToDoList+5 #define WNDOFFSET_ToDoList_ListBox1 7 #define WND_ToDoList_ListBox1 WND_ToDoList + WNDOFFSET_ToDoList_ListBox1 Find the first #define statement in the todolist.h file. It is the RC_ToDoList #define statement. The number to the right of this #define statement, 10000, is the starting resource ID. This is the default number that Visual Builder inserts when you select the check box next to the Starting resource id field in the Class Editor. Visual Builder uses this number as the resource ID of the first text string and increments the resource ID of each successive text string by 1. We chose to use the default number 10000 for the following reasons:  The resource ID must be a number.  The number specified must be either high enough or low enough that it does not conflict with the resource IDs that Visual Builder generates for the primitive parts (entry field, push buttons, and so forth) that are used to compose the ToDoList part. When determining resource IDs for window resources, Visual Builder begins with 15000 and increments the resource ID of each successive primitive part by 5. Therefore, we recommend using starting resource IDs between 100 and 14500 for most applications for the following reasons:  You should not use resource IDs below 100 because Presentation Manager has reserved many of them for its own use.  Numbers between 100 and 14500 are low enough to prevent you from experiencing any resource ID conflicts in most cases. Specifying the starting resource ID for subparts If you use a part that you have created as a subpart, specify a starting resource ID for both the subpart and the part in which the subpart is embedded. Do this to prevent conflicts between the resource IDs that Visual Builder generates for your subpart and those it generates for the part in which the subpart is embedded, as described in the preceding section. Otherwise, Visual Builder uses the same starting resource IDs for both the subpart and the part in which it is embedded, which causes compile errors. For example, suppose you have a reusable Address part (a canvas with entry fields and static text) that you want to embed as a subpart in the frame window of your application's main view. You might give the main view a starting resource ID of 5000 and the Address part a starting resource ID of 6000. Doing this would prevent conflicts with the resource IDs that Visual Builder generates for the main view and those it generates for the Address part. ═══ 53.2. Use canvases to adjust size for translated text ═══ When text is translated from one language to another, the translated text often occupies more space than the original text occupied. This can cause problems because the layout of the user interface can be disrupted by the longer text strings. Two of the canvas parts that Visual Builder provides solve this problem for you: ISetCanvas* and IMultiCellCanvas*. These parts allow you to insert translated text and rebuild your application without having to change the position of any of the parts in the user interface. The ISetCanvas* and IMultiCellCanvas* parts automatically adjust their size at run time to allow for longer text strings, taking into account the current window's text size and font. For example, suppose you are using an ISetCanvas* part with three vertical decks and three rows of IRadioButton* parts in each deck. Once the text strings for the IRadioButton* parts are translated, all you have to do is rebuild your application. The decks in the ISetCanvas* part automatically adjust their widths to allow for the size of the translated text strings. The IMultiCellCanvas part is also good for translation purposes because the rows and columns automatically adjust themselves to fit the translated text. ═══ 53.3. Specify parts with country-sensitive formatting ═══ Visual Builder provides the following class interface parts that allow you to specify how information is presented for specific national languages: IDate This part allows you to customize the date formatting for the selected part. This includes specifying the order for the month, day, and year, and the character to use as a separator. ITime This part allows you to customize the time formatting for the selected part. This includes specifying the 12- or 24-hour format and the character to use as a separator. ═══ 53.4. Provide double-byte character support for Asian languages ═══ The following Visual Builder parts provide DBCS support: IBuffer Class interface part that defines the contents of an IString. This part provides attributes to determine whether part or all of the characters in a buffer are DBCS or multi-byte character set (MBCS) characters, and whether they are valid DBCS or MBCS characters. IDBCSBuffer Class interface part that implements the version of IString contents that supports mixed OS/2 DBCS characters. This part ensures that MBCS characters are processed properly. IEntryField Visual part that creates and manages an entry field control. On the General page of the settings notebook for this part, you can specify the type of data that the user can enter. It can be one of the following: SBCS Sets the entry field to accept SBCS text only. DBCS Sets the entry field to accept DBCS text only. Mixed Sets the entry field to accept text that is a mixture of SBCS and DBCS characters. Conversion from an ASCII DBCS code page to an EBCDIC DBCS code page can result in a possible increase in the length of the data because of the addition of shift-in and shift-out characters, but it does not exceed the text limit of the entry field. Any Sets the entry field to accept text that is a mixture of SBCS and DBCS characters. This setting is the opposite of mixed. If the text contains both SBCS and DBCS characters and is to be converted from an ASCII code page into an EBCDIC code page, this style causes an entry field to not account for shift-in and shift-out characters that would be introduced into its text. IFrameWindow Visual part that creates and manages a frame window control. This part has a style option, appDBCSStatus, that includes a DBCS status area in the frame window when it is displayed in a DBCS environment. IFrameWindow also has a member function, shareParentDBCSStatus, that causes a child frame window to share the DBCS status area of its parent. IKeyboardEvent Class interface part that represents a keyboard-related event. An IKeyboardEvent object is created by a keyboard handler when a user presses or releases a key. The part provides a virtualKey attribute that returns the virtual key code of the key. Two of the codes it can return are firstDBCS and lastDBCS. IString Class interface part that is an array of characters. This part provides attributes to determine whether part or all of the characters in a string are DBCS or MBCS characters, and whether they are valid DBCS or MBCS characters. ═══ 54. ...Use Direct-to-SOM objects in Visual Builder applications ═══  Creating and importing the part information file  Using DTS objects in a Visual Builder application  Bypassing DTS limitations ═══ 54.1. Create and import the part information file ═══ In Defining the Part Interface Using Part Information Files, you learned how to create a part information file. Create a file like this for your DTS objects. There are only two requirements when creating this file:  DTS objects can only have actions. This makes DTS objects the equivalent of class interface parts because they have no notification capability. Therefore, you must set the VBComposerInfo statement for each DTS object to class.  Since DTS objects can only have actions, you cannot code any attributes or events in your part information file. The following example shows a part information file, mydtsdt.vbe, that contains the information for the following sample DTS objects: MyDTSDate Returns the current date. MyDTSTime Returns the current time. // // SOM classes as Visual Builder classes // //VBBeginPartInfo: MyDTSDate, "My DTS SOM Date Class" //VBIncludes: "mydtsdat.hh" MyDTSDate_hh //VBPartDataFile: 'mydtsdt.vbb' //VBLibFile: 'mydtsdat.lib' //VBComposerInfo: class //VBAction: getTodaysDate //VB: ,"Get today's date action.",char*, //VB: char* getTodaysDate() //VBPreferredFeatures: this, getTodaysDate //VBEndPartInfo: MyDTSDate // //VBBeginPartInfo: MyDTSTime, "My DTS SOM Time Class" //VBIncludes: "mydtstim.hh" MyDTSTime_hh //VBPartDataFile: 'mydtsdt.vbb' //VBLibFile: 'mydtstim.lib' //VBComposerInfo: class //VBAction: getCurrentTime //VB: ,"Get current time action.",char*, //VB: char* getCurrentTime() //VBPreferredFeatures: this, getCurrentTime //VBEndPartInfo: MyDTSTime // The mydtsdt.vbe file contains statements that refer to the following files that are needed for each of the sample DTS objects: mydtsdat.hh and mydtstim.hh The header files for the MyDTSDate and MyDTSTime SOM classes. mydtsdat.lib and mydtstim.lib The library files that were created when the DTS objects were compiled. mydtsdt.vbb The part (.vbb) file that is to contain the information about the DTS parts when you import the part information from the mydtsdt.vbe file. You must load the mydtsdt.vbb file into Visual Builder before you can add the MyDTSDate and MyDTSTime parts to the free-form surface in the Composition Editor. Once you create your part information file, you must import it into Visual Builder before you can use your DTS objects in a Visual Builder application. For information on how to do this, see Importing Part Information. The next step is using DTS objects in a Visual Builder application. ═══ 54.2. Use DTS objects in a Visual Builder application ═══ Using DTS objects in a Visual Builder application is no different from using a class interface part. You simply place the DTS objects on the free-form surface and make the necessary connections to use their actions. The following figure shows how we used the MyDTSDate and MyDTSTime objects in a simple application. To create the application, we placed the MyDTSDate and MyDTSTime parts on the free-form surface by selecting OptionsAdd part and providing the necessary information in the Add Part window for each part. In this application, when a user clicks on the Current push button, the buttonClickEvent feature causes the getTodaysDate and getTodaysTime actions to get the date and time that is currently set in your computer's operating system. In addition, the actionResult attribute of each connection updates the text attribute of each entry field with the result of the two actions, the current date and time. Earlier, we mentioned that actions in DTS classes can return only basic C data types. The getTodaysDate and getTodaysTime actions in our example both return a data type of char*. Therefore, when we connected the actionResult attribute to the text attribute of the entry field, Visual Builder displayed a message saying that the types did not match and asking if we wanted to continue. In this case, we could make the connection because IString has a constructor that takes a char*. You can find out whether to complete a connection in situations like this by looking at the IBM Open Class Library Reference. When you have generated your code and are ready to compile your application, make sure you have the .hh and .lib files that contain the code for your DTS objects in the current directory. Also, make sure the SOM Toolkit is installed because the VisualAge C++ compiler must have access to several of its files. When you are ready to run your application, the .dll for the DTS objects must be accessible. ═══ 54.3. Bypass DTS limitations ═══ Earlier, we told you that DTS objects have certain limitations, such as not being able to use attributes and events, and not being able to notify other parts. You can bypass these limitations by using nonvisual parts to manage the things your DTS objects cannot do. In the example shown in Using DTS Objects in a Visual Builder Application, we could have created two nonvisual parts called MyDate and MyTime in addition to the two DTS parts, MyDTSDate and MyDTSTime. We could give these nonvisual parts attributes such as theDate and theTime and notify other parts when the values of these attributes change. We could also give these attributes get and set member functions that call actions in the DTS objects to get and set the values of the attributes. Once this is done, we would place the nonvisual parts MyDate and MyTime on the free-form surface, instead of MyDTSDate and MyDTSTime, and make the same connections as described previously. ═══ 55. Glossary ═══ ═══ Glossary description ═══ This glossary defines terms and abbreviations that are used in this book. If you do not find the term you are looking for, refer to the IBM Dictionary of Computing, New York:McGraw-Hill, 1994. This glossary includes terms and definitions from the American National Standard Dictionary for Information Systems, ANSI X3.172-1990, copyright 1990 by the American National Standards Institute (ANSI). Copies may be purchased from the American National Standards Institute, 1430 Broadway, New York, New York 10018. ═══ Glossary listing ═══ A abstract class access action argument attribute attribute-to-action connection attribute-to-attribute connection attribute-to-member function connection B base class behavior C caller category class Class Editor class hierarchy class library class member function client area object client object collection Common User Access (CUA) composite part Composition Editor concrete class connection const construction from parts constructor CUA cursored emphasis custom logic connection D data abstraction data member data model data object declaration DEF file derivation destructor DLL dynamic link library (DLL) E encapsulation event event-to-action connection event-to-attribute connection event-to-member function connection expansion area F feature full attribute free-form surface G graphical user interface (GUI) GUI H handles header file I inheritance instance L legacy code loaded M main part member member function member function call member function name message model module definition file N nested class nonvisual part no-event attribute no-set attribute notebook part O object object class object factory object-oriented programming observer operation overloading P palette parameter connection parent class part part event part event ID part interface Part Interface Editor parts palette preferred features primary selection private process program protected prototype primitive part process property pure virtual function R receiver resource file S selection handles server service settings view sticky structure subpart superclass T tear-off attribute template thread tool bar U UI unloaded user interface (UI) V variable view virtual function visual part visual programming tool W white space window ═══ abstract class ═══ A class that provides common behavior across a set of subclasses but is not itself designed to have instances that work. An abstract class represents a concept; classes derived from it represent implementations of the concept. For example, IControl is the abstract base class for control view windows; the ICanvas and IListBox classes are controls derived from IControl. An abstract class must have at least one pure virtual function. See also base class. ═══ access ═══ A property of a class that determines whether a class member is accessible in an expression or declaration. ═══ action ═══ A specification of a function that a part can perform. The visual builder uses action specifications to generate connections between parts. Actions are resolved to member function calls in the generated code. Compare to event and attribute. ═══ argument ═══ A data element, or value, included as part of a member function call. Arguments provide additional information that the called member function can use to perform the requested operation. ═══ attribute ═══ A specification of a property of a part. For example, a customer part could have a name attribute and an address attribute. An attribute can itself be a part with its own behavior and attributes. The visual builder uses attribute specifications to generate code to get and set part properties. Compare to event and action. ═══ attribute-to-action connection ═══ A connection that starts an action whenever an attribute's value changes. It is similar to an event-to-action connection because the attribute's event ID is used to notify the action when the value of the attribute changes. See also connection. Compare to event-to-action connection. ═══ attribute-to-attribute connection ═══ A connection from an attribute of one part to an attribute of another part. When one attribute is updated, the other attribute is updated automatically. See also connection. ═══ attribute-to-member function connection ═══ A connection from an attribute of a part to a member function. The connected attribute receives its value from the member function, which can make calculations based on the values of other parts. See also connection. ═══ base class ═══ A class from which other classes or parts are derived. A base class may itself be derived from another base class. See also abstract class. ═══ behavior ═══ The set of external characteristics that an object exhibits. ═══ caller ═══ An object that sends a member function call to another object. Contrast with receiver. ═══ category ═══ In the Composition Editor, a selectable grouping of parts represented by an icon in the left-most column. Selecting a category displays the parts belonging to that category in the next column. See also parts palette. ═══ class ═══ An aggregate that can contain functions, types, and user-defined operators, in addition to data. Classes can be defined hierarchically, allowing one class to be an expansion of another, and can restrict access to its members. ═══ Class Editor ═══ The editor you use to specify the names of files that Visual Builder writes to when you generate default code. You can also use this editor to do the following:  Enter a description of the part  Specify a different .vbb file in which to store the part  See the name of the part's base class  Modify the part's default constructor  Enter additional constructor and destructor code  Specify a .lib file for the part  Specify a resource DLL and ID to assign an icon to the part  Specify other files that you want to include when you build your application Compare to Composition Editor and Part Interface Editor. ═══ class hierarchy ═══ A tree-like structure showing relationships among object classes. It places one abstract class at the top (a base class) and one or more layers of less abstract classes below it. ═══ class library ═══ A collection of classes. ═══ class member function ═══ See member function. ═══ client area object ═══ An intermediate window between a frame window (IFrameWindow) and its controls and other child windows. ═══ client object ═══ An object that requests services from other objects. ═══ collection ═══ A set of features in which each feature is an object. ═══ Common User Access (CUA) ═══ An IBM architecture for designing graphical user interfaces using a set of standard components and terminology. ═══ composite part ═══ A part that is composed of a part and one or more subparts. A composite part can contain visual parts, nonvisual parts, or both. See also nonvisual part, part, subpart, and visual part. ═══ Composition Editor ═══ A view that is used to build a graphical user interface and to make connections between parts. Compare to Class Editor and Part Interface Editor. ═══ concrete class ═══ A subclass of an abstract class that is a specialization of the abstract class. ═══ connection ═══ A formal, explicit relationship between parts. Making connections is the basic technique for building any visual application because that defines the way in which parts communicate with one another. The visual builder generates the code that then implements these connections. See also attribute-to-action connection, attribute-to-attribute connection, attribute-to-member function connection, parameter connection, custom logic connection, event-to-action connection, event-to-attribute connection, and event-to-member function connection. ═══ const ═══ An attribute of a data object that declares that the object cannot be changed. ═══ construction from parts ═══ A software development technology in which applications are assembled from existing and reusable software components, known as parts. ═══ constructor ═══ A special class member function that has the same name as the class and is used to construct and possibly initialize class objects. ═══ CUA ═══ See Common User Access. ═══ cursored emphasis ═══ When the selection cursor is on a choice, that choice has cursored emphasis. ═══ custom logic connection ═══ A connection that causes your customized C or C++ code to be run. This connection can be triggered either when an attribute's value changes or an event occurs. ═══ data abstraction ═══ A data type with a private representation and a public set of operations. The C++ language uses the concept of classes to implement data abstraction. ═══ data member ═══ Private data that belongs to a given object and is hidden from direct access by all other objects. Data members can only be accessed by the member functions of the defining class and its subclasses. ═══ data model ═══ A combination of the base classes and parts shipped with the product and the classes and parts you save and create. They are saved in a file named vbbase.vbb. ═══ data object ═══ A storage area used to hold a value. ═══ declaration ═══ A description that makes an external object or function available to a function or a block. ═══ DEF file ═══ See module definition file. ═══ derivation ═══ The creation of a new or abstract class from an existing or base class. ═══ destructor ═══ A special class member function that has the same name as the class and is used to destruct class objects. ═══ DLL ═══ See dynamic link library. ═══ dynamic link library (DLL) ═══ In OS/2, a library containing data and code objects that can be used by programs or applications during loading or at run time. Although they are not part of the program's executable (.exe) file, they are sometimes required for an .exe file to run properly. ═══ encapsulation ═══ The hiding of a software object's internal representation. The object provides an interface that queries and manipulates the data without exposing its underlying structure. ═══ event ═══ A specification of a notification from a part. Compare to action, attribute, and part event. ═══ event-to-action connection ═══ A connection that causes an action to be performed when an event occurs. See also connection. ═══ event-to-attribute connection ═══ A connection that changes the value of an attribute when a certain event occurs. See also connection. ═══ event-to-member function connection ═══ A connection from an event of a part to a member function. When the connected event occurs, the member function is executed. See also connection. ═══ expansion area ═══ The section of a multicell canvas between the current cell grid and the outer edge of the canvas. Visually, this area is bounded by the rightmost column gridline and the bottommost row gridline. ═══ feature ═══ A major component of a software product that can be installed separately. In Visual Builder, an action, attribute, or event that is available from a part's part interface and that other parts can connect to. ═══ full attribute ═══ An attribute that has all of the behaviors and characteristics that an attribute can have: a data member, a get member function, a set member function, and an event identifier. ═══ free-form surface ═══ The large open area of the Composition Editor window. The free-form surface holds the visual parts contained in the views you build and representations of the nonvisual parts (models) that your application includes. ═══ graphical user interface (GUI) ═══ A type of interface that enables users to communicate with a program by manipulating graphical features, rather than by entering commands. Typically, a graphical user interface includes a combination of graphics, pointing devices, menu bars and other menus, overlapping windows, and icons. ═══ GUI ═══ See graphical user interface. ═══ handles ═══ Small squares that appear on the corners of a selected visual part in the visual builder. Handles are used to resize parts. Compare to primary selection. ═══ header file ═══ A file that contains system-defined control information that precedes user data. ═══ inheritance ═══ A mechanism by which an object class can use the attributes, relationships, and member functions defined in more abstract classes related to it (its base classes). An object-oriented programming technique that allows you to use existing classes as bases for creating other classes. ═══ instance ═══ Synonym for object, a particular instantiation of a data type. ═══ legacy code ═══ Existing code that a user might have. Legacy applications often have character-based, nongraphical user interfaces; usually they are written in a nonobject-oriented language, such as C or COBOL. ═══ loaded ═══ The state of the mouse pointer between the time you select a part from the parts palette and deposit the part on the free-form surface. ═══ main part ═══ The part that users see when they start an application. This is the part from which the main() function C++ code for the application is generated. The main part is a special kind of composite part. See also part and subpart. ═══ member ═══ A data object in a structure or a union. In C++, classes and structures can also contain functions and types as members. ═══ member function ═══ An operator or function that is declared as a member of a class. A member function has access to the private and protected data members and member functions of objects of its class. ═══ member function call ═══ A communication from one object to another that requests the receiving object to execute a member function. A member function call consists of a member function name that indicates the requested member function and the arguments to be used in executing the member function. The member function call always returns some object to the requesting object as the result of performing the member function. Synonym for message. ═══ member function name ═══ The component of a member function call that specifies the requested operation. ═══ message ═══ A request from one object that the receiving object implement a member function. Because data is encapsulated and not directly accessible, a message is the only way to send data from one object to another. Each message specifies the name of the receiving object, the member function to be implemented, and any arguments the member function needs for implementation. Synonym for member function call. ═══ model ═══ A nonvisual part that represents the state and behavior of a object, such as a customer or an account. Contrast with view. ═══ module definition file ═══ A file that describes the code segments within a load module. Synonym for DEF file. ═══ nested class ═══ A class defined within the scope of another class. ═══ nonvisual part ═══ A part that has no visual representation at run time. A nonvisual part typically represents some real-world object that exists in the business environment. Compare to model. Contrast with view and visual part. ═══ no-event attribute ═══ An attribute that does not have an event identifier. ═══ no-set attribute ═══ An attribute that does not have a set member function. ═══ notebook part ═══ A visual part that resembles a bound notebook containing pages separated into sections by tabbed divider pages. A user can turn the pages of a notebook or select the tabs to move from one section to another. ═══ object ═══ A computer representation of something that a user can work with to perform a task. An object can appear as text or an icon. A collection of data and member functions that operate on that data, which together represent a logical entity in the system. In object-oriented programming, objects are grouped into classes that share common data definitions and member functions. Each object in the class is said to be an instance of the class. An instance of an object class consisting of attributes, a data structure, and operational member functions. It can represent a person, place, thing, event, or concept. Each instance has the same properties, attributes, and member functions as other instances of the object class, though it has unique values assigned to its attributes. ═══ object class ═══ A template for defining the attributes and member functions of an object. An object class can contain other object classes. An individual representation of an object class is called an object. ═══ object factory ═══ A nonvisual part capable of dynamically creating new instances of a specified part. For example, during the execution of an application, an object factory can create instances of a new class to collect the data being generated. ═══ object-oriented programming ═══ A programming approach based on the concepts of data abstraction and inheritance. Unlike procedural programming techniques, object-oriented programming concentrates on those data objects that comprise the problem and how they are manipulated, not on how something is accomplished. ═══ observer ═══ An object that receives notification from a notifier object. ═══ operation ═══ A member function or service that can be requested of an object. ═══ overloading ═══ An object-oriented programming technique that allows you to redefine functions and most standard C++ operators when the functions and operators are used with class types. ═══ palette ═══ See parts palette. ═══ parameter connection ═══ A connection that satisfies a parameter of an action or member function by supplying either an attribute's value or the return value of an action, member function, or custom logic. The parameter is always the source of the connection. See also connection. ═══ parent class ═══ The class from which another part or class inherits data, member functions, or both. ═══ part ═══ A self-contained software object with a standardized public interface, consisting of a set of external features that allow the part to interact with other parts. A part is implemented as a class that supports the INotifier protocol and has a part interface defined. The parts on the palette can be used as templates to create instances or objects. ═══ part event ═══ A representation of a change that occurs to a part. The events on a part's interface enable other interested parts to receive notification when something about the part changes. For example, a push button generates an event signaling that it has been clicked, which might cause another part to display a window. ═══ part event ID ═══ The name of a part static-data member used to identify which notification is being signaled. ═══ part interface ═══ A set of external features that allows a part to interact with other parts. A part's interface is made up of three characteristics: attributes, actions, and events. ═══ Part Interface Editor ═══ An editor that the application developer uses to create and modify attributes, actions, and events, which together make up the interface of a part. Compare to Class Editor and Composition Editor. ═══ parts palette ═══ The parts palette holds a collection of visual and nonvisual parts used in building additional parts for an application. The parts palette is organized into categories. Application developers can add parts to the palette for use in defining applications or other parts. ═══ preferred features ═══ A subset of the part's features that appear in a pop-up connection menu. Generally, they are the features used most often. ═══ primary selection ═══ In the Composition Editor, the part used as a base for an action that affects several parts. For example, an alignment tool will align all selected parts with the primary selection. Primary selection is indicated by closed (solid) selection handles, while the other selected parts have open selection handles. See also selection handles. ═══ private ═══ Pertaining to a class member that is accessible only to member functions and friends of that class. ═══ process ═══ A program running under OS/2, along with the resources associated with it (memory, threads, file system resources, and so on). ═══ program ═══ One or more files containing a set of instructions conforming to a particular programming language syntax. A self-contained, executable module. Multiple copies of the same program can be run in different processes. ═══ protected ═══ Pertaining to a class member that is only accessible to member functions and friends of that class, or to member functions and friends of classes derived from that class. ═══ prototype ═══ A function declaration or definition that includes both the return type of the function and the types of its arguments. ═══ primitive part ═══ A basic building block of other parts. A primitive part can be relatively complex in terms of the function it provides. ═══ process ═══ A collection of code, data, and other system resources, including at least one thread of execution, that performs a data processing task. ═══ property ═══ A unique characteristic of a part. ═══ pure virtual function ═══ A virtual function that has a function definition of = 0;. ═══ receiver ═══ The object that receives a member function call. Contrast with caller. ═══ resource file ═══ A file that contains data used by an application, such as text strings and icons. ═══ selection handles ═══ In the Composition Editor, small squares that appear on the corners of a selected visual part. Selection handles are used to resize parts. See also primary selection. ═══ server ═══ A computer that provides services to multiple users or workstations in a network; for example, a file server, a print server, or a mail server. ═══ service ═══ A specific behavior that an object is responsible for exhibiting. ═══ settings view ═══ A view of a part that provides a way to display and set the attributes and options associated with the part. ═══ sticky ═══ In the Composition Editor, the mode that enables you to add multiple parts of the same class (for example, three push buttons) without going back and forth between the parts palette and the free-form surface. ═══ structure ═══ A construct that contains an ordered group of data objects. Unlike an array, the data objects within a structure can have varied data types. ═══ subpart ═══ A part that is used to create another part. See also nonvisual part, part, and visual part. ═══ superclass ═══ See abstract class and base class. ═══ tear-off attribute ═══ An attribute that an application developer has exposed to work with as though it were a stand-alone part. ═══ template ═══ A family of classes or functions with variable types. ═══ thread ═══ A unit of execution within a process. ═══ tool bar ═══ The strip of icons along the top of the free-form surface. The tool bar contains tools to help you construct composite parts. ═══ UI ═══ See user interface. ═══ unloaded ═══ The state of the mouse pointer before you select a part from the parts palette and after you deposit a part on the free-form surface. In addition, you can unload the mouse pointer by pressing the Esc key. ═══ user interface (UI) ═══ The hardware, software, or both that enable a user to interact with a computer. The term user interface normally refers to the visual presentation and its underlying software with which a user interacts. ═══ variable ═══ A storage place within an object for a data feature. The data feature is an object, such as number or date, stored as an attribute of the containing object. A part that receives an identity at run time. A variable by itself contains no data or program logic; it must be connected such that it receives runtime identity from a part elsewhere in the application. ═══ view ═══ A visual part, such as a window, push button, or entry field. A visual representation that can display and change the underlying model objects of an application. Views are both the end result of developing an application and the basic unit of composition of user interfaces. Compare to visual part. Contrast with model. ═══ virtual function ═══ A function of a class that is declared with the keyword virtual. The implementation that is executed when you make a call to a virtual function depends on the type of the object for which it is called. This is determined at run time. ═══ visual part ═══ A part that has a visual representation at run time. Visual parts, such as windows, push buttons, and entry fields, make up the user interface of an application. Compare to view. Contrast with nonvisual part. ═══ visual programming tool ═══ A tool that provides a means for specifying programs graphically. Application programmers write applications by manipulating graphical representations of components. ═══ white space ═══ Space characters, tab characters, form-feed characters, and new-line characters. ═══ window ═══ A rectangular area of the screen with visible boundaries in which information is displayed. Windows can overlap on the screen, giving it the appearance of one window being on top of another. In the Composition Editor, a window is a part that can be used as a container for other visual parts, such as push buttons.