home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cset21v1.zip / IBMCPP / TUTORIAL / DEBUGGER / DPMLINES / DPMLINES.C next >
Text File  |  1993-04-16  |  28KB  |  628 lines

  1. #pragma strings( readonly )
  2.  
  3. /*+--------------------------------------------------------------------------+*/
  4. /*|                                                                          |*/
  5. /*| PROGRAM NAME: DPMLINES                                                   |*/
  6. /*| -------------                                                            |*/
  7. /*|  A Simple OS/2 Presentation Manager Graphics Demonstration Program       |*/
  8. /*|                                                                          |*/
  9. /*| COPYRIGHT:                                                               |*/
  10. /*| ----------                                                               |*/
  11. /*|  Copyright (C) International Business Machines Corp., 1991,1992.         |*/
  12. /*|                                                                          |*/
  13. /*| REVISION LEVEL: 1.0                                                      |*/
  14. /*| ---------------                                                          |*/
  15. /*|                                                                          |*/
  16. /*| WHAT THIS PROGRAM DOES:                                                  |*/
  17. /*| -----------------------                                                  |*/
  18. /*|  This program displays a standard window and then draws lines in the     |*/
  19. /*|  window.  Both the line and background colours change.                   |*/
  20. /*|                                                                          |*/
  21. /*| WHAT THIS PROGRAM DEMONSTRATES:                                          |*/
  22. /*| -------------------------------                                          |*/
  23. /*|  This program demonstrates how to create and display a standard window,  |*/
  24. /*|  use simple menus and dialog boxes, use a second thread for drawing,     |*/
  25. /*|  and displaying graphics using some basic GPI calls.                     |*/
  26. /*|                                                                          |*/
  27. /*| WHAT YOU NEED TO COMPILE THIS PROGRAM:                                   |*/
  28. /*| --------------------------------------                                   |*/
  29. /*|                                                                          |*/
  30. /*|  REQUIRED FILES:                                                         |*/
  31. /*|  ---------------                                                         |*/
  32. /*|                                                                          |*/
  33. /*|    DPMLINES.C     - Source code                                          |*/
  34. /*|    BUILD.CMD      - Command file to build this program                   |*/
  35. /*|    DPMLINES.MAK   - Make file for this program                           |*/
  36. /*|    DPMLINES.DEF   - Module definition file                               |*/
  37. /*|    DPMLINES.H     - Application header file                              |*/
  38. /*|    DPMLINES.ICO   - Icon file                                            |*/
  39. /*|    DPMLINES.RC    - Resource file                                        |*/
  40. /*|    DPMLINES.DLG   - Dialog file                                          |*/
  41. /*|                                                                          |*/
  42. /*|    OS2.H          - Presentation Manager include file                    |*/
  43. /*|    STDLIB.H       - Standard library function declarations               |*/
  44. /*|    STRING.H       - String handling function declarations                |*/
  45. /*|                                                                          |*/
  46. /*|  REQUIRED LIBRARIES:                                                     |*/
  47. /*|  -------------------                                                     |*/
  48. /*|                                                                          |*/
  49. /*|    OS2386.LIB     - Presentation Manager/OS2 library                     |*/
  50. /*|    DDE4NBS.LIB    - Subsystem Development Library                        |*/
  51. /*|                                                                          |*/
  52. /*|  REQUIRED PROGRAMS:                                                      |*/
  53. /*|  ------------------                                                      |*/
  54. /*|                                                                          |*/
  55. /*|    IBM C Set/2 Compiler                                                  |*/
  56. /*|    IBM Linker                                                            |*/
  57. /*|    Resource Compiler                                                     |*/
  58. /*|                                                                          |*/
  59. /*| EXPECTED INPUT:                                                          |*/
  60. /*| ---------------                                                          |*/
  61. /*|                                                                          |*/
  62. /*| EXPECTED OUTPUT:                                                         |*/
  63. /*| ----------------                                                         |*/
  64. /*|                                                                          |*/
  65. /*+--------------------------------------------------------------------------+*/
  66.  
  67. /*+--------------------------------------------------------------------------+*/
  68. /*| System and library header files.                                         |*/
  69. /*+--------------------------------------------------------------------------+*/
  70.  
  71. #define INCL_NOCOMMON
  72. #define INCL_DOSPROCESS
  73. #define INCL_DOSSEMAPHORES
  74. #define INCL_DOSERRORS
  75. #define INCL_WINWINDOWMGR
  76. #define INCL_WINMESSAGEMGR
  77. #define INCL_WINFRAMEMGR
  78. #define INCL_WINDIALOGS
  79. #define INCL_WININPUT
  80. #define INCL_WINSWITCHLIST
  81. #define INCL_WINPROGRAMLIST
  82. #define INCL_GPICONTROL
  83. #define INCL_GPIPRIMITIVES
  84. #include <os2.h>
  85. #include <stdlib.h>
  86. #include <string.h>
  87.  
  88. /*+--------------------------------------------------------------------------+*/
  89. /*| Application header files.                                                |*/
  90. /*+--------------------------------------------------------------------------+*/
  91.  
  92. #include "dpmlines.h"
  93.  
  94. /*+--------------------------------------------------------------------------+*/
  95. /*| Internal function prototypes.                                            |*/
  96. /*+--------------------------------------------------------------------------+*/
  97.  
  98. static MRESULT EXPENTRY ClientWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
  99. static MRESULT EXPENTRY HelpDlgProc( HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2 );
  100. static FNTHREAD DrawingThread;
  101. static void DisplayMessage( HAB, ULONG );
  102.  
  103. /*+--------------------------------------------------------------------------+*/
  104. /*| Static global variables and local constants.                             |*/
  105. /*+--------------------------------------------------------------------------+*/
  106.  
  107. #define WINDOW_CLASS   "My_Window"          /* window class name              */
  108. #define COLOUR_TBL_LEN 16                   /* number of colour table entries */
  109. #define MSG_BOX_ID     256                  /* error message box id           */
  110. #define STRING_LENGTH  128
  111.  
  112. static HWND   hwndClient = NULLHANDLE;      /* client window handle           */
  113. static HMQ    hmqThread2 = NULLHANDLE;      /* message queue handle for thread*/
  114. static POINTL ptl1;                         /* line start point               */
  115. static POINTL ptl2;                         /* line end point                 */
  116. static LONG   lFcolour = CLR_BLUE;          /* foreground (line) colour       */
  117. static LONG   lBcolour = CLR_DARKGRAY;      /* background colour              */
  118. static LONG   cxClient, cyClient;           /* client window X and Y size     */
  119. static LONG   fcolourcounter = 1L;          /* wait time to change line colour*/
  120. static TID    tidDrawing;                   /* drawing thread identifier      */
  121. static char   szAppName[ MAXNAMEL + 1 ];    /* application name string        */
  122. static float  x = 2.0;                      /* Some float data so the debugger*/
  123. static float  y = 3.0;                      /* will display the 387 registers */
  124. static LONG   oldFcolour = 0L;
  125.  
  126. /*+--------------------------------------------------------------------------+*/
  127. /*| Dummy argument parsing routine so that real one does not get linked in.  |*/
  128. /*+--------------------------------------------------------------------------+*/
  129.  
  130. void _setuparg( void ) {}
  131.  
  132. /*+--------------------------------------------------------------------------+*/
  133. /*| Main control procedure.                                                  |*/
  134. /*+--------------------------------------------------------------------------+*/
  135.  
  136. int main( void )
  137. {
  138.    HAB     hab = NULLHANDLE;                /* PM anchor block handle         */
  139.    HMQ     hmq = NULLHANDLE;                /* message queue handle           */
  140.    HWND    hwndFrame = NULLHANDLE;          /* frame window handle            */
  141.    ULONG   flCreate = 0UL;                  /* window creation control flags  */
  142.    QMSG    qmsg;                            /* message from message queue     */
  143.    SWCNTRL tSwcntrl;                        /* task switch structure          */
  144.    int     rc = 1;
  145.  
  146.    do
  147.    {
  148.       /* Initialize PM and create a message queue of default size.            */
  149.  
  150.       if ( ( hab = WinInitialize( 0UL ) ) == NULLHANDLE )
  151.          break;
  152.  
  153.       if ( ( hmq = WinCreateMsgQueue( hab, 0UL ) ) == NULLHANDLE )
  154.          break;
  155.  
  156.       /* Register client window class.                                        */
  157.  
  158.       if ( !WinRegisterClass( hab,          /* PM anchor block handle         */
  159.                               WINDOW_CLASS, /* window class name              */
  160.                           ClientWindowProc, /* address of window procedure    */
  161.                               CS_SIZEREDRAW,/* size changes cause redrawing   */
  162.                               0UL ) )       /* window data                    */
  163.       {
  164.          DisplayMessage( hab, IDS_NOREGISTER );
  165.          break;
  166.       }
  167.  
  168.       /* Create the standard windows but do not add the application to the    */
  169.       /* task manager list.                                                   */
  170.  
  171.       flCreate = FCF_STANDARD & ~FCF_TASKLIST;
  172.  
  173.       hwndFrame =
  174.          WinCreateStdWindow( HWND_DESKTOP,  /* make desktop window the parent */
  175.                              WS_VISIBLE,    /* frame window class style       */
  176.                              &flCreate,     /* frame control flags            */
  177.                              WINDOW_CLASS,  /* client window class name       */
  178.                              "",            /* title bar text                 */
  179.                              CS_SIZEREDRAW, /* client window class style      */
  180.                              0UL,           /* resource file handle - in EXE  */
  181.                              ID_WINDOW,     /* resources identifier           */
  182.                              &hwndClient ); /* client window handle           */
  183.       if ( hwndFrame == NULLHANDLE )
  184.       {
  185.          DisplayMessage( hab, IDS_NOSTDWINDOWS );
  186.          break;
  187.       }
  188.  
  189.       /* Load the application name from the resources in the EXE.  Set the    */
  190.       /* title bar text to this name.  Then add this application to the       */
  191.       /* task manager list with the loaded application name.                  */
  192.  
  193.       WinLoadString( hab, 0UL, IDS_APPNAME, MAXNAMEL, szAppName );
  194.       WinSetWindowText( hwndFrame, szAppName );
  195.  
  196.  
  197.       tSwcntrl.hwnd = hwndFrame;
  198.       tSwcntrl.hwndIcon = NULLHANDLE;
  199.       tSwcntrl.hprog = NULLHANDLE;
  200.       tSwcntrl.idProcess = 0;
  201.       tSwcntrl.idSession = 0;
  202.       tSwcntrl.uchVisibility = SWL_VISIBLE;
  203.       tSwcntrl.fbJump = SWL_JUMPABLE;
  204.       strcpy( tSwcntrl.szSwtitle, szAppName );
  205.       tSwcntrl.bProgType = PROG_PM;
  206.       WinAddSwitchEntry( &tSwcntrl );
  207.  
  208.  
  209.       /* Create the thread that will draw the lines.                          */
  210.       /* NOTE: _beginthread MUST be used if the thread contains CRT calls     */
  211.  
  212.       DosCreateThread( &tidDrawing, DrawingThread, 0UL, 0UL, 8192UL );
  213.  
  214.       /* While the WM_QUIT message is not received, dispatch the message.     */
  215.       /* When the WM_QUIT message is received, WinGetMsg will return FALSE.   */
  216.  
  217.       while( WinGetMsg( hab, &qmsg, 0UL, 0UL, 0UL ) )
  218.          WinDispatchMsg( hab,               /* PM anchor block handle         */
  219.                          &qmsg );           /* pointer to message             */
  220.       rc = 0;
  221.  
  222.    } while ( FALSE );
  223.  
  224.    /* Destroy the standard windows if they were created.                      */
  225.  
  226.    if ( hwndFrame != NULLHANDLE )
  227.       WinDestroyWindow( hwndFrame );        /* frame window handle            */
  228.  
  229.    /* Destroy the message queue and release the anchor block.                 */
  230.  
  231.    if ( hmq != NULLHANDLE )
  232.       WinDestroyMsgQueue( hmq );
  233.  
  234.    if ( hab != NULLHANDLE )
  235.       WinTerminate( hab );
  236.  
  237.    return rc;
  238. }
  239.  
  240.  
  241.  
  242. /*+--------------------------------------------------------------------------+*/
  243. /*| ClientWindowProc - Client window procedure.                              |*/
  244. /*+--------------------------------------------------------------------------+*/
  245.  
  246. static MRESULT EXPENTRY ClientWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  247. {
  248.    HPS hps = NULLHANDLE;                    /* Presentation space handle      */
  249.  
  250.    /* Process the message.                                                    */
  251.  
  252.    switch( msg )
  253.    {
  254.       case WM_CREATE:
  255.          /* The client window has been created but is not visible yet.        */
  256.          /* Initialize the window here.                                       */
  257.          break;
  258.  
  259.       case WM_CLOSE:
  260.          /* Tell the main procedure to terminate the application.             */
  261.  
  262.          WinPostMsg( hwnd, WM_QUIT, NULL, NULL );
  263.          break;
  264.  
  265.       case WM_PAINT:
  266.          /* Post a message to the second thread to make it repaint the        */
  267.          /* background.                                                       */
  268.  
  269.          hps = WinBeginPaint( hwnd, NULLHANDLE, NULL );
  270.  
  271.          WinPostQueueMsg( hmqThread2, WM_USER_REPAINT, 0UL, 0UL );
  272.  
  273.          WinEndPaint( hps );
  274.          break;
  275.  
  276.       case WM_COMMAND:
  277.          /* The user has chosen a menu item.  Process the selection           */
  278.          /* accordingly.                                                      */
  279.  
  280.          switch ( SHORT1FROMMP( mp1 ) )
  281.          {
  282.             case IDM_EXITPROG:
  283.                /* Post a close message.                                       */
  284.  
  285.                WinPostMsg( hwnd, WM_CLOSE, NULL, NULL );
  286.                break;
  287.  
  288.             case IDM_RESUME:
  289.                break;
  290.  
  291.             case IDM_HELPINSTRUCTIONS:
  292.                /* Display the help dialog box.                                */
  293.  
  294.                WinMessageBox( HWND_DESKTOP,      /* desktop is the parent     */
  295.                               hwnd,              /* owned by client window    */
  296.                               INSTRUCTIONS,      /* pointer to message text   */
  297.                               szAppName,         /* pointer to title text     */
  298.                               1UL,               /* message box identifier    */
  299.                               MB_OK | MB_INFORMATION | /* message box style   */
  300.                               MB_APPLMODAL | MB_MOVEABLE );
  301.  
  302.                /* Force a repaint.                                            */
  303.  
  304.                WinInvalidateRegion( hwnd, NULLHANDLE, FALSE );
  305.                break;
  306.  
  307.             case IDM_HELPABOUT:
  308.                /* Display the help dialog box.                                */
  309.  
  310.                WinDlgBox( HWND_DESKTOP,     /* make the desktop the parent    */
  311.                           hwnd,             /* owned by client window         */
  312.                           HelpDlgProc,      /* address of dialog procedure    */
  313.                           0UL,              /* module handle                  */
  314.                           IDD_HELP,         /* dialog identifier in resource  */
  315.                           NULL );           /* initialization data            */
  316.  
  317.                /* Force a repaint.                                            */
  318.  
  319.                WinInvalidateRegion( hwnd, NULLHANDLE, FALSE );
  320.                break;
  321.          }
  322.          break;
  323.  
  324.       case WM_SIZE:
  325.          /* Window is being resized so get new client window size and         */
  326.          /* recompute the end points for the lines.                           */
  327.  
  328.          cxClient = SHORT1FROMMP( mp2 );    /* Get new client window size     */
  329.          cyClient = SHORT2FROMMP( mp2 );
  330.          ptl1.x = cxClient / 2;             /* Set new points for lines based */
  331.          ptl1.y = cyClient / 2;             /* on the size of client window   */
  332.          ptl2.x = ptl1.x / 2;
  333.          ptl2.y = ptl1.y / 2;
  334.          break;
  335.  
  336.       case WM_BUTTON1DOWN:
  337.          /* The user has pushed mouse button 1 which means change the         */
  338.          /* foreground colour.                                                */
  339.  
  340.          /* Make sure that this window has the focus.                         */
  341.  
  342.          WinSetFocus( HWND_DESKTOP, hwnd );
  343.  
  344.          /* Reset foreground colour counter and increment foreground colour.  */
  345.  
  346.          fcolourcounter = 1;
  347.          oldFcolour = lFcolour;
  348.          lFcolour++;
  349.  
  350.          /* Make sure foreground and background colours are different.        */
  351.  
  352.          if ( lFcolour == lBcolour )
  353.             lFcolour++;
  354.  
  355.          /* Make sure the foregound colour does not exceed CLR_PALEGRAY.      */
  356.  
  357.          if ( lFcolour >= CLR_PALEGRAY )
  358.             lFcolour = CLR_BLUE;
  359.  
  360.          return ( MRESULT )TRUE;
  361.  
  362.       case WM_BUTTON1DBLCLK:
  363.          /* The user has double clicked mouse button 1 which means change     */
  364.          /* the background colour.                                            */
  365.  
  366.          /* Make sure that this window has the focus.                         */
  367.  
  368.          WinSetFocus( HWND_DESKTOP, hwnd );
  369.  
  370.          /* Increment the backgound colour but make sure the background       */
  371.          /* does not exceed CLR_PALEGRAY.                                     */
  372.  
  373.          if ( lBcolour == CLR_PALEGRAY )
  374.             lBcolour = CLR_BLUE;
  375.          else
  376.             ++lBcolour;
  377.  
  378.          /* Make sure foreground and background colours are different.        */
  379.  
  380.          if ( lFcolour == lBcolour )
  381.             lFcolour++;
  382.  
  383.          /* Make sure the foregound colour does not exceed CLR_PALEGRAY.      */
  384.  
  385.          if ( lFcolour >= CLR_PALEGRAY )
  386.             lFcolour = CLR_BLUE;
  387.  
  388.          /* Force the client window to repaint so that the background colour  */
  389.          /* is updated.                                                       */
  390.  
  391.          WinInvalidateRegion( hwnd, 0UL, FALSE );
  392.  
  393.          return ( MRESULT )TRUE;
  394.  
  395.       case WM_BUTTON2DOWN:
  396.          /* Erase the client window by forcing a repaint.                     */
  397.  
  398.          WinInvalidateRegion( hwnd, NULLHANDLE, FALSE );
  399.  
  400.          return ( MRESULT )TRUE;
  401.  
  402.       case WM_DESTROY:
  403.          /* The client window is being destroyed so tell the second thread to */
  404.          /* stop running.                                                     */
  405.  
  406.          WinPostQueueMsg( hmqThread2, WM_USER_END_THREAD, 0UL, 0UL );
  407.  
  408.          /* Wait for the drawing thread to terminate before returning.        */
  409.  
  410.          DosWaitThread( &tidDrawing, DCWW_WAIT );
  411.  
  412.          break;
  413.  
  414.       default:
  415.          /* For all other messages, let the default window procedure          */
  416.          /* process them.                                                     */
  417.  
  418.          return ( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
  419.    }
  420.    return NULL;
  421. }
  422.  
  423.  
  424.  
  425.  
  426. /*+--------------------------------------------------------------------------+*/
  427. /*| HelpDlgProc - Help Dialog Procedure                                      |*/
  428. /*+--------------------------------------------------------------------------+*/
  429.  
  430. static MRESULT EXPENTRY HelpDlgProc( HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2 )
  431. {
  432.    switch( msg )
  433.    {
  434.       case WM_COMMAND:
  435.          switch( SHORT1FROMMP( mp1 ) )      /* Extract the command value      */
  436.          {
  437.             case DID_OK:                    /* The Enter pushbutton or key    */
  438.                WinDismissDlg( hwndDlg, TRUE );
  439.                break;
  440.  
  441.             default:
  442.                break;
  443.          }
  444.          break;
  445.  
  446.       default:
  447.          return WinDefDlgProc( hwndDlg, msg, mp1, mp2 );
  448.    }
  449.    return NULL;
  450. }
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458. /*+--------------------------------------------------------------------------+*/
  459. /*| DrawingThread - Procedure that draws the lines in the client window.     |*/
  460. /*+--------------------------------------------------------------------------+*/
  461.  
  462. static void DrawingThread( ULONG ulThreadArg )
  463. {
  464.    /* Declare local variables.                                                */
  465.  
  466.    HPS   hps = NULLHANDLE;                  /* Presentation Space handle      */
  467.    HAB   habThread2 = NULLHANDLE;           /* Anchor block handle for thread */
  468.    LONG  delta1x = START_DELTA_X;           /* start point delta values       */
  469.    LONG  delta1y = START_DELTA_Y;
  470.    LONG  delta2x = END_DELTA_X;             /* end point delta values         */
  471.    LONG  delta2y = END_DELTA_Y;
  472.    RECTL rclClient;                         /* rectangle for client window    */
  473.    QMSG  qmsgThread2;                       /* message queue structure        */
  474.    LONG  count;
  475.    char  buffer[20],*p;
  476.    POINTL ptlt;                             /* Text start point               */
  477.  
  478.    /* Initialize thread to PM.                                                */
  479.  
  480.    habThread2 = WinInitialize( 0UL );
  481.    hmqThread2 = WinCreateMsgQueue( habThread2, 0UL );
  482.  
  483.    /* Get a presentation space.                                               */
  484.  
  485.    hps = WinGetPS( hwndClient );
  486.  
  487.    /* Run drawing thread.                                                     */
  488.  
  489.    qmsgThread2.msg = WM_USER_REPAINT;
  490.  
  491.    while ( qmsgThread2.msg != WM_USER_END_THREAD )
  492.    {
  493.       if ( qmsgThread2.msg == WM_USER_REPAINT )
  494.       {
  495.          WinQueryWindowRect( hwndClient, &rclClient );
  496.          WinFillRect( hps, &rclClient, lBcolour );
  497.       }
  498.       else
  499.       {
  500.          /* Increment the foreground colour if necessary.                     */
  501.  
  502.          if ( ++fcolourcounter > ( ( cxClient + cyClient ) >> 1 ) )
  503.          {
  504.             fcolourcounter = 1;                /* Reset fcolourcounter and    */
  505.             oldFcolour = lFcolour;
  506.             lFcolour++;                        /* increment foreground colour.*/
  507.  
  508.             /* Make sure foreground and background colours are different.     */
  509.  
  510.             if ( lFcolour == lBcolour )
  511.                lFcolour++;
  512.  
  513.             /* Make sure the foregound colour does not exceed CLR_PALEGRAY.   */
  514.  
  515.             if ( lFcolour >= CLR_PALEGRAY )
  516.                lFcolour = CLR_BLUE;
  517.          }
  518.  
  519.          /* Add deltas to the start and end points for a line.                */
  520.  
  521.          /* If the start point would be invalid then negate the delta.        */
  522.  
  523.          if ( ( ptl1.x + delta1x ) > cxClient )
  524.             delta1x = -delta1x;
  525.  
  526.          if ( ( ptl1.x + delta1x ) < 1 )
  527.             delta1x = -delta1x;
  528.  
  529.          if ( ( ptl1.y + delta1y ) > cyClient )
  530.             delta1y = -delta1y;
  531.  
  532.          if ( ( ptl1.y + delta1y ) < 1 )
  533.             delta1y = -delta1y;
  534.  
  535.          /* Add delta to start point.                                         */
  536.  
  537.          ptl1.x += delta1x;
  538.          ptl1.y += delta1y;
  539.  
  540.          /* If the end point would be invalid then negate the delta.          */
  541.  
  542.          if ( ( ptl2.x + delta2x ) > cxClient )
  543.             delta2x = -delta2x;
  544.          if ( ( ptl2.x + delta2x ) < 1 )
  545.             delta2x = -delta2x;
  546.          if ( ( ptl2.y + delta2y ) > cyClient )
  547.             delta2y = -delta2y;
  548.          if ( ( ptl2.y + delta2y ) < 1 )
  549.             delta2y = -delta2y;
  550.  
  551.          /* Add delta to end point.                                           */
  552.  
  553.          ptl2.x += delta2x;
  554.          ptl2.y += delta2y;
  555.  
  556.          /* Now draw the line.                                                */
  557.  
  558.          GpiSetColor( hps, lFcolour );
  559.          GpiMove( hps, &ptl1 );                /* Move to start point         */
  560.          GpiLine( hps, &ptl2 );                /* Draw new line               */
  561.  
  562.          /* Display the value of the active                                   */
  563.          /* line color in the lower left                                      */
  564.          /* corner of the display                                             */
  565.  
  566.  
  567.          ptlt.x = 1;
  568.          ptlt.y = 1;
  569.          count = 2;
  570.          x = x * y;
  571.          if ( oldFcolour != lFcolour ) {
  572.             GpiSetColor( hps, lFcolour );
  573.             GpiCharStringAt( hps, &ptlt, 12, "Color Value:" );
  574.             ptlt.x = 100;
  575.             GpiSetColor( hps, lBcolour);
  576.                                                /* Convert the current color   */
  577.                                                /* number to an ASCII string   */
  578.             p = _ltoa(oldFcolour, buffer, 10);
  579.                                                /* Erase the previous value by */
  580.                                                /* writing the character in the*/
  581.                                                /* background color            */
  582.             GpiCharStringAt( hps, &ptlt, count, buffer);
  583.                                                /* Write the new color value   */
  584.                                                /* CLR_BLACK                   */
  585.             GpiSetColor( hps, lBcolour);
  586.             GpiCharStringAt( hps, &ptlt, count, _ltoa(lFcolour, buffer, 10));
  587.             oldFcolour = lFcolour;
  588.          }
  589.       }
  590.  
  591.       /* Peek in the message queue to see if the main thread has posted a msg.*/
  592.  
  593.       WinPeekMsg( habThread2, &qmsgThread2, NULLHANDLE, 0UL, 0UL, PM_REMOVE );
  594.    }
  595.  
  596.    /* Clean up and terminate drawing thread.                                  */
  597.  
  598.    WinReleasePS( hps );
  599.    WinDestroyMsgQueue( hmqThread2 );
  600.    WinTerminate( habThread2 );
  601.    DosExit( EXIT_THREAD, 0UL );
  602. }
  603.  
  604.  
  605. /*+--------------------------------------------------------------------------+*/
  606. /*| DisplayMessage - display an error message in a message box.              |*/
  607. /*+--------------------------------------------------------------------------+*/
  608.  
  609. static void DisplayMessage( HAB hab, ULONG ulStringNum )
  610. {
  611.    char szTemp[ STRING_LENGTH ];
  612.  
  613.    WinLoadString( hab, 0UL, ulStringNum, STRING_LENGTH, szTemp );
  614.  
  615.    WinAlarm( HWND_DESKTOP,                  /* desktop window handle          */
  616.              WA_ERROR );                    /* type of alarm                  */
  617.  
  618.    WinMessageBox( HWND_DESKTOP,             /* parent window handle           */
  619.                   HWND_DESKTOP,             /* owner window handle            */
  620.                   szTemp,                   /* pointer to message text        */
  621.                   szAppName,                /* pointer to title text          */
  622.                   MSG_BOX_ID,               /* message box identifier         */
  623.                   MB_OK | MB_ERROR |        /* message box style              */
  624.                   MB_SYSTEMMODAL );
  625.  
  626.    return;
  627. }
  628.