home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 16 Announce / 16-Announce.zip / opminf.zip / OPMINFO.TXT
Text File  |  1993-07-15  |  36KB  |  1,008 lines

  1.             ObjectPM 2.0 Class Library
  2.  
  3.  
  4. INTRODUCTION
  5. ------------
  6.  
  7. ObjectPM is a library of objects called a "class library" that
  8. provides the means to develop object-oriented OS/2 applications in
  9. C++. This allows industrial strength applications to be developed in a
  10. fraction of the time required to develop the same applications in C.
  11. In addition, the benefits of C++ can be realized in smaller, more
  12. reliable and maintainable programs. 
  13.  
  14. Developing object-oriented applications means that you will be working
  15. with objects. For example, to create a Presentation Manager window,
  16. you create a "window" object. In C++, these objects are defined as a
  17. "class". Defining an object involves specifying the data that
  18. represents the object, and then a set of functions or "methods" that
  19. are used to manipulate that data. For a window object, the data can
  20. be its window handle, position, style and parent. The methods that
  21. manipulate the window are for example: "ChangeSize", "ChangePosition",
  22. "CaptureMouse", etc. ObjectPM applications are built by defining,
  23. creating, and manipulating such objects. 
  24.  
  25. Increase Productivity
  26.  
  27. Programming the Presentation Manager is much easier with Objectpm and
  28. C++.  Objectpm provides a clear and well organized application
  29. framework that removes the "grunt work" normally associated with
  30. Presentation Manager programming.  Creating and manipulating window
  31. and graphical objects is easy and consistent.
  32.  
  33. Architecture 
  34.  
  35. The Objectpm application framework is not a re-engineered windowing
  36. environment.  It is a true object-oriented representation of the
  37. Presentation Manager.  It is therefore an open and expandable system
  38. that allows direct calls to OS/2 to be made at will.  Through class
  39. methods, Objectpm makes all OS/2 handles and objects available.  This
  40. feature is important because no application framework, no matter how
  41. powerful, can provide all services required by all applications.
  42.  
  43. Window Classes
  44.  
  45. Objectpm provides a full complement of classes to create and manage
  46. windows, frame and dialog windows, controls, icons, menus, and event
  47. handling.  In addition, Objectpm provides additional control windows
  48. such as bitmap and icon buttons, and a listbox that supports column
  49. formatting, character attributes, bitmaps, and a better multi-select
  50. mode.  The "drag & drop" direct manipulation protocol, Workplace
  51. Shell integration, the new CUA-91 controls, and IPF help classes are 
  52. also provided.
  53.  
  54. Graphics Classes
  55.  
  56. The graphics objects include those used for drawing and management of
  57. devices such as windows and printers.  The drawing classes are used
  58. to draw lines, arcs, text, bitmaps, paths, and areas.  Graphics areas
  59. may be scaled, rotated, and translated.  Objectpm supports the
  60. retained drawing mode and transformation capabilities of the
  61. Presentation Manager.  Lastly, a class is provided for each type of
  62. output device including windows, printers, memory, and metafiles. 
  63.  
  64.  
  65. Forms Manager
  66.  
  67. Anyone who has programmed a dialog box in the PM understands just how
  68. low level the PM can be.  The Forms Manager provides the means to do
  69. high level dialog window programming, and build sophisticated data
  70. entry screens.  The Forms Manager changes a dialog window into a
  71. "form" and edit controls and buttons into "fields".  It features
  72. nearly a dozen edit field types as well as a framework for adding new
  73. types.  Other features supported include field and form level
  74. validation, true enter-field / exit-field events, character
  75. filtering, NLS, and a powerful list region class that supports 
  76. management of row-oriented data.  
  77.  
  78. Foundation Classes
  79.  
  80. The Objectpm windowing class library is built on top of a foundation
  81. library called the BaseSet.  This library consists of over 70 general
  82. purpose classes that applications can use for managing threads,
  83. interprocess communications, exception and error condition handling,
  84. and OS/2 files.  In addition, a complete set of multi-threaded
  85. collections are supplied including support for templates.  These
  86. collections use a special locking semaphore that allows
  87. multi-threaded applications to lock a collection for update and allow
  88. multiple threads to iterate over a collection at the same time.  To 
  89. further help multi-threaded applications, a set of guardian classes
  90. have been provided to make it easy to add multi- threaded support
  91. into application classes.  
  92.  
  93. The Objectpm classes for supporting the OS/2 file system include
  94. classes to manage files, directories, long filenames, extended
  95. attributes.
  96.  
  97. The Package 
  98.  
  99. The ObjectPM package contains primarily two dynamic-link libraries
  100. (DLL's), an import library, and a set of header files that define the
  101. objects. All applications created with ObjectPM will require the DLL.
  102. You may distribute this DLL in binary form without royalties of any
  103. kind (provided that you own a license to ObjectPM in the first place).
  104.  
  105. If you purchased a source code license, then a directory will be
  106. installed that contains all files necessary to make the library such
  107. as source files, header files, definition files, and a makefile. In
  108. addition, you will have a copy of the DLL that was compiled will full
  109. debugging enabled so that it is possible to debug code within the
  110. library itself. 
  111.  
  112. The package also contains a set of sample applications used to
  113. demonstrate various features of the library. These programs are
  114. organized under the SAMPLES directory and include: 
  115.  
  116. hello        ObjectPM's version of the famous hello world application. 
  117.              This program however demonstrates the fundamental 
  118.              architecture of ObjectPM programs and the use of many 
  119.              classes. 
  120. cmapdemo     A program that demonstrates multi-keyed sorted collections 
  121.              using the bCMap and tCMap classes. 
  122. controls     Demonstrates the use and notifier of some control windows. 
  123. formdemo     Demonstrates the Forms Manager classes by building data 
  124.              entry windows. 
  125. graph        A simple program that draws a bar graph using various wPen, 
  126.              wTextPen, wFont, and wFillPattern objects. 
  127. listdemo     A program that demonstrates the use of the bDList 
  128.              collection class. 
  129. listea       A program that lists the extended attributes of a file 
  130. mapdemo      A program that demonstrates sorted collections using 
  131.              the bMap and tMap classes. 
  132. mdiEdit      An MDI version of the OS/2 system editor. 
  133. pcalc        A simple programmers calculator. 
  134. puzzle       A game program that demonstrates the picture, printer, 
  135.              and other graphics classes. 
  136. seefont      A program that demonstrates the font and textpen classes. 
  137. semdemo      A simple multi-threaded application that demonstrates 
  138.              how to start and stop new threads, and illustrates 
  139.              the use of the wSemaphore and wSemaphoreList objects. 
  140. setea        A program that sets extended attributes on a file. 
  141. spindemo     Demonstrates the use of spin buttons. 
  142. threads      A demonstration of creating windows in other threads. 
  143.  
  144.  
  145.  
  146. ObjectPM 2.0 
  147.  
  148. Is available in binary form, or bundled with full source code for
  149. Borland C++.  Support for IBM, Zortech, Metaware, and Watcom C++ 
  150. compilers will be available soon.  Programs created with Objectpm can
  151. be distributed along with the dynamic link libraries without
  152. royalties or additional purchases.  
  153.  
  154.  
  155.  
  156.  
  157. OBJECTPM CLASS HIERARCHY
  158. -------------------------
  159.  
  160.  bCondition
  161.  bFacility
  162.  bEventHandler
  163.       └─bConditionHandler
  164.  
  165.  bProfile
  166.  bFileName
  167.  bExtAttr
  168.  bFSFile
  169.       ├─bDirectory
  170.       └─bFile
  171.  
  172.  bRWSemaphore
  173.  bSemaphore
  174.       ├─bMutexSemaphore
  175.       │      └─bNamedMutexSemaphore
  176.       │
  177.       ├─bEventSemaphore
  178.       │      └─bNamedEventSemaphore
  179.       │
  180.       ├─bSemaphoreList [bDList]
  181.       │      └─bNamedSemaphoreList
  182.       │
  183.       ├bGuardian
  184.       ├bEndGuardian
  185.       └bCriticalGuardian
  186.  
  187.  bModule
  188.  bApp
  189.  bCountry
  190.  bMoney
  191.  bUChar
  192.  bUCharPtr
  193.  bString
  194.  bPosition
  195.  bTimeStamp
  196.  bDate
  197.  bTime
  198.  
  199.  bIterator
  200.  bNode
  201.       └─bDNode
  202.  
  203.  bCltn
  204.       ├─bDList
  205.       │      ├─bStack
  206.       │      └─bQueue
  207.       │
  208.       └─wContainerItemCltn
  209.  
  210.  tDList
  211.       ├─bEAList
  212.       ├─bFileList
  213.       ├─bDirList
  214.       ├─wPictureList
  215.       ├─wObjectExchangeList
  216.       ├─wContainerFieldList
  217.       ├─wNoteBookPageList
  218.       ├─wPrinterFormList
  219.       ├─wPrinterList
  220.       ├─wFontDefList
  221.       └─wMdiDocumentList
  222.  
  223.  bRecord
  224.  bType
  225.       ├─bSortedCltn
  226.       │      └─bMap
  227.       │            └─bComplexMap
  228.       │
  229.       ├─bDArray
  230.       │      └─bArgArray
  231.       │
  232.       └─bBitArray
  233.  
  234.  wFixed
  235.  fDataType
  236.       ├─fStringType
  237.       │      ├─fChar
  238.       │      │      └─fBool
  239.       │      └─fString
  240.       │            └─fCharArray
  241.       ├─fDate
  242.       ├─fTime
  243.       ├─fIntegerType
  244.       │      ├─fCharArray
  245.       │      │      └─fUShort
  246.       │      └─fLong
  247.       │             └─fULong
  248.       └─fDecimalType
  249.              ├─fDouble
  250.              └─fMoney
  251.  
  252.  bEventListener
  253.       ├─bThread
  254.       │      └─bMainThread
  255.       │
  256.       └─wWorkplaceObject
  257.              ├─wWindow
  258.              │      ├─wFrameWindow
  259.              │      │      ├─wMdiDesktop
  260.              │      │      └─wMdiDocument
  261.              │      │
  262.              │      ├─wControlWindow
  263.              │      │      ├─wCheckBox
  264.              │      │      ├─wPushButton
  265.              │      │      ├─wRadioButton
  266.              │      │      ├─wStaticControl
  267.              │      │      │      ├─wTextBox
  268.              │      │      │      ├─wGroupBox
  269.              │      │      │      ├─wStaticFrame
  270.              │      │      │      ├─wStaticFrame
  271.              │      │      │      ├─wStaticBitmap
  272.              │      │      │      └─wStaticIcon
  273.              │      │      │
  274.              │      │      ├─wScrollBar
  275.              │      │      ├─wIconWindow
  276.              │      │      ├─wListBox
  277.              │      │      ├─wCellBox
  278.              │      │      ├─wComboBox
  279.              │      │      ├─wContainer
  280.              │      │      ├─wMLEntry
  281.              │      │      ├─wSpinButton
  282.              │      │      ├─wSlider
  283.              │      │      ├─wValueSet
  284.              │      │      ├─wNoteBook
  285.              │      │      └─wEntry
  286.              │      │
  287.              │      └─wPageWindow
  288.              │             └─wDialogWindow
  289.              │                    ├─wFormWindow
  290.              │                    ├─wMdiWinList
  291.              │                    ├─StdErrorDialog
  292.              │                    ├─StdFontDialog
  293.              │                    └─StdFileDialog
  294.              │                           ├─StdFileOpenDialog
  295.              │                           └─StdFileSaveAsDialog
  296.              │
  297.              ├─wContainerItem
  298.              ├─wValueSetItem
  299.              └─wNoteBookPage
  300.  
  301.  wHelpManager
  302.  
  303.  wMessage
  304.       ├─wCommandMsg
  305.       ├─wControlMsg
  306.       │      ├─wContainerEnterMsg
  307.       │      ├─wContainerEmphasisMsg
  308.       │      ├─wContainerItemMsg
  309.       │      ├─wContainerEditMsg
  310.       │      ├─wMLEOverflowMsg
  311.       │      ├─wMLEMarginMsg
  312.       │      ├─wSliderPositionMsg
  313.       │      ├─wVSItemMsg
  314.       │      └─wNBPageMsg
  315.       ├─wSizeMsg
  316.       ├─wTimerMsg
  317.       ├─wCreateMsg
  318.       ├─wInitDlgMsg
  319.       ├─wActivateMsg
  320.       ├─wMenuActionMsg
  321.       ├─wScrollBarMsg
  322.       ├─wKeyStrokeMsg
  323.       ├─wFocusChangeMsg
  324.       ├─wFormActionMsg
  325.       ├─wSemaphoreMsg
  326.       ├─wIPFHelpMsg
  327.       ├─wButtonClickMsg
  328.       ├─wMouseMoveMsg
  329.       ├─wBeginDragMsg
  330.       ├─wFileFilterMsg
  331.       ├─wFileValidateMsg
  332.       ├─wFileErrorMsg
  333.       ├─wFaceNameChangedMsg
  334.       ├─wPointSizeChangedMsg
  335.       ├─wStyleChangedMsg
  336.       ├─wUpdatePreviewMsg
  337.       └─wFontFilterMsg
  338.  
  339.  wDragImage
  340.  wDragInfo
  341.  wRenderRequest
  342.  wObjectExchange
  343.  
  344.  wCoord
  345.       ├─wPointl
  346.       ├─wDimension
  347.       └─wRange
  348.  
  349.  wRectl
  350.  wColor
  351.  wIcon
  352.       └─wPointer
  353.  
  354.  wCursor
  355.  wWindowClass
  356.  
  357.  wMessageBox
  358.  wTrackRectangle
  359.  
  360.  wMenu
  361.       ├─wSysMenu
  362.       └─wPopupMenu
  363.  
  364.  wAccelTable
  365.       └─wSysAccelTable
  366.  
  367.  wField
  368.       ├─wButtonField
  369.       │      ├─wPushButtonField
  370.       │      ├─wCheckBoxField
  371.       │      └─wRadioButtonField
  372.       └─wEditField
  373.              └─wComboField
  374.  
  375.  wListRegion
  376.  wFieldRange
  377.  
  378.  wDevice
  379.       ├─wMemoryDevice
  380.       ├─wWindowDevice
  381.       ├─wMetaFile
  382.       └─wPrinter
  383.              └─wTextPrinter
  384.  
  385.  wPrinterForm
  386.  wPrinterSetup
  387.  wPrinterInfo
  388.  
  389.  wGraphicsTool
  390.       ├─wPicture
  391.       │      ├─wDynamicPicture
  392.       │      └─wSubPicture
  393.       ├─wRegion
  394.       └─wConnectedGraphicsTool
  395.              ├─wFont
  396.              ├─wFillPattern
  397.              ├─wPen
  398.              ├─wTextPen
  399.              └─wBitmap
  400.                     └─wMemoryBitmap
  401.  
  402.  wPresSpace
  403.  
  404.  
  405.  
  406. OBJECTPM APPLICATIONS
  407. --------------------- 
  408.  
  409. The remainder of this document describes many of the objects used to
  410. create an application and how to use them. To do this we will use the
  411. source code from the "Hello" demo program as well as others. The demo
  412. programs are supplied with the package and organized under the
  413. SAMPLES directory. The listing of the two source files for this demo
  414. are also appended to the end of this section. 
  415.  
  416. The Hello application is a very simple application that creates a
  417. standard frame window and displays one of five messages in the client
  418. window. The message can be changed by choosing the "Next" or "Prev"
  419. menu options or by pressing the left or right arrow keys on the
  420. keyboard. The application also contains an "About box" which provides
  421. some basic information about the program in a dialog window, and a
  422. "confirm exit" dialog. 
  423.  
  424. Let's start a the beginning. When an ObjectPM application is started,
  425. control is passed to a function called main contained within the
  426. library. The main function initializes the application by creating an
  427. instance of a class called "bMainThread". Once the object is created,
  428. main calls the virtual method Start of the bMainThread class. All
  429. ObjectPM applications must supply the bMainThread::Start method
  430. because this is where execution of the application starts. Let's look
  431. at the bMainThread::Start method for Hello. 
  432.  
  433. void bMainThread :: Start()     // Program execution starts here
  434. {
  435.     HelloWindow w;      // Construct the top level frame window
  436.     Exec();             // Go to the message loop.
  437. }
  438.  
  439. The first thing this method does is create an instance of the
  440. HelloWindow object. As we will see shortly, this creates the frame
  441. window for the application as well as some other objects that are
  442. associated with the frame window. 
  443.  
  444. Once the objects are created, there is nothing left to do except paint
  445. the "client" window and wait for commands from the user. All
  446. Presentation Manager programs are event driven. For example, it is
  447. common for text-based program to poll the keyboard to see if a key
  448. has been pressed. In Presentation Manager programs, the systems tells
  449. the application that a key is ready by sending it a message. In other
  450. words, a "keystroke" event occurred. 
  451.  
  452. To get messages and process them, Presentation Manager programs must
  453. implement a routine that continually gets and dispatches messages.
  454. This is called the message loop. In ObjectPM, the message loop is
  455. contained in the bThread::Exec method. This method is usually called
  456. from bMainThread::Start and does not return until the application is 
  457. given the command to close. 
  458.  
  459. When Exec returns it is time to close down, and in the Hello
  460. application this is done in a somewhat sneaky way. The instance of
  461. the HelloWindow object was created in the form of an automatic
  462. variable. In other words, it was created on the stack. Upon exit from
  463. Start, the object goes out of scope and must be destroyed. Thus the
  464. object, it's associated window, and the objects it created are
  465. destroyed via the HelloWindow destructor method and the other 
  466. destructors in the wWindow class hierarchy. 
  467.  
  468. Let us now focus on the HelloWindow object. It is defined as a class
  469. in the hello.hpp file as follows: 
  470.  
  471. class HelloWindow : public wFrameWindow
  472. {
  473.   private:
  474.        wMenu *menubar;
  475.        wIcon *icon;
  476.        wAccelTable *acceltab;
  477.        short msg;
  478.  
  479.        long MenuCommand(wCommandMsg);
  480.        long Close(wMessage);
  481.        void Paint();
  482.  
  483.   public:
  484.        HelloWindow();
  485.        ~HelloWindow();
  486. };
  487.  
  488. The HelloWindow object is derived from the "wFrameWindow" object
  489. contained in the ObjectPM library. wFrameWindow in turn is derived
  490. from the "wWindow" class. These classes, along with the other classes
  491. derived from wWindow, form the window class hierarchy. All ObjectPM
  492. applications that create window objects must do so by deriving a
  493. class from one of the ObjectPM window classes, such as wFrameWindow,
  494. and then creating an object that is an instance of that class. 
  495.  
  496. Inside the HelloWindow class definition, four data members are
  497. declared. The menubar, icon, and acceltab members will hold pointers
  498. to dynamically created wMenu, wIcon, and wAccelTable objects. These
  499. objects are created in the constructor of HelloWindow and are created
  500. dynamically because they must exist for the duration of the
  501. application. The msg member represents which message will be
  502. displayed by the Paint method. 
  503.  
  504. The three methods: MenuCommand, Close, and Paint are special methods
  505. called "message handlers". These methods are called from the ObjectPM
  506. library when the appropriate event occurs (such as a selecting an item
  507. from the menu). They are virtual, overloaded functions that are
  508. initially defined in "wWindow" class which is the base class of the 
  509. wWindow class hierarchy. There are many of these special methods
  510. including: 
  511.  
  512. Create                 TimeOut 
  513. Destroy                ButtonClick 
  514. InitDlg                Activate 
  515. Paint                  Close 
  516. MenuCommand            MenuAction 
  517. PushButtonCommand      MouseMove 
  518. Control                wScrollBar 
  519. Size                   SaveApplication 
  520. Move                   KeyStroke 
  521. FocusChange            Semaphore 
  522. FormAction          
  523.  
  524. Each of these methods represents an event or message generated by the
  525. Presentation Manager.    If you need to process a message that is
  526. not included in one of the standard ObjectPM event methods, you can
  527. install a message handler method, using the AddMessageHandler method
  528. of wWindow, that would be called any time the desired message was
  529. sent or posted to the window. 
  530.  
  531. To put things in simpler terms, defining objects derived from a class
  532. in the wWindow hierarchy such as wFrameWindow, involves three things:
  533.  
  534.  1.  Define the data that is private to the new class 
  535.  2.  Choose which message handler methods your window will process by 
  536.      including them in the class definition. ObjectPM will take the 
  537.      default action for all methods that are not included. For 
  538.      example, if the window has a menu bar, then it will be necessary 
  539.      to include the MenuCommand method. 
  540.  3.  Define public methods that can be called from elsewhere in the 
  541.      application that manipulate the window in some way that is 
  542.      specific to the new class. In many cases, this step is not necessary. 
  543.  
  544. The remainder of the class definition specifies a public constructor 
  545. and destructor for creating and destroying HelloWindow objects. The 
  546. following code is for the constructor: 
  547.  
  548. HelloWindow :: HelloWindow()
  549. {
  550.     CreateWindow(OpmStdFrame);
  551.     SetCaption("Hello World");
  552.     SetSwitchTitle("Hello World Demo Program");
  553.     SetIcon(icon = new wIcon(ResIcon, I_OBJPM));
  554.     msg = 0;
  555.  
  556.     menubar = new wMenu(this, MB_MESSAGE, "Message\\");
  557.     menubar->SetSubMenuItems(MB_MESSAGE, MI_NEXT, "Next\t\x1a;Previous\t\x1b");
  558.  
  559.     wSysMenu sm(this);
  560.     sm.AppendSeparator();
  561.     sm.AppendItem(SC_ABOUT, "~About...");
  562.  
  563.     acceltab = new wAccelTable(this);
  564.     acceltab->Set(VkRight, MI_NEXT, AsVirtualKey);
  565.     acceltab->Set(VkLeft,  MI_PREV, AsVirtualKey);
  566.  
  567.     Show();
  568. }
  569.  
  570. The code fragment: 
  571.  
  572.     CreateWindow(OpmStdFrame);
  573.  
  574. actually creates the window. For a number of reasons, the physical
  575. windows are not created when the objects are created in the wWindow
  576. hierarchy. The application must use the CreateWindow method to do
  577. this. The OpmStdFrame identifier is a define that sets a number of
  578. frame creation flags that specify the frame controls and options: 
  579.  
  580. Option                 Meaning 
  581. FaShellPosition        Allows the PM to choose the size and position 
  582. FaTaskList             Creates a Task Manager entry 
  583. FaSysMenu              Creates a system menu 
  584. FaSizeBorder           Creates a sizing border 
  585. FaTitleBar             Creates a titlebar 
  586. FaMinMax               Creates minimize and maximize    buttons buttons 
  587.  
  588. The next two lines: 
  589.  
  590.     SetCaption("Hello World");
  591.     SetSwitchTitle("Hello World Demo Program");
  592.  
  593. Set the text that appears both in the titlebar of the frame window and
  594. in the Task Manager's switch list. 
  595.  
  596.     SetIcon(icon = new wIcon(ResIcon, I_OBJPM));
  597.  
  598. This statement dynamically creates an wIcon object from an icon
  599. defined in the resource file and sets that icon to be shown when the
  600. frame window is minimized. 
  601.  
  602. Note that the methods CreateWindow, SetCaption, SetSwitchTitle, and
  603. SetIcon are members of the wFrameWindow class and thus are inherited
  604. by our HelloWindow class. 
  605.  
  606. The code: 
  607.  
  608.     menubar = new wMenu(this, MB_MESSAGE, "Message\\");
  609.     menubar->SetSubMenuItems(MB_MESSAGE, MI_NEXT,
  610.     "Next\t\x1a;Previous\t\x1b");
  611.  
  612. creates the menu bar for the frame window. It defines one submenu with
  613. the name "wMessage". The next line defines the actual menu items in
  614. the wMessage submenu. 
  615.  
  616. Menus in ObjectPM may be defined such as this or constructed from a
  617. menu definition in a resource file. In the notation above, submenus
  618. end with a backslash (\\), menu items end with a semicolon (;),
  619. separator are indicated with a minus sign(-), and the menu items are
  620. separated from the accelerator key text with a tab character (\t).
  621. This scheme allows menus to be easily created and modified. 
  622.  
  623. The MB_MESSAGE and MI_NEXT identifiers are defines that set the id's
  624. of the submenu and menu items. When a menu item is selected, the id
  625. of the menu item will be used to determine which item was selected. 
  626.  
  627. As illustrated above, the Hello application contains a system menu.
  628. Most frame windows do. Often times it is desired to modify the
  629. contents of this menu by adding new items or deleting items. The code
  630. fragment: 
  631.  
  632.     wSysMenu sm(this);
  633.     sm.AppendSeparator();
  634.     sm.AppendItem(SC_ABOUT, "~About...");
  635.  
  636. creates a temporary wSysMenu object that allows the application to
  637. work with the system menu. Note that creating a wSysMenu object does
  638. not actually create the menu. It simply registers the object with the
  639. system menu of "this" frame window, and allows the application to use
  640. the methods in the wMenu class to work with it. Once the needed items
  641. are appended to the menu, the application does not need this object
  642. anymore. 
  643.  
  644. The last object to be created is the wAccelTable object. Creating an
  645. wAccelTable object in turn causes an accelerator table to be created
  646. for the frame window. Accelerators are a neat little trick implemented
  647. by the Presentation Manager, that allow key strokes to be linked to a
  648. menu item. In the Hello application, pressing the right arrow key
  649. causes the "Next" menu item to be selected, and pressing the left
  650. arrow key causes the "Previous" menu item to selected. The code to
  651. create our accelerator table is: 
  652.  
  653.     acceltab = new wAccelTable(this);
  654.     acceltab->Set(VkRight, MI_NEXT, AsVirtualKey);
  655.     acceltab->Set(VkLeft, MI_PREV, AsVirtualKey);
  656.  
  657. And finally: 
  658.  
  659.     Show();
  660.  
  661. causes the frame window to become visible. 
  662.  
  663. When a frame window is created, the frame window will in turn create a
  664. number of "child" windows such as the titlebar, the min/max buttons,
  665. etc. The frame window manages these windows automatically and takes
  666. care of drawing them. The frame window also creates a window called
  667. the "client" window. Your application will appear in this window, and
  668. thus the application is responsible for painting it. The Show method
  669. shown above will cause the frame to draw itself, and then post a
  670. "Paint" message to the client window. When the paint message arrives,
  671. the Paint method of the HelloWindow object will be called. It's code
  672. is as follows: 
  673.  
  674. void HelloWindow :: Paint()
  675. {
  676.   static char *msgtext[LAST_MSG+1] = {
  677.        "Hello World",
  678.        "Welcome to OS/2 Object Oriented Programming",
  679.        "Introducing ObjectPM",
  680.        "A C++ Class Library and Application Framework",
  681.        "Have a Good Day!!!"
  682.   };
  683.   WindowPS()->Erase();
  684.   wTextPen t(WindowPS());
  685.   t.SetColor(ClrBlue);
  686.   wFont f(TmsRmn14, UnderscoreFont, WindowPS());
  687.   t.Display(WindowRectangle(), DfCenter+DfVCenter,
  688.             msgtext[msg]);
  689. }
  690.  
  691. Before we get into this code, a few concepts need explaining. Within
  692. the Presentation Manager (and ObjectPM) there exists an object called
  693. a presentation space. This object is a virtual graphics medium that is
  694. drawn on, and provides independence from the output device connected
  695. to it. Applications do not draw on windows! They draw on presentation
  696. spaces. A window is an output device. This mechanism allows a picture
  697. drawn in a window to be drawn on a laser printer by simply connecting
  698. a different output device to the presentation space. 
  699.  
  700. Presentation spaces are created in one of two ways. First, the
  701. application can create one by creating an instance of a wPresSpace
  702. object. Applications that need to draw in units other than pels, or
  703. that need advanced graphics capabilities should do this. 
  704.  
  705. The other way of creating a presentation space, is to let ObjectPM do
  706. it. If the Paint method is to be called, and no presentation space
  707. has been created by the application for the window, the ObjectPM
  708. library will create one just prior to calling the Paint method. A
  709. pointer to the wPresSpace object is returned from the
  710. wWindow::WindowPS method. Thus the statement: 
  711.  
  712.     WindowPS()->Erase();
  713.  
  714. erases the visible portion of the presentation space and thus erases
  715. the client window. Understanding this concept is key to doing any
  716. drawing in the Presentation Manager no matter what platform you
  717. choose. 
  718.  
  719. The next fragment of code: 
  720.  
  721.     wTextPen t(WindowPS());
  722.  
  723. creates a wTextPen object used for drawing text, and connects the pen
  724. to the wPresSpace object. There are five primary objects within
  725. ObjectPM that are used for drawing. These are: 
  726.  
  727. wPen         Draws lines, arcs, polygons, paths, and areas. 
  728. wTextPen     Draws and formats text. 
  729. wFillPattern Defines patterns and colors used to fill objects drawn 
  730.              with a pen, or rectangles. 
  731. wBitmap      Used to draw, size, and move bit images. 
  732. wFont        Defines a font to be used with a wTextPen or wFillPattern. 
  733.  
  734. The code: 
  735.  
  736.     wFont f(TmsRmn14, UnderscoreFont, WindowPS());
  737.  
  738. creates a wFont object representing a 14pt-underlined Times Roman 
  739. wFont, and sets it as the current font. 
  740.  
  741. The last line of code in the Paint method finally draws the text using the blue wTextPen and the Times-Roman font: 
  742.  
  743.     t.Display(WindowRectangle(), DfCenter+DfVCenter,
  744.     msgtext[msg]);
  745.  
  746. This statement first calls the wWindow::WindowRectange method which
  747. returns a wRectl object representing the position and size of the
  748. client window. The wTextPen::Display method is then called which
  749. displays the appropriate text horizontally and vertically centered in
  750. the rectangle. 
  751.  
  752. Upon exit from the Paint method, both the wTextPen and the wFont will
  753. be destroyed. 
  754.  
  755. At this point, both the frame and client window's are drawn. The
  756. application has nothing left to do except wait for a menu command.
  757. Because of the accelerator keys, a menu command can be generated by a
  758. choosing a menu item, or pressing the left or right arrow keys. Let's
  759. say for example the "Next" menu item was chosen. When this occurs, the
  760. ObjectPM library will call the MenuCommand method and pass it a
  761. wCommandMsg object. Here is the code for the MenuCommand method: 
  762.  
  763. long HelloWindow :: MenuCommand(wCommandMsg m)
  764. {
  765.   switch(m.usCmd())
  766.   {
  767.        case MI_NEXT:
  768.             msg = msg == LAST_MSG? 0: msg + 1;
  769.             break;
  770.  
  771.        case MI_PREV:
  772.             msg = msg == 0? LAST_MSG: msg - 1;
  773.             break;
  774.  
  775.        case SC_ABOUT:
  776.             {
  777.                  AboutDialog aboutWin(this);
  778.                  return FALSE;
  779.             }
  780.   }
  781.   RePaint();
  782.   return FALSE;
  783. }
  784.  
  785. The operation of this method is very simple. The usCmd method of the
  786. wCommandMsg object returns the id of the selected menu item. If the
  787. menu item was MI_NEXT or MI_PREV, then the msg member will be adjusted
  788. accordingly and the RePaint method of the wWindow class will be
  789. called to invalidate the window. This will cause the ObjectPM library
  790. to call the Paint method at a later time. 
  791.  
  792. If the "About..." menu item is selected from the system menu, the
  793. MenuCommand method will be called with the id set to SC_ABOUT. In
  794. this case, an instance of the AboutDialog class is created. This class
  795. implements a simple dialog window that displays some basic
  796. information about the Hello application. To create a dialog window,
  797. you must first draw it in the dialog box editor. The definition of
  798. the dialog window must then be compiled into the program as a 
  799. resource using the resource compiler. Within the code, a class must be
  800. defined which is derived from the wDialogWindow class. The definition
  801. of the AboutDialog class looks like this: 
  802.  
  803. class AboutDialog : public wDialogWindow
  804. {
  805.   private:
  806.        long InitDlg(wInitDlgMsg)
  807.                    { ChangePosition(PosCenter, OwnerWindow());
  808.                      return FALSE; }
  809.        long PushButtonCommand(wCommandMsg)
  810.                    { Dismiss(); return FALSE; }
  811.   public:
  812.        AboutDialog(wWindow *owner) : (D_ABOUT)
  813.                    { CreateWindow(owner); }
  814. };
  815.  
  816. Notice that the code is in-lined along with the definition of the
  817. class methods. In fact, all the processing for the dialog window is
  818. contained within this class definition. The AboutDialog method is the
  819. constructor for the class. It passes the resource id of the dialog
  820. window to the wDialogWindow constructor, and then calls the
  821. wDialogWindow::CreateWindow method to create the actual window. 
  822.  
  823. The InitDlg and PushButtonCommand methods are both message handlers.
  824. The ObjectPM library calls the InitDlg method after all the dialog
  825. controls are created and before the window is actually shown. The
  826. AboutDialog class uses the InitDlg method to implements the code
  827. needed to center the dialog window inside the main window. 
  828.  
  829. Whenever a push button is clicked in a dialog window, the
  830. PushButtonCommand method is called. Like the MenuCommandmethod, a
  831. wCommandMsg object is passed that indicates which button was clicked.
  832. Since the about dialog window contains only one push button, it's not
  833. hard to figure it out. The code for this method simply dismisses 
  834. (destroys) the dialog window. 
  835.  
  836.  
  837. Source Files: 
  838.  
  839.  
  840. /***************
  841.  * hello.hpp *
  842.  ***************/
  843.  
  844. #include "hello.h"
  845. #include "about.h"
  846.  
  847. // The app level frame window class
  848.  
  849. class HelloWindow : public wFrameWindow
  850. {
  851.     private:
  852.         wMenu *menubar;
  853.         wIcon *icon;
  854.         wAccelTable *acceltab;
  855.         short msg;
  856.  
  857.     public:
  858.         HelloWindow();
  859.         ~HelloWindow();
  860.         long MenuCommand(wCommandMsg);
  861.         long Close(wMessage);
  862.         void Paint();
  863. };
  864.  
  865.  
  866. // The about dialog box class.  Note that this all the code!
  867.   
  868. class AboutDialog : public wDialogWindow
  869. {
  870.     public:
  871.         AboutDialog(wWindow *owner) : (D_ABOUT) { CreateWindow(owner); }
  872.         long InitDlg(wInitDlgMsg) { ChangePosition(PosCenter, OwnerWindow()); return FALSE; }
  873.         long PushButtonCommand(wCommandMsg) { Dismiss(); return FALSE; }
  874. };
  875.  
  876. /***************
  877.  * hello.cxx *
  878.  ***************/
  879.  
  880. #define InclGraphics
  881. #include <ObjectPM.hpp>
  882. #include "hello.hpp"
  883.  
  884. void App :: Start()     // Program execution starts here
  885. {
  886.     HelloWindow w;   // Construct the top level frame window
  887.     Exec();             // Go to the message loop.
  888. }
  889.  
  890. HelloWindow :: HelloWindow()
  891. {
  892.     CreateWindow(OpmStdFrame);                   // Create the frame
  893.     SetCaption("Hello World");                   // Set captions
  894.     SetSwitchTitle("Hello World Demo Program");
  895.     SetIcon(icon = new wIcon(ResIcon, I_OBJPM)); // Set the app's icon
  896.     msg = 0;
  897.  
  898.     // This section create a menu bar and then adds items to the
  899.     // sub menu itself. It is also possible to construct the menu
  900.     // from the resource file if desired
  901.  
  902.     menubar = new wMenu(this, MB_MESSAGE, "~Message\\");
  903.     menubar->SetSubMenuItems(MB_MESSAGE, MI_NEXT, "Next\t\x1a;Previous\t\x1b");
  904.  
  905.     // Create a temporary system menu object for the purposes of adding
  906.     // a separator and the "About..." menu item.
  907.  
  908.     wSysMenu sm(this);
  909.     sm.AppendSeparator();
  910.     sm.AppendItem(SC_ABOUT, "~About...");
  911.  
  912.     // Finally, create an accelerator table to bind the left and right
  913.     // arrow keys to the "Next" and "Prev" menu options. Like the menu's,
  914.     // it is also possible to load an accelerator table from the resource
  915.     // file
  916.  
  917.     acceltab = new wAccelTable(this);
  918.     acceltab->Set(VkRight, MI_NEXT, AsVirtualKey);
  919.     acceltab->Set(VkLeft, MI_PREV, AsVirtualKey);
  920.  
  921.     Show();              // Make the frame visible
  922. }
  923.  
  924. HelloWindow :: ~HelloWindow()
  925. {
  926.     delete acceltab;     // destroy the allocated frame objects
  927.     delete menubar;
  928.     delete icon;
  929. }
  930.  
  931. // The MenuCommand member is sent a Command message each time
  932. // an item on the menu bar is selected.
  933.  
  934. long HelloWindow :: MenuCommand(wCommandMsg m)
  935. {
  936.     switch(m.usCmd())
  937.     {
  938.         case MI_NEXT:
  939.             msg = msg == LAST_MSG? 0: msg + 1;
  940.             break;
  941.  
  942.         case MI_PREV:
  943.             msg = msg == 0? LAST_MSG: msg - 1;
  944.             break;
  945.  
  946.         case SC_ABOUT:
  947.             {
  948.                 AboutDialog aboutWin(this);      // Create the "about" box
  949.                 return FALSE;
  950.             }
  951.     }
  952.     RePaint();      // invalidate the client window
  953.     return FALSE;
  954. }
  955.  
  956. // The Paint member is responsible for painting the invalid
  957. // area of the client window. This program, like many programs that
  958. // do simple drawing, let the object library create a wPresSpace
  959. // object on which to draw on. The wPresSpace object is accessed
  960. // through the member function WindowPS() of the wWindow class.
  961.  
  962. void HelloWindow :: Paint()
  963. {
  964.     static char *msgtext[LAST_MSG+1] = {
  965.         "Hello World",
  966.         "Welcome to OS/2 Object Oriented Programming",
  967.         "Introducing ObjectPM",
  968.         "A C++ Class Library and Application Framework",
  969.         "Have a Good Day!!!"
  970.     };
  971.  
  972.     WindowPS()->Erase();         // Erase the client window
  973.     wTextPen t(WindowPS());      // Create a new wTextPen object
  974.     t.SetColor(ClrBlue);
  975.     wFont f(TmsRmn14, UnderscoreFont, WindowPS());
  976.     t.Display(WindowRectangle(), DfCenter+DfVCenter, msgtext[msg]);
  977. }
  978.  
  979. // The Close member is called when the "Close" menu option is chosen
  980. // from the system menu. Returning TRUE from this function allows the
  981. // exit process to continue. Otherwise, a return of FALSE will prevent
  982. // the application from being closed
  983.  
  984. long HelloWindow :: Close(wMessage)
  985. {
  986.     // create a message box to confirm exit from the application
  987.     wMessageBox m(this, " Are You Sure?", "Exit", MbYesNo + MbIconQuestion);
  988.     return m.MessBoxVal() == MbidYes;
  989. }
  990.  
  991.  
  992. MORE INFORMATION
  993. ----------------
  994.  
  995. If you want to see more examples (along with working code),  you can
  996. download the complete sample program set from our BBS.  On the BBS,
  997. you need to jump to the FILES/SAMPLES area, and download the
  998. SAMPLES.BAR, DLL.BAR, and BAR.EXE files.  The BSS can be reached at
  999. (216) 831-4805 using a 300-14KBaud modem with line settings of 8 bit,
  1000. no parity, and one stop bit.  You can also leave a message on the BBS
  1001. if you have questions.
  1002.  
  1003. For ordering information: contact The Connection @ 1-800-336-1166
  1004.  
  1005. Thanks for your interest!
  1006.  
  1007. RSI/JP
  1008.