home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dho.zip / DHO / TUTORIAL / TUTORIAL.TXT < prev   
Text File  |  1995-09-03  |  23KB  |  785 lines

  1.  
  2.    Developer Helper Tutorial
  3.    -------------------------
  4.  
  5.    This tutorial demonstrates the basic operations required to 
  6. begin to develop an application with the Developer Helper
  7. Application Framework.  While it is not a primer on OS/2 
  8. Presentation Manager programming, those who are familliar
  9. with C++, and with object oriented techniques should be 
  10. able to understand this tutorial, and possibly glean some
  11. OS/2 programming techniques.
  12.  
  13.  
  14. ====================================================================
  15. Part 1: Creating a skeleton Application.
  16.  
  17.    It's pretty simple to create the base for you application.  The
  18. following code will create an application, along with a main window.
  19. --------------------------------------------------------------------
  20.  
  21. // example1.cc
  22. #include<applicat.h>
  23.  
  24.  
  25. #define kAppId 100
  26.  
  27.  
  28. //=========================================
  29. //  program entry point
  30. INT main(void)
  31. {
  32.    TApplication app(kAppId);
  33.  
  34.    app.init();     // initialize object
  35.    app.run();      // begin event loop          
  36.  
  37.    return 0;
  38. }
  39.  
  40.  
  41. --------------------------------------------------------------------
  42.  
  43.    The main event loop creates an application object, which 
  44. in turn initializes itself and creates a main window in the
  45. member function init.  The event loop is then executed, and 
  46. proceeds untill the application is terminated.  Notice the
  47. parameter sent to the application obkect's constructor -- 
  48. it will be the resource id for all major resources in future
  49. examples.
  50.  
  51. Note -- most objects in Developer Helper  have an initialization
  52. function along with a constructor.  The constructor will set up the
  53. object to a safe state, but the initializer will perform the actual
  54. memory allocations, etc.  The init function members all return 
  55. BOOL values -- TRUE upon object creation success, and FALSE upon failure.
  56.  
  57.  
  58. ====================================================================
  59. Part 2:  Redefining the type of Main Window
  60.  
  61.    Once the skeleton application is created, the next major step is to 
  62. customize the kind of main window the application creates.  The function
  63. TApplication::CreateMainWindow is called during application initialization
  64. and it is here where one can change the type of the window which is to be
  65. the application's main window.
  66.  
  67. --------------------------------------------------------------------
  68.  
  69. // example2.cc
  70. //   This example demonstrates how to customize
  71. //   an application object, specifically how to modify
  72. //   the type of main window for the application
  73.  
  74.  
  75. //DHO application object header file
  76. #include<applicat.h>
  77. #include<framewin.h>
  78.  
  79. #define kAppId 100
  80.  
  81.  
  82. class TExampleApp : public TApplication
  83. {
  84.    public:
  85.       TExampleApp(ULONG res):TApplication(res){;};
  86.       virtual void CreateMainWindow()
  87.       {
  88.          MainWin=new TFrameWindow(fResource, "DHO Tutorial App");
  89.       }
  90. };
  91.  
  92.  
  93.  
  94. //=========================================
  95. //  program entry point
  96. INT main(void)
  97. {
  98.    TExampleApp app(kAppId);
  99.  
  100.    app.init();     // initialize object
  101.    app.run();      // begin event loop          
  102.  
  103.    return 0;
  104. }
  105.  
  106. --------------------------------------------------------------------
  107.  
  108.    The only difference in this example from the default inirialization
  109. is in the name of the main window.  However, in the next example we will
  110. redefine the main window's default behavior, further customizing the 
  111. application
  112.  
  113.  
  114. ====================================================================
  115. Part 3: Redefining Window Behavior
  116.  
  117.    By automating the window registration procedures required by
  118. the OS/2 Presentation Manager, the Developer Helper framework
  119. makes it easy to define window behaviors.  The following example
  120. demonstrates some simple customization by having the main window
  121. include a frame window icon in the system menu.
  122.  
  123. --------------------------------------------------------------------
  124.  
  125.  
  126. class TExampleFrameWin : public TFrameWindow
  127. {
  128.  
  129.    public:
  130.       TExampleFrameWin(ULONG id, char *title):TFrameWindow(id, title)
  131.       {   fShellPos = TRUE;};
  132.       virtual BOOL init()
  133.       {
  134.          if (TFrameWindow::init())
  135.          {   // add a frame icon
  136.             this->setIcon(WinQuerySysPointer(HWND_DESKTOP, 
  137.                     SPTR_ICONINFORMATION, FALSE));
  138.             return TRUE;
  139.          }
  140.          return FALSE;
  141.       }
  142. };
  143.  
  144.  
  145.  
  146. class TExampleApp : public TApplication
  147. {
  148.    public:
  149.       TExampleApp(ULONG res):TApplication(res){;};
  150.       virtual void CreateMainWindow()
  151.       {
  152.          MainWin=new TExampleFrameWin(fResource, "DHO Tutorial App");
  153.       }
  154. };
  155.  
  156. --------------------------------------------------------------------
  157.  
  158.    The sample application now has a main window which is starting to
  159. define it's own appearance and behaviors.
  160.  
  161.  
  162. ====================================================================
  163. Part4:  Adding a client window to a frame window
  164.  
  165.    In the Developer Helper Application framework, the class function
  166. members for windows which begin with the word do are called in response
  167. to a message from the OS/2 Presentation Manager.  For example, the doSize
  168. function of the class TWindow will be called as a direct result of the
  169. window receiving a WM_SIZE message from PM.  It is easy to define 
  170. window behavior in response to these operating system messages.  In the
  171. next example, we add a client window to our main window which defines
  172. behavior in response to the WM_SIZE and WM_PAINT messages.
  173.  
  174.  
  175. --------------------------------------------------------------------
  176.  
  177.  
  178.  
  179. class TExampleClientWin : public TWindow
  180. {
  181.       SHORT sPageX, sPageY;
  182.    public:
  183.       TExampleClientWin(ULONG id, TWinBase *parent):TWindow(id, parent){;};
  184.       virtual void doSize(WinMsg wm)
  185.       {
  186.          sPageX = SHORT1FROMMP(wm.mp2);
  187.          sPageY = SHORT2FROMMP(wm.mp2);
  188.       }
  189.       virtual void paintWindow(HPS ps, RECTL rcl)
  190.       {
  191.          POINTL ptl;
  192.          SHORT w;
  193.  
  194.          if ((sPageX == 0) && (sPageY == 0))         
  195.          {
  196.             sPageX = rcl.xRight - rcl.xLeft;
  197.             sPageY = rcl.yTop - rcl.yBottom; 
  198.          }
  199.  
  200.          if (sPageX > sPageY)
  201.             w = sPageY / 2;
  202.          else
  203.             w = sPageX / 2;         
  204.  
  205.          WinFillRect(ps, &rcl, CLR_BLUE);
  206.  
  207.          rcl.xLeft = (sPageX/2) -(w/2);
  208.          rcl.xRight = rcl.xLeft +w;
  209.          rcl.yBottom = (sPageY /2) -(w/2);
  210.          rcl.yTop = rcl.yBottom+w;
  211.  
  212.          WinFillRect(ps, &rcl, CLR_YELLOW);
  213.          
  214.       }
  215. };
  216.  
  217.  
  218.  
  219.  
  220. class TExampleFrameWin : public TFrameWindow
  221. {
  222.  
  223.    public:
  224.       TExampleFrameWin(ULONG id, char *title):TFrameWindow(id, title)
  225.       {   fShellPos = TRUE;};
  226.       virtual BOOL init()
  227.       {
  228.          if (TFrameWindow::init())
  229.          {   // add a frame icon
  230.             this->setIcon(WinQuerySysPointer(HWND_DESKTOP, 
  231.                     SPTR_ICONINFORMATION, FALSE));
  232.  
  233.             TExampleClientWin *client = new
  234.                 TExampleClientWin(FID_CLIENT, this);
  235.             return client->init();
  236.          }
  237.          return FALSE;
  238.       }
  239. };
  240.  
  241.  
  242.  
  243. --------------------------------------------------------------------
  244.  
  245.    The example program now has a more complex, as well as a more
  246. colorful main window.  One minor note to mention here -- the
  247. function TWindow::paintWindow is called by the function 
  248. TWindow::doPaint.  This is becase of some preliminary behavior 
  249. that the class TWindow performs to alleviate some tediousness
  250. of drawing in windows.  For those who are more interested, 
  251. examine the source code for the function TWindow::doPaint 
  252. in the DHO source code file window.cc
  253.  
  254.  
  255. ====================================================================
  256. Part 5:  Adding a menu to the frame window
  257.  
  258.    
  259.    The TFrameWindow class has an attribute structure which is
  260. used in the init member to set various features of the window.
  261. Various fields of this structure can be modified at any point
  262. from the object's creation untill the initialization of the
  263. OS/2 window in the init call, and these changes will manifest
  264. themselves in the appearance and behavior of the window.
  265.  
  266.    For example, by setting the field menu of the fFrAttr member
  267. of the class TFrameWindow, the init function will attempt to 
  268. load and bind a menu resource to the menu.  In this example,
  269. our sample application will load a memu resource which is defined
  270. in the file example5.rc
  271.  
  272.  
  273. --------------------------------------------------------------------
  274.  
  275. // example5.cc
  276.  
  277. class TExampleFrameWin : public TFrameWindow
  278. {
  279.  
  280.    public:
  281.       TExampleFrameWin(ULONG id, char *title):TFrameWindow(id, title)
  282.       {   
  283.          fShellPos = TRUE;
  284.          fFrAttr.menu = TRUE;
  285.       };
  286.  
  287. };
  288.  
  289.  
  290.  
  291. /* example5.rc */
  292. #include<os2.h>
  293.  
  294. MENU 100
  295. BEGIN
  296.    SUBMENU "~File", 101
  297.       BEGIN
  298.          MENUITEM "Change Colors", 102
  299.          MENUITEM "", 5, MIS_SEPARATOR         
  300.          MENUITEM  "E~xit", 103
  301.       END
  302.    SUBMENU "~Help", 201
  303.       BEGIN
  304.          MENUITEM "Product Information", 104
  305.       END
  306. END
  307.  
  308.  
  309. --------------------------------------------------------------------
  310.  
  311.    Other behaviors which can be modified in this way are:
  312.  
  313.    TFrameWindowAttr field                 Behavior
  314.    -----------------------             ---------------
  315.    BOOL titlebar            TRUE  -- has titlebar *
  316.                                         FALSE -- no titlebar
  317.  
  318.    BOOL sysmenu                         TRUE  -- has system menu *
  319.                                         FALSE -- no system menu
  320.  
  321.    BOOL menu                            TRUE  -- Load menu
  322.                                         FALSE -- do not load menu *
  323.  
  324.    BOOL icon                            TRUE  -- Load icon
  325.                                         FLASE -- Do not load icon *
  326.  
  327.    BOOL minbutton                       TRUE  -- has min button *
  328.                                         FALSE -- no min button
  329.  
  330.    BOOL maxbutton                       TRUE  -- has max button *
  331.                                         FLASE -- no max button
  332.  
  333.    BOOL sizeborder                      TRUE  -- has a size border *
  334.                                         FALSE -- no size border
  335.  
  336.    BOOL tasklist                        TRUE  -- included in task list 
  337.                                         FLASE -- not included in task list *
  338.  
  339.    BOOL vscroll                         TRUE  -- include vertical scroll 
  340.                                         FALSE -- no vertical scroll bar *
  341.  
  342.    BOOL hscroll                         TRUE  -- include horizontal scroll 
  343.                                         FALSE -- no horizontal scroll bar *
  344.  
  345.    BOOL acceltable                      TRUE  -- load accelerator table
  346.                                         FALSE -- no accelerator table  *
  347.  
  348.    BOOL shellPos                        TRUE  -- shell positions window *
  349.                                         FALSE -- window positions self
  350.  
  351.    ULONG x                              initial x axis position
  352.                                         DEFAULT -- 0
  353.  
  354.    ULONG y                              initial y axis position
  355.                                         DEFAULT -- 0
  356.  
  357.    ULONG width                          initial width
  358.                                         DEFAULT -- 0
  359.  
  360.    ULONG height                         initial height
  361.                                         DEFAULT -- 0
  362.  
  363.         * denotes the default for the class TFrameWindow
  364.  
  365.  
  366.  
  367. ====================================================================
  368. Part 6: Responding to Command Events
  369.  
  370.    In the OS/2 presentation managers, messages from various controls
  371. (such as menus and push buttons) are sent to a window in the form 
  372. of a WM_COMMAND message.  In Developer Helper, the doCommand function
  373. is called in reponse to a WM_COMMAND message, and it is here where most
  374. of the functionality of an application is fleshed out.
  375.  
  376.    In this next example, we will override TExampleFrameWin's member
  377. doCommand to provide functionality for each of the selections in
  378. the frame window's menu.
  379.  
  380.  
  381. --------------------------------------------------------------------
  382. // example6.cc
  383.  
  384.  
  385. class TExampleFrameWin : public TFrameWindow
  386. {
  387.  // various members
  388.  
  389.    virtual void doCommand(WinMsg wm)
  390.    {
  391.       SHORT command = SHORT1FROMMP(wm.mp1);
  392.       if (command == 103)
  393.       {
  394.          WinPostMsg(wm.hwnd, WM_QUIT, 0,0);
  395.       }
  396.       else if (command == 104)
  397.       {
  398.          WinMessageBox(HWND_DESKTOP, hwnd, (PSZ)aboutText, 
  399.                 (PSZ)"Product Information", 0, MB_MOVEABLE | MB_OK 
  400.                 | MB_ICONEXCLAMATION);
  401.       }
  402.    }
  403.  
  404.  // more various members
  405. };
  406.  
  407.  
  408. --------------------------------------------------------------------
  409.  
  410.  
  411.    The macro SHORT1FROMMP is called a 'cracker' macro, and is 
  412. supplied in os2.h.  In this case, it is used to extract the 
  413. command id from the message structure.  
  414.  
  415.  
  416.  
  417. ====================================================================
  418. Part 7:  introduction To Dialogs
  419.  
  420.  
  421.    There are two types of dialog boxes in the OS/2 Presentation
  422. Manager -- Modal Dialogs and Non-Modal Dialogs.  Modal dialogs
  423. seize the applications focus, and retain it untill they are
  424. dismissed.   Non-modal dialogs can gain and loose the applications
  425. focus much like normal windows do.  
  426.  
  427.    In this example, we will be addding a modal dialog to our
  428. example program.  The DHO class which handles the modal dialog
  429. is called TNonModalDialog, and is created and initialized much
  430. like a normal window.  However, a dialog will not be displayed
  431. until the member function TModalDialof::Execute is called.  
  432.  
  433.  
  434. --------------------------------------------------------------------
  435. // example7.cc
  436.  
  437.  
  438. class TColorSelectDlog : public TModalDialog
  439. {
  440.       TValueSet *fBkgndColors, *fShapeColors;
  441.    public:
  442.       TColorSelectDlog(ULONG resource, TWinBase *owner, void *buffer):
  443.          TModalDialog(resource, owner, buffer){;};
  444.       virtual BOOL init()
  445.       {
  446.          ULONG index, i, j;
  447.          if (TModalDialog::init())
  448.          {
  449.             fBkgndColors=new TValueSet(201, this);
  450.             fShapeColors=new TValueSet(202, this);
  451.             index = 1;
  452.             j=1;
  453.             for (i=1; i<4; i++)
  454.             {
  455.                for (j=1; j<6; j++)
  456.                {
  457.                   fBkgndColors->setItem(i,j,(VOID*)index);
  458.                   fShapeColors->setItem(i,j,(VOID*)index);
  459.                   index++;
  460.                }
  461.             }
  462.             return TRUE;
  463.          }
  464.          return FALSE;
  465.       }
  466. };
  467.  
  468.  
  469.  
  470.  
  471. class TExampleFrameWin : public TFrameWindow
  472. {
  473.  
  474.    public:
  475.       TExampleFrameWin(ULONG id, char *title):TFrameWindow(id, title)
  476.       {   
  477.          fShellPos = TRUE;
  478.          fFrAttr.menu = TRUE;
  479.          fFrAttr.icon = TRUE;
  480.       };
  481.       virtual BOOL init()
  482.       {
  483.          if (TFrameWindow::init())
  484.          {  
  485.             TExampleClientWin *client = new
  486.                 TExampleClientWin(FID_CLIENT, this);
  487.             return client->init();
  488.          }
  489.          return FALSE;
  490.       }
  491.       virtual void doCommand(WinMsg wm)
  492.       {
  493.          SHORT command = SHORT1FROMMP(wm.mp1);
  494.          if (command == 102)
  495.          {
  496.              TColorSelectDlog dlog(200, this, NULL);
  497.              dlog.init();
  498.              dlog.Execute();
  499.          }
  500.          if (command == 103)
  501.          {
  502.             WinPostMsg(wm.hwnd, WM_QUIT, 0,0);
  503.          }
  504.          else if (command == 104)
  505.          {
  506.             WinMessageBox(HWND_DESKTOP, hwnd, (PSZ)aboutText, 
  507.                    (PSZ)"Product Information", 0, MB_MOVEABLE | MB_OK 
  508.                    | MB_ICONEXCLAMATION);
  509.          }
  510.       }
  511. };
  512.  
  513.  
  514. --------------------------------------------------------------------
  515.  
  516.    This example, in addition to creating a modal dialog also creates
  517. two Value Set controls.  The resource code to create this dialog 
  518. follows:
  519.  
  520. --------------------------------------------------------------------
  521. /* example7.rc */
  522.  
  523.  
  524. DLGTEMPLATE 200 LOADONCALL MOVEABLE DISCARDABLE
  525. BEGIN
  526.    DIALOG "Window Colors", 200, 30,10, 150, 125, WS_VISIBLE, 
  527.            FCF_TITLEBAR 
  528.       BEGIN
  529.         LTEXT "Background Colors", 203, 3, 114, 80, 8
  530.         CONTROL "", 201, 10, 73, 130, 40, WC_VALUESET,
  531.                  VS_COLORINDEX | VS_BORDER | VS_ITEMBORDER |
  532.                  WS_TABSTOP | WS_VISIBLE
  533.          CTLDATA         8, 0, 3, 5
  534.         LTEXT "Shape Colors", 204, 3, 65, 80, 8
  535.         CONTROL "", 202, 10, 25, 130, 40, WC_VALUESET,
  536.                  VS_COLORINDEX | VS_BORDER | VS_ITEMBORDER |
  537.                  WS_TABSTOP | WS_VISIBLE
  538.          CTLDATA         8, 0, 3, 5
  539.          PUSHBUTTON    "Cancel", DID_CANCEL, 34, 3, 55, 15
  540.          DEFPUSHBUTTON "OK", DID_OK, 92, 3, 55, 15
  541.       END
  542. END
  543.  
  544. --------------------------------------------------------------------
  545.  
  546.    Notice the code in TExampleFrameWin::doCommand which actually
  547. creates and executes the dialog -- only 3 lines of code are required
  548. to perform this operation.
  549.  
  550.  
  551.  
  552. ====================================================================
  553. Part 8: Finishing Touches
  554.  
  555.    Now, all that is left to do in order to finish this demo
  556. application is to initialize the value set objects in the 
  557. color select dialog class and to change the Frame Window's
  558. client window's colors according to the inputs in these
  559. value sets.  
  560.  
  561.    The final code for the application is:
  562.  
  563. --------------------------------------------------------------------
  564.  
  565. /****************************************/
  566. /*    Developer Helper Object Set       */
  567. /*  (C) 1994-95 Thomas E. Bednarz, Jr.  */
  568. /*     All rights reserved              */
  569. /***************************************/
  570.  
  571. /* $Id: tutorial.txt 1.1 1995/09/03 00:49:18 teb Exp $ */
  572.  
  573. /*******************************************
  574.  *   Example8.cc 
  575.  * 
  576.  *******************************************/
  577.  
  578. #define INCL_WIN
  579. #include<os2.h>
  580.  
  581. //DHO application object header file
  582. #include<applicat.h>
  583. #include<framewin.h>
  584. #include<moddlog.h>
  585. #include<vset.h>
  586.  
  587. #define kAppId 100
  588. #define aboutText "Developer Helper Sample App\n (c) 1994-95 Tom Bednarz\n     All Rights Reserved."
  589.  
  590.  
  591.  
  592.  
  593. class TColorSelectDlog : public TModalDialog
  594. {
  595.       TValueSet *fBkgndColors, *fShapeColors;
  596.    public:
  597.       TColorSelectDlog(ULONG resource, TWinBase *owner, void *buffer)
  598.          TModalDialog(resource, owner, buffer){;};
  599.       virtual~TColorSelectDlog()
  600.       {
  601.          if(fBkgndColors)
  602.             delete fBkgndColors;
  603.          if(fShapeColors)
  604.             delete fShapeColors;
  605.       }
  606.       virtual BOOL init()
  607.       {
  608.          ULONG index, i, j;
  609.          if (TModalDialog::init())
  610.          {
  611.             fBkgndColors=new TValueSet(201, this);
  612.             fShapeColors=new TValueSet(202, this);
  613.             index = 1;
  614.             j=1;
  615.             for (i=1; i<4; i++)
  616.             {
  617.                for (j=1; j<6; j++)
  618.                {
  619.                   fBkgndColors->setItem(i,j,(VOID*)index);
  620.                   fShapeColors->setItem(i,j,(VOID*)index);
  621.                   index++;                   
  622.               }
  623.             }
  624.             return TRUE;
  625.          }
  626.          return FALSE;
  627.       }
  628.       virtual void doControl(WinMsg wm)
  629.       { 
  630.          if (SHORT2FROMMP(wm.mp1) == VN_SELECT)
  631.          {
  632.             USHORT i,j;
  633.             fBkgndColors->getSelection(i,j);
  634.             fBackground=((i-1)*5)+j;
  635.             fShapeColors->getSelection(i,j);
  636.             fShape=((i-1)*5)+j;  
  637.          }
  638.          else
  639.             TModalDialog::doControl(wm);
  640.                
  641.       }
  642.       void getColors(ULONG &bgnd, ULONG &shape)
  643.       {
  644.          bgnd = fBackground;
  645.          shape = fShape;
  646.       }
  647. };
  648.  
  649.  
  650.  
  651.  
  652. class TExampleClientWin : public TWindow
  653. {
  654.       SHORT sPageX, sPageY;
  655.       ULONG fBkgColor, fShapeColor;
  656.    public:
  657.       TExampleClientWin(ULONG id, TWinBase *parent):TWindow(id, parent)
  658.       {
  659.         fBkgColor = CLR_BLUE;
  660.         fShapeColor = CLR_YELLOW;
  661.       };
  662.       virtual void doSize(WinMsg wm)
  663.       {
  664.          sPageX = SHORT1FROMMP(wm.mp2);
  665.          sPageY = SHORT2FROMMP(wm.mp2);
  666.       }
  667.       virtual void paintWindow(HPS ps, RECTL rcl)
  668.       {
  669.          POINTL ptl;
  670.          SHORT w;
  671.  
  672.          if ((sPageX == 0) && (sPageY == 0))         
  673.          {
  674.             sPageX = rcl.xRight - rcl.xLeft;
  675.             sPageY = rcl.yTop - rcl.yBottom; 
  676.          }
  677.  
  678.          if (sPageX > sPageY)
  679.             w = sPageY / 2;
  680.          else
  681.             w = sPageX / 2;         
  682.  
  683.          WinFillRect(ps, &rcl, fBkgColor);
  684.  
  685.          rcl.xLeft = (sPageX/2) -(w/2);
  686.          rcl.xRight = rcl.xLeft +w;
  687.          rcl.yBottom = (sPageY /2) -(w/2);
  688.          rcl.yTop = rcl.yBottom+w;
  689.  
  690.          WinFillRect(ps, &rcl, fShapeColor);
  691.       }
  692.       void setColors(ULONG bgnd, ULONG shape)
  693.       {
  694.           fBkgColor = bgnd;
  695.           fShapeColor = shape;
  696.       }
  697.       void getColors(ULONG &bgnd, ULONG &shape)
  698.       {
  699.           bgnd = fBkgColor;
  700.           shape = fShapeColor;
  701.       }
  702. };
  703.  
  704.  
  705.  
  706. class TExampleFrameWin : public TFrameWindow
  707. {
  708.      TExampleClientWin *client;
  709.    public:
  710.       TExampleFrameWin(ULONG id, char *title):TFrameWindow(id, title)
  711.       {   
  712.          fShellPos = TRUE;
  713.          fFrAttr.menu = TRUE;
  714.          fFrAttr.icon = TRUE;
  715.       };
  716.       virtual BOOL init()
  717.       {
  718.          if (TFrameWindow::init())
  719.          {   
  720.             client = new TExampleClientWin(FID_CLIENT, this);
  721.             return client->init();
  722.          }
  723.          return FALSE;
  724.       }
  725.       virtual void doCommand(WinMsg wm)
  726.       {
  727.          SHORT command = SHORT1FROMMP(wm.mp1);
  728.          if (command == 102)
  729.          {
  730.              TColorSelectDlog dlog(200, this, NULL, 1, 1);
  731.              dlog.init();
  732.              if (dlog.Execute() == MBID_OK)
  733.              {
  734.                 ULONG i,j;
  735.                 dlog.getColors(i,j);
  736.                 client->setColors(i,j);
  737.                 client->forceUpdate();
  738.              }
  739.          }
  740.          if (command == 103)
  741.          {
  742.             WinPostMsg(wm.hwnd, WM_QUIT, 0,0);
  743.          }
  744.          else if (command == 104)
  745.          {
  746.             WinMessageBox(HWND_DESKTOP, hwnd, (PSZ)aboutText, 
  747.                    (PSZ)"Product Information", 0, MB_MOVEABLE | MB_OK 
  748.                    | MB_ICONEXCLAMATION);
  749.          }
  750.       }
  751. };
  752.  
  753.  
  754. class TExampleApp : public TApplication
  755. {
  756.    public:
  757.       TExampleApp(ULONG res):TApplication(res){;};
  758.       virtual void CreateMainWindow()
  759.       {
  760.          MainWin=new TExampleFrameWin(fResource, "DHO Tutorial App");
  761.       }
  762. };
  763.  
  764.  
  765.  
  766. //=========================================
  767. //  program entry point
  768. INT main(void)
  769. {
  770.    TExampleApp app(kAppId);
  771.  
  772.    app.init();     // initialize object
  773.    app.run();      // begin event loop          
  774.  
  775.    return 0;
  776. }
  777.  
  778.  
  779.  
  780. --------------------------------------------------------------------
  781.  
  782.    
  783.  
  784.  
  785.