home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cset21v1.zip / IBMCPP / SAMPLES / COMPILER / SAMPLE1B / PMLINES.CPP < prev    next >
Text File  |  1993-05-07  |  15KB  |  399 lines

  1. /*+--------------------------------------------------------------------------+*/
  2. /*|                                                                          |*/
  3. /*| PROGRAM NAME: PMLINES                                                    |*/
  4. /*| -------------                                                            |*/
  5. /*|  A Simple OS/2 Presentation Manager Graphics Demonstration Program       |*/
  6. /*|                                                                          |*/
  7. /*| COPYRIGHT:                                                               |*/
  8. /*| ----------                                                               |*/
  9. /*|  Copyright (C) International Business Machines Corp., 1992, 1993.        |*/
  10. /*|                                                                          |*/
  11. /*| DISCLAIMER OF WARRANTIES:                                                |*/
  12. /*| -------------------------                                                |*/
  13. /*|  The following [enclosed] code is sample code created by IBM Corporation.|*/
  14. /*|  This sample code is not part of any standard IBM product and is provided|*/
  15. /*|  to you solely for the purpose of assisting you in the development of    |*/
  16. /*|  your applications.  The code is provided "AS IS", without warranty of   |*/
  17. /*|  any kind.  IBM shall not be liable for any damages arising out of your  |*/
  18. /*|  use of the sample code, even if they have been advised of the           |*/
  19. /*|  possibility of such damages.                                            |*/
  20. /*|                                                                          |*/
  21. /*| REVISION LEVEL: 1.0                                                      |*/
  22. /*|                                                                          |*/
  23. /*| CHANGE HISTORY:                                                          |*/
  24. /*| Rel Programmer        Stamp Date     Description                         |*/
  25. /*| --- ----------------- ----- -------- ------------------------------------|*/
  26. /*| 1.0 Noel Sales        njCs  12/16/92 Port the PMLINES program to code it |*/
  27. /*|                                      in C++ and to implement the PM      |*/
  28. /*|                                      interface using the User Interface  |*/
  29. /*|                                      Class Library. The original PMLINES |*/
  30. /*|                                      program is coded in C and uses the  |*/
  31. /*|                                      PM API directly.                    |*/
  32. /*|                                                                          |*/
  33. /*+--------------------------------------------------------------------------+*/
  34.  
  35. /*+--------------------------------------------------------------------------+*/
  36. /*|                                                                          |*/
  37. /*| The following features of the User Interface Class Library are           |*/
  38. /*| demonstrated by this program:                                            |*/
  39. /*|  1. Window Creation.                                                     |*/
  40. /*|  2. Event Handling                                                       |*/
  41. /*|  3. Simple multitasking                                                  |*/
  42. /*|  4. Use of GPI or native PM API with User Interface Library objects      |*/
  43. /*|                                                                          |*/
  44. /*+--------------------------------------------------------------------------+*/
  45.  
  46. /*+--------------------------------------------------------------------------+*/
  47. /*| The following includes are for thread handling only.                     |*/
  48. /*+--------------------------------------------------------------------------+*/
  49. #define  INCL_DOSPROCESS
  50. #define  INCL_DOSSEMAPHORES
  51. #define  INCL_DOSERRORS
  52. #include <os2.h>
  53.  
  54. /*+--------------------------------------------------------------------------+*/
  55. /*| Include headers for the User Interface Class Library                     |*/
  56. /*+--------------------------------------------------------------------------+*/
  57. #include <iapp.hpp>           // IApplication
  58. #include <ireslib.hpp>        // IResourceLibrary/IResourceId
  59. #include <itrace.hpp>         // ITrace
  60. #include <imsgbox.hpp>
  61.  
  62. /*+--------------------------------------------------------------------------+*/
  63. /*| include our class declarations                                           |*/
  64. /*+--------------------------------------------------------------------------+*/
  65. #include "pmlines.hpp"
  66.  
  67. /*+--------------------------------------------------------------------------+*/
  68. /*| include our symbols definitions                                          |*/
  69. /*+--------------------------------------------------------------------------+*/
  70. #include "pmlines.h"
  71.  
  72. /*+--------------------------------------------------------------------------+*/
  73. /*| main                                                                     |*/
  74. /*|  Application entry point                                                 |*/
  75. /*+--------------------------------------------------------------------------+*/
  76. void main()
  77. {
  78.    IApplication app();
  79.    MyWindow myWin(ID_WINDOW);     /* Create the Main Window    */
  80.  
  81.    IApplication::current().run(); /* Run the application       */
  82.  
  83. }/* end main */
  84.  
  85. /*+--------------------------------------------------------------------------+*/
  86. /*| MyWindow::MyWindow                                              nCs 16/12|*/
  87. /*|   Constructor for our main window                                        |*/
  88. /*+--------------------------------------------------------------------------+*/
  89. MyWindow::MyWindow( unsigned long windowId )
  90.          :IFrameWindow( animated | border | sizingBorder | windowList |
  91.                         IFrameWindow::accelerator |
  92.                         classDefaultStyle,
  93.                         windowId )
  94. {
  95.    /* Set ourselves in the event handler stack. */
  96.  
  97.    addHandler((ICommandHandler *)this);
  98.    addHandler((IPaintHandler *)this);
  99.    addHandler((IMouseClickHandler *)this);
  100.  
  101.    /* Set the main menu */
  102.  
  103.    IMenuBar* pabmnMain=new IMenuBar(ID_WINDOW,this);
  104.  
  105.    /* Instantiate the Client */
  106.  
  107.    pMyClient = new MyClientWindow(ID_CLIENT,this,this);
  108.    setClient(pMyClient);
  109.  
  110.    /* Display the application window */
  111.  
  112.    update();
  113.    setFocus();
  114.    show();
  115.  
  116.    /* Compute the initial Client Area dimensions */
  117.  
  118.    long   cx, cy, bx, by, ex, ey;
  119.    ISize  ClientSize = pMyClient->size();
  120.  
  121.    pMyClient->SetcxClient(cx= ClientSize.width());
  122.    pMyClient->SetcyClient(cy= ClientSize.height());
  123.    bx= cx / 2;
  124.    by= cy / 2;
  125.    pMyClient->SetBeginPoint(IPoint(bx,by));
  126.    ex= bx / 2;
  127.    ey= ex / 2;
  128.    pMyClient->SetEndPoint(IPoint(ex,ey));
  129.  
  130.    /* Dispatch the DrawLines function on a separate thread. */
  131.  
  132.    Thread.start(new IThreadMemberFn<MyClientWindow> (*pMyClient,
  133.                     MyClientWindow::DrawLines));
  134.  
  135. }/* end MyWindow :: MyWindow(...) */
  136.  
  137. /*+--------------------------------------------------------------------------+*/
  138. /*| MyWindow :: mouseClicked                                        nCs 16/12|*/
  139. /*|   Handle mouse Clicked Event                                             |*/
  140. /*+--------------------------------------------------------------------------+*/
  141. Boolean MyWindow :: mouseClicked(IMouseClickEvent &evt)
  142. {
  143.    if (IMouseClickEvent::button1 == evt.mouseNumber() &&
  144.        IMouseClickEvent::click   == evt.mouseAction())
  145.    {
  146.       /* Change the foreground color */
  147.  
  148.       setFocus();
  149.       pMyClient->IncColorCount();
  150.  
  151.       long Fc= pMyClient->GetFcolor();
  152.       Fc++;
  153.       pMyClient->SetFcolor(Fc);
  154.  
  155.       if (pMyClient->GetFcolor() == pMyClient->GetBcolor())
  156.       {
  157.          Fc++;
  158.          pMyClient->SetFcolor(Fc);
  159.       }
  160.       if (pMyClient->GetFcolor() >= CLR_PALEGRAY)
  161.          pMyClient->SetFcolor(CLR_BLUE);
  162.  
  163.       pMyClient->SetThreadMessage(WM_USER_REPAINT);
  164.       return true;
  165.    }
  166.  
  167.    else if (IMouseClickEvent::button1     == evt.mouseNumber() &&
  168.             IMouseClickEvent::doubleClick == evt.mouseAction())
  169.    {
  170.       /* Change the background color */
  171.  
  172.       setFocus();
  173.  
  174.       if (pMyClient->GetBcolor() == CLR_PALEGRAY)
  175.          pMyClient->SetBcolor(CLR_BLUE);
  176.       else
  177.       {
  178.          long Bc= pMyClient->GetBcolor();
  179.          Bc++;
  180.          pMyClient->SetBcolor(Bc);
  181.       }
  182.       if (pMyClient->GetFcolor() == pMyClient->GetBcolor())
  183.          pMyClient->SetFcolor(CLR_BLUE);
  184.  
  185.       pMyClient->SetThreadMessage(WM_USER_REPAINT);
  186.       return true;
  187.    }
  188.  
  189.    else if (IMouseClickEvent::button2 == evt.mouseNumber() &&
  190.             IMouseClickEvent::click   == evt.mouseAction())
  191.    {
  192.       /* Reset the drawing cycle */
  193.  
  194.       pMyClient->SetThreadMessage(WM_USER_REPAINT);
  195.       return true;
  196.    }
  197.    else
  198.       return false;
  199. }
  200.  
  201. /*+--------------------------------------------------------------------------+*/
  202. /*| MyWindow :: paintWindow                                         nCs 16/12|*/
  203. /*|   Handle paint Event                                                     |*/
  204. /*+--------------------------------------------------------------------------+*/
  205. Boolean MyWindow :: paintWindow(IPaintEvent& evt)
  206. {
  207.  
  208.    IPresSpaceHandle   hps= presSpace();
  209.    long   cx, cy, bx, by, ex, ey;
  210.    ISize  ClientSize= pMyClient->size();
  211.  
  212.    pMyClient->SetcxClient(cx= ClientSize.width());
  213.    pMyClient->SetcyClient(cy= ClientSize.height());
  214.    bx= cx / 2;
  215.    by= cy / 2;
  216.    pMyClient->SetBeginPoint(IPoint(bx,by));
  217.    ex= bx / 2;
  218.    ey= ex / 2;
  219.    pMyClient->SetEndPoint(IPoint(ex,ey));
  220.  
  221.    releasePresSpace(hps);
  222.  
  223.    pMyClient->SetThreadMessage(WM_USER_REPAINT);
  224.    return true;
  225. }
  226.  
  227. /*+--------------------------------------------------------------------------+*/
  228. /*| MyWindow :: command                                             nCs 16/12|*/
  229. /*|   Handle command event                                                   |*/
  230. /*+--------------------------------------------------------------------------+*/
  231. Boolean MyWindow :: command(ICommandEvent& cmdevt)
  232. {
  233.   switch(cmdevt.commandId())
  234.   {
  235.      case IDM_EXITPROG:
  236.      {
  237.         pMyClient->SetThreadMessage(WM_USER_END_THREAD);
  238.         IThreadId   Tid= Thread.id();
  239.         DosWaitThread((PTID)&Tid, DCWW_WAIT);
  240.         WinPostMsg(handle(), WM_CLOSE, 0L, 0L);
  241.         return true;
  242.      }
  243.  
  244.      case IDM_RESUME:
  245.         return true;
  246.  
  247.      case IDM_HELPINSTRUCTIONS:
  248.      {
  249.         IMessageBox   *Mbox= new IMessageBox(this);
  250.         Mbox->setTitle("PMLINES");
  251.         Mbox->show(INSTRUCTIONS, IMessageBox::information);
  252.         delete Mbox;
  253.         return true;
  254.      }
  255.  
  256.      case IDM_HELPABOUT:
  257.      {
  258.         IMessageBox   *Mbox= new IMessageBox(this);
  259.         Mbox->setTitle("PMLINES");
  260.         Mbox->show(ABOUT,IMessageBox::information);
  261.         delete Mbox;
  262.         return true;
  263.      }
  264.   }
  265.   return false;
  266. }
  267.  
  268. /*+--------------------------------------------------------------------------+*/
  269. /*| Define MyClientWindow Methods                                            |*/
  270. /*+--------------------------------------------------------------------------+*/
  271. MyClientWindow::MyClientWindow(unsigned long Id,
  272.                                IWindow* parent,
  273.                                IWindow* owner)
  274.               : ICanvas(Id, parent, owner),
  275.                 MyParent(parent),
  276.                 lFcolour(CLR_BLUE),
  277.                 lBcolour(CLR_DARKGRAY),
  278.                 cxClient(0),cyClient(0),
  279.                 fcolourcounter(0l)
  280. {
  281.    ptl1.x= ptl1.y= 0;
  282.    ptl2.x= ptl2.y= 0;
  283.    SetThreadMessage(WM_USER_REPAINT);
  284. }
  285.  
  286. /*+--------------------------------------------------------------------------+*/
  287. /*| DrawLines                                                                |*/
  288. /*+--------------------------------------------------------------------------+*/
  289.  
  290. void MyClientWindow::DrawLines( )
  291. {
  292.    /* Declare local variables.                                                */
  293.  
  294.    LONG  delta1x = START_DELTA_X;           /* start point delta values       */
  295.    LONG  delta1y = START_DELTA_Y;
  296.    LONG  delta2x = END_DELTA_X;             /* end point delta values         */
  297.    LONG  delta2y = END_DELTA_Y;
  298.  
  299.    /* Change the priority class of this thread to idle class.  */
  300.  
  301.    DosSetPriority( PRTYS_THREAD, PRTYC_IDLETIME, 0L, 0UL );
  302.  
  303.    /* Initialize thread to PM. */
  304.  
  305.    habThread2 = WinInitialize( 0UL );
  306.  
  307.    /* Get a presentation space. */
  308.  
  309.    hps= MyParent->presSpace();
  310.  
  311.    /* Run drawing loop */
  312.  
  313.    while ( GetThreadMessage() != WM_USER_END_THREAD )
  314.    {
  315.       if ( GetThreadMessage() == WM_USER_REPAINT )
  316.       {
  317.           rclClient= rect().asRECTL();
  318.           WinFillRect( hps, &rclClient, GetBcolor() );
  319.           SetThreadMessage(WM_USER_REPAINT+1);
  320.       }
  321.  
  322.       else
  323.       {
  324.          /* Increment the foreground colour if necessary. */
  325.  
  326.          IncColorCount();
  327.          long   ColorCount= GetColorCount();
  328.          if ( ColorCount > ((cxClient + cyClient ) >> 1 ))
  329.          {
  330.             SetColorCount(1);     /* Reset fcolourcounter and  */
  331.             long Fc= GetFcolor(); /* increment foreground color*/
  332.             Fc++;
  333.             SetFcolor(Fc);
  334.  
  335.             /* Foreground and background colors must differ */
  336.  
  337.             if (GetFcolor() == GetBcolor())
  338.             {
  339.                Fc++;
  340.                SetFcolor(Fc);
  341.             }
  342.  
  343.             /* Make sure the foregound colour does not exceed CLR_PALEGRAY. */
  344.  
  345.             if (GetFcolor() >= CLR_PALEGRAY )
  346.                SetFcolor(CLR_BLUE);
  347.          }
  348.  
  349.          /* Add deltas to the start and end points for a line.    */
  350.          /* If the start point would be invalid, negate the delta.*/
  351.  
  352.          if ( ( ptl1.x + delta1x ) > cxClient )
  353.             delta1x = -delta1x;
  354.  
  355.          if ( ( ptl1.x + delta1x ) < 1 )
  356.             delta1x = -delta1x;
  357.  
  358.          if ( ( ptl1.y + delta1y ) > cyClient )
  359.             delta1y = -delta1y;
  360.  
  361.          if ( ( ptl1.y + delta1y ) < 1 )
  362.             delta1y = -delta1y;
  363.  
  364.          /* Add delta to start point. */
  365.  
  366.          ptl1.x += delta1x;
  367.          ptl1.y += delta1y;
  368.  
  369.          /* If the end point would be invalid, negate the delta. */
  370.  
  371.          if ( ( ptl2.x + delta2x ) > cxClient )
  372.             delta2x = -delta2x;
  373.          if ( ( ptl2.x + delta2x ) < 1 )
  374.             delta2x = -delta2x;
  375.          if ( ( ptl2.y + delta2y ) > cyClient )
  376.             delta2y = -delta2y;
  377.          if ( ( ptl2.y + delta2y ) < 1 )
  378.             delta2y = -delta2y;
  379.  
  380.          /* Add delta to end point.*/
  381.  
  382.          ptl2.x += delta2x;
  383.          ptl2.y += delta2y;
  384.  
  385.          /* Now draw the line.*/
  386.  
  387.          GpiSetColor( hps, GetFcolor());
  388.          GpiMove( hps, &ptl1 );         /* Move to start point */
  389.          GpiLine( hps, &ptl2 );         /* Draw new line       */
  390.       }
  391.    }
  392.  
  393.    /* Clean up and terminate drawing thread.*/
  394.  
  395.    MyParent->releasePresSpace( hps );
  396.    WinTerminate( habThread2 );
  397.    DosExit( EXIT_THREAD, 0UL );
  398. }
  399.