═══ 1. About this Book ═══  About Visual Builder  Who should use this book  Notices  Trademarks  How to use the Contents  How to obtain additional information  How to use action bar choices - Placing bookmarks - Searching for information - Printing information - Copying information to a file  How to cut and paste examples  How to read syntax diagrams  Highlighting conventions  Other information you might find helpful - Visual Builder books - User interface programming and design books - Object-oriented programming and design books  Communicating your comments to IBM ═══ 1.1. About Visual Builder ═══ Welcome to Visual Builder-a quick and easy way to create an application from reuseable parts! Just about any construction project that you can imagine involves assembling standard or customized basic parts into more complex parts. This process is repeated until the final product is complete. If you are building a birdhouse, these basic parts might be lumber, screws, wire, and paint. Some parts, such as screws and paint, can be used in their standard form. Other parts, such as lumber and wire, come in a standard form but need to be customized, or cut, before you use them. If reusable software parts are available, building a software application can be conceptually similar to building a birdhouse. You can use the software parts as-is, as you would with the screws, or tailor the software parts to your exact needs, as you would with the lumber. In both scenarios, you need to decide whether to build or buy the basic parts for your construction project. If you decide to build some basic software parts, this book guides you through the process (you will need to read about creating the parts of a birdhouse somewhere else). If you decide to buy the software parts, this book can help you to choose well-constructed software parts. Reusable parts can be thought of as the building blocks of the applications you are constructing with Visual Builder. As with any construction project, you need to either buy or build the parts you need. This book describes how to design and construct basic building-block parts using the C++ programming language. If you are familiar with VisualAge Smalltalk, you already know about constructing applications from parts. The details of how to implement C++ parts is a little different than implementing IBM Smalltalk parts, but the overall concepts and architecture are the same. ═══ 1.2. Who Should Use This Book ═══ This book is designed for experienced C++ programmers who need to build parts for use with Visual Builder. It can also be useful to Visual Builder users who need a deeper understanding of how Visual Builder works or who want an introduction to C++ parts. Before you begin to use this information, it would be helpful to understand how to navigate through it. You can use the Table of Contents and Index facility to locate topics and the Search facility to search the text of this document. You can 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, here is a link to another panel: Communicating Your Comments to IBM 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. When you open a panel, the first link has the focus; to shift the focus to other links, use the Tab key. You should also understand the following:  How to use the Contents  How to obtain additional information  How to use action bar choices  How to cut and paste examples ═══ 1.3. Notices ═══ Copyright International Business Machines Corporation, 1992, 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. First Edition, June 1995. 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. ═══ 1.4. Trademarks ═══ The following terms are trademarks of the IBM Corporation in the United States or other countries: AIX BookManager CUA Common User Access IBM IBMLink Library Reader Open Class OS/2 PROFS Presentation Manager SAA VisualAge Workplace Shell The following terms are trademarks of other companies: C++ American Telephone & Telegraph Company Motif Open Software Foundation, Inc. ═══ 1.5. How to Use the Contents ═══ When the Contents window first appears, some topics have a plus (+) sign beside them. The plus sign indicates that additional topics are available. To expand the Contents if you are using a mouse, click on the plus sign. If you are using the keyboard, use the Up or Down Arrow key to highlight the topic, and press the plus (+) key. For example, How to Use the Contents has a plus sign beside it. To see additional topics for that heading, click on the plus sign 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). ═══ 1.6. 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. ═══ 1.7. How to Use Action Bar Choices ═══ Several choices are available for managing the information presented in this document. There are three menus on the action bar: 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 pull-down. You can also press the Ctrl 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. ═══ 1.7.1. 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. ═══ 1.7.2. 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. ═══ 1.7.3. 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 pull-down. 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. ═══ 1.7.4. 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. ═══ 1.8. How to Cut and Paste Examples ═══ You can copy examples (or information) from this reference/guide/book to compile, link, and run them, or to paste them into your own code. To copy an example or information: 1. Make the topic you want to copy the active window. 2. From the Services menu, select Copy to file. The text in that topic is placed in the temporary file text.tmp, in the same directory as this reference. 3. You can then modify or use text.tmp as you want. Note: Because the system copies the entire contents of the topic to the file, you may need to edit it to remove additional text. ═══ 1.9. Highlighting Conventions ═══ This book uses the following highlighting conventions: Highlighting Element Example Bold Key interface items in code Select Tools from the menu bar. listings. Areas in code examples that are described in accompanying text Monospace C++ coding examples, text that The following code from the the user enters, and messages IAddress illustrates ... (within text) The street member function returns the current street. Italics Emphasis of words, first time a stored in persistent objects glossary term is used Refer to Object-Oriented User Titles of books Interface Design - IBM Common User Access Guidelines. ═══ 1.10. How to Read Syntax Diagrams ═══ This book uses syntax diagrams to show the syntax of some of the commands described.  Read the syntax diagrams from left to right, from top to bottom, following the path of the line. The ─── symbol indicates the beginning of a command. The ─── symbol indicates that the command is continued on the next line. The ─── symbol indicates that a command is continued from the previous line. The ─── symbol indicates the end of a command. Diagrams of syntactical units other than complete commands start with the ─── symbol and end with the ─── symbol. Note: In the following diagrams, COMMAND represents a command.  Required items appear on the horizontal line (the main path). ──COMMAND ── required_item ──────────────────────────────────────────  Optional items appear below the main path. ──COMMAND ─┬─────────────────┬─────────────────────────────────────── └─ optional_item ─┘  If you can choose from two or more items, they appear vertically in a stack. If you must choose one of the items, one item of the stack appears on the main path. ──COMMAND ─┬──required_choice1──┬──────────────────────────────────── └─ required_choice2 ─┘ If choosing one of the items is optional, the entire stack appears below the main path. ──COMMAND ─┬────────────────────┬──────────────────────────────────── ├─ optional_choice1 ─┤ └─ optional_choice2 ─┘ The item that is the default appears above the main path. ┌── default_item ────┐ ──COMMAND ─┴── alternate_item ──┴────────────────────────────────────  An arrow returning to the left above the main line indicates an item that can be repeated. ┌────────────────────┐  │ ──COMMAND ──── repeatable_item ─┴──────────────────────────────────── A repeat arrow above a stack indicates that you can make more than one choice from the stacked items, or repeat a single choice.  Keywords appear in nonitalic letters and should be entered exactly as shown (for example, pragma). Variables appear in italicized lowercase letters (for example, identifier). They represent user-supplied names or values.  If punctuation marks, parentheses, arithmetic operators, or other such symbols are shown, you must enter them as part of the syntax. Note: The white space is not always required between tokens, but it is recommended that you include at least one blank between tokens unless specified otherwise. ═══ 1.11. Other Information You Might Find Useful ═══ This product provides a number of online guides and references that we hope you'll find helpful as you develop applications. This information includes User's Guides, References, and How Do I help that 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. You can consult the following books for additional information about Visual Builder, user interface software design, and object-oriented software design: Visual Builder books User interface programming and design books Object-oriented programming and design books ═══ 1.11.1. Visual Builder Books ═══  VisualAge C++: Visual Builder User's Guide (S25H-6960-00)  VisualAge C++: Visual Builder Parts Reference (S25H-6967-00) ═══ 1.11.2. User Interface Programming and Design Books ═══ In addition to the specific Visual Builder books listed previously, the following books help you give a professional appearance to your part's user interfaces:  Object-Oriented User Interface Design - IBM Common User Access Guidelines, Carmel, IN: Que Corporation, 1993. ISBN: 1-56529-170-0.  Volume 6A: Motif Programming Manual, 2nd Edition, Sebastopol, CA: O'Reilly & Associates, Inc., 1993.  Volume 6B: Motif Reference Manual, Sebastopol, CA: O'Reilly & Associates, Inc., 1993. ISBN: 1-56592-038-4. ═══ 1.11.3. Object-Oriented Programming and Design Books ═══ In addition to the specific Visual Builder books listed previously, you might want to refer to a book about application design in the object-oriented and the cooperative-processing environments. Some of the available books are as follows:  Booch, Grady, Object-Oriented Design with Applications, Redwood City, CA: Benjamin/Cummings Publishing Company, 1991. ISBN: 0-8053-0091-0.  Coplien, James O., Advanced C++ Programming Styles and Idioms, Addison Wesley Publishing Company, 1992. ISBN: 0-201-54855-0.  Cox, Brad J., Object-Oriented Programming: An Evolutionary Approach, Reading, MA: Addison Wesley Publishing Company, 1987. ISBN: 0201103931.  Stroustrup, Bjarne, The Design and Evolution of C++, Murray Hill, NJ: Addison Wesley Publishing Company, 1994. ISBN: 0-201-54330-3.  Tibbetts, John et al., Building Cooperative Processing Applications Using SAA, New York, NY: John Wiley & Sons, Inc., 1992. ISBN: 0-471-55485-5.  Wirfs-Brock, Rebecca et al., Designing Object-Oriented Software, Englewood Cliffs, NJ: Prentice Hall, 1990. ISBN: 0-13-629825-7. ═══ 1.12. Communicating Your Comments to IBM ═══ If there is something you like, or dislike, about this book, 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. 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 you 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 ═══ 2. What Is C++ Construction from Parts? ═══  Overview  The origins of C++ Construction from Parts  The benefits of using parts  What is a part?  How parts and classes are related  How you can connect parts  Sources of parts Personal notes: ═══ 2.1. Overview ═══ C++ construction from parts is a technology for application development in which applications are built from existing, reusable software components called parts. Parts provide a wide range of capability, from very simple function through complete, highly sophisticated applications. The following figure shows a few examples. An entry field, a window, and a data array are examples of primitive parts. You combine primitive parts to form more complex composite parts, such as a person view. You can then extend this approach by combining primitive parts with composite parts to create entire applications, such as a customer query application. In general, parts are either visual or nonvisual. In the previous example, the entry field, window, and person view are visual parts. The data array is a nonvisual part. For more information about types of parts, see Kinds of Parts Supported in Visual Builder. ═══ 2.2. The Origins of C++ Construction from Parts ═══ The C++ construction from parts technology is just becoming popular in the software industry, but it is based on well-established techniques from other industries, such as manufacturing. The figure below compares the manufacturing process of constructing a computer system and the software process of constructing an application. Just as electronic chips can be combined to form a functional board and functional boards can be combined to form a computer, software parts can be combined to form a composite part and composite parts can be combined to form an application. To build a new computer today, you probably would not consider designing and constructing every single electronic and mechanical component from raw materials. Likewise, rather than always designing and developing new code for your applications, you can now use available standard parts. Now the software application development industry can realize the same benefits of reduced cycle time and increased quality that have become so prevalent in the manufacturing industry. ═══ 2.3. The Benefits of Using Parts ═══ The benefits that you and your company can realize from using the C++ construction from parts technology to build applications include the following:  Reduced application development cost through division of labor. Application developers are able to focus their expertise on rapid development of superior solutions for their users by tailoring reusable parts and assembling them into applications. Meanwhile, part designers can concentrate on developing new and innovative parts to meet the needs of the application developers.  Enhanced application quality and reliability. Reusing existing parts reduces the chance of introducing errors when building applications. As parts are reused and refined, they become the solid building blocks for your applications.  Reduced cycle time to respond to users' needs. Building an application prototype from a library of pre-existing parts allows you to rapidly verify your users' requirements. You can then smoothly and quickly extend this prototype into a production application. Your success in using this technology depends on the availability of easy-to-use construction tools, standard interface protocols to enable the tools and parts to interoperate, and an ever-growing library of standard, increasingly powerful parts to be reused. ═══ 2.4. What Is a C++ Part? ═══ A C++ part is a software object implemented as a C++ class with some special characteristics:  It supports a simple, standard interface protocol. This protocol supports the interconnection of parts to form higher-function parts or entire applications. You can think of this protocol as being like the "innies" and "outies" on puzzle pieces that enable them to be interlocked into larger portions of the puzzle. The part interface is composed of three distinct features: attributes, actions, and events. These features correspond to a natural way of viewing parts (and objects in general) in terms of what properties (attributes) they have, what behaviors (actions) they can perform, and what unsolicited information (events) they can notify other parts about. The following figure shows an example of a part interface.  It can extend the functions of application building tools. The part itself can extend the construction environment by providing tool functions specifically customized to the part. Examples of these tool functions are icons, automated view builders, and attribute value initialization. You can think of the picture on the top of real jigsaw puzzle pieces as a tool extension-it enhances the ability of the tool (you) to complete the job (putting this particular puzzle together). ═══ 2.5. How Parts and Classes Are Related ═══ If you are familiar with object-oriented concepts, you have probably noticed that a part is very much like an object in object-oriented programming. In fact, parts and classes are closely related because C++ classes form the underlying software implementation of parts. It might seem to you that we are not always talking about the same thing when we talk about a part. This is because the word part can mean different things at different times. Part is most often used as shorthand for part class. A part class is nothing more than an object class with some special characteristics (such as a class method that defines the part interface of the part). A part class is used as a form for creating part instances. You can develop a new part, or enable an existing class to become a part, by supplying support for these characteristics in addition to the normal operations of the object class. Part is also used as shorthand for part instance. A part instance is a particular object created from a part class. In C++, you might code an expression such as BananaClass * aBananaInstance = new BananaClass(); to create a particular instance of a part class. In a visual programming environment, you might create a particular part instance by picking a Banana part class from a palette of part classes and dropping it on a free-form surface. You can tell which kind of part we are talking about from the context in which the word appears. When we talk about parts on a palette or parts that you create by writing code, we are referring to part classes. When we talk about parts on a free-form surface or parts that are connected together to form an application, we are referring to part instances. The Architecture of C++ C++ Construction from Parts provides the blueprint for adding the characteristics that turn an object class into a part class. It sets the stage for you to build your own part classes. ═══ 2.6. How You Can Connect Parts ═══ Visual Builder's Composition Editor enables you to connect different kinds of parts:  Two visual parts  Two nonvisual parts  A visual part and a nonvisual part You can also make the following kinds of connections:  Event-to-action connections start an action when a certain event occurs. A variation of this, the attribute-event-to-action connection, starts an action when a certain attribute event (for example, attribute changing value) occurs. The action can have parameters; these parameters are attributes of the connection. You can connect a single event to many actions. You can also specify the order in which the actions are processed. Connecting the clicked event from a push button to the clear action on an entry field is an example of an event-to-action connection. Connecting the street attribute event from an address to the enable action on a Save push button is an example of an attribute-event-to-action connection.  Attribute-to-attribute connections link two data values so that they always stay the same. You can connect a single attribute to many attributes. Connecting the street attribute of an address part to the text (contents) attribute of an entry field part is an example of an attribute-to-attribute connection. ═══ 2.7. Sources of Parts ═══ There are many possible sources for parts that you can combine to build new parts or complete applications.  Visual Builder is shipped with a collection of prefabricated parts. These parts are the basic visual and nonvisual building blocks of an application. Examples are entry fields, push buttons, and data arrays.  Software providers will be creating additional parts. These parts might provide additional system support, such as facsimile transmission or E-mail access, common business functions, such as charting or report writing, or industry-specific functions, such as hospital patient charting or wholesale distribution.  Finally, if none of the available parts fulfills your needs, you (or someone in your organization) can create new parts either by modifying existing parts to add functions, by modifying existing C++ classes to enable them as parts, or by building parts just as you would any other C++ class. ═══ 3. Object Technology Overview ═══  The origins of object technology  The application segmentation paradigm  Separation of model objects from view objects  Segmentation within the model Personal notes: ═══ 3.1. The Origins of Object Technology ═══ As the cost of processing power has decreased, enterprises have taken the opportunity to make people more effective. One way of increasing people's effectiveness is to make the computer system into an extension of their everyday business environment. In the batch and transaction environments, you were presented with lists of functions that you could use. These functions did not necessarily correspond to the problem you were trying to solve. Rather, they were the application designer's idea of the solutions to the problem you were supposed to have. With computer power moving to the desktop, a new approach to building applications has emerged. This approach provides you with the impression that the computer is able to deal with the things that are common to your business, such as calendars, notepads, invoices, bank accounts, or a wastebasket. Your desktop computer becomes an extension of your real world. Designing applications to operate in this new environment can be challenging. Many books are available to guide you in this endeavor. We only touch lightly on the design issues here and suggest that you consult a book devoted to the subject if you need in-depth knowledge (see Other Information You Might Find Useful. ═══ 3.2. The Application Segmentation Paradigm ═══ The following figure shows the structure of an application developed using the guidelines presented in this book. This structure follows a common application segmentation paradigm in the cooperative processing environment, where an application is divided into three segments: user interface, business logic, and data access. The user interface segment defines how the user and the system interact. It presents information to the user and accepts input from the user on behalf of the business logic. Because it does not implement any of the business logic behavior, it can be updated, or completely replaced, without affecting the business logic. We refer to this user interface function as a view. The business logic segment implements the real-world objects of the application. It defines the behaviors of these objects and their interrelationships without consideration for how they are presented to users or how users interact with them. We refer to the business logic segment as a model. The implementation of the model can be totally contained in a single computer, or it can be distributed among several computers using available inter-computer communication mechanisms to interconnect the distributed components of the model. The third segment of an application is data access. From the application builder's perspective, this segment can be thought of as simply an extension of the model. Because of this, we do not discuss it in this book. You can refer to one of the books on cooperative processing environments (see Object-Oriented Programming and Design Books) for a detailed discussion. Segmenting an application in this way provides you several benefits, even outside the C++ construction from parts environment.  It enhances parallel development. Prototyping of the views can be done by user interface specialists working with end users. This activity can take place in parallel and is somewhat independent of the development of the underlying model.  It supports connecting multiple views to the same model. Users can access several concurrent views of the business model objects.  It facilitates cooperative processing. The business logic can be effectively distributed between the workstation and one or more servers. ═══ 3.3. Separation of Model Objects from View Objects ═══ To segment your application into manageable chunks, first separate your view objects from your model objects. By segmenting them, you can provide several views of the same model object or objects. The following figure shows two views (a detailed view and a tabular view) of a single model. To use this method of designing applications effectively, keep two important points in mind:  Views can directly update models, but models cannot directly update views.  Views contain only presentation and user-manipulation logic. Business logic exists only in the model objects. The dependency manager (in C++, the notification framework) is used to communicate between views and models in place of sending direct messages. Systems that support the model-view or model-view-controller (MVC) application structure also support a dependency manager function. The specific implementation details may differ from system to system, but the overall concept remains constant. The dependency manager maintains lists of objects that depend on the occurrence of specific events. It provides a set of interfaces so that objects can register their dependency on an event or remove their dependency from it. An object can signal the occurrence of each of its events to the dependency manager. The dependency manager searches its lists and forwards the notification to the objects that are dependent on the event. These objects can then take action based on the occurrence of the event. To see how this works, consider a simple example. You might want to refer back to the previous figure as we go through the example. In this example we define one event (nameChanged) that is associated with a change in the name of a person. Assume the upper-left object in the model is a person object. Because it maintains the data about a person, it has a dependency on the nameChanged event. Both view objects must also be notified when the nameChanged event occurs so they can update the content of the name field on the screen. Each of these objects registers a dependency on the nameChanged event with the dependency manager. Now suppose you type over the contents of the name field in the detailView object and then tab out of the field. The view object signals a notification that the nameChanged event has occurred. The dependency manager receives this notification message and looks for its list of nameChanged event dependents. It finds the list and forwards the notification to the objects that have registered their dependency on the event. The person object receives the notification and updates its internal data. The tabularView object receives the notification and refreshes the display with the updated name. Because the detailView object is also dependent on the nameChanged event, you might wonder why the notification was not forwarded back to it. Also, because the tabularView object signals a notification when the name changes, you might wonder why the program does not go into an endless loop sending this notification around. The answer to both these issues is that the dependency manager recognizes recursive notifications and discards them. ═══ 3.4. Segmentation within the Model ═══ We have described one major approach to segmenting your application-dividing it into a model and one or more views of that model. You can further segment the model into several categories of objects. The following figure shows these divisions using the analogy of an iceberg, because most models contain many more hidden (nonvisual) objects than visible real-world objects. The categories shown in the figure are as follows: View objects (V). These objects create the user interface display. They implement the interface between users of the application and the application business model. Real-world objects (R). These objects implement the physical objects of your business enterprise, such as a car, an invoice, a notepad, or a calendar. Their behavior closely models the behavior of these physical objects. They have a formally specified interface, which allows them to be widely used by application construction tools. Implementation objects (I). These objects provide the internal implementation of the real-world objects. They generally correspond to more traditional computer-related entities, such as arrays, numbers, or abstract objects used to collect common behavior. These objects often do not have formally specified interfaces because they are usually designed to be used by programmers rather than by application builders. Service objects (S). These objects provide access to external services, such as communication support, database access, or operating system functions. They insulate the real-world and implementation objects from the details of these external services. These objects are also generally designed for programmers, so they might not have formally specified interfaces. As an example of this application segmentation, consider an application that shows you the contents of a customer file:  The windows, entry fields, push buttons, and all other parts of the application's visual interface are view objects.  The customer object is the real-world object, providing the data about a selected customer to the view objects.  An array implementation object might be used internally by the customer object to hold the data.  Service objects support querying a data store and returning the customer information, which insulates all the other objects from dependence upon the kind of data store used to hold the customer records or its location. ═══ 4. The Architecture of C++ Construction from Parts ═══  Overview  The origins of C++ construction from parts architecture  Architecture characteristics Part interface architecture:  Access to part properties  Access to part behavior  Notification of changes to parts Kinds of parts supported in Visual Builder Personal notes: ═══ 4.1. Overview ═══ The C++ construction from parts architecture has been developed to meet the specific need of application developers to have an easier, more productive way to create high-quality applications in today's complex application development environment. Our ability to conceive this architecture was enabled by the evolution of application structure and by the emergence of application-building power tools. This chapter describes the following:  The origins of the C++ construction from parts architecture  Architecture characteristics  The part interface architecture  Kinds of parts supported in Visual Builder ═══ 4.2. The Origins of the C++ Construction from Parts Architecture ═══ In the past, applications were designed and implemented with a monolithic structure. In these applications, embedded logic usually governed the flow of control. Such applications controlled the user, rather than allowing the user to control the application. In addition, the monolithic structure led to application components that were highly customized for the application in which they were developed. The following figure shows how these applications evolved from the first generation, monolithic batch applications, to the second generation, online transaction applications. While this evolution did enable users to gain direct access to the applications through fixed-function terminals, it still left the applications in control of the users' interactions with the system. As workstations became popular, another step in application structure evolution began. This evolutionary step came in response to the distributed nature of systems, the needs of the users to control system flow, and the desire of enterprises to reuse previously developed application components. While these three factors seem to be independent of each other, they drove toward a single solution. The application structure that developed in response to these factors represents the third generation in the evolutionary flow. The third-generation application structure embodies the concept of event-driven application design and implementation. Event-driven applications allow the user to control the flow of operations. This structure also supports dividing applications into cooperating elements that can run on different systems. A natural outgrowth of this application structure is small, modularized components with increasingly standard interface protocols. The C++ construction from parts architecture formalizes certain aspects of this application structure. ═══ 4.3. Architecture Characteristics ═══ The C++ construction from parts architecture facilitates the development of parts to be used in this new environment. To be successful, this architecture must be both useful and easy to implement. It specifies the following:  A structural paradigm for applications that is independent of implementation. This maximizes the flexibility afforded to implementers. The only implementation constraints in the specification are those needed to provide reliable semantics for the interfaces.  A standard interface protocol. A small, simple protocol suite achieves greater acceptance by part builders and users than a large complex suite. This protocol supports communication among application parts and between application parts and the tools used to build the applications. This standardized interface is called the part interface. Applications can be built from parts by connecting the part interface features. The architecture specification supports both new and pre-existing object classes. You can apply the interface protocol to existing classes without making extensive code modifications. In a C++ programming environment where applications are created using an editor or C++ browser, implementing the part interface of a part is sufficient. As more sophisticated tools, such as visual application builders, become available, parts can play a larger role in assisting the application developer to build applications. ═══ 4.4. Part Interface Architecture ═══ As stated earlier, a part interface is composed of three clearly defined programming interface features: attributes, actions, and events. The part interface architecture specifies the general format of the programming interfaces, not the particular implementation behind the interface. For example, the protocol describes how to build an attribute interface, independent of the contents, address, name, or other properties that are specific to this part. ═══ 4.4.1. Access to Part Properties ═══ Attributes provide access to the properties of a part. A property can be any of the following:  An actual data object stored as a data member, such as the street in an address object  An actual data object that is accessed via another object or the system, such as the contents of an entry field (the contents are stored within the system entry field control or widget)  A computed data object that is a transformed version of an actual data object, such as the temperature in Fahrenheit when the actual data object is the temperature in Celsius  A computed data object that is not stored, such as the sum of all numbers in an array or the profit that is computed by subtracting dealer cost from the retail price. You can use the attribute interface to return the value of a property, to set the value of a property, and to notify other parts when the value of a property changes. You are not required to supply a complete attribute interface for a property. For example, a property might be read-only, in which case the part's attribute interface would not support the ability to set the property's value. The attribute interface is represented as follows: aType aQueryMember(); aSetMember(aType aValue); static INotificationId const anEventId; aQueryMember is the public member function to get the current value of the property; aSetMember is the public member function to set the value of the property to aValue; aType is the type of aValue; anEventId is the notification ID for the property change event. The member function that sets the value of the property can use the following expression to notify dependent parts that the value of its property has changed: notifyObservers(INotificationEvent(anEventId, *this, true, (void*)aValue)); notifyObservers is the member function that signals the event; anEventId is the notification ID for the property change event; *this is the notifier object; true indicates that the value of the attribute has changed; aValue is the event data. (For more information about events, see Notification of Changes to Parts.) The following simpler call can be made if no event parameters are to be passed: notifyObservers(INotificationEvent(anEventId, *this)); The member function that sets a property's value usually signals the value change, but any member function that is aware of the change can signal the event. While a property is often represented as a data member of a part, it need not be; the property could be a computed value. What is important is that whenever the value of the property changes, the change takes place using the set member function for the property. Changes made in any other way might not cause the event to be signalled. A part implements the attribute interface protocol by implementing the member functions declared in the header files. For example, the following two member functions support the attribute interface protocol for the temperature property of the IThermometer part: unsigned long IThermometer::temperature () const { return iTemperature; } IThermometer& IThermometer::setTemperature (unsigned long newTemp) { if (iTemperature != newTemp) { iTemperature = newTemp; notifyObservers(INotificationEvent(temperatureId, *this, true, (void*)newTemp)); } return *this; } Because temperature has two common representations, Celsius and Fahrenheit, a more general solution would be to have an attribute for each representation. If the temperature was stored internally in Celsius, then you could rename the two member functions to setTempInCelsius and tempInCelsius. You could then implement two additional member functions, such as the following, that return and set the temperature in Fahrenheit: unsigned long IThermometer::tempInFahrenheit () const { return ((iTemperature * (9/5)) + 32); } IThermometer & IThermometer::setTempInFahrenheit (unsigned long newTemp) { return setTempInCelsius ((newTemp - 32) * (5/9)); } Notice that we did not introduce any additional data members when we added these two new member functions. There is still only one property (iTemperature) being maintained. However, now it is being maintained through two different attribute interfaces. This illustrates the design guideline to use a set member function (for example, setTempInFahrenheit) to change the value of a property. It also shows that a property is not always a data member. ═══ 4.4.2. Access to Part Behavior ═══ An action provides access to the behavior of a part. Actions represent the tasks you can assign a part to do, such as open a window or add an object to a collection of objects. The action interface is represented as follows: aType aMemberFunction(); aMemberFunction is the public member function for the action to be performed. A part implements the action interface by supplying a member function that responds to the behavior declared in the header file. For example, the following member function supports the action interface to set the default value of the city attribute in the IAddress class: IAddress & IAddress :: setCityToDefault () { return setCity("Hometown"); } This example shows that actions can cause values of attributes to change. In fact, most Boolean attributes can be set to false using the disable member function. For example, the disableMouseClickFocus member function in the IButton class causes the mouseClickFocus attribute to be set to false. ═══ 4.4.3. Notification of Changes to Parts ═══ By signalling events, a part can notify other parts that a state or value in its interface has changed. Events can be signalled when the state of a view part changes, such as when a push button is clicked or when a window is opened, as well as when the state of a model part changes, such as when the balance in a bank account goes negative. Events can also be signalled when the value of a part's property changes, such as when money is deposited into or withdrawn from a bank account. Notifications appear as messages broadcast to all parts that are observers of the event. Observers of an event are those parts that depend on the event's occurrence. The event interface is represented as follows: static INotificationId const anEventId; anEventId is the notification ID for the event. Several different options are available to signal events. The first option is an example of using the event interface for attribute notification with event parameters: notifyObservers(INotificationEvent(anEventId, *this, true, (void*)aValue)); notifyObservers is the member function that causes the event notification; anEventId is the notification ID for the property change event; *this is the notifier object; true indicates that the value of the attribute has changed; aValue is the new value of the property. The following simpler call can be made if no event parameters are to be passed: notifyObservers(INotificationEvent(anEventId, *this)); Parts can also signal events when no attributes have changed, as follows: notifyObservers(INotificationEvent(anEventId, *this, false, (void*)aValue)); notifyObservers is the member function that signals the event; anEventId is the notification ID for the property change event; *this is the notifier object; false indicates that the value of the attribute has not changed; aValue is the value of the property. The following simpler call can be made if no event parameters are to be passed: notifyObservers(INotificationEvent(anEventId, *this, false)); To implement notification within a part, code the notifyObservers expression within one or more of its member functions. For example, the following setTempInCelsius member function notifies other parts when the temperature has changed and when the temperature is above the boiling point of water: IThermometer& IThermometer::setTempInCelsius (unsigned long newTemp) { if (iTemperature != newTemp) { iTemperature = newTemp; notifyObservers(INotificationEvent(temperatureId, *this, true, (void*)newTemp)); if (iTemperature > 100) { notifyObservers(INotificationEvent(boilingId, *this)); } } return *this; } ═══ 4.5. Kinds of Parts Supported in Visual Builder ═══ You can use many kinds of parts to construct applications. These different kinds of parts, categorized according to their characteristics, are shown in the following figure: As stated earlier, all parts are either primitive parts, which are the basic building blocks from which other parts are constructed, or composite parts, which are parts constructed from other parts. You must construct new primitive parts using a programming language because there are no similar parts to use in building them. In turn, primitive parts can be either visual or nonvisual.  Visual parts are elements of the application that the user can see at run time, such as view parts. They are components of a presentation surface, such as a window, an entry field, or a push button. The development-time representations of visual parts on the Composition Editor's free-form surface closely match their runtime visual forms. Users can edit these parts on the Composition Editor in their visual runtime forms (visual editing).  Nonvisual parts are elements of the application that are not seen by the user at run time, such as model parts. On the Composition Editor's free-form surface, users can manipulate these parts only as icons (iconic editing). Examples of nonvisual parts are business logic parts, data array parts, communication access protocol parts, and database query parts. Parts that the user can see at run time but that support iconic editing only are treated as nonvisual parts at development time. A prompter message box part and a file selection dialog part are examples of this kind of nonvisual part. ═══ 5. Designing a C++ Part ═══  Overview  Design guidelines  Conventions to consider - Naming parts - Naming actions, attributes, and events Personal notes: ═══ 5.1. Overview ═══ This chapter highlights some factors to consider when designing a C++ part. Before creating a new primitive part, answer the following questions:  Is the part visual or nonvisual? (See Kinds of Parts Supported in Visual Builder.)  Can it be created as a composite part?  Do you have a good model of the part and its responsibilities?  Is it a real-world implementation or a service part? (See Segmentation within the Model.) ═══ 5.2. Design Guidelines ═══ Designing a good part is very similar to designing a good class. In fact, a good part can be used as a traditional class in applications that are not otherwise being built using C++ construction from parts. Consider the following when designing your part:  Keep it simple.  Keep the number of actions, events, and attributes to a reasonable size. In practice, 10-20 part features per part is a good target.  Minimize the dependencies on other parts and classes. Do not make nonvisual parts dependent upon visual parts.  Specify several actions with a small number of parameters rather than a single action with many parameters. When possible, provide default parameter values.  Minimize the number of connections that need to be made when using the Composition Editor. To design a new part, do the following: 1. Determine the attributes (properties) of the part. 2. Determine the events (notifications) that the part will signal. 3. Determine the actions (behaviors) for the part. 4. After determining the part interface, investigate the available parts to see if one already exists or to determine which class to use as a base. Determine if any classes can be converted to parts. ═══ 5.3. Conventions to Consider ═══ This section gives you some high-level conventions to follow when creating parts. For more information about conventions, see IBM Open Class Library Conventions. ═══ 5.3.1. Naming Parts ═══ Because the names of C++ classes come from a flat name-space, developers of parts must ensure that their class names are unlikely to duplicate the class names used by other developers. Using a prefix on your class names is a good way to reduce the chances of duplicating a class name. All IBM Open Class names in the global name space begin with the letter "I". ═══ 5.3.2. Naming Actions, Attributes, and Events ═══ A part feature is an element of a part's interface. It is used as a collective term for a part action, attribute, or event. If you follow these simple conventions in choosing your feature names, it is easier for users of your parts to recognize the function of a feature:  Name actions with phrases that indicate activities to be performed, together with an optional receiver of that activity. Examples of feature names for actions are startTimer, openWindow, hide, and setFocus.  Name attributes with phrases that indicate the physical property they represent. Examples of feature names for attributes are height, buttonLabel, and contents.  Name events with phrases that indicate activities that either have happened or are about to happen. Examples of feature names for events are clicked, aboutToCloseWindow, and timeExpired. Note: Do not use feature names that start with avl or vb. These are reserved for use by Visual Builder. The main place that users see your action, attribute, and event names is on the Connections pop-up menu of the Composition Editor. Because features are shown on this pop-up menu in alphabetical order, the phrasing you use for a feature name is the only way to distinguish between actions, attributes, and events. It is important to choose unique names for your new actions, attributes, or events. This prevents you from unintentionally overriding an inherited part feature. If you intend to replace an existing part feature that your part inherits, then your new name must be the same as the name of the part feature you are replacing. The scope within which your feature name must be unique in your part class and all its base classes in the class hierarchy. ═══ 6. Implementing a C++ Part ═══  Overview  Positioning a part within the class hierarchy  Implementing events  Implementing attributes - Get member functions - Set member functions - Attribute notification IDs  Implementing actions  Implementing constructors  Implementing destructors  Implementing assignment operators  Implementation checklists Personal notes: ═══ 6.1. Overview ═══ This chapter explains how to implement a C++ part. It explains how to create the header and code files for a C++ class that supports the parts architecture. No matter which kind of part you are building, you need to read the concepts and techniques introduced early in the chapter to understand later material. The key items covered in this chapter follow:  Positioning the part within the class hierarchy  Implementing events (notification)  Implementing attributes (properties)  Implementing actions (behaviors) ═══ 6.2. Positioning a Part within the Class Hierarchy ═══ The first step associated with implementing a part is positioning the part class in the C++ class hierarchy. Place your nonvisual part as shown in the following table, under the IStandardNotifier class hierarchy. Inserted in this location, your part inherits certain default behavior from IStandardNotifier and the INotifier protocol. Class Hierarchy for Nonvisual Parts ┌─────────────────────────────┬─────────────────────────┐ │Class │Responsibility │ │IBase │Base class │ │ IVBase │Virtual base class │ │ INotifier │Notification protocol │ │ IStandardNotifier │Implementation of │ │ │notification protocol │ │ New nonvisual part │ │ └─────────────────────────────┴─────────────────────────┘ An example from the IAddress header file follows: class IAddress : public IStandardNotifier In some cases, you might want your nonvisual part to be abstract. Be aware that your users cannot drop abstract nonvisual parts onto the Composition Editor's free-form surface. If you do not provide concrete parts derived from this abstract part, your users must derive their own concrete parts. For more information about the syntax to define a part as abstract, see VBComposerInfo Statement for a Part. Once you have found your part's position in the class hierarchy, you are ready to begin the actual building. Creating a C++ class for a part is not much different from creating any other C++ class. There are just a few additional guidelines to keep in mind for those member functions that support your part's part interface. ═══ 6.3. Implementing Events ═══ Events might be occurring inside your part that you want to signal to other parts. The mechanism for signalling this information to other parts is event notification. In a simple event notification, dependent parts are notified only that the event occurred. An example of this type of event notification is when a push button visual part notifies all observer parts that it has been selected. The public section of the IButton class header file contains the following definition for the buttonClickId notification ID: static INotificationId const buttonClickId; In addition, the IButton code file contains the following: const INotificationId IButton::buttonClickId="IButton::buttonClick"; The notification string ID contains the class name followed by the event name. IButton can notify others of this event by using notifyObservers with the buttonClickId notification event ID: notifyObservers(INotificationEvent(buttonClickId, *this, false)); This function call signals that something happened (the button was clicked) but provides no additional information. The false parameter on the INotificationEvent constructor indicates that no attributes have changed. A part can provide additional information about the event by passing parameters with the notification. An example of this use of an event notification is when a push button part that represents a key on a calculator notifies all observer parts that it has been selected. In addition to notifying other parts that it has been selected, the push button part can also pass the value of its label, as follows: notifyObservers(INotificationEvent(buttonClickId, *this, false, (void *)5)); This notifies other parts that push button 5 was selected. Event notification is also used to inform other parts that attributes have changed. An example of this type of event notification is when the street changes in the IAddress part. The part can do this with the following code: IString eventData(iStreet); notifyObservers(INotificationEvent(streetId, *this, true, (void*)&eventData)); ═══ 6.4. Implementing Attributes ═══ Each property that your part exposes through its attribute interface has one or two corresponding member functions to support the attribute interface protocol for accessing the property. The public member function that retrieves the value of a property is called the get member function. The public member function that sets the value of a property is called the set member function. In addition, you need to define a public static notification event ID for notification of changes to the attribute. An example of the definition of the street attribute from the public section of the header file for the IAddress class follows: virtual IString street () const; virtual IAddress &setStreet (const IString& aStreet); static INotificationId const streetId; Get and set member functions usually come in pairs. The exception is when a property is read-only (such as a property that represents the serial number of the computer you are currently using). In this case, the property has only a get member function. Always use the get and set member functions to access the value of a property so that the associated behaviors are performed. In particular, if you update the value of a property without triggering event notification, the application might fail to operate correctly. Define property data members as private to ensure that other classes do not access the properties directly. ═══ 6.4.1. Defining Get Member Functions ═══ Get member functions return the value of a part's property. They are always accessed using a public member function without parameters. The simplest get member function returns the data member that holds the value of a property. The street member function of the IAddress class is an example of a simple get member function, as follows: IString IAddress::street () const { return iStreet; } Because this get member function does not change any values within the object, it is defined as const. ═══ 6.4.2. Defining Set Member Functions ═══ Set member functions modify the value of a part's property and notify dependent objects that the value has changed. Set member functions are always accessed using a member function with one parameter-the value to be set into the property. Normally this parameter is defined as const because most set member functions do not change the parameter. A simple set member function sets the IStreet data member and signals a notification using notifyObservers. The following set member function, taken from the IAddress example part, does just that: IAddress& IAddress::setStreet (const IString& aStreet) { if (iStreet != aStreet) { iStreet = aStreet; IString eventData(iStreet); notifyObservers(INotificationEvent(streetId, *this, true, (void*)&eventData)); } /* endif */ return *this; } An even simpler set member function can be implemented that does not signal a notification when its property is changed. You might use such a set member function when you know that a group of properties is always changed together. In this case, only one set member function out of the group would actually signal the event. This couples the event signalling with the entire sequence of set member function calls. Set member functions can also perform other operations, such as computing values for many properties based on the value supplied or signalling an additional notification when the value of a property crosses a threshold value. Signal events only when the value of the property has changed. In addition, providing the new value of the attribute in the notification event can improve the overall system performance. ═══ 6.4.3. Attribute Notification IDs ═══ You define notification IDs using public static data members. An example from the public section of the IAddress class header file follows: static INotificationId const streetId, cityId, stateId, zipId; This defines streetId, cityId, stateId and zipId as notification IDs. In addition, the IAddress code file contains the following: const INotificationId IAddress::streetId="IAddress::street"; const INotificationId IAddress::cityId="IAddress::city"; const INotificationId IAddress::stateId="IAddress::state"; const INotificationId IAddress::zipId="IAddress::zip"; The notification string ID contains the class name followed by the attribute name. ═══ 6.5. Implementing Actions ═══ Each behavior that your part exposes in its action interface has a corresponding public member function to support the action protocol for that behavior. An example of the setCityToDefault public member function from the IAddress class header file follows: virtual IAddress &setCityToDefault (); Just like other C++ member functions, actions can have parameters and a return value. You can specify the return value and parameters as part of the action interface (see Describing Part Interfaces in Part Information Files. The only thing unique to Visual Builder about these member functions is that they should not directly access data members for properties; instead, use the attribute's get and set member functions to access the data members. You need to do this because the get and set member functions often have additional behavior beyond simply accessing the value of the data member. For example, the setCityToDefault member function of the IAddress class uses the following setCity to set the city to Hometown instead of setting it directly: IAddress& IAddress::setCityToDefault () { return setCity("Hometown"); } Consider providing an action to reset each attribute to a default value when implementing a part. For Boolean attributes, provide a public member function (for example, a disable action) that causes the attribute to be set to false and a public set member function (for example, an enable action) with a default parameter equal to true. You can use the set member function (for example, enableMouseClickFocus) with a default value as the set member function for the Boolean attribute and an action member function. An example from the IButton class for the mouseClickFocus Boolean attribute follows: IButton &enableMouseClickFocus (Boolean turnOn = true), &disableMouseClickFocus (); ═══ 6.6. Implementing Constructors ═══ Nonvisual parts should have a default constructor. An example of the IAddress class default constructor follows: IAddress(); The implementation of the standard constructor for the IAddress class follows: IAddress::IAddress() : IStandardNotifier (), iStreet("101 Main Street"), iCity("Hometown"), iState("NC"), iZip("27511") { } For most nonvisual parts, supply a copy constructor. An example follows: IAddress (const IAddress& partCopy); The implementation of the copy constructor for IAddress follows: IAddress::IAddress (const IAddress& partCopy) : IStandardNotifier (partCopy), iStreet(partCopy.street()), iCity(partCopy.city()), iState(partCopy.state()), iZip(partCopy.zip()) { } ═══ 6.7. Implementing Destructors ═══ For all visual and nonvisual parts, specify a virtual destructor. An example follows: virtual ~IAddress (); The implementation of the IAddress destructor follows: IAddress::~IAddress() { } ═══ 6.8. Implementing Assignment Operators ═══ To ensure that attribute changes are signalled, specify an assignment operator for nonvisual parts with attributes, as follows: IAddress& operator= (const IAddress& aIAddress); The implementation of the IAddress class assignment operator follows: IAddress& IAddress::operator= (const IAddress& aIAddress) { if (this == &aIAddress) { return *this; } /* endif */ IStandardNotifier::operator=(aIAddress); setStreet(aIAddress.street()); setCity(aIAddress.city()); setState(aIAddress.state()); setZip(aIAddress.zip()); return *this; } Note the following in the previous example:  The assignment operator checks to ensure that the new value is not the current object.  The part's base class is called to ensure that the base class' data is assigned correctly.  To ensure notification of attribute changes, the attribute set member functions are used to change the value of the attributes. ═══ 6.9. Implementation Checklists ═══ The following checklists contain the items required to implement a new part or to convert an existing class to a part. Because parts are implemented as classes, you can convert existing classes to parts and still use them as classes. In the header file, make the following changes to support parts: 1. For nonvisual parts, publicly inherit from IStandardNotifier or a derived class. For visual parts, publicly inherit from IWindow or a derived class. 2. Define the constructors and a virtual destructor. 3. If appropriate, define the assignment operator for nonvisual parts. 4. Define a public notification ID for each event. 5. Define a public notification ID for each attribute. 6. Define a public get member function with no parameters so users can obtain the value of each attribute. 7. If the attribute can be changed, define a public set member function with a single parameter containing the new value. If this attribute is Boolean, set the default to true. 8. Define any public action member functions. Consider reset or default actions for attributes, including disable and enable actions for Boolean attributes. In the code or inline file, make the following changes in the code logic to support parts: 1. Code each event notification ID using a string containing the class name and event name. 2. Code each attribute notification ID using a string containing the class name and attribute name. 3. Code the constructors and a virtual destructor. 4. If defined, code the assignment operator. 5. Code the public get member functions for each attribute. 6. Code the public set member functions for each attribute. Notify observers when the value changes. 7. Call get and set member functions to return and change attribute values in actions. In addition, notify observers of events specified by the part. ═══ 7. Describing Part Interfaces in Part Information Files ═══  Overview  Part information syntax - VBBeginPartInfo statement - VBParent statement - VBIncludes statement - VBPartDataFile statement - VBLibFile statement - VBComposerInfo statement - VBConstructor statement - VBEvent statement - VBAttribute statement - VBAction statement - VBPreferredFeatures statement - VB statement - VBEndPartInfo statement - Sample part information for IAddress  Class information syntax - VBBeginPartInfo statement - VBParent statement - VBIncludes statement - VBPartDataFile statement - VBComposerInfo statement - VBConstructor statement - VBAction statement - VBAttribute statement - VBPreferredFeatures statement - VB statement - VBEndPartInfo statement - Sample class information for IRange  Function group information syntax - VBBeginPartInfo statement - VBIncludes statement - VBPartDataFile statement - VBComposerInfo statement - VBAction statement - VB statement - VBPreferredFeatures statement - VBEndPartInfo statement - Sample function group information  Enumeration information syntax - VBBeginEnumInfo statement - VBIncludes statement - VBPartDataFile statement - VBEnumerators statement - VB statement - VBEndEnumInfo statement - Sample alignment enumeration for IEntryField  Type definition information syntax - VBBeginTypedefInfo statement - VBIncludes statement - VBPartDataFile statement - VB statement - VBEndTypedefInfo statement - Sample type definition information  Other syntax examples Personal notes: ═══ 7.1. Overview ═══ You describe the interface information that Visual Builder needs by using the Part Interface Editor or by creating files containing the interface information and importing these files into Visual Builder. This chapter describes the format of the interface information and is divided into the following sections:  Part information syntax  Class information syntax  Function group information syntax  Enumeration information syntax  Type definition information syntax You can include the statements describing the interface in a C++ header file or in a separate file (sometimes called a part information file, or .vbe file). All interface information code lines begin with //VB in column 1. Between statements, lines that do not start with //VB are ignored. You can arrange statements on a single line or continue them on multiple lines by using the VB statement. The following rules apply to all interface information: 1. All part, class, function group, enumeration, and type definition names must be unique. 2. A single file can contain information about multiple parts, classes, function groups, enumerations, and type definitions. 3. The interface information about a specific part, class, function group, enumeration, and type definition must be contained in a single file. ═══ 7.2. Part Information Syntax ═══ This section describes the interface information for nonvisual parts that Visual Builder uses. Syntax descriptions appear in the recommended order of occurrence in a file. The following rules apply to the interface information for parts: 1. All feature names (attributes, events, actions) within a part hierarchy must be unique. If duplicate feature names exist, the information for the derived part is used and the information for the base part is ignored for that specific feature. 2. All part names must be unique and must be a valid C++ class name. 3. The name on the VBBeginPartInfo statement and VBEndPartInfo statement must match. 4. Attribute, event and action information statements can appear more than once for a specific part, but all other information statements must appear only once. For information about how to read these syntax diagrams, see How to Read Syntax Diagrams. ═══ 7.2.1. VBBeginPartInfo Statement for a Part ═══ The first statement describing the interface is the VBBeginPartInfo statement. This statement specifies the part name and the part description. ──//VBBeginPartInfo: ── part_name ──┬──────────────────┬─────────────── └──,"description" ─┘ part_name Valid and unique C++ class name that implements the part interface. description Optional part description. ═══ 7.2.2. VBParent Statement for a Part ═══ The VBParent statement describes the part's base part. The attributes, actions and events defined by the base part are inherited. The part class hierarchy must include the IStandardNotifier class for nonvisual parts. ────┬──────────────────────────────────────┬──────────────────────────── └── //VBParent: ───── parent_name ─────┘ parent_name Valid and unique C++ class name. ═══ 7.2.3. VBIncludes Statement for a Part ═══ The VBIncludes statement describes the include file that contains the declaration of the C++ class that implements the part interface. ─── //VBIncludes: ──────┬────────────────────┬──────────── └── include_define ──┘ include_file Header file required by the compiler to use this part. If you want to specify a link dependency in your application make file, use double quotation marks (" ") to delimit the file name instead of the angle brackets (<>). include_define Optional statement that associates a variable with the include statement, enabling generated code to test for duplicate include statements. ═══ 7.2.4. VBPartDataFile Statement for a Part ═══ The optional VBPartDataFile statement specifies the file in which to save the part information. If you do not use this statement, the imported file name is used with a .vbb extension. ──┬─────────────────────────────────────┬─────────────────────────────── └── //VBPartDataFile: ─── file_name ──┘ file_name File name in which to save the part interface information. ═══ 7.2.5. VBLibFile Statement for a Part ═══ The optional VBLibFile statement specifies the library file that will contain the part when it is compiled. Visual Builder uses this data as follows:  It inserts a #pragma statement in the part's generated header code.  It adds the file name to the dependency list in the make file generated for applications using the part. ──┬────────────────────────────────┬──────────────────────────────────── └── //VBLibFile: ─── file_name ──┘ file_name Name of the file that will contain the compiled nonvisual part. ═══ 7.2.6. VBComposerInfo Statement for a Part ═══ The nonvisual part VBComposerInfo statement specifies the composer information needed to support nonvisual parts. This information includes the icon resource ID and icon resource DLL name. ──//VBComposerInfo: ── nonvisual ─────────────────────────────────────── ──┬──────────────────────────────────────────────┬─,─┬──────────────┬─── └──,─── icon_resource_id ───,─── resource_dll ─┘ └── abstract ──┘ icon_resource_id Optional resource number of the icon to be used to represent the part. If you specify this, you must also specify the resource DLL name. resource_dll Resource DLL name containing the icon to be used. Do not include the .dll extension. abstract Optional keyword to indicate that the part is abstract. Abstract parts cannot be dropped on the free-form surface. ═══ 7.2.7. VBConstructor Statement for a Part ═══ The optional VBConstructor statement specifies the constructor information. If you do not use this statement, nonvisual parts use the default constructor. ──┬──────────────────────────────────────┬────────────────────────────── └── //VBConstructor: ─── constructor ──┘ constructor C++ public constructor definition. The parameter names are used in the Visual Builder settings pages to specify the parameters. Each parameter name must match an attribute name. ═══ 7.2.8. VBEvent Statement for a Part ═══ The optional VBEvent statement specifies the event information. This information includes the event name, event description, event notification ID, parameter name, and parameter type. Use this statement to describe events implemented by the part that are useful in making connections. Do not use the VBEvent statement to describe events that occur as a result of attribute changes; specify this information on the VBAttribute statement. ──//VBEvent: ── event_name ──,──┬─────────────────┬─,──notificationID─── └─ "description" ─┘ ──┬────────────────────────────────────────────┬──────────────────────── └──,parameter_name ──┬────────────────────┬──┘ └──,parameter_type ──┘ event_name Event name to be used by the Visual Builder user interface. description Optional event description. notificationID C++ public notification ID. parameter_name Optional event parameter name. parameter_type Optional event parameter type. ═══ 7.2.9. VBAttribute Statement for a Part ═══ The optional VBAttribute statement specifies the attribute information. This information includes the attribute name, attribute description, attribute type (class name), get member function declaration, set member function declaration, and attribute notification ID. Use this statement to describe attributes implemented by the part that are useful in making connections. ──//VBAttribute: ── attribute_name ──,──┬─────────────────┬─,── type──,─ └─ "description" ─┘ ──query_member──┬───────────────┬───┬────────────────────┬────────────── └──,set_member──┘ └──,notificationID ──┘ ──┬───────────────────────────────────┬───────────────────────────────── └──,──┬── NOSETTING ────────────┬───┘ ├── NOSETTING NOCONNECT ──┤ └── NOCONNECT ────────────┘ attribute_name Attribute name to be used by the Visual Builder user interface. description Optional attribute description. type Attribute type. query_member C++ public get member function that returns the attribute value. Specify this as a forward declaration. set_member Optional C++ public set member function that changes the attribute value. Specify this as a forward declaration. notificationID Optional C++ public attribute notification ID. NOSETTING Optional keyword to prevent the attribute's appearance on a generic settings page. NOSETTING NOCONNECT Optional keyword combination to hide a feature defined by a base part. NOCONNECT Optional keyword to disable connections to this feature. ═══ 7.2.10. VBAction Statement for a Part ═══ The optional VBAction statement specifies the action information. This information includes the action name, action description, return type and the C++ action member that implements the action. Use this statement to describe actions implemented by the part that are useful in making connections. To describe member functions that support attributes, use the VBAttribute statement. ──//VBAction: ── action_name ──,──┬─────────────────┬─,───────────────── └─ "description" ─┘ ──┬─────────────────┬──,── action_member ──┬───────────────┬──────────── └── return_type ──┘ └──,NOCONNECT ──┘ action_name Action name to be used by the Visual Builder user interface. Connections to this action are allowed unless the NOCONNECT option has been specified. description Optional action description. return_type Optional return type that specifies the type of the return value from the action and allows the user to make connections to this value. action_member C++ public member function that implements the action. The parameter names are used in the Visual Builder user interface to make connnections to parameters. NOCONNECT Optional keyword to disable connections to this feature. ═══ 7.2.11. VBPreferredFeatures Statement for a Part ═══ The optional VBPreferredFeatures statement specifies the preferred part features. If you do not use this statement, the base part's preferred list is used. If you do use this statement, the base part's preferred list is not inherited, and you must specify the complete list of preferred features for this part. ──┬─────────────────────────────────────────────────────────┬─────────── │ ┌──,──────────────────────┐ │ │  │ │ └──//VBPreferredFeatures: ─────┬── action_name ─────┬─┴───┘ ├── attribute_name ──┤ └── event_name ──────┘ action_name Preferred action name. attribute_name Preferred attribute name. event_name Preferred event name. ═══ 7.2.12. VB Statement for a Part ═══ The optional VB statement allows interface information to be continued on the next statement line. This can be useful when a single statement exceeds a reasonable length. For example, you can use this statement to keep each line under 80 characters. ──┬───────────┬──────────────────────────────────────────────────────── └── //VB: ──┘ ═══ 7.2.13. VBEndPartInfo Statement for a Part ═══ The VBEndPartInfo statement specifies the end of the part interface information. ──//VBEndPartInfo: ── part_name ─────────────────────────────────────── part_name Valid and unique C++ class name. ═══ 7.2.14. Sample Part Information for IAddress ═══ The following is an example of interface information for the IAddress nonvisual part: //VBBeginPartInfo: IAddress, "IBM sample address" //VBParent: IStandardNotifier //VBIncludes: _IADD_ //VBPartDataFile: 'VBSample.vbb' //VBComposerInfo: nonvisual, 10058, dde4vr30 // //VBAttribute: city, //VB: "Query the city (IString) attribute.", //VB: IString, //VB: virtual IString city() const, //VB: virtual IAddress& setCity(const IString& city), //VB: cityId //VBAttribute: state, //VB: "Query the state (IString) attribute.", //VB: IString, //VB: virtual IString state() const, //VB: virtual IAddress& setState(const IString& state), //VB: stateId //VBAttribute: street, //VB: "Query the street (IString) attribute.", //VB: IString, //VB: virtual IString street() const, //VB: virtual IAddress& setStreet(const IString& street), //VB: streetId //VBAttribute: zip, //VB: "Query the zip (IString) attribute.", //VB: IString, //VB: virtual IString zip() const, //VB: virtual IAddress& setZip(const IString& zip), //VB: zipId //VBAction: operator != //VB: ,, Boolean, //VB: Boolean operator !=(const IAddress* aValue) const //VBAction: operator == //VB: ,, Boolean, //VB: Boolean operator ==(const IAddress* aValue) const //VBAction: setCityToDefault //VB: ,"Perform the setCityToDefault action.",, //VB: virtual IAddress& setCityToDefault() //VBAction: setStateToDefault //VB: ,"Perform the setStateToDefault action.",, //VB: virtual IAddress& setStateToDefault() //VBAction: setStreetToDefault //VB: ,"Perform the setStreetToDefault action.",, //VB: virtual IAddress& setStreetToDefault() //VBAction: setToDefault //VB: ,"Perform the setToDefault action.",, //VB: virtual IAddress& setToDefault() //VBAction: setZipToDefault //VB: ,"Perform the setZipToDefault action.",, //VB: virtual IAddress& setZipToDefault() //VBPreferredFeatures: this, city, state, street, zip //VBEndPartInfo: IAddress ═══ 7.3. Class Information Syntax ═══ This section describes the interface information for classes that Visual Builder uses. Syntax descriptions appear in the recommended order of occurrence in a part information file. Many of the statements are similar to the part interface statements documented in the previous section. The following rules apply to the interface information for classes: 1. All feature names (attributes, actions) within a class hierarchy must be unique. If duplicate feature names exist, the information for the derived class is used and the information for the base class is ignored for that specific feature. 2. All class names must be unique and be a valid C++ class name. 3. The names on the VBBeginPartInfo statement and VBEndPartInfo statement must match. 4. Attribute and action information statements can appear more than once for a specific part, but all other information statements must appear only once. For information about how to read these syntax diagrams, see How to Read Syntax Diagrams. ═══ 7.3.1. VBBeginPartInfo Statement for a Class ═══ The first statement describing the interface is the VBBeginPartInfo statement. This statement specifies the class name and the class description. ──//VBBeginPartInfo: ── class_name ──┬──────────────────┬────────────── └──,"description" ─┘ class_name Valid and unique C++ class name that implements the interface. description Optional class description. ═══ 7.3.2. VBParent Statement for a Class ═══ The optional VBParent statement describes the class' base class. The actions defined by the base class are inherited. ────┬──────────────────────────────────────┬──────────────────────────── └── //VBParent: ───── parent_name ─────┘ parent_name Valid and unique C++ class name. ═══ 7.3.3. VBIncludes Statement for a Class ═══ The VBIncludes statement describes the include file that contains the declaration of the C++ class that implements the interface. ─── //VBIncludes: ──────┬────────────────────┬──────────── └── include_define ──┘ include_file Header file required by the compiler to use this class. If you want to specify a link dependency in your application make file, use double quotation marks (" ") to delimit the file name instead of the angle brackets (<>). include_define Optional statement that associates a variable with the include statement, enabling generated code to test for duplicate include statements. ═══ 7.3.4. VBPartDataFile Statement for a Class ═══ The optional VBPartDataFile statement specifies the file in which to save the class interface information. If you do not use this statement, the imported file name is used with a .vbb extension. ──┬─────────────────────────────────────┬─────────────────────────────── └── //VBPartDataFile: ─── file_name ──┘ file_name File name in which to save the class interface information. ═══ 7.3.5. VBComposerInfo Statement for a Class ═══ The class VBComposerInfo statement specifies the composer information needed to support classes. This information includes the icon resource ID and icon resource DLL name. ──//VBComposerInfo: ── class ─────────────────────────────────────────── ──┬──────────────────────────────────────────────┬─,─┬──────────────┬─── └──,─── icon_resource_id ───,─── resource_dll ─┘ └── abstract ──┘ icon_resource_id Resource number of the icon to be used to represent the class. If you specify this, you must also specify the resource DLL name. resource_dll Resource DLL name containing the icon to be used. Do not include the .dll extension. abstract Optional keyword to indicate that the class is abstract. Abstract classes cannot be dropped on the free-form surface. ═══ 7.3.6. VBConstructor Statement for a Class ═══ The optional VBConstructor statement specifies the class constructor information. ──┬──────────────────────────────────────┬────────────────────────────── └── //VBConstructor: ─── constructor ──┘ constructor C++ public constructor definition. The parameter names are used in the Visual Builder settings pages to specify the parameters. Each parameter name must match an attribute name. ═══ 7.3.7. VBAction Statement for a Class ═══ The optional VBAction statement specifies the action information. This information includes the action name, action description, return type, and the action member that implements the action. ──//VBAction: ── action_name ──,──┬─────────────────┬─,───────────────── └─ "description" ─┘ ──┬─────────────────┬──,── action_member ──┬───────────────┬──────────── └── return_type ──┘ └──,NOCONNECT ──┘ action_name Action name to be used by the Visual Builder user interface. Connections to this action are allowed unless the NOCONNECT option has been specified. description Optional action description. return_type Optional return type. action_member C++ public member function that implements the action. The parameter names are used in the Visual Builder user interface to make connnections to parameters. NOCONNECT Optional keyword to disable connections to this feature. ═══ 7.3.8. VBAttribute Statement for a Class ═══ The optional VBAttribute statement specifies the attribute information. This information includes the attribute name, attribute description, attribute type (class name), get member function declaration, set member function declaration, and attribute notification ID. ──//VBAttribute: ── attribute_name ──,──┬─────────────────┬─,── type──,─ └─ "description" ─┘ ──query_member──┬───────────────┬─┬───────────────────────────────────┬─ └──,set_member──┘ └─,,──┬── NOSETTING ────────────┬───┘ ├── NOSETTING NOCONNECT ──┤ └── NOCONNECT ────────────┘ attribute_name Attribute name to be used by the Visual Builder user interface. description Optional attribute description. type Attribute type. query_member C++ public get member function that returns the attribute value. Specify this in the form of a forward declaration. set_member Optional C++ public set member function that changes the attribute value. Specify this in the form of a forward declaration. NOSETTING Optional keyword to prevent the attribute's appearance on a generic settings page. NOSETTING NOCONNECT Optional keyword combination to hide a feature defined by a base class. NOCONNECT Optional keyword to disable connections to this feature. ═══ 7.3.9. VBPreferredFeatures Statement for a Class ═══ The optional VBPreferredFeatures statement specifies the preferred part features. If you do not use this statement, the base class' preferred list is used. If you do use this statement, the base class preferred list is not inherited, and you must specify the complete list of preferred features for this class. ──┬─────────────────────────────────────────────────────────┬─────────── │ ┌──,──────────────────────┐ │ │  │ │ └──//VBPreferredFeatures: ─────┬── action_name ─────┬─┴───┘ └── attribute_name ──┘ action_name Preferred action name. attribute_name Preferred attribute name. ═══ 7.3.10. VB Statement for a Class ═══ The optional VB statement allows the information to be continued on the next statement line. This can be useful when a single statement exceeds a reasonable length. For example, you can use this statement to keep each line under 80 characters. ──┬───────────┬──────────────────────────────────────────────────────── └── //VB: ──┘ ═══ 7.3.11. VBEndPartInfo Statement for a Class ═══ The VBEndPartInfo statement specifies the end of the class interface information. ──//VBEndPartInfo: ── class_name ────────────────────────────────────── class_name Valid and unique C++ class name. ═══ 7.3.12. Sample Class Information for IRange ═══ The following is an example of interface information for the IRange class: //VBBeginPartInfo: IRange, "IBM range of coordinate values" //VBParent: IPair //VBIncludes: _IPOINT_ //VBPartDataFile: 'VBBase.vbb' //VBComposerInfo: class, 204, dde4vr30 // //VBAttribute: lowerBound, //VB: "Returns the lower bound of the range.", //VB: Coord, //VB: Coord lowerBound() const, //VB: IRange& setLowerBound(Coord lowerBound) //VBAttribute: upperBound, //VB: "Returns the upper bound of the range.", //VB: Coord, //VB: Coord upperBound() const, //VB: IRange& setUpperBound(Coord upperBound) //VBAction: includes, //VB: "Returns true if the range contains the specified coordinate value.", //VB: Boolean, //VB: Boolean includes(Coord aValue) const //VBPreferredFeatures: this, lowerBound, upperBound //VBEndPartInfo: IRange ═══ 7.4. Function Group Information Syntax ═══ This section describes the interface information for a group of related C functions that you want to use within Visual Builder. Syntax descriptions appear in the recommended order of occurrence in a file. The following rules apply to the interface information for function groups: 1. All action names within a function group must be unique. 2. All function group names must be unique. 3. The name on the VBBeginPartInfo statement and VBEndPartInfo statement must match. 4. Action information statements can appear more than once for a specific part, but all other information statements must appear only once. For information about how to read these syntax diagrams, see How to Read Syntax Diagrams. ═══ 7.4.1. VBBeginPartInfo Statement for Function Groups ═══ The first statement describing a group of functions is the VBBeginPartInfo statement. This statement specifies the function group name and the function group description. ──//VBBeginPartInfo: ── function_group_name ──┬──────────────────┬───── └──,"description" ─┘ function_group_name A unique name that keeps a set of related functions together as a group. description Optional description. ═══ 7.4.2. VBIncludes Statement for Function Groups ═══ The VBIncludes statement describes the include file that contains the definition of the function group implemented in the interface. ─── //VBIncludes: ──────┬────────────────────┬──────────── └── include_define ──┘ include_file Header file required by the compiler to use this function group. If you want to specify a link dependency in your application make file, use double quotation marks (" ") to delimit the file name instead of the angle brackets (<>). include_define Optional statement that associates a variable with the include statement, enabling generated code to test for duplicate include statements. ═══ 7.4.3. VBPartDataFile Statement for Function Groups ═══ The optional VBPartDataFile statement specifies the file in which to save the function information. If you do not use this statement, the imported file name is used with a .vbb extension. ──┬─────────────────────────────────────┬─────────────────────────────── └── //VBPartDataFile: ─── file_name ──┘ file_name File name in which to save the function group interface information. ═══ 7.4.4. VBComposerInfo Statement for Function Groups ═══ The VBComposerInfo statement specifies the composer information needed to support a group of functions. This information includes the icon resource ID and icon resource DLL name. ──//VBComposerInfo: ── functions ───,─────────────────────────────────── ──┬──────────────────────┬──,──┬──────────────────┬───────────────────── └── icon_resource_id ──┘ └── resource_dll ──┘ icon_resource_id Resource number of the icon to be used to represent the function group. If you specify this, you must also specify the resource DLL name. resource_dll Resource DLL name containing the icon to be used. Do not include the .dll extension. ═══ 7.4.5. VBAction Statement for Function Groups ═══ The optional VBAction statement specifies the action information. This information includes the action name, action description, return type and the C++ function definition. ──//VBAction: ── action_name ──,──┬─────────────────┬─,───────────────── └─ "description" ─┘ ──┬─────────────────┬──,── function_definition ───────────────────────── └── return_type ──┘ action_name Action name to be used by the Visual Builder user interface. description Optional action description. return_type Optional return type. function_definition C public function that implements the action. The parameter names are used in the Visual Builder user interface to make connnections to parameters. ═══ 7.4.6. VB Statement for Function Groups ═══ The optional VB statement allows the information to be continued on the next statement line. This can be useful when a single statement exceeds a reasonable length. For example, the VB statement can be used to keep each line under 80 characters. ──┬───────────┬──────────────────────────────────────────────────────── └── //VB: ──┘ ═══ 7.4.7. VBPreferredFeatures Statement for Function Groups ═══ The optional VBPreferredFeatures statement specifies the preferred actions. ──┬─────────────────────────────────────────────────────────┬─────────── │ ┌──,──────────────────────┐ │ │  │ │ └──//VBPreferredFeatures: ──────── action_name ───────┴───┘ action_name Preferred action name. ═══ 7.4.8. VBEndPartInfo Statement for Function Groups ═══ The VBEndPartInfo statement specifies the end of the interface information. ──//VBEndPartInfo: ── function_group_name ───────────────────────────── function_group_name Function group name matching the previous VBBeginPartInfo statement. ═══ 7.4.9. Sample Function Group Information ═══ The following is an example of a function group interface: // // process function group information // //VBBeginPartInfo: ProcessFunctions, "Process functions" //VBIncludes: //VBPartDataFile: 'Process.vbb' //VBComposerInfo: functions, 10701, dde4vr30 //VBAction: abort, "Abort program.",, //VB: void _LNK_CONV abort( ) //VBAction: exit, "Exit program.",, //VB: void _LNK_CONV exit( int exitCode) //VBAction: system, "Execute system command.",, //VB: void _LNK_CONV system( const char * commandString) //VBEndPartInfo: ProcessFunctions ═══ 7.5. Enumeration Information Syntax ═══ This section describes the interface information for enumerations that Visual Builder uses. Syntax descriptions appear in the recommended order of occurrence in a file. For information about how to read these syntax diagrams, see How to Read Syntax Diagrams. ═══ 7.5.1. VBBeginEnumInfo Statement ═══ The first statement describing the interface is the VBBeginEnumInfo statement. This statement specifies the enumeration name and description. The enum_name must be a valid and unique C++ enumeration name. ──//VBBeginEnumInfo: ── enum_name ──┬──────────────────┬─────────────── └──,"description" ─┘ enum_name Fully qualified C++ enumeration name. description Optional enumeration description. ═══ 7.5.2. VBIncludes Statement for an Enumeration ═══ The VBIncludes statement describes the include file that contains the definition of the enumeration. ─── //VBIncludes: ──────┬────────────────────┬──────────── └── include_define ──┘ include_file Header file that defines the enumeration. If you want to specify a link dependency in your application make file, use double quotation marks (" ") to delimit the file name instead of the angle brackets (<>). include_define Optional statement that associates a variable with the include statement, enabling generated code to test for duplicate include statements. ═══ 7.5.3. VBPartDataFile Statement for an Enumeration ═══ The optional VBPartDataFile statement specifies the file in which to save the enumeration information. If you do not use this statement, the imported file name is used with a .vbb extension. ──┬─────────────────────────────────────┬─────────────────────────────── └── //VBPartDataFile: ─── file_name ──┘ file_name File name in which to save the enumeration interface information. ═══ 7.5.4. VBEnumerators Statement ═══ The VBEnumerators statement describes the enumerators for the enumeration. ┌───,─────────────────────────────┐  │ ──//VBEnumerators: ───── enumerator──┬────────────┬────┴─────────────── └── =value ──┘ enumerator Enumerator name. value Value assigned to this enumerator. ═══ 7.5.5. VB Statement for an Enumeration ═══ The optional VB statement allows the information to be continued on the next statement line. This can be useful when a single statement exceeds a reasonable length. For example, the VB statement can be used to keep each line under 80 characters. ──┬───────────┬──────────────────────────────────────────────────────── └── //VB: ──┘ ═══ 7.5.6. VBEndEnumInfo Statement ═══ The VBEndEnumInfo statement specifies the end of the interface information. ──//VBEndEnumInfo: ── enum_name ─────────────────────────────────────── enum_name Enumeration name matching the previous VBBeginEnumInfo statement. ═══ 7.5.7. Sample Alignment Enumeration for IEntryField ═══ The IEntryField class defined in the ientryfd.hpp header file contains the following nested public Alignment enumeration: #ifndef _IENTRYFD_ #define _IENTRYFD_ class IEntryField : public ITextControl { pubic: enum Alignment { left, center, right }; }; #endif An example of how you could define this Alignment enumeration in an interface file follows: //VBBeginEnumInfo: IEntryField::Alignment //VBIncludes: _IENTRYFD_ //VBPartDataFile: 'VBBase.vbb' //VBEnumerators: left //VB: ,center //VB: ,right //VBEndEnumInfo: IEntryField::Alignment ═══ 7.6. Type Definition Information Syntax ═══ This section describes the interface information for type definitions that Visual Builder uses. Syntax descriptions appear in the recommended order of occurrence in a file. For information about how to read these syntax diagrams, see How to Read Syntax Diagrams. ═══ 7.6.1. VBBeginTypedefInfo Statement ═══ The first statement describing the interface is the VBBeginTypedefInfo statement. This statement specifies the type definition name and the type definition description. ──//VBBeginTypedefInfo: ── typedef_name ────┬──────────────────┬─────── └──,"description" ─┘ typedef_name Fully qualified C++ type definition name. description Optional type definition description. ═══ 7.6.2. VBIncludes Statement for a Type Definition ═══ The VBIncludes statement describes the include file that contains the type definition. ─── //VBIncludes: ──────┬────────────────────┬──────────── └── include_define ──┘ include_file Header file that contains the type definition. If you want to specify a link dependency in your application make file, use double quotation marks (" ") to delimit the file name instead of the angle brackets (<>). include_define Optional statement that associates a variable with the include statement, enabling generated code to test for duplicate include statements. ═══ 7.6.3. VBPartDataFile Statement for a Type Definition ═══ The optional VBPartDataFile statement specifies the file in which to save the type definition information. If you do not use this statement, the imported file name is used with a .vbb extension. ──┬─────────────────────────────────────┬─────────────────────────────── └── //VBPartDataFile: ─── file_name ──┘ file_name File name in which to save the type definition interface information. ═══ 7.6.4. VB Statement for a Type Definition ═══ The optional VB statement allows the information to be continued on the next statement line. This can be useful when a single statement exceeds a reasonable length. For example, you can use this statement to keep each line under 80 characters. ──┬───────────┬──────────────────────────────────────────────────────── └── //VB: ──┘ ═══ 7.6.5. VBEndTypedefInfo Statement ═══ The VBEndTypedefInfo statement specifies the end of the interface information. ──//VBEndTypedefInfo: ── typedef_name ───────────────────────────────── typedef_name Type definition name matching the previous VBBeginTypedefInfo statement. ═══ 7.6.6. Sample Type Definition Information ═══ The following type definition in the isynonym.hpp file: typedef int IBoolean; Could be defined by the following .vbe file: //VBBeginTypedefInfo: IBoolean //VBIncludes: _ISYNONYM_ //VBPartDataFile: 'VBBase.vbb' //VBEndTypedefInfo: IBoolean ═══ 7.7. Other Syntax Examples ═══ An example of the clicked event in the IButton part information file follows: //VBEvent: buttonClickEvent, //VB: "Notification ID provided to observers when button is clicked" //VB: buttonClickId An example of the importFromFile action with an IString parameter from the IMLE part information file follows: //VBAction: importFromFile, //VB: "Inserts the contents of a file into the MLE" //VB: unsigned long, //VB: virtual unsigned long importFromFile(const char* fileName, //VB: EOLFormat type = cfText) ═══ 8. The IBM Class Notification Framework ═══  Overview  Notifiers and observers  Notification protocol  IBM C++ notification class hierarchy Personal notes: ═══ 8.1. Overview ═══ This chapter provides an overview of the IBM class notification framework. You use this framework to implement event and attribute notification for visual and nonvisual parts. Developers coding to the IBM Open Class Library can also use it. The notification framework is different than the previously existing event handler framework. Handlers are capable of stopping the dispatching of events to the remaining handlers in the chain. This is unsatisfactory for a notification framework, where registered observer objects must always be notified of an event regardless of how the event was handled. The notification framework contains the following entities:  Notifier objects that support the notifier protocol defined by the INotifier class.  Observer objects that support the observer protocol defined by the IObserver class.  Notification IDs, which are defined for parts that have been enabled for event notification  Notification event objects defined by the INotificationEvent class. For examples of how this can be implemented in code, see C++ Code to Enable Notification. ═══ 8.2. Notifiers and Observers ═══ Notifier objects enable other objects in the system to register dependence upon the state of the notifier objects' properties. To register dependence, objects add an observer object to the notifier object by using the following function in the IObserver class: virtual IObserver &handleNotificationsFor (INotifier& aNotifier, const IEventData& userData = IEventData()), The IObserver class also supports removing an observer from a notifier via the following: virtual IObserver &stopHandlingNotificationsFor (INotifier& aNotifier ); Notifier objects are responsible for publishing their supported notification events, managing the list of observers, and notifying observers when an event occurs. To notify observers of attribute changes or events, notifiers use the following member function defined by the INotifier class: virtual INotifier ¬ifyObservers (const INotificationEvent& anEvent) = 0; The INotifier abstract base class defines the notifier protocol and requires its derived classes to completely implement its interface. To ensure that all notifier objects can co-exist, no data is stored in any notifier object. A notifier adds observers to an observer list and uses this list to notify observers in a first-in, first-notified manner. The IObserver class defines the protocol that accepts event signals from the notifier object by overriding the member function in the IObserver class as follows: virtual IObserver &dispatchNotificationEvent (const INotificationEvent&)=0; Because a single list of observers is kept for each notifier, all observers in the list get called when any notification occurs within the notifier. Each observer must test to determine if a given notification event should be processed. Normally, this is done by checking notificationId in an INotificationEvent object. Notifier objects publish the notification events that they support by providing a series of unique identifiers in their interface. These notification IDs are string objects that are defined in the notifier. The string is in the form of the class name followed by the event name, such as IStaticText::backgroundColor. Each notification event provides a unique public static notification ID. Events are typically a notification of changes in the attributes or intrinsic data that can be accessed in a notifier object. Attributes can represent any logical property of a part, such as the balance of an account, the size of a shipment, or the label of a push button. A notification event is the data provided to an observer object when a change occurs in the attributes of an object. Included in this data is the identity of the attribute being changed and the part in which the change has occurred. Also, some of the data supplied to the observer can be the actual data being changed in the notifier object. A notification event can also include observer-specific data. The caller that registers the observer with a notifier provides this data as the userData parameter on the following call in the IObserver class: virtual IObserver &handleNotificationsFor (INotifier& aNotifier, const IEventData& userData = IEventData()), The notifier passes this data to that observer anytime it notifies the observer of an event. To support the use of existing classes in a part-building tool, it is highly desirable to be able to derive from these classes and add all required notification behavior in the derived class. You do this by multiply inheriting from the base class and the INotifier class. You can then update the derived class to provide the required notifier behavior and the appropriate notification IDs. Ideally, the class can also provide the required notification behavior. Whether this can actually be done depends on the design of the base class. ═══ 8.3. Notification Protocol ═══ Concrete classes that inherit from the INotifier class implement its protocol. This includes the following:  Enabling, disabling, and querying the ability to signal events. In general, notifiers are created disabled and must be enabled before they can signal events. This allows notifier objects to delay the setup to support notification until the notifier is enabled. (It also allows the Visual Builder connection objects to initialize themselves and related connection objects.) The following member functions in the INotifier class enable you to enable and disable notification: virtual INotifier &enableNotification (Boolean enabled = true) = 0, &disableNotification () = 0;  Managing the collection of observers, including adding and removing observers. These are defined by the following protected members in INotifier: virtual INotifier &addObserver (IObserver& anObserver, const IEventData& userData) = 0, &removeObserver (const IObserver& anObserver) = 0, &removeAllObservers () = 0;  Within the notifier object, calling the following member function every time an event of interest occurs: notifyObservers(const INotificationEvent&) While the classes providing notification must call this function, in many cases it makes sense that the responsibility be delegated to another class. For instance, in the IBM Open Class User Interface Class Library, this responsibility is typically delegated to handler style objects.  The protected member INotifier::addObserver accepts a piece of typeless data as a const IEventData& that is forwarded to the IObserver instance with any notification request. This enables a piece of data to be maintained for each instance of an observer. (One concern in the window handler framework today is that data cannot be stored in a handler object because the handler might be handling many windows.) The IStandardNotifier class provides the concrete implementation of the notifier protocol and provides the base support for nonvisual parts. The notifier protocol is also supported in the subclasses of IWindow. These classes inherit from a notifier class that supports registration of and notification to observer objects. The notification under the IWindow classes occurs primarily using the existing handler classes. ═══ 8.4. IBM C++ Notification Class Hierarchy ═══ IBase │ ┌───────────┴───────────────┐ │ │ IVBase INotificationEvent │ ┌──────┴───────────┐ │ │ INotifier IObserver │ ┌──────┴──────┐ │ │ IWindow IStandardNotifier │ │ IControl Within this partial hierarchy, note the following:  The INotifier abstract class defines the notifier protocol.  The IObserver abstract class defines the observer protocol.  The INotificationEvent class implements the notification event object.  The IStandardNotifier and IWindow classes are concrete implementations of the notifier protocol.  Nonvisual parts would normally be derived from IStandardNotifier.  Visual parts would normally be derived from IWindow or IControl. ═══ 9. C++ Code to Enable Notification ═══ Overview Code for an observer class Code for a notifier class Sample notification flow Personal notes: ═══ 9.1. Overview ═══ Normally, parts are connected by using the Composition Editor; however, developers can also create code that uses the notification framework. This chapter describes a sample program that uses the notification framework to test the IAddress class. The following example shows how the streetChangedAction member function (action) in the IAddressTest class is executed when the street attribute changes (streetId) in the address object. ═══ 9.2. Code for an Observer Class ═══ The first step is to code the connection or observer class to be used. The StreetConnection class in the IAddressTest example follows: //************************************************************************** // StreetConnection Event-to-Action Connection Class //************************************************************************** class StreetConnection : public IObserver { public: StreetConnection(IAddressTest * newTestTarget) { iTestTarget = newTestTarget; //Save source } ; ~StreetConnection () {}; protected: IObserver &dispatchNotificationEvent (const INotificationEvent& anEvent) { if (IAddress::streetId == anEvent.notificationId()) { try {iTestTarget->streetChangedAction();} catch (IException& exc) {} } return *this; } ; IAddressTest * iTestTarget; } ; The key points in the previous sample code follow:  The StreetConnection class is publicly derived from the IObserver class.  The connection target is required on the StreetConnection constructor and is saved in ITestTarget to be used later in the dispatchNotificationEvent member function.  The dispatchNotificationEvent member function is defined, and the code checks if this event is the street-changed event, streetId, as follows: if (IAddress::streetId == anEvent.notificationId()) followed by the code (action) to execute if the test is true: try {iTestTarget->streetChangedAction();} catch (IException& exc) {}: //************************************************************************* // main - Application entry point * //************************************************************************* int main(int argc, char **argv) //Main procedure with no parameters { IApplication::current(). //Get current setArgs(argc, argv); // and set command line parameters IAddress* sourceNotifier; IAddressTest* testTarget; testTarget = new IAddressTest (); sourceNotifier = new IAddress (); { StreetConnection * iStreet = new StreetConnection (testTarget); iStreet->handleNotificationsFor(*sourceNotifier); } { CityConnection * iCity = new CityConnection (testTarget); iCity->handleNotificationsFor(*sourceNotifier); } { StateConnection * iState = new StateConnection (testTarget); iState->handleNotificationsFor(*sourceNotifier); } { ZipConnection * iZip = new ZipConnection (testTarget); iZip->handleNotificationsFor(*sourceNotifier); } sourceNotifier->enableNotification(); sourceNotifier->setStreet(""); sourceNotifier->setCity(""); sourceNotifier->setState(""); sourceNotifier->setZip(""); delete sourceNotifier; delete testTarget; } /* end main */ ═══ 9.3. Code for a Notifier Class ═══ The following code creates a notifier object called sourceNotifier and an observer object called testTarget that is called when events in sourceNotifier are signalled: testTarget = new IAddressTest (); sourceNotifier = new IAddress (); The following code creates a StreetConnection object and adds it as an observer to the sourceNotifier: StreetConnection * iStreet = new StreetConnection (testTarget); iStreet->handleNotificationsFor(*sourceNotifier); The following code enables notification in sourceNotifier and changes the value of the street attribute in the sourceNotifier object: sourceNotifier->enableNotification(); sourceNotifier->setStreet(""); ═══ 9.4. Sample Notification Flow ═══ Calling the setStreet member function in the IAddress class starts a flow of control that results in the calling of the streetChangedAction in the IAddressTest class. Follow this flow starting with the setStreet member function in IAddress: IAddress& IAddress::setStreet (const IString& aStreet) { if (iStreet != aStreet) { iStreet = aStreet; IString eventData(iStreet); notifyObservers(INotificationEvent(streetId, *this, true, (void*)&eventData)); } /* endif */ return *this; } Because a street connection observer has been added to the address object and event notification has been enabled, executing notifyObservers in setStreet causes dispatchNotificationEvent in StreetConnection to run: IObserver &dispatchNotificationEvent (const INotificationEvent& anEvent) { if (IAddress::streetId == anEvent.notificationId()) { try {iTestTarget->streetChangedAction();} catch (IException& exc) {} } return *this; } ; When notifyObservers is called, all observers are called. Each observer must determine if this notification event should be processed. So the dispatchNotificationEvent in StreetConnection compares the notification ID, determines that this is a streetId notification event, and calls streetChangedAction in IAddressTest: class IAddressTest : public IStandardNotifier { streetChangedAction() { printf("The Street Attribute has been changed\n"); } } ; This completes the flow from the street notification (streetId) to the target action, streetChangedAction. ═══ 10. IBM Open Class Library Conventions ═══  Overview  File extensions  File names  Class names, function names, and data member names  Enumerations  Function return types  Function arguments  Feature names  Notification IDs  Other standards Personal notes: ═══ 10.1. Overview ═══ This appendix introduces you to the conventions used in the IBM Open Class Library, as follows:  File extensions  File names  Class, function, and data member names  Enumerations  Function return types  Function arguments  Feature names (attributes, actions, events), for Visual Builder only  Notification IDs  Other standards ═══ 10.2. File Extensions ═══ .c C code file or C++ template code file. .cpp C++ code file. .def Import module definition file. .dll Dynamic link library file. .h C header file or C++ template header file. .hpp C++ header file. .inl C++ inline functions file. .lib Library file. .mak Make file. .rc Resource file. .rsp Import linker automatic response file. .vbb Visual Builder class (binary) file. .vbe Part information (external) file. ═══ 10.3. File Names ═══ All files provided by the IBM Open Class Library begin with the letter "i", such as iapp.hpp. File names have a maximum of eight characters, including the "i". Following is a list of the file name extensions that are used: ixxxxxxx.hpp IBM Open Class Library header file. ixxxxxxx.inl IBM Open Class Library inline functions. The file name generally indicates the class or classes it contains. For example, the iapp.hpp file contains the IApplication and ICurrentApplication classes. ═══ 10.4. Class Names, Function Names, and Data Member Names ═══ Class names are mixed case, with the first letter of each word capitalized, as in ICurrentApplication. All class names in the global name space begin with the letter "I". Function names and data member names are also mixed case, except the first letter is always lowercase, as in the autoSize data member. Here are some more general rules about class and function names:  Acronyms are uppercase, as in IDBCSBuffer (DBCS is the acronym for double-byte character set). Other acronyms are GUI (graphical user interface) and DDE (dynamic data exchange).  Abbreviations are mixed case, as IPresSpaceHandle, which is the class for presentation space handles.  Functions that query begin with a prefix that implies a query is being conducted, such as is or has. The IDragItem class, for example, has the isCopyable function, which queries whether an object can be copied.  Functions that render an object as a different type begin with the as prefix, as in asUnsignedLong, which renders an object as an unsigned long.  Functions that provide enabling or disabling capabilities begin with the enable or disable prefix, respectively. The IEntryField class, for example, provides the enableAutoScroll function, which enables automatic scrolling.  Functions that set something begin with the set prefix. The setDefaultStyle function, to follow the preceding example, is used to set the default style for a class.  Functions that get something, however, have no get prefix. For example, many classes use the defaultStyle function to get the default style for that class.  Functions that act on objects are verbs, such as copy and move.  Function names and arguments are virtually self-explanatory. The following example would move the IWindow object aWindow to the position specified by the IPoint object aPoint. aWindow.moveTo( aPoint );  Many functions that toggle the state of an object are provided with an optional Boolean argument that can be used to perform the opposite action of the function. This allows the result of a prior query function to be used as an input argument, such as the following: Boolean initialVisibility = isVisible(); hide(); /* Do some hidden work */ show(initialVisibility); ═══ 10.5. Enumerations ═══ The conventions for enumeration types and enumerators follow:  The first character of each enumeration name is uppercase. If two words are joined, each begins with an uppercase letter.  Enumerators use the same naming conventions as functions; they begin with lowercase letters, but if two words are joined, the second begins with an uppercase letter. ═══ 10.6. Function Return Types ═══ The return types for the various types of functions follow:  A testing function typically returns a Boolean (true or false) as follows: Boolean isValid() const  Other accessor functions typically return an object as follows: ISize size() const; //Returns an object IWindow* owner(); //Returns a pointer to an object  Functions that act on an object return an object reference, as follows: IWindow& hide(); This enables the chaining of function calls, as follows: aWindow.moveTo(IPoint(10,10)).show(); ═══ 10.7. Function Arguments ═══ Function arguments are usually passed using the following conventions:  Built-in types (ints, doubles) and enumerations are passed in by value.  Objects are passed by reference (a const reference if the argument is not modified by the function).  Optional objects are passed by pointer. For example, a 0 pointer can be passed.  IWindow objects are usually passed by pointer.  IContainerObjects are usually passed by pointer.  Strings are passed as const char *. This enables you to pass either an IString or a literal character array. ═══ 10.8. Feature Names ═══ Give attributes, events, and actions meaningful names, and start them with a lowercase letter to avoid confusion with part or class names. If you follow these simple conventions in choosing your feature names, it is easier for users of your parts to recognize the function of a feature:  Name actions with phrases that indicate activities to be performed, together with an optional receiver of that activity. Examples of feature names for actions are startTimer, openWindow, hide, and setFocus.  Name attributes with phrases that indicate the physical property they represent. Examples of feature names for attributes are height, buttonLabel, and contents.  Name events with phrases that indicate activities that either have happened or are about to happen. Examples of feature names for events are clicked, aboutToCloseWindow, and timeExpired. Note: Do not use feature names that start with avl or vb. These are reserved for use by Visual Builder. ═══ 10.9. Notification IDs ═══ Notification IDs are defined in the header files as public static data members. The notification ID name is attribute or event name followed by Id. The following is an example of the notification ID for the buttonClick event in the IButton class: INotificationId const buttonClickId; The notification ID is implemented in the code files as strings with the class name followed by the attribute or event name. An example from IButton code file follows: const INotificationId IButton::buttonClickId="IButton::buttonClick"; ═══ 10.10. Other Standards ═══ The following are additional standards followed by the IBM Open Class Library:  Header files are wrapped to ensure that files are not included more than once. An example from the ibutton.hpp file follows: #ifndef _IBUTTON_ #define _IBUTTON_  All functions that can be inlined are placed in separate .inl files with a user option (I_NO_INLINES) to determine whether they should be inlined into the application code. An example from the inotifev.hpp file follows: #ifndef I_NO_INLINES #include #endif If you do not want to inline these functions, then define I_NO_INLINES.  isynonym.hpp contains the names of the types and values that are in the global name space but do not begin with the letter "I". If you have collisions with other libraries, you can change the names in isynonym.hpp. ═══ 11. Code Listings ═══  Overview  INotifier header code  IStandardNotifier header code  IObserver header code  INotificationEvent header code  IButton header code  Sample IAddress Part - Header code - Source code - Test code Personal notes: ═══ 11.1. Overview ═══ This chapter presents sample code listings for the following IBM Open Class Library header files:  INotifier  IStandardNotifier  IObserver  INotificationEvent  IButton This chapter also presents the following for a sample IAddress part:  Header code (.hpp)  Source code (.cpp)  Test code There might be differences between these printed samples and the sample code shipped with Visual Builder. Where differences exist, use the shipped sample code. ═══ 11.2. INotifier Header Code ═══ This abstract class contains the notication protocol. #ifndef _INOTIFY_ #define _INOTIFY_ /******************************************************************************* * FILE NAME: inotify.hpp * * * * DESCRIPTION: * * Declaration of the class: * * INotifier - Abstract Notifier protocol. * * * * COPYRIGHT: * * Licensed Materials - Property of IBM * * (C) Copyright IBM Corporation 1992, 1993, 1995 * * All Rights Reserved * * US Government Users Restricted Rights - Use, duplication, or disclosure * * restricted by GSA ADP Schedule Contract with IBM Corp. * *******************************************************************************/ #ifndef _IVBASE_ #include #endif /*----------------------------------------------------------------------------*/ /* Align classes on a four-byte boundary. */ /*----------------------------------------------------------------------------*/ #pragma pack(4) // Forward declarations class IObserver; class IObserverList; class INotificationEvent; class IEventData; typedef const char* const INotificationId; class INotifier : public IVBase { typedef IVBase Inherited; INotifier public public: /*------------------------- Constructors/Destructor ---------------------------- | This class is an abstract base class, so objects cannot be constructed. | | | ------------------------------------------------------------------------------*/ /*---------------------------- Activation -------------------------------------- | The following functions affect the ability of an INotifier to notify | | of events of interest: | | enableNotification - Causes the notifier to send notifications to any | | observer objects added. | | disableNotification - Causes the notifier to stop sending notifications to | | all observer objects added. | | isEnabledForNotification - Returns true if a notifier is sending | | notifications to its observers. | ------------------------------------------------------------------------------*/ virtual INotifier &enableNotification ( Boolean enabled = true ) = 0, &disableNotification ( ) = 0; virtual Boolean isEnabledForNotification ( ) const = 0; /*---------------------------- Observer Notification --------------------------- | The following function is used to notify observers of a change in a notifier notification ID, and optional data provided by the | | specific instance of the notifier. | ------------------------------------------------------------------------------*/ virtual INotifier ¬ifyObservers ( const INotificationEvent& anEvent) = 0; INotifier protected and private protected: /*---------------------------- Observer Addition/Removal ----------------------- | The following functions add and remove observers from the notifier's | | collection: | | addObserver - Adds an observer to the notifier's collection. | | removeObserver - Removes an observer from the notifier's collection. | | removeAllObservers - Removes all observers from the notifier's collection.| ------------------------------------------------------------------------------*/ virtual INotifier &addObserver ( IObserver& anObserver, const IEventData& userData) = 0, &removeObserver ( const IObserver& anObserver) = 0, &removeAllObservers ( ) = 0; /*---------------------------- ObserverList ------------------------------------ | observerList Returns the collection of IObservers. | ------------------------------------------------------------------------------*/ virtual IObserverList &observerList ( ) const = 0; /*---------------------------- Observer Notification --------------------------- | The following function is used to notify observers of a change in a notifier notification ID, and optional data provided by the | | specific instance of the notifier. | ------------------------------------------------------------------------------*/ virtual INotifier ¬ifyObservers (const INotificationId& nId) = 0; private: friend class IObserver; }; /*------------------------------------------------------------------------------ | Resume compiler default packing. | ------------------------------------------------------------------------------*/ #pragma pack() /*----------------------------- Inline Functions -----------------------------*/ #endif /* _INOTIFY_ */ ═══ 11.3. IStandardNotifier Header Code ═══ The IStandardNotifier class implements the notification (INotifier) protocol. Nonvisual parts are derived from this class. #ifndef _ISTDNTFY_ #define _ISTDNTFY_ /******************************************************************************* * FILE NAME: istdntfy.hpp * * * * DESCRIPTION: * * Declaration of the class: * * IStandardNotifier - Concrete implementation of the INotifier protocol. * * * * COPYRIGHT: * * Licensed Materials - Property of IBM * * (C) Copyright IBM Corporation 1992, 1993, 1995 * * All Rights Reserved * * US Government Users Restricted Rights - Use, duplication, or disclosure * * restricted by GSA ADP Schedule Contract with IBM Corp. * *******************************************************************************/ #ifndef _INOTIFY_ #include #endif #ifndef _IEVTDATA_ #include #endif /*----------------------------------------------------------------------------*/ /* Align classes on a four-byte boundary. */ /*----------------------------------------------------------------------------*/ #pragma pack(4) class IObserverList; class IObserver; class INotificationEvent; class IStandardNotifier : public INotifier { typedef IStandardNotifier Inherited; /******************************************************************************* * An IStandardNotifier provides a concrete implementation of the INotifier * * protocol. If you want to create classes that provide notification, * * you can do so by inheriting from IStandardNotifier. Alternatively, you can * * inherit from INotifier directly and provide the notifier protocol yourself. * *******************************************************************************/ IStandardNotifier public public: /*------------------------- Constructors/Destructor ---------------------------- | The only constructor for an IStandardNotifier object is the default | | constructor that accepts no parameters. | ------------------------------------------------------------------------------*/ IStandardNotifier ( ); IStandardNotifier (const IStandardNotifier& partCopy); IStandardNotifier& operator= (const IStandardNotifier& aPart); virtual ~IStandardNotifier ( ); /*---------------------------- Activation -------------------------------------- | The following functions affect the ability of a part to notify observers | | of events of interest: | | enableNotification - Causes the part to send notifications to any | | observer objects added. | | disableNotification - Causes the part to stop sending notifications to | | all observer objects added. | ------------------------------------------------------------------------------*/ virtual IStandardNotifier &enableNotification ( Boolean enable = true), &disableNotification ( ); virtual Boolean isEnabledForNotification ( ) const; /*---------------------------- Observer Notification --------------------------- | The following function is used to notify observers of a change in a notifier& anEvent); /*----------------------- Notification Event Descriptions ---------------------- | These INotificationId strings are used for all notifications that | | IStandardNotifier provides to its observers: | | deleteId - Notification identifier provided to observers when the part | | object is deleted. | ------------------------------------------------------------------------------*/ static INotificationId const deleteId; IStandardNotifier protected and private protected: /*---------------------------- Observer Addition/Removal ----------------------- | The following functions add and remove observers from the notifiers | | collection: | | addObserver - Adds an observer to the part's collection. | | removeObserver - Removes an observer from the part's collection. | | removeAllObservers - Removes all observers from the part's collection. | ------------------------------------------------------------------------------*/ virtual IStandardNotifier &addObserver ( IObserver& anObserver, const IEventData& userData = IEventData(0)), &removeObserver ( const IObserver& anObserver), &removeAllObservers ( ); /*---------------------------- ObserverList ------------------------------------ | observerList - Returns the collection of IObservers. | ------------------------------------------------------------------------------*/ IObserverList &observerList ( ) const; /*---------------------------- Observer Notification --------------------------- | The following function is used to notify observers of a change in a notifier */ /*----------------------------------------------------------------------------*/ #pragma pack() #endif /* _ISTDNTFY_ */ ═══ 11.4. IObserver Header Code ═══ IObserver is an abstract class that can be subclassed and added to notifiers to receive event notification. #ifndef _IOBSERVR_ #define _IOBSERVR_ /******************************************************************************* * FILE NAME: iobservr.hpp * * * * DESCRIPTION: * * Declaration of the class: * * IObserver - Abstract Observer protocol. * * * * COPYRIGHT: * * Licensed Materials - Property of IBM * * (C) Copyright IBM Corporation 1992, 1993, 1995 * * All Rights Reserved * * US Government Users Restricted Rights - Use, duplication, or disclosure * * restricted by GSA ADP Schedule Contract with IBM Corp. * * * *******************************************************************************/ #ifndef _IVBASE_ #include #endif #ifndef _IEVTDATA_ #include #endif /*----------------------------------------------------------------------------*/ /* Align classes on a four-byte boundary. */ /*----------------------------------------------------------------------------*/ #pragma pack(4) // Forward declarations class IObserver; class INotificationEvent; class INotifier; class IObserver : public IVBase { typedef IVBase Inherited; IObserver public public: /*------------------------- Constructors/Destructor ---------------------------- | This class is an abstract class, so objects cannot be constructed. | | | ------------------------------------------------------------------------------*/ ~IObserver (); /*---------------------------- Notifier Attachment ----------------------------- | These functions permit attaching and detaching the observer object to/from | | a given notifier | | handleNotificationsFor - Attaches the observer to the argument | | INotifier object. | | stopHandlingNotificationsFor - Detaches the observer from the argument | | INotifier object. | ------------------------------------------------------------------------------*/ virtual IObserver &handleNotificationsFor ( INotifier& aNotifier, const IEventData& userData = IEventData()), &stopHandlingNotificationsFor ( INotifier& aNotifier ); IObserver protected and private protected: /*---------------------------- Overrides -------------------------------------- | The following function must be overriden in a subclass. | | dispatchNotificationEvent - An object of a class that inherits from | | INotifier calls this function to notify an observer | | of a change in itself. The notification event | | also includes notification-specific information. | ------------------------------------------------------------------------------*/ virtual IObserver &dispatchNotificationEvent ( const INotificationEvent&)=0; private: friend class INotifier; friend class IObserverList; }; /*----------------------------------------------------------------------------*/ /* Resume compiler default packing. */ /*----------------------------------------------------------------------------*/ #pragma pack() /*----------------------------- Inline Functions -----------------------------*/ #endif /* _IOBSERVR_ */ ═══ 11.5. INotificationEvent Header Code ═══ The class INotificationEvent provides the details of a notification event to an observer object as shown in the following example: #ifndef _INOTIFEV_ #define _INOTIFEV_ /******************************************************************************* * FILE NAME: inotifev.hpp * * * * DESCRIPTION: * * Declaration of the class: * * INotificationEvent - The details of a notification to an IObserver * * object. * * * * COPYRIGHT: * * Licensed Materials - Property of IBM * * (C) Copyright IBM Corporation 1992, 1993, 1995 * * All Rights Reserved * * US Government Users Restricted Rights - Use, duplication, or disclosure * * restricted by GSA ADP Schedule Contract with IBM Corp. * *******************************************************************************/ #ifndef _INOTIFY_ #include #endif #ifndef _IEVTDATA_ #include #endif /*----------------------------------------------------------------------------*/ /* Align classes on a four-byte boundary. */ /*----------------------------------------------------------------------------*/ #pragma pack(4) class INotificationEvent : public IBase { typedef IBase Inherited; /******************************************************************************* * The class INotificationEvent provides the details of a notification event * * to an observer object. Included in the event is the notification ID and * * the notifier object. Optionally included in the event is notifier-specific * * data (see the notifier for details) and observer-specific data provided * * to the notifier when the observer was added to the notifier. * *******************************************************************************/ INotificationEvent public public: enum EventType { attribute=1, event}; /*------------------------- Constructors/Destructor ---------------------------- ------------------------------------------------------------------------------*/ INotificationEvent ( const INotificationId& anId, INotifier& aNotifier, Boolean notifierAttrChanged=true, const IEventData& eventData=IEventData(), const IEventData& observerData=IEventData()); INotificationEvent (const INotificationEvent& anEvent); /*---------------------------- Accessors --------------------------------------- ------------------------------------------------------------------------------*/ INotificationEvent &setNotifierAttrChanged ( Boolean changed=true), &setEventData ( const IEventData& eventData ), &setObserverData ( const IEventData& observerData); INotificationId notificationId ( ) const; INotifier ¬ifier ( ) const; Boolean pnotifierAttrChanged ( ) const; IEventData eventData ( ) const, observerData ( ) const; // INotificationEvent protected and private private: INotificationId evtId; INotifier *evtNotifier; Boolean attrChanged; IEventData evtData, obsData; }; /*----------------------------------------------------------------------------*/ /* Resume compiler default packing. */ /*----------------------------------------------------------------------------*/ #pragma pack() /*----------------------------- Inline Functions -----------------------------*/ #ifndef I_NO_INLINES #include #endif #endif /* _INOTIFEV_ */ ═══ 11.6. IButton Header Code ═══ IButton is an abstract class for button controls. #ifndef _IBUTTON_ #define _IBUTTON_ /******************************************************************************* * FILE NAME: ibutton.hpp * * * * DESCRIPTION: * * Declaration of the class: * * IButton - The IButton class is the abstract base class for button controls. * * * COPYRIGHT: * * Licensed Materials - Property of IBM * * (C) Copyright IBM Corporation 1992, 1993, 1995 * * All Rights Reserved * * US Government Users Restricted Rights - Use, duplication, or disclosure * * restricted by GSA ADP Schedule Contract with IBM Corp. * *******************************************************************************/ #ifndef _ITEXTCTL_ #include #endif #ifndef _IBUTTON1_ #include #endif /*----------------------------------------------------------------------------*/ /* Align classes on a four-byte boundary. */ /*----------------------------------------------------------------------------*/ #pragma pack(4) // Forward declarations for other classes: class IColor; class IButton : public ITextControl { typedef ITextControl Inherited; /******************************************************************************* * The IButton class is the abstract base class for button controls. This * * class contains the common functions for all button controls. Actual button * * controls are created by deriving from this base class. * *******************************************************************************/ public: /*----------------------- Style ----------------------------------------------- The following functions provide a means to set and query button styles: Style - Nested class that provides static members that define the set of valid button styles. These styles can be used in conjunction with the styles defined by the nested classes IWindow::Style and IControl::Style. For example, you could define an instance of the IButton::Style class and initialize it as follows: IButton::Style style = IControl::tabStop; An object of this type is provided when the button is created. A customizable default is used if no styles are specified. Once the object is constructed, you can use IButton, IWindow, and IControl member functions to set or query the object's style. The declaration of the IButton::Style nested class is generated by the INESTEDBITFLAGCLASSDEF2 macro. The valid button styles are: noPointerFocus - Buttons with this style do not set the focus to themselves when the user clicks on them using the mouse. This enables the cursor to stay on a control for which information is required, rather than moving to the button. This has no effect on keyboard interaction. -----------------------------------------------------------------------------*/ INESTEDBITFLAGCLASSDEF2(Style, IButton, IWindow, IControl); // style class definition static const Style noPointerFocus; /*-------------------------- Constructor/Destructor ---------------------------- | Instances of this class cannot be created. | ------------------------------------------------------------------------------*/ IButton ( ); virtual ~IButton ( ); /*------------------------------- Mouse Focus ---------------------------------- | The following functions are used to set and query whether the button can | | receive the input focus when clicked with the mouse pointer: | | enableMouseClickFocus - Enables the button to receive the focus when the | | user clicks on the button using the mouse. | | disableMouseClickFocus - Prevents the button from receiving the focus | | when the user clicks on the button using the | | mouse. | | allowsMouseClickFocus - Queries whether the button can receive the focus. | ------------------------------------------------------------------------------*/ #ifndef IC_MOTIF_FLAGNOP IButton &enableMouseClickFocus ( Boolean turnOn = true ), &disableMouseClickFocus ( ); Boolean allowsMouseClickFocus ( ) const; #endif // end of IC_MOTIF_FLAGNOP /*--------------------------- Highlighted State -------------------------------- | These operations test and set a button's highlight state. A highlighted | | button has the same appearance as if the mouse selection button (mouse | | button 1) was pressed while the mouse pointer was over the button control: | | isHighlighted - Returns true if the button's highlight state is set. | | highlight - Sets the button's highlight state. | | unhighlight - Turns off the button's highlight state. | ------------------------------------------------------------------------------*/ #ifndef IC_MOTIF_FLAGNOP Boolean isHighlighted ( ) const; virtual IButton &highlight ( ), &unhighlight ( ); #endif // end of IC_MOTIF_FLAGNOP /*----------------------------- Click the Button ------------------------------- | click - Simulates the user clicking on the button control using the | | mouse selection button. | ------------------------------------------------------------------------------*/ virtual IButton &click ( ); #ifdef IC_PM //#ifndef IC_MOTIF /*----------------------------- Color Functions -------------------------------- | foregroundColor - Returns the foreground color value of the button | | or the default if no color for the area has been | | set. | | backgroundColor - Returns the background color value of the button | | or the default if no color for the area has been | | set. | | disabledForegroundColor - Returns the disabled foreground color value of | | the button or the default if no color for the | | area has been set. | | hiliteForegroundColor - Returns the hilite foreground color value of the | | button or the default if no color for the area | | has been set. | | hiliteBackgroundColor - Returns the hilite background color value of the | | button or the default if no color for the area | | has been set. | ------------------------------------------------------------------------------*/ virtual IColor foregroundColor () const, backgroundColor () const, disabledForegroundColor () const, hiliteForegroundColor () const, hiliteBackgroundColor () const; //#endif #endif /*----------------------- Notification Event Descriptions ---------------------- | These INotificationId strings are used for all notifications that IButton | | provides to its observers: | | buttonClickId - Notification identifier provided to observers when the | | button control is clicked by the user. | ------------------------------------------------------------------------------*/ // Attribute Change Notifications static INotificationId const buttonClickId; /*-------------------------------- Overrides ----------------------------------- | This class overrides the following inherited functions: | | setText - Sets the text for the button and notifies a parent canvas to | | update the layout for its children, if appropriate. | ------------------------------------------------------------------------------*/ virtual IButton &setText ( const char* text ), &setText ( const IResourceId& text ); protected: private: /*--------------------------------- Private ----------------------------------*/ IButton ( const IButton& ); IButton &operator= ( const IButton& ); public: /*--------------------- Obsolete data and Functions ---------------------------- | The following enumerations are defined: | | ColorArea - Used to replace the color for a particular region. | | Values are: | | foreground - Sets the color of the foreground text. | | disabledForeground - Sets the foreground color for disabled | | text. | | background - Sets the color of the background of | | the button window. | | highlightForeground - Sets the foreground color for | | highlighted text. | | border - Sets the color of the border that | | surrounds the button window. | | setColor - Changes the color of the given region. | | color - Returns the color of the given region. | ------------------------------------------------------------------------------*/ enum ColorArea { foreground, background, disabledForeground, highlightForeground, border }; IButton &setColor ( ColorArea value, const IColor& color ); IColor color ( ColorArea value ) const; }; // class IButton INESTEDBITFLAGCLASSFUNCS(Style, IButton); // global style functions /*----------------------------------------------------------------------------*/ /* Resume compiler default packing. */ /*----------------------------------------------------------------------------*/ #pragma pack() #endif /* _IBUTTON_ */ ═══ 11.7. Sample IAddress Part ═══ The IAddress nonvisual part contains several attributes, including street, city, state and zip. ═══ 11.7.1. IAddress Header Code (iadd.hpp) ═══ #ifndef _IADD_ #define _IADD_ /******************************************************************************* * FILE NAME: iadd.hpp * * * * DESCRIPTION: * * Declaration of the class: * * IAddress - Address Class * * * * COPYRIGHT: * * Licensed Materials - Property of IBM * * (C) Copyright IBM Corporation 1994, 1995 * * All Rights Reserved * * US Government Users Restricted Rights - Use, duplication, or disclosure * * restricted by GSA ADP Schedule Contract with IBM Corp. * *******************************************************************************/ #ifndef _ISTRING_ #include #endif #ifndef _ISTDNTFY_ #include #endif /*----------------------------------------------------------------------------*/ /* Align classes on a four-byte boundary. */ /*----------------------------------------------------------------------------*/ #pragma pack(4) class IAddress : public IStandardNotifier { public: /*--------------------------- PUBLIC -----------------------------------------*/ /*------------------------- Constructors/Destructor ---------------------------- ------------------------------------------------------------------------------*/ IAddress (); IAddress (const IAddress& partCopy); virtual ~IAddress (); IAddress& operator= (const IAddress& aIAddress); /*-------------------------------- Attributes ---------------------------------- | The following members support attributes for this class: | | street - Returns the street attribute. | | city - Returns the city attribute. | | state - Returns the state attribute. | | zip - Returns the zip attribute. | | setStreet - Sets the street attribute. | | setCity - Sets the city attribute. | | setState - Sets the state attribute. | | setZip - Sets the zip attribute. | ------------------------------------------------------------------------------*/ virtual IString street () const, city () const, state () const, zip () const; virtual IAddress &setStreet (const IString& aStreet), &setCity (const IString& aCity), &setState (const IString& aState), &setZip (const IString& aZip); /*-------------------------------- Actions ------------------------------------- | These operations or services provided by this class: | | setStreetToDefault - Sets street to a default value. | | setCityToDefault - Sets city to a default value. | | setStateToDefault - Sets state to a default value. | | setZipToDefault - Sets zip to a default value. | | setToDefault - Sets all attributes to their default values. | ------------------------------------------------------------------------------*/ virtual IAddress &setStreetToDefault (), &setCityToDefault (), &setStateToDefault (), &setZipToDefault (), &setToDefault (); /*----------------------- Notification Event Descriptions ---------------------- | These INotificationId strings are used for all notifications that IWindow | | provides to its observers: | | streetId - Notification identifier provided to observers| | when the street attribute changes. | | cityId - Notification identifier provided to observers| | when the city attribute changes. | | stateId - Notification identifier provided to observers| | when the state attribute changes. | | zipId - Notification identifier provided to observers| | when the zip attribute changes. | ------------------------------------------------------------------------------*/ static INotificationId const streetId, cityId, stateId, zipId; private: /*--------------------------- PRIVATE ----------------------------------------*/ IString iStreet; IString iCity; IString iState; IString iZip; }; /*----------------------------------------------------------------------------*/ /* Resume compiler default packing. */ /*----------------------------------------------------------------------------*/ #pragma pack() #endif ═══ 11.7.2. IAddress Source Code (iadd.cpp) ═══ /******************************************************************************* * FILE NAME: iadd.cpp * * * * DESCRIPTION: * * Class implementation of the class: * * IAddress - Address Class * * * * COPYRIGHT: * * Licensed Materials - Property of IBM * * (C) Copyright IBM Corporation 1994, 1995 * * All Rights Reserved * * US Government Users Restricted Rights - Use, duplication, or disclosure * * restricted by GSA ADP Schedule Contract with IBM Corp. * *******************************************************************************/ #ifndef _IADD_ #include //IAddress class header #endif #ifndef _INOTIFEV_ #include #endif const INotificationId IAddress::streetId="IAddress::street"; const INotificationId IAddress::cityId="IAddress::city"; const INotificationId IAddress::stateId="IAddress::state"; const INotificationId IAddress::zipId="IAddress::zip"; /*------------------------------------------------------------------------------ | IAddress::IAddress | | | | Standard constructor. | ------------------------------------------------------------------------------*/ IAddress::IAddress() : IStandardNotifier (), iStreet("101 Main Street"), iCity("Hometown"), iState("NC"), iZip("27511") { } /*------------------------------------------------------------------------------ | IAddress::IAddress | | | | Standard copy constructor. | ------------------------------------------------------------------------------*/ IAddress::IAddress (const IAddress& partCopy) : IStandardNotifier (partCopy), iStreet(partCopy.street()), iCity(partCopy.city()), iState(partCopy.state()), iZip(partCopy.zip()) { } /*------------------------------------------------------------------------------ | IAddress::~IAddress | | | | Empty destructor here for page tuning. | ------------------------------------------------------------------------------*/ IAddress::~IAddress() { } /*------------------------------------------------------------------------------ | IAddress::IAddress | | | | Standard operator= | ------------------------------------------------------------------------------*/ IAddress& IAddress::operator= (const IAddress& aIAddress) { if (this == &aIAddress) { return *this; } /* endif */ IStandardNotifier::operator=(aIAddress); setStreet(aIAddress.street()); setCity(aIAddress.city()); setState(aIAddress.state()); setZip(aIAddress.zip()); return *this; } /*------------------------------------------------------------------------------ | IAddress::street | | | | Returns the street attribute. | ------------------------------------------------------------------------------*/ IString IAddress::street () const { return iStreet; } /*------------------------------------------------------------------------------ | IAddress::setStreet | | | | Sets the street attribute. | ------------------------------------------------------------------------------*/ IAddress& IAddress::setStreet (const IString& aStreet) { if (iStreet != aStreet) { iStreet = aStreet; IString eventData(iStreet); notifyObservers(INotificationEvent(streetId, *this, true, (void*)&eventData)); } /* endif */ return *this; } /*------------------------------------------------------------------------------ | IAddress::city | | | | Returns the city attribute. | ------------------------------------------------------------------------------*/ IString IAddress::city () const { return iCity; } /*------------------------------------------------------------------------------ | IAddress::setCity | | | | Sets the city attribute. | ------------------------------------------------------------------------------*/ IAddress& IAddress::setCity (const IString& aCity) { if (iCity != aCity) { iCity = aCity; IString eventData(iCity); notifyObservers(INotificationEvent(cityId, *this, true, (void*)&eventData)); } /* endif */ return *this; } /*------------------------------------------------------------------------------ | IAddress::state | | | | Returns the state attribute. | ------------------------------------------------------------------------------*/ IString IAddress::state () const { return iState; } /*------------------------------------------------------------------------------ | IAddress::setState | | | | Sets the state attribute. | ------------------------------------------------------------------------------*/ IAddress& IAddress::setState (const IString& aState) { if (iState != aState) { iState = aState; IString eventData(iState); notifyObservers(INotificationEvent(stateId, *this, true, (void*)&eventData)); } /* endif */ return *this; } /*------------------------------------------------------------------------------ | IAddress::zip | | | | Returns the zip attribute. | ------------------------------------------------------------------------------*/ IString IAddress::zip () const { return iZip; } /*------------------------------------------------------------------------------ | IAddress::setZip | | | | Sets the zip attribute. | ------------------------------------------------------------------------------*/ IAddress& IAddress::setZip (const IString& aZip) { if (iZip != aZip) { iZip = aZip; IString eventData(iZip); notifyObservers(INotificationEvent(zipId, *this, true, (void*)&eventData)); } /* endif */ return *this; } /*------------------------------------------------------------------------------ | IAddress::.setStreetToDefault | | | | Performs the setStreetToDefault action. | ------------------------------------------------------------------------------*/ IAddress& IAddress::setStreetToDefault () { setStreet("101 Main Street"); return *this; } /*------------------------------------------------------------------------------ | IAddress::setCityToDefault | | | | Performs the setCityToDefault action. | ------------------------------------------------------------------------------*/ IAddress& IAddress::setCityToDefault () { setCity("Hometown"); return *this; } /*------------------------------------------------------------------------------ | IAddress::setStateToDefault | | | | Performs the setStateToDefault action. | ------------------------------------------------------------------------------*/ IAddress& IAddress::setStateToDefault () { setState("NC"); return *this; } /*------------------------------------------------------------------------------ | IAddress::setZipToDefault | | | | Performs the setZipToDefault action. | ------------------------------------------------------------------------------*/ IAddress& IAddress::setZipToDefault () { setZip("27511"); return *this; } /*------------------------------------------------------------------------------ | IAddress::setToDefault | | | | Performs the setToDefault action. | ------------------------------------------------------------------------------*/ IAddress& IAddress::setToDefault () { setStreetToDefault(); setCityToDefault(); setStateToDefault(); setZipToDefault(); return *this; } ═══ 11.7.3. IAddress Test Code (iadd.cxx) ═══ /******************************************************************************* * FILE NAME: iadd.cxx * * * * COPYRIGHT: * * Licensed Materials - Property of IBM * * (C) Copyright IBM Corporation 1994, 1995 * * All Rights Reserved * * US Government Users Restricted Rights - Use, duplication, or disclosure * * restricted by GSA ADP Schedule Contract with IBM Corp. * *******************************************************************************/ #include #include #ifndef _IOBSERVR_ #include #endif #ifndef _INOTIFEV_ #include #endif #ifndef _IAPP_ #include #endif class IAddressTest : public IStandardNotifier { public: IAddressTest () {} ~IAddressTest () {} streetChangedAction() { printf("The Street Attribute has been changed\n"); } cityChangedAction() { printf("The City Attribute has been changed\n"); } stateChangedAction() { printf("The State Attribute has been changed\n"); } zipChangedAction() { printf("The Zip Attribute has been changed\n"); } } ; //************************************************************************** // StreetConnection Event-to-Action Connection Class //************************************************************************** class StreetConnection : public IObserver { public: StreetConnection(IAddressTest * newTestTarget) { iTestTarget = newTestTarget; //Save source } ; ~StreetConnection () {}; protected: IObserver& dispatchNotificationEvent (const INotificationEvent& anEvent) { if (IAddress::streetId == anEvent.notificationId()) { try {iTestTarget->streetChangedAction();} catch (IException& exc) {} } return *this; } ; IAddressTest * iTestTarget; } ; //************************************************************************** // CityConnection Event-to-Action Connection Class //************************************************************************** class CityConnection : public IObserver { public: CityConnection(IAddressTest * newTestTarget) { iTestTarget = newTestTarget; //Save source } ; ~CityConnection () {}; protected: IObserver& dispatchNotificationEvent (const INotificationEvent& anEvent) { if (IAddress::cityId == anEvent.notificationId()) { try {iTestTarget->cityChangedAction();} catch (IException& exc) {} } return *this; } ; IAddressTest * iTestTarget; } ; //************************************************************************** // StateConnection Event-to-Action Connection Class //************************************************************************** class StateConnection : public IObserver { public: StateConnection(IAddressTest * newTestTarget) { iTestTarget = newTestTarget; //Save source } ; ~StateConnection () {}; protected: IObserver& dispatchNotificationEvent (const INotificationEvent& anEvent) { if (IAddress::stateId == anEvent.notificationId()) { try {iTestTarget->stateChangedAction();} catch (IException& exc) {} } return *this; } ; IAddressTest * iTestTarget; } ; //************************************************************************** // ZipConnection Event-to-Action Connection Class //************************************************************************** class ZipConnection : public IObserver { public: ZipConnection(IAddressTest * newTestTarget) { iTestTarget = newTestTarget; //Save source } ; ~ZipConnection () {}; protected: IObserver& dispatchNotificationEvent (const INotificationEvent& anEvent) { if (IAddress::zipId == anEvent.notificationId()) { try {iTestTarget->zipChangedAction();} catch (IException& exc) {} } return *this; } ; IAddressTest * iTestTarget; } ; //************************************************************************* // main - Application entry point * //************************************************************************* int main(int argc, char **argv) //Main procedure with no parameters { IApplication::current(). //Get current setArgs(argc, argv); // and set command line parameters IAddress * sourceNotifier; IAddressTest * testTarget; testTarget = new IAddressTest (); sourceNotifier = new IAddress (); { StreetConnection * iStreet = new StreetConnection (testTarget); iStreet->handleNotificationsFor(*sourceNotifier); } { CityConnection * iCity = new CityConnection (testTarget); iCity->handleNotificationsFor(*sourceNotifier); } { StateConnection * iState = new StateConnection (testTarget); iState->handleNotificationsFor(*sourceNotifier); } { ZipConnection * iZip = new ZipConnection (testTarget); iZip->handleNotificationsFor(*sourceNotifier); } sourceNotifier->enableNotification(); sourceNotifier->setStreet(""); sourceNotifier->setCity(""); sourceNotifier->setState(""); sourceNotifier->setZip(""); delete sourceNotifier; delete testTarget; } /* end main */ ═══ 12. VisualAge C++ Classes by Include and Data File ═══ Name Include File Data File AnyNetSockets anysock.hh VBSOM AttributeDef attribdf.hh VBSOM BOA boa.hh VBSOM ConstantDef constdef.hh VBSOM Contained containd.hh VBSOM Container containr.hh VBSOM Context cntxt.hh VBSOM dictKeyCharPjw keycpjw.hh VBSOM DrawingArea darea.hpp DArea ExceptionDef excptdef.hh VBSOM floatSamples float.h VBSample I0String i0string.hpp IABag<..> iabag.h VBCC IAccelerator iaccel.hpp IACollection<..> iacllct.h IAddress iadd.hpp VBSample IADeque<..> iadeque.h VBCC IAEqualityCollection<..> iaequal.h VBCC IAEqualityKeyCollection<..> iaeqkey.h VBCC IAEqualityKeySortedCollection<..> iaeqksrt.h VBCC IAEqualitySequence<..> iaeqseq.h VBCC IAEqualitySortedCollection<..> iaeqsrt.h VBCC IAHeap<..> iaheap.h VBCC IAKeyBag<..> iakeybag.h VBCC IAKeyCollection<..> iakey.h VBCC IAKeySet<..> iakeyset.h VBCC IAKeySortedBag<..> iaksbag.h VBCC IAKeySortedCollection<..> iaksrt.h VBCC IAKeySortedSet<..> iaksset.h VBCC IAlias ialias.hpp VBRapSht IAliasClientMgr ialscmgr.hpp VBRapSht IAMap<..> iamap.h VBCC IAnimatedButton ianimbut.hpp IAOrderedCollection<..> iaorder.h IApplication iapp.hpp IAPriorityQueue<..> iaprioqu.h VBCC IAQueue<..> iaqueue.h VBCC IARelation<..> iarel.h VBCC IArrest iarrest.hpp VBRapSht IArrestClientMgr iarscmgr.hpp VBRapSht IASequence<..> iaseq.h IASequentialCollection<..> iasqntl.h IASet<..> iaset.h VBCC IASortedBag<..> iasrtbag.h VBCC IASortedCollection<..> iasrt.h VBCC IASortedMap<..> iasrtmap.h VBCC IASortedRelation<..> iasrtrel.h VBCC IASortedSet<..> iasrtset.h VBCC IAStack<..> iastack.h VBCC IBase ibase.hpp IBaseComboBox icombobs.hpp IBaseListBox ilistbas.hpp IBaseSpinButton ispinbas.hpp IBitFlag ibitflag.hpp IBitmapControl ibmpctl.hpp IButton ibutton.hpp ICalcAdditionChip icalcac.hpp icalcprt ICalcClearFunction icalcclr.hpp icalcprt ICalcDivisionChip icalcdc.hpp icalcprt ICalcEqualFunction icalceql.hpp icalcprt ICalcFunction icalcfnc.hpp icalcprt ICalcMultiplicationChip icalcmc.hpp icalcprt ICalcOperator icalcop.hpp icalcprt ICalcPU icalcpu.hpp icalcprt ICalcSubtractionChip icalcsc.hpp icalcprt ICalcTally icalctly.hpp icalcprt ICanvas icanvas.hpp ICheckBox icheckbx.hpp ICircularSlider icslider.hpp ICLibErrorInfo iexcept.hpp IClipboard iclipbrd.hpp ICollectionViewComboBox<..> icombovw.hpp ICollectionViewListBox<..> ilistcvw.hpp IColor icolor.hpp IComboBox icombobx.hpp ICompany icompany.hpp VBSample IContainerColumn icnrcol.hpp IContainerControl icnrctl.hpp IContainerObject icnrobj.hpp IControl icontrol.hpp ICurrentApplication iapp.hpp ICurrentThread ithread.hpp ICustomButton icustbut.hpp ICustomer icust.hpp VBSample IDate idate.hpp IDynamicLinkLibrary ireslib.hpp IElemPointer<..> iptr.h VBCC IEntryField ientryfd.hpp IErrorInfo iexcept.hpp IFileDialog ifiledlg.hpp IFlyOverHelpHandler iflyhhdr.hpp IFlyText iflytext.hpp IFont ifont.hpp IFontDialog ifontdlg.hpp IFrameWindow iframe.hpp IGraphicPushButton igraphbt.hpp IGroupBox igroupbx.hpp IGUIErrorInfo iexcept.hpp IHandle ihandle.hpp IHandler ihandler.hpp IHelpWindow ihelp.hpp IIconControl iiconctl.hpp IInfoArea iinfoa.hpp IKeypad ikeypad.hpp icalcprt ILastSeen ilstseen.hpp VBRapSht ILastSeenClientMgr ilscmgr.hpp VBRapSht IListBox ilistbox.hpp IMenu imenu.hpp IMenuBar imenubar.hpp IMenuCascade imnItem.hpp IMenuHandler imenuhdr.hpp IMenuItem imnitem.hpp IMenuSeparator imnItem.hpp IMessageBox imsgbox.hpp IMM24FramesPerSecondTime immtime.hpp VBMM IMM25FramesPerSecondTime immtime.hpp VBMM IMM30FramesPerSecondTime immtime.hpp VBMM IMMAmpMixer immamix.hpp VBMM IMMAudioBuffer immabuf.hpp VBMM IMMAudioCD immcdda.hpp VBMM IMMAudioCDContents immcdda.hpp VBMM IMMAudioHeader immahead.hpp VBMM IMMCDXA immcdxa.hpp VBMM IMMConfigurableAudio immaud.hpp VBMM IMMDevice immdev.hpp VBMM IMMDigitalVideo immdigvd.hpp VBMM IMMErrorInfo immexcpt.hpp VBMM IMMFileMedia immfilem.hpp VBMM IMMHourMinSecFrameTime immtime.hpp VBMM IMMHourMinSecTime immtime.hpp VBMM IMMMasterAudio immmaud.hpp VBMM IMMMillisecondTime immtime.hpp VBMM IMMMinSecFrameTime immtime.hpp VBMM IMMPlayableDevice immplayd.hpp VBMM IMMPlayerPanel immplypn.hpp VBMM IMMRecordable immrecrd.hpp VBMM IMMRemovableMedia immremed.hpp VBMM IMMSequencer immsequ.hpp VBMM IMMSpeed immspeed.hpp VBMM IMMTime immtime.hpp VBMM IMMTrackMinSecFrameTime immttime.hpp VBMM IMMWaveAudio immwave.hpp VBMM IMngPointer<..> iptr.h VBCC ImplementationDef impldef.hh VBSOM ImplRepository implrep.hh VBSOM IMultiCellCanvas imcelcv.hpp IMultiLineEdit imle.hpp INotebook inotebk.hpp INotebook::PageSettings inotebk.hpp INotifier inotify.hpp InterfaceDef intfacdf.hh VBSOM INumericSpinButton ispinnum.hpp IObserver iobservr.hpp IOrderedRecord iordrrec.hpp VBSample ioSamples io.h VBSample IOutlineBox ioutlbox.hpp IPair ipoint.hpp IPartOrderedCollection<..> ipartccl.h VBCC IPercentAvailable ipercent.hpp IPerson iperson.hpp VBRapSht IPoint ipoint.hpp IPointArray iptarray.hpp IPopUpMenu ipopmenu.hpp IProfile iprofile.hpp IProgressIndicator islider.hpp IPushButton ipushbut.hpp IPXSockets ipxsock.hh VBSOM IRadioButton iradiobt.hpp IRange ipoint.hpp IRBag<..> irbag.h VBCC IRDeque<..> irdeque.h VBCC IRecord irecord.hpp VBSample IRectangle irect.hpp IRefCounted irefcnt.hpp IREqualitySequence<..> ireqseq.h VBCC IResource ireslock.hpp IResourceId ireslib.hpp IResourceLibrary ireslib.hpp IRHeap<..> irheap.h VBCC IRKeyBag<..> irkeybag.h VBCC IRKeySet<..> irkeyset.h VBCC IRKeySortedBag<..> irksbag.h VBCC IRKeySortedSet<..> irksset.h VBCC IRMap<..> irmap.h VBCC IRPriorityQueue<..> irprioqu.h VBCC IRQueue<..> irqueue.h VBCC IRRelation<..> irrel.h VBCC IRSequence<..> irseq.h IRSet<..> irset.h VBCC IRSortedBag<..> irsrtbag.h VBCC IRSortedMap<..> irsrtmap.h VBCC IRSortedRelation<..> irsrtrel.h VBCC IRSortedSet<..> irsrtset.h VBCC IRStack<..> irstack.h VBCC IScrollBar iscroll.hpp ISetCanvas isetcv.hpp ISettingButton isetbut.hpp ISize ipoint.hpp ISlider islider.hpp ISplitCanvas isplitcv.hpp IStandardNotifier istdntfy.hpp IStaticText istattxt.hpp IString istring.hpp IStringGenerator<..> istrgen.hpp ISubmenu isubmenu.hpp ISuspect isuspect.hpp VBRapSht ISuspectClientMgr isuscmgr.hpp VBRapSht ISuspectWindowFactory isuswfac.hpp VBRapSht ISystemErrorInfo iexcept.hpp ITextControl itextctl.hpp ITextSpinButton ispintxt.hpp ITime itime.hpp ITitle ititle.hpp IToolBar itbar.hpp IToolBarButton itbarbut.hpp ITrace itrace.hpp IVAvlKeySortedSet<..> ivksset.h VBCC IVBag<..> ivbag.h VBCC IVBagOnBase<..> ivbag.h VBCC IVBagOnBSTKeySortedSet<..> ivbag.h VBCC IVBagOnHashKeySet<..> ivbag.h VBCC IVBagOnSortedDilutedSequence<..> ivbag.h VBCC IVBagOnSortedLinkedSequence<..> ivbag.h VBCC IVBagOnSortedTabularSequence<..> ivbag.h VBCC IVBase ivbase.hpp IVBBooleanPart ivbbool.hpp VBSample IVBCheckMenuHandler ivbmenuh.hpp IVBCnrPopupMenuHandler ivbmenuh.hpp IVBContainerControl<..> ivbcnr.h IVBDataTypePart ivbdtype.hpp VBSample IVBDoublePart ivbdbl.hpp VBSample IVBDragDropHandler ivbdragh.hpp IVBFactory VBBase abstract IVBFileDialog ivbfiled.hpp IVBFlyText ivbfly.hpp IVBFontDialog ivbfontd.hpp IVBLongPart ivblong.hpp VBSample IVBMinSize ipoint.hpp vbbase IVBMinSizeViewPortHandler ivbvpmsz.hpp IVBNotebookPage ivbnbkpg.hpp IVBPopupMenuHandler ivbmenuh.hpp IVBShortPart ivbshort.hpp VBSample IVBSTKeySortedSet<..> ivksset.h VBCC IVBStringPart ivbstrng.hpp VBSample IVBTitle ititle.hpp IVBUnsignedLongPart ivbulong.hpp VBSample IVBUnsignedShortPart ivbushrt.hpp VBSample IVBVariableClass<..> ivbvcls.h IVBVariableClassBase ivbvclss.hpp IVBVariableClassPointer<..> ivbvclsp.h IVBVariablePart<..> ivbvprt.h IVBVariablePartBase ivbvpart.hpp IVBVariablePartPointer<..> ivbvprtp.h IVDeque<..> ivdeque.h VBCC IVDequeOnBase<..> ivdeque.h VBCC IVDequeOnDilutedSequence<..> ivdeque.h VBCC IVDilutedSequence<..> ivseq.h VBCC IVEqualitySequence<..> iveqseq.h VBCC IVEqualitySequenceOnBase<..> iveqseq.h VBCC IVEqualitySequenceOnDilutedSequence<..> iveqseq.h VBCC IVEqualitySequenceOnTabularSequence<..> iveqseq.h VBCC IVGAvlKeySortedSet<..> ivksset.h VBCC IVGBag<..> ivbag.h VBCC IVGBagOnBSTKeySortedSet<..> ivbag.h VBCC IVGBagOnHashKeySet<..> ivbag.h VBCC IVGBagOnSortedDilutedSequence<..> ivbag.h VBCC IVGBagOnSortedLinkedSequence<..> ivbag.h VBCC IVGBagOnSortedTabularSequence<..> ivbag.h VBCC IVGBSTKeySortedSet<..> ivksset.h VBCC IVGDeque<..> ivdeque.h VBCC IVGDequeOnDilutedSequence<..> ivdeque.h VBCC IVGDilutedSequence<..> ivseq.h VBCC IVGEqualitySequence<..> iveqseq.h VBCC IVGEqualitySequenceOnDilutedSequence<..> iveqseq.h VBCC IVGEqualitySequenceOnTabularSequence<..> iveqseq.h VBCC IVGHashKeyBag<..> ivkeybag.h VBCC IVGHashKeySet<..> ivkeyset.h VBCC IVGHeap<..> ivheap.h VBCC IVGHeapOnDilutedSequence<..> ivheap.h VBCC IVGKeyBag<..> ivkeybag.h VBCC IVGKeySet<..> ivkeyset.h VBCC IVGKeySetOnBSTKeySortedSet<..> ivkeyset.h VBCC IVGKeySetOnSortedDilutedSequence<..> ivkeyset.h VBCC IVGKeySetOnSortedLinkedSequence<..> ivkeyset.h VBCC IVGKeySetOnSortedTabularSequence<..> ivkeyset.h VBCC IVGKeySortedBag<..> ivksbag.h VBCC IVGKeySortedBagOnSortedDilutedSequence<..> ivksbag.h VBCC IVGKeySortedBagOnSortedTabularSequence<..> ivksbag.h VBCC IVGKeySortedSet<..> ivksset.h VBCC IVGKeySortedSetOnSortedDilutedSequence<..> ivksset.h VBCC IVGKeySortedSetOnSortedLinkedSequence<..> ivksset.h VBCC IVGKeySortedSetOnSortedTabularSequence<..> ivksset.h VBCC IVGLinkedSequence<..> ivseq.h VBCC IVGMap<..> ivmap.h VBCC IVGMapOnBSTKeySortedMap<..> ivsrtmap.h VBCC IVGMapOnBSTKeySortedSet<..> ivmap.h VBCC IVGMapOnHashKeySet<..> ivmap.h VBCC IVGMapOnSortedDilutedSequence<..> ivmap.h VBCC IVGMapOnSortedLinkedSequence<..> ivmap.h VBCC IVGMapOnSortedTabularSequence<..> ivmap.h VBCC IVGPriorityQueue<..> ivprioqu.h VBCC IVGQueue<..> ivqueue.h VBCC IVGQueueOnDilutedSequence<..> ivqueue.h VBCC IVGQueueOnTabularSequence<..> ivqueue.h VBCC IVGRelation<..> ivrel.h VBCC IVGSequence<..> ivseq.h IVGSet<..> ivset.h VBCC IVGSetOnBSTKeySortedSet<..> ivset.h VBCC IVGSetOnHashKeySet<..> ivset.h VBCC IVGSetOnSortedDilutedSequence<..> ivset.h VBCC IVGSetOnSortedLinkedSequence<..> ivset.h VBCC IVGSetOnSortedTabularSequence<..> ivset.h VBCC IVGSortedBag<..> ivsrtbag.h VBCC IVGSortedBagOnSortedDilutedSequence<..> ivsrtbag.h VBCC IVGSortedBagOnSortedLinkedSequence<..> ivsrtbag.h VBCC IVGSortedBagOnSortedTabularSequence<..> ivsrtbag.h VBCC IVGSortedMap<..> ivsrtmap.h VBCC IVGSortedMapOnSortedDilutedSequence<..> ivsrtmap.h VBCC IVGSortedMapOnSortedLinkedSequence<..> ivsrtmap.h VBCC IVGSortedMapOnSortedTabularSequence<..> ivsrtmap.h VBCC IVGSortedRelation<..> ivsrtrel.h VBCC IVGSortedRelationOnSortedDilutedSequence<..> ivsrtrel.h VBCC IVGSortedRelationOnSortedTabularSequence<..> ivsrtrel.h VBCC IVGSortedSet<..> ivsrtset.h VBCC IVGSortedSetOnBSTKeySortedSet<..> ivsrtset.h VBCC IVGSortedSetOnSortedDilutedSequence<..> ivsrtset.h VBCC IVGSortedSetOnSortedLinkedSequence<..> ivsrtset.h VBCC IVGSortedSetOnSortedTabularSequence<..> ivsrtset.h VBCC IVGStack<..> ivstack.h VBCC IVGStackOnDilutedSequence<..> ivstack.h VBCC IVGStackOnTabularSequence<..> ivstack.h VBCC IVGTabularSequence<..> ivseq.h VBCC IVHashKeyBag<..> ivkeybag.h VBCC IVHashKeySet<..> ivkeyset.h VBCC IVHeap<..> ivheap.h VBCC IVHeapOnBase<..> ivheap.h VBCC IVHeapOnDilutedSequence<..> ivheap.h VBCC IViewPort ivport.hpp IVKeyBag<..> ivkeybag.h VBCC IVKeyBagOnBase<..> ivkeybag.h VBCC IVKeySet<..> ivkeyset.h VBCC IVKeySetOnBase<..> ivkeyset.h VBCC IVKeySetOnBSTKeySortedSet<..> ivkeyset.h VBCC IVKeySetOnSortedDilutedSequence<..> ivkeyset.h VBCC IVKeySetOnSortedLinkedSequence<..> ivkeyset.h VBCC IVKeySetOnSortedTabularSequence<..> ivkeyset.h VBCC IVKeySortedBag<..> ivksbag.h VBCC IVKeySortedBagOnBase<..> ivksbag.h VBCC IVKeySortedBagOnSortedDilutedSequence<..> ivksbag.h VBCC IVKeySortedBagOnSortedTabularSequence<..> ivksbag.h VBCC IVKeySortedSet<..> ivksset.h VBCC IVKeySortedSetOnBase<..> ivksset.h VBCC IVKeySortedSetOnSortedLinkedSequence<..> ivksset.h VBCC IVKeySortedSetOnSortedTabularSequence<..> ivksset.h VBCC IVLinkedSequence<..> ivseq.h VBCC IVMap<..> ivmap.h VBCC IVMapOnBase<..> ivmap.h VBCC IVMapOnBSTKeySortedSet<..> ivmap.h VBCC IVMapOnHashKeySet<..> ivmap.h VBCC IVMapOnSortedDilutedSequence<..> ivmap.h VBCC IVMapOnSortedLinkedSequence<..> ivmap.h VBCC IVMapOnSortedTabularSequence<..> ivmap.h VBCC IVPriorityQueue<..> ivprioqu.h VBCC IVPriorityQueueOnBase<..> ivprioqu.h VBCC IVQueue<..> ivqueue.h VBCC IVQueueOnBase<..> ivqueue.h VBCC IVQueueOnDilutedSequence<..> ivqueue.h VBCC IVQueueOnTabularSequence<..> ivqueue.h VBCC IVRelation<..> ivrel.h VBCC IVRelationOnBase<..> ivrel.h VBCC IVSequence<..> ivseq.h IVSequenceOnBase<..> ivseq.h IVSet<..> ivset.h VBCC IVSetOnBase<..> ivset.h VBCC IVSetOnBSTKeySortedSet<..> ivset.h VBCC IVSetOnHashKeySet<..> ivset.h VBCC IVSetOnSortedDilutedSequence<..> ivset.h VBCC IVSetOnSortedLinkedSequence<..> ivset.h VBCC IVSetOnSortedTabularSequence<..> ivset.h VBCC IVSortedBag<..> ivsrtbag.h VBCC IVSortedBagOnBase<..> ivsrtbag.h VBCC IVSortedBagOnSortedDilutedSequence<..> ivsrtbag.h VBCC IVSortedBagOnSortedLinkedSequence<..> ivsrtbag.h VBCC IVSortedBagOnSortedTabularSequence<..> ivsrtbag.h VBCC IVSortedMap<..> ivsrtmap.h VBCC IVSortedMapOnBase<..> ivsrtmap.h VBCC IVSortedMapOnSortedDilutedSequence<..> ivsrtmap.h VBCC IVSortedMapOnSortedLinkedSequence<..> ivsrtmap.h VBCC IVSortedMapOnSortedTabularSequence<..> ivsrtmap.h VBCC IVSortedRelation<..> ivsrtrel.h VBCC IVSortedRelationOnBase<..> ivsrtrel.h VBCC IVSortedRelationOnSortedDilutedSequence<..> ivsrtrel.h VBCC IVSortedRelationOnSortedTabularSequence<..> ivsrtrel.h VBCC IVSortedSet<..> ivsrtset.h VBCC IVSortedSetOnBase<..> ivsrtset.h VBCC IVSortedSetOnBSTKeySortedSet<..> ivsrtset.h VBCC IVSortedSetOnSortedLinkedSequence<..> ivsrtset.h VBCC IVSortedSetOnSortedTabularSequence<..> ivsrtset.h VBCC IVStack<..> ivstack.h VBCC IVStackOnBase<..> ivstack.h VBCC IVStackOnTabularSequence<..> ivstack.h VBCC IVTabularSequence<..> ivseq.h VBCC IWindow iwindow.hpp mathSamples math.h VBSample ModuleDef moduledf.hh VBSOM M_SOMPPersistentObject po.hh VBSOM NBSockets nbsock.hh VBSOM NVList nvlist.hh VBSOM OAContract Contrctg.hpp OANONVIS OAContractor Cntrctor.hpp OANONVIS OASkill skillg.hpp OANONVIS OASkillBase SkllBase.hpp OANONVIS ObjectMgr om.hh VBSOM OperationDef operatdf.hh VBSOM ORB orb.hh VBSOM ParameterDef paramdef.hh VBSOM Principal principl.hh VBSOM Repository repostry.hh VBSOM Request request.hh VBSOM Sockets somssock.hh VBSOM SOMAPI somapi.h VBSOM SOMClass somcls.hh VBSOM SOMClassMgr somcm.hh VBSOM SOMDClientProxy somdcprx.hh VBSOM SOMDMetaproxy somdmprx.hh VBSOM SOMDObject somdobj.hh VBSOM SOMDObjectMgr somdom.hh VBSOM SOMDServer somdserv.hh VBSOM SOMDServerMgr servmgr.hh VBSOM SOMEClientEvent clientev.hh VBSOM SOMEEMan eman.hh VBSOM SOMEEMRegisterData emregdat.hh VBSOM SOMEEvent event.hh VBSOM SOMESinkEvent sinkev.hh VBSOM SOMETimerEvent timerev.hh VBSOM SOMEWorkProcEvent workprev.hh VBSOM somf_MCollectible mcollect.hh VBSOM somf_MLinkable mlink.hh VBSOM somf_MOrderableCollectible morder.hh VBSOM somf_TAssoc tassoc.hh VBSOM somf_TCollectibleLong tclong.hh VBSOM somf_TCollection tcollect.hh VBSOM somf_TDeque tdeq.hh VBSOM somf_TDequeIterator tdeqitr.hh VBSOM somf_TDequeLinkable tdeqlink.hh VBSOM somf_TDictionary tdict.hh VBSOM somf_TDictionaryIterator tdictitr.hh VBSOM somf_THashTable thash.hh VBSOM somf_THashTableIterator thashitr.hh VBSOM somf_TIterator titeratr.hh VBSOM somf_TPrimitiveLinkedList tpll.hh VBSOM somf_TPrimitiveLinkedListIterator tpllitr.hh VBSOM somf_TPriorityQueue tpq.hh VBSOM somf_TPriorityQueueIterator tpqitr.hh VBSOM somf_TSequence tseq.hh VBSOM somf_TSequenceIterator tseqitr.hh VBSOM somf_TSet tset.hh VBSOM somf_TSetIterator tsetitr.hh VBSOM somf_TSortedSequence tss.hh VBSOM somf_TSortedSequenceIterator tssitr.hh VBSOM somf_TSortedSequenceNode tssnode.hh VBSOM SOMMBeforeAfter sombacls.hh VBSOM SOMMBeforeAfterDispatcher sombadis.hh VBSOM SOMMCooperative sommeta.hh VBSOM SOMMCooperativeRedispatched sommeta.hh VBSOM SOMMCooperativeSistered sommeta.hh VBSOM SOMMSingleInstance snglicls.hh VBSOM SOMMTraced somtrcls.hh VBSOM SOMOA somoa.hh VBSOM SOMObject somobj.hh VBSOM SOMPAscii fsagm.hh VBSOM SOMPAsciiMediaInterface fmi.hh VBSOM SOMPAttrEncoderDecoder defedidl.hh VBSOM SOMPBinary fsgm.hh VBSOM SOMPBinaryFileMedia fmib.hh VBSOM SOMPEncoderDecoderAbstract eda.hh VBSOM SOMPFileMediaAbstract fma.hh VBSOM SOMPIdAssigner poid.hh VBSOM SOMPIdAssignerAbstract poida.hh VBSOM SOMPIOGroup iogrp.hh VBSOM SOMPIOGroupMgrAbstract iogma.hh VBSOM SOMPKeyedSet srkset.hh VBSOM SOMPMediaInterfaceAbstract mia.hh VBSOM SOMPNameSpaceMgr nsma.hh VBSOM SOMPObjectSet objset.hh VBSOM SOMPPersistentId pid.hh VBSOM SOMPPersistentObject po.hh VBSOM SOMPPersistentStorageMgr psma.hh VBSOM SOMR somr.hh VBSOM SOMRLinearizable linear.hh VBSOM SOMRNameable nameable.hh VBSOM SOMRReplicable somrmcls.hh VBSOM SOMRReplicableObject somrcls.hh VBSOM SOMRReplicbl replicbl.hh VBSOM SOMStringTableC somstrt.hh VBSOM SOMTAttributeEntryC scattrib.hh VBSOM SOMTBaseClassEntryC scbase.hh VBSOM SOMTClassEntryC scclass.hh VBSOM SOMTCommonEntryC sccommon.hh VBSOM SOMTConstEntryC scconst.hh VBSOM SOMTDataEntryC scdata.hh VBSOM SOMTEmitC scemit.hh VBSOM SOMTEntryC scentry.hh VBSOM SOMTEnumEntryC scenum.hh VBSOM SOMTEnumNameEntryC scenumnm.hh VBSOM SOMTMetaClassEntryC scmeta.hh VBSOM SOMTMethodEntryC scmethod.hh VBSOM SOMTModuleEntryC scmodule.hh VBSOM SOMTParameterEntryC scparm.hh VBSOM SOMTPassthruEntryC scpass.hh VBSOM SOMTSequenceEntryC scseqnce.hh VBSOM SOMTStringEntryC scstring.hh VBSOM SOMTStructEntryC scstruct.hh VBSOM SOMTTemplateOutputC sctmplt.hh VBSOM SOMTTypedefEntryC sctdef.hh VBSOM SOMTUnionEntryC scunion.hh VBSOM SOMTUserDefinedTypeEntryC scusrtyp.hh VBSOM SOMUTId somida.hh VBSOM SOMUTStringId somsid.hh VBSOM stdioSamples stdio.h VBSample stdlibSamples stdlib.h VBSample TCPIPSockets tcpsock.hh VBSOM TCPIPSockets32 tcp32.hh VBSOM TSIdentification tsident.hh VBSOM TypeDef typedef.hh VBSOM ═══ 13. 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 attribute-to-parameter 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 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. ═══ attribute-to-parameter connection ═══ A connection that satisfies a parameter of an action or member function by supplying an attribute's value. 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, attribute-to-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. ═══ 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.