home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / pm / clipbrd / clipbrd.c < prev    next >
C/C++ Source or Header  |  1999-05-11  |  51KB  |  1,591 lines

  1. /**************************************************************************
  2.  *  File name  :  clipbrd.c
  3.  *
  4.  *  Description:  This program displays a standard window containing a
  5.  *                picture.  The action bar contains the choices Edit and
  6.  *                Help.  The Edit pull-down contains choices that let the
  7.  *                user perform clipboard operations on the picture.
  8.  *
  9.  *                This source file contains the following functions:
  10.  *
  11.  *                  main( VOID );
  12.  *                  ClipbrdHelp ( HWND, USHORT );
  13.  *                  ClearRoutine( VOID );
  14.  *                  CopyRoutine( VOID );
  15.  *                  CutRoutine( VOID );
  16.  *                  DrawRect( VOID );
  17.  *                  EraseRect( VOID );
  18.  *                  ExitRoutine( HWND );
  19.  *                  Finalize( VOID );
  20.  *                  GetBitmap( VOID );
  21.  *                  Initialize( VOID );
  22.  *                  MenuInitialization( MPARAM, MPARAM);
  23.  *                  MouseButtonDown( HWND, MPARAM);
  24.  *                  PaintRoutine( HWND );
  25.  *                  PasteRoutine( VOID );
  26.  *                  RemoveRect( VOID );
  27.  *                  Report_Error( HAB );
  28.  *                  WindowDestroy( VOID );
  29.  *                  WindowInitialization( HWND );
  30.  *                  ReportAPIError( PSZ );
  31.  *                  ProductInfoDlgProc( HWND, ULONG, MPARAM, MPARAM );
  32.  *                  HelpProductInfo( HWND );
  33.  *                  SetSysMenu( HWND );
  34.  *
  35.  *  Concepts   :  clipboard
  36.  *
  37.  *  API's      :  DevOpenDC
  38.  *                DevCloseDC
  39.  *
  40.  *                DosExit
  41.  *
  42.  *                GpiAssociate
  43.  *                GpiBox
  44.  *                GpiBitBlt
  45.  *                GpiCreateBitmap
  46.  *                GpiCreatePS
  47.  *                GpiDestroyPS
  48.  *                GpiDeleteBitmap
  49.  *                GpiLoadBitmap
  50.  *                GpiQueryBitmapParameters
  51.  *                GpiQueryColor
  52.  *                GpiQueryLineType
  53.  *                GpiSetCurrentPosition
  54.  *                GpiSetColor
  55.  *                GpiSetLineType
  56.  *                GpiSetBitmap
  57.  *
  58.  *                WinCreateStdWindow
  59.  *                WinCreateMsgQueue
  60.  *                WinCloseClipbrd
  61.  *                WinDispatchMsg
  62.  *                WinDefDlgProc
  63.  *                WinDefWindowProc
  64.  *                WinDestroyWindow
  65.  *                WinDestroyMsgQueue
  66.  *                WinDlgBox
  67.  *                WinFillRect
  68.  *                WinFreeErrorInfo
  69.  *                WinGetMsg
  70.  *                WinGetErrorInfo
  71.  *                WinIsRectEmpty
  72.  *                WinInitialize
  73.  *                WinLoadString
  74.  *                WinMessageBox
  75.  *                WinOpenClipbrd
  76.  *                WinOpenWindowDC
  77.  *                WinPostMsg
  78.  *                WinQuerySysValue
  79.  *                WinQueryClipbrdData
  80.  *                WinQuerySysPointer
  81.  *                WinQueryWindowText
  82.  *                WinQueryWindowRect
  83.  *                WinQueryUpdateRect
  84.  *                WinRegisterClass
  85.  *                WinSendMsg
  86.  *                WinSetFocus
  87.  *                WinSetPointer
  88.  *                WinSetClipbrdData
  89.  *                WinSetRect
  90.  *                WinSetWindowText
  91.  *                WinTerminate
  92.  *                WinTrackRect
  93.  *                WinValidateRect
  94.  *                WinWindowFromID
  95.  *
  96.  *  Required
  97.  *    Files    :  OS2.H, STRING.H, CLIPBRD.H
  98.  *
  99.  *  Copyright (C) 1991 IBM Corporation
  100.  *
  101.  *      DISCLAIMER OF WARRANTIES.  The following [enclosed] code is
  102.  *      sample code created by IBM Corporation. This sample code is not
  103.  *      part of any standard or IBM product and is provided to you solely
  104.  *      for  the purpose of assisting you in the development of your
  105.  *      applications.  The code is provided "AS IS", without
  106.  *      warranty of any kind.  IBM shall not be liable for any damages
  107.  *      arising out of your use of the sample code, even if they have been
  108.  *      advised of the possibility of such damages.                                                    *
  109.  *************************************************************************/
  110.  
  111. #define INCL_DEV
  112. #define INCL_WINWINDOWMGR
  113. #define INCL_WINDIALOGS
  114. #define INCL_WININPUT
  115. #define INCL_WINRECTANGLES
  116. #define INCL_WINACCELERATORS
  117. #define INCL_WINPOINTERS
  118. #define INCL_WINSETERRORINFO
  119. #define INCL_WINMESSAGEMGR
  120. #define INCL_WINBUTTONS
  121. #define INCL_WINEDITCTLS
  122. #define INCL_WINLISTBOXES
  123. #define INCL_WINMENUS
  124. #define INCL_WINSCROLLBARS
  125. #define INCL_WINFRAMEMGR
  126. #define INCL_WINFRAMECTLS
  127. #define INCL_WINSYS
  128. #define INCL_WINTRACKRECT
  129. #define INCL_WINCLIPBOARD
  130. #define INCL_GPICONTROL
  131. #define INCL_GPITRANSFORMS
  132. #define INCL_GPIPRIMITIVES
  133. #define INCL_GPIREGIONS
  134. #define INCL_GPICORRELATION
  135. #define INCL_GPILCIDS
  136. #define INCL_GPIBITMAPS
  137. #define INCL_ERRORS
  138. #define INCL_DOSPROCESS
  139. #include <os2.h>
  140. #include <string.h>
  141. #include "clipbrd.h"
  142.  
  143. /*----------------- various window-dependent globals -------------------------*/
  144.  
  145. HAB     habMain;                       /* Anchor block handle                 */
  146. HMQ     hmqMain;                       /* Application queue handle            */
  147. HWND    hwndFrame=0L;                /* Frame control handle                */
  148. HWND    hwndClient;                    /* Client area handle                  */
  149. HPS     hpsClient=0L;                /* Client area gpi ps handle           */
  150. HDC     hdcClient;                     /* Window dc handle                    */
  151. HACCEL haccelMain;                     /* Accelerator table handle            */
  152. HACCEL haccelTrack;                    /* Tracking rect accelerator table     */
  153.  
  154. /*-------------------------- memory bit map globals --------------------------*/
  155.  
  156. HDC     hdcMemory;
  157. HBITMAP bmapMemory;
  158. HPS     hpsMemory;
  159.  
  160. DRIVDATA    drvdata = {44L, 0L, "DISPLAY", 0L};
  161.  
  162.   struct {
  163.     PSZ   address;
  164.     PSZ   driver_name;
  165.     PSZ   driver_data;
  166.     PSZ   data_type;
  167.     PSZ   comment;
  168.     PSZ   proc_name;
  169.     PSZ   proc_params;
  170.     PSZ   spl_params;
  171.     PSZ   network_params;
  172.          }
  173.  
  174.     dcdatablk = {0L, "DISPLAY", 0L, 0L, 0L, 0L, 0L, 0L, 0L};
  175.  
  176. BITMAPINFOHEADER2 bmpMemory;           /* bitmap information header for
  177.                                           create bitmap API                   */
  178. POINTL  aptlCorners[4];                /* rectangle corners for BitBlting     */
  179.  
  180.  
  181. /*---------------------- tracking rectangle info structure -------------------*/
  182.  
  183. TRACKINFO tiStruct;
  184.  
  185. /*----------------- only process WM_PAINT when we are ready ------------------*/
  186.  
  187. BOOL fPaintable = FALSE;
  188.  
  189. /*----------------------- Line attribute bundle ------------------------------*/
  190.  
  191. LINEBUNDLE lbndLineAttr = {(LONG)0,         /*  lColor;       */
  192.                            (LONG)0,         /*  lBackColor;   */
  193.                            FM_XOR,          /*  usMixMode;    */
  194.                            (USHORT)0,       /*  usBackMixMode */
  195.                            (FIXED)0,        /*  fxWidth;      */
  196.                            (LONG)0,         /*  lGeomWidth;   */
  197.                            (USHORT)0,       /*  usType;       */
  198.                            (USHORT)0,       /*  usEnd;        */
  199.                            (USHORT)0};      /*  usJoin;       */
  200.  
  201.  
  202. /*---------------------------- loaded strings --------------------------------*/
  203.  
  204. char szTitleBar[CCHMAXSTRING];
  205. char szTerminate[CCHMAXSTRING];
  206. char szHelp[CCHMAXSTRING];
  207. char szDefErrMesg[]  = "No further infomation";  /* message when no other     */
  208. char szApiErrTitle[] = "API Error Return";       /* title for error message   */
  209. LONG Status = SUCCESSX;
  210. BOOL fErrMem=FALSE;
  211.  
  212. /*
  213.  * Function prototypes
  214.  */
  215.  
  216. MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  217.  
  218. /**************************************************************************
  219.  *
  220.  *  Name       : main()
  221.  *
  222.  *  Description: Initializes the PM environment and processes
  223.  *               the application message queue until a WM_QUIT
  224.  *               message is received.  It then destroys all OS/2
  225.  *               PM services and terminates.
  226.  *
  227.  *  Concepts   : - obtains anchor block handle and creates message
  228.  *                   queue
  229.  *               - calls the initialization routine
  230.  *               - creates the main frame window which creates the
  231.  *                   main client window
  232.  *               - polls the message queue via Get/Dispatch Msg loop
  233.  *               - upon exiting the loop, exits
  234.  *
  235.  *  API's      :   WinInitialize
  236.  *                 WinCreateMsgQueue
  237.  *                 WinGetMsg
  238.  *                 WinDispatchMsg
  239.  *                 WinTerminate
  240.  *
  241.  *  Parameters :  [none]
  242.  *
  243.  *  Return     :  1 - if successful execution completed
  244.  *                0 - if error
  245.  *
  246.  *************************************************************************/
  247. int main()
  248. {
  249.    QMSG qmsgMain;                             /* application queue structure */
  250.  
  251.    habMain = WinInitialize(0L);
  252.    hmqMain = WinCreateMsgQueue(habMain,0);
  253.  
  254.   /*
  255.    * Test to see if the queue handle is 0L. If it is, it probably
  256.    * means that the program has been installed in Desktop Manager as
  257.    * VIO or Full Screen. In this case, the WinInitialize works,
  258.    * but creating the message queue will fail and if you continue
  259.    * with anything else you will get invalid selectors.
  260.    * You can't even put up a message box so the program will
  261.    * not start and the user will not know why!
  262.    */
  263.    if (hmqMain != (HMQ)0L)
  264.    {
  265.       if (!Initialize())
  266.       {
  267.          Report_Error(habMain);
  268.          Finalize();
  269.       }
  270.  
  271.       while (WinGetMsg(habMain, &qmsgMain, 0L, 0,0))
  272.          WinDispatchMsg(habMain, &qmsgMain);
  273.  
  274.       Finalize();
  275.    }
  276.    else
  277.    {
  278.        WinTerminate(habMain);
  279.    }
  280.    return SUCCESSX;
  281. }   /* end of main  */
  282.  
  283. /**************************************************************************
  284.  *
  285.  *  Name       : ClientWndProc
  286.  *
  287.  *  Description: This is the window procedure associated with the client
  288.  *               area in the standard frame window.  It processes all
  289.  *               messages either sent or posted to the client area,
  290.  *               depending on the message command and parameters.
  291.  *
  292.  *  Concepts   : messaging
  293.  *
  294.  *  API's      : WinMessageBox
  295.  *               WinDefWindowProc
  296.  *
  297.  *  Parameters :  hwnd = window handle
  298.  *                msg  = message i.d.
  299.  *                mp1  - first message parameter
  300.  *                mp2  - second message parameter
  301.  *
  302.  *  Return     :  depends on type of message processed
  303.  *
  304.  *************************************************************************/
  305. MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  306. {
  307.    switch (msg)
  308.    {
  309.    case WM_CREATE:
  310.       WindowInitialization(hwnd);
  311.       break;
  312.  
  313.    case WM_DESTROY:
  314.       WindowDestroy();
  315.       break;
  316.  
  317.    case WM_HELP:
  318.       WinMessageBox(HWND_DESKTOP,
  319.                     hwnd,
  320.                    (PSZ)szHelp,
  321.                    (PSZ)szTitleBar,
  322.                     0,
  323.                     MB_MOVEABLE | MB_CUANOTIFICATION | MB_OK
  324.                    );
  325.  
  326.       break;
  327.  
  328.    case WM_PAINT:
  329.       PaintRoutine(hwnd);
  330.       break;
  331.  
  332.    case WM_CLOSE:
  333.       ExitRoutine(hwnd);
  334.       break;
  335.  
  336.    case WM_INITMENU:
  337.       MenuInitialization(mp1,mp2);
  338.       break;
  339.  
  340.     /*
  341.      * process menu item commands
  342.      */
  343.    case WM_COMMAND:
  344.       switch (LOUSHORT(mp1))
  345.       {
  346.       case MENU_EXTHELP:
  347.          ClipbrdHelp( hwnd, EXTHELP );
  348.          break;
  349.       case MENU_HELPINDEX:
  350.          ClipbrdHelp( hwnd, HELPINDEX );
  351.          break;
  352.       case MENU_KEYSHELP:
  353.          ClipbrdHelp( hwnd, KEYSHELP );
  354.          break;
  355.       case MENU_HELPUSING:
  356.          ClipbrdHelp( hwnd, GENHELP );
  357.          break;
  358.       case MENU_PRODINFO:
  359.          HelpProductInfo( hwnd );
  360.          break;
  361.  
  362.       case MENU_COPY:
  363.          CopyRoutine();
  364.          break;
  365.       case MENU_PASTE:
  366.          PasteRoutine();
  367.          break;
  368.       case MENU_CUT:
  369.          CutRoutine();
  370.          break;
  371.       case MENU_CLEAR:
  372.          ClearRoutine();
  373.          break;
  374.         /*
  375.          * Unrecognized WM_COMMAND IDs are processed in a default manner.
  376.          */
  377.       default:
  378.          return(WinDefWindowProc(hwnd, msg, mp1, mp2));
  379.       }
  380.       break;
  381.  
  382.     /*
  383.      * Clear an existing rectangle from the screen, and set the process into
  384.      * track rectangle mode loop, after setting up the required parameters
  385.      */
  386.    case WM_BUTTON1DOWN:
  387.       MouseButtonDown(hwnd,mp1);
  388.       break;
  389.  
  390.  
  391.    default:
  392.       return(WinDefWindowProc(hwnd, msg, mp1, mp2));
  393.    }
  394.    return (MRESULT)0;
  395. }  /*  end of ClientWndProc  */
  396.  
  397. /**************************************************************************
  398.  *
  399.  *  Name       : ClearRoutine
  400.  *
  401.  *  Description: erases a bounding rectangle from the screen
  402.  *
  403.  *  Concepts   :
  404.  *
  405.  *  API's      : WinIsRectEmpty
  406.  *               WinSetRect
  407.  *
  408.  *  Parameters : [none]
  409.  *
  410.  *  Return     : [none]
  411.  *
  412.  *************************************************************************/
  413. VOID ClearRoutine()
  414. {
  415.     /*
  416.      * If a bounding rectangle has been defined, erase that part of the
  417.      * picture from the screen and the memory bit map.
  418.      */
  419.    if(!WinIsRectEmpty(habMain, &tiStruct.rclTrack))
  420.    {
  421.       EraseRect();
  422.       WinSetRect(habMain, &tiStruct.rclTrack, 0, 0, 0, 0);
  423.    } /* endif */
  424.    return;
  425. }  /*  end of ClearRoutine */
  426.  
  427. /**************************************************************************
  428.  *
  429.  *  Name       : ClipbrdHelp
  430.  *
  431.  *  Description: displays the appropriate help string
  432.  *
  433.  *  Concepts   : help
  434.  *
  435.  *  API's      : WinLoadString
  436.  *               WinMessageBox
  437.  *
  438.  *  Parameters : hwnd  = window handle
  439.  *               HelpId = help string i.d.
  440.  *
  441.  *  Return     : [none]
  442.  *
  443.  *************************************************************************/
  444. VOID ClipbrdHelp(HWND hwnd, USHORT HelpId)
  445. {
  446.    CHAR szTemp[CCHMAXSTRING];
  447.  
  448.    /*
  449.     * Get the appropriate help string.
  450.     */
  451.    if (!WinLoadString(habMain, (HMODULE)0L, HelpId, (SHORT)CCHMAXSTRING,
  452.                           (PSZ)szTemp))
  453.       ReportAPIError("Error loading Help String");
  454.  
  455.    /*
  456.     * Display the help string.
  457.     */
  458.    WinMessageBox(HWND_DESKTOP,
  459.                   hwnd,
  460.                   (PSZ)szTemp,
  461.                   (PSZ)szTitleBar,
  462.                   0,
  463.                   MB_MOVEABLE | MB_CUANOTIFICATION | MB_OK );
  464.    return;
  465. }  /*  end of ClipbrdHelp  */
  466.  
  467. /**************************************************************************
  468.  *
  469.  *  Name       : CopyRoutine
  470.  *
  471.  *  Description: copies a rectangle into a fresh bitmap
  472.  *
  473.  *  Concepts   :
  474.  *
  475.  *  API's      : WinOpenClipbrd
  476.  *               WinSetClipbrdData
  477.  *               WinCloseClipbrd
  478.  *
  479.  *  Parameters : [none]
  480.  *
  481.  *  Return     : [none]
  482.  *
  483.  *************************************************************************/
  484. VOID CopyRoutine()
  485. {
  486.    HBITMAP bmapTempMem;
  487.     /*
  488.      * If a bounding rectangle has been defined, copy that part of the
  489.      * memory bit map into a newly-created bitmap.
  490.      * Give the new bit map to the clipboard. Finally, clear the
  491.      * bounding rectangle.
  492.      */
  493.    bmapTempMem = GetBitmap();
  494.    if(bmapTempMem != (HBITMAP)0L)
  495.    {
  496.       WinOpenClipbrd(habMain);
  497.       WinSetClipbrdData(habMain, (ULONG)bmapTempMem, CF_BITMAP, 0L);
  498.       WinCloseClipbrd(habMain);
  499.       RemoveRect();
  500.    } /* endif */
  501.    return;
  502. }  /*  end of CopyRoutine  */
  503.  
  504. /**************************************************************************
  505.  *
  506.  *  Name       : CutRoutine
  507.  *
  508.  *  Description: cuts a rectangle to the clipboard and removes it from the
  509.  *               window
  510.  *
  511.  *  Concepts   : clipboard
  512.  *
  513.  *  API's      : WinOpenClipbrd
  514.  *               WinSetClipbrdData
  515.  *               WinCloseClipbrd
  516.  *               WinSetRect
  517.  *
  518.  *  Parameters : [none]
  519.  *
  520.  *  Return     : [none]
  521.  *
  522.  *************************************************************************/
  523. VOID CutRoutine()
  524. {
  525.   HBITMAP bmapTempMem;
  526.     /*
  527.      * If a bounding rectangle has been defined, copy that part of the
  528.      * memory bit map into a newly created bitmap.
  529.      * Give the new bitmap to the clipboard. Finally clear the
  530.      * bounding rectangle and erase that part of the picture from the
  531.      * screen and the memory bit map.
  532.      */
  533.    bmapTempMem = GetBitmap();
  534.    if (bmapTempMem != (HBITMAP)0L)
  535.    {
  536.       WinOpenClipbrd(habMain);
  537.       WinSetClipbrdData(habMain, (ULONG)bmapTempMem, CF_BITMAP, 0L);
  538.       WinCloseClipbrd(habMain);
  539.       EraseRect();
  540.       WinSetRect(habMain, &tiStruct.rclTrack, 0, 0, 0, 0);
  541.    } /* endif */
  542.    return;
  543. }  /*  end of CutRoutine  */
  544.  
  545. /**************************************************************************
  546.  *
  547.  *  Name       : DrawRect
  548.  *
  549.  *  Description: Draw a rectangle on the screen, using the last position
  550.  *               and size of the tracking rectangle.
  551.  *
  552.  *  Concepts   :
  553.  *
  554.  *  API's      : GpiQueryLineType
  555.  *               GpiSetLineType
  556.  *               GpiQueryColor
  557.  *               GpiSetColor
  558.  *               GpiSetCurrentPosition
  559.  *               GpiBox
  560.  *
  561.  *  Parameters : [none]
  562.  *
  563.  *  Return     : [none]
  564.  *
  565.  *************************************************************************/
  566. VOID DrawRect()
  567. {
  568.    POINTL ptlWork;
  569.    LONG lSaveType;
  570.    LONG lSaveColor;
  571.  
  572.    lSaveType = GpiQueryLineType(hpsClient);
  573.    GpiSetLineType(hpsClient, LINETYPE_DOT);
  574.  
  575.    lSaveColor = GpiQueryColor(hpsClient);
  576.    GpiSetColor(hpsClient,CLR_RED);
  577.  
  578.    ptlWork.x = tiStruct.rclTrack.xLeft;
  579.    ptlWork.y = tiStruct.rclTrack.yBottom;
  580.    GpiSetCurrentPosition(hpsClient, &ptlWork);
  581.  
  582.    ptlWork.x = tiStruct.rclTrack.xRight;
  583.    ptlWork.y = tiStruct.rclTrack.yTop;
  584.    GpiBox(hpsClient, DRO_OUTLINE, &ptlWork, 0L, 0L);
  585.  
  586.    GpiSetLineType(hpsClient, lSaveType);
  587.    GpiSetColor(hpsClient,lSaveColor);
  588.    return;
  589. } /*  end of DrawRect  */
  590.  
  591. /**************************************************************************
  592.  *
  593.  *  Name       : EraseRect
  594.  *
  595.  *  Description: Erase a rectangle from the screen and from the memory
  596.  *               bit map
  597.  *
  598.  *  Concepts   :
  599.  *
  600.  *  API's      : WinFillRect
  601.  *
  602.  *  Parameters : [none]
  603.  *
  604.  *  Return     : [none]
  605.  *
  606.  *************************************************************************/
  607. VOID EraseRect()
  608. {
  609.    RECTL rclErase;
  610.  
  611.    rclErase = tiStruct.rclTrack;
  612.    WinFillRect(hpsMemory, &rclErase, CLR_WHITE);
  613.    RemoveRect();
  614.    return;
  615. }  /*  end of EraseRect  */
  616.  
  617. /**************************************************************************
  618.  *
  619.  *  Name       : ExitRoutine
  620.  *
  621.  *  Description: called when PF3 is pushed, when Close is selected from
  622.  *               the System Menu, or when Exit is selected
  623.  *
  624.  *  Concepts   :
  625.  *
  626.  *  API's      : WinFillRect
  627.  *
  628.  *  Parameters : hwnd = window handle
  629.  *
  630.  *  Return     : [none]
  631.  *
  632.  *************************************************************************/
  633. VOID ExitRoutine(HWND hwnd)
  634. {
  635.    WinPostMsg(hwnd, WM_QUIT, (MPARAM)0, (MPARAM)0);
  636.    return;
  637. }   /*  end of ExitRoutine  */
  638.  
  639. /**************************************************************************
  640.  *
  641.  *  Name       : Finalize
  642.  *
  643.  *  Description: destroy all Presentation Manager resources and end the
  644.  *               process
  645.  *
  646.  *  Concepts   : termination
  647.  *
  648.  *  API's      : WinDestroyWindow
  649.  *               WinDestroyMsgQueue
  650.  *               WinTerminate
  651.  *               DosExit
  652.  *
  653.  *  Parameters : [none]
  654.  *
  655.  *  Return     : [none]
  656.  *
  657.  *************************************************************************/
  658. VOID Finalize( VOID )
  659. {
  660.    WinDestroyWindow(hwndFrame);
  661.    WinDestroyMsgQueue(hmqMain);
  662.    WinTerminate(habMain);
  663.    DosExit( Status, 0);
  664.    return;
  665. }   /*  end of Finalize  */
  666.  
  667. /**************************************************************************
  668.  *
  669.  *  Name       : GetBitmap
  670.  *
  671.  *  Description: If a bounding rectangle has been defined, create a screen
  672.  *               compatible device context and a screen compatible bit map.
  673.  *               Select the bit map into the DC, create a
  674.  *               suitably sized GPI PS and associate it with the DC.
  675.  *               BitBlt that part of the
  676.  *               screen defined by the rectangle into the new bit map.
  677.  *               Destroy all other resources but return the bit map handle
  678.  *               (to be passed to the clipboard)
  679.  *
  680.  *  Concepts   :
  681.  *
  682.  *  API's      :  WinIsRectEmpty
  683.  *                WinQuerySysPointer
  684.  *                WinSetPointer
  685.  *                DevOpenDC
  686.  *                GpiCreatePS
  687.  *                GpiCreateBitmap
  688.  *                GpiSetBitmap
  689.  *                GpiBitBlt
  690.  *                GpiAssociate
  691.  *                GpiDestroyPS
  692.  *                DevCloseDC
  693.  *
  694.  *  Parameters : [none]
  695.  *
  696.  *  Return     : bitmap handle
  697.  *
  698.  *************************************************************************/
  699. HBITMAP GetBitmap()
  700. {
  701.    HDC   hdc;
  702.    HPS   hps;
  703.    HBITMAP bmap;
  704.    register HPOINTER tptr;
  705.  
  706.    SIZEL sizlWork;
  707.  
  708.    if(WinIsRectEmpty(habMain, &tiStruct.rclTrack))
  709.    {
  710.       return((HBITMAP)0L);
  711.    } /* endif */
  712.  
  713.    if ( (tptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE)) == 0 )
  714.       ReportAPIError("Failed to get System pointer handle");
  715.    WinSetPointer(HWND_DESKTOP, tptr);
  716.   /*
  717.    * It is a bounding rectangle, so we only want what is inside.
  718.    */
  719.    sizlWork.cx = tiStruct.rclTrack.xRight - tiStruct.rclTrack.xLeft - 1;
  720.    sizlWork.cy = tiStruct.rclTrack.yTop - tiStruct.rclTrack.yBottom - 1;
  721.  
  722.    hdc = DevOpenDC(habMain,
  723.                   OD_MEMORY,
  724.                  (PSZ)"*",
  725.                   8L,
  726.                  (PDEVOPENDATA)&dcdatablk,
  727.                  (HDC)0L
  728.                  );
  729.    if (hdc == 0) ReportAPIError("DevOpenDC Failure");
  730.  
  731.    bmpMemory.cbFix           = sizeof(bmpMemory);
  732.    bmpMemory.cx              = (USHORT)sizlWork.cx;
  733.    bmpMemory.cy              = (USHORT)sizlWork.cy;
  734.    bmpMemory.cPlanes         = 1L;
  735.    bmpMemory.cBitCount       = 24L;
  736.    bmpMemory.ulCompression   = BCA_UNCOMP;
  737.    bmpMemory.cxResolution    = 0;
  738.    bmpMemory.cyResolution    = 0;
  739.    bmpMemory.cclrUsed        = 0;
  740.    bmpMemory.cclrImportant   = 0;
  741.    bmpMemory.usUnits         = BRU_METRIC;
  742.    bmpMemory.usRecording     = BRA_BOTTOMUP;
  743.    bmpMemory.usRendering     = BRH_NOTHALFTONED;
  744.    bmpMemory.cSize1          = 0;
  745.    bmpMemory.cSize2          = 0;
  746.    bmpMemory.ulColorEncoding = 0;
  747.    bmpMemory.ulIdentifier    = 0;
  748.  
  749.    hps = GpiCreatePS(habMain, hdc, &sizlWork, GPIA_ASSOC | PU_PELS);
  750.    if (hps == 0)
  751.    {
  752.      ReportAPIError("GpiCreatePS Failure");
  753.    }
  754.  
  755.    bmap = GpiCreateBitmap(hps,
  756.            (PBITMAPINFOHEADER2)&bmpMemory,
  757.            0L,
  758.            (PBYTE)NULL,
  759.            (PBITMAPINFO2)NULL
  760.             );
  761.    if (bmap ==0)
  762.    {
  763.       ReportAPIError("GpiCreateBitmap Failure");
  764.    }
  765.  
  766.    GpiSetBitmap(hps, bmap);
  767.  
  768.   /*
  769.    * No adjustments to the top and right top (using lengths) since the
  770.    * rectangles used for the BitBlt are non-inclusive (the bottom and
  771.    * left are included, but not the top and right)
  772.    */
  773.    aptlCorners[0].x = 0;
  774.    aptlCorners[0].y = 0;
  775.    aptlCorners[1].x = sizlWork.cx;
  776.    aptlCorners[1].y = sizlWork.cy;
  777.   /*
  778.    * Want to copy from inside the bounding rect. Increase the left & bottom
  779.    * by one but leave the top & right since the rectangles used for the BitBlt
  780.    * are non-inclusive (the bottom and left are included, but not the
  781.    * top and right).
  782.    */
  783.    aptlCorners[2].x = tiStruct.rclTrack.xLeft + 1;
  784.    aptlCorners[2].y = tiStruct.rclTrack.yBottom + 1;
  785.    aptlCorners[3].x = tiStruct.rclTrack.xRight;
  786.    aptlCorners[3].y = tiStruct.rclTrack.yTop;
  787.    GpiBitBlt(hps, hpsMemory, 4L, aptlCorners, ROP_SRCCOPY, BBO_IGNORE);
  788.  
  789.    GpiSetBitmap(hps, (HBITMAP)0L);
  790.    GpiAssociate(hps, (HDC)0L);
  791.    GpiDestroyPS(hps);
  792.    DevCloseDC(hdc);
  793.    WinSetPointer(HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP,
  794.                                                  SPTR_ARROW,
  795.                                                  FALSE)
  796.                                                  );
  797.    return(bmap);
  798. }  /*  end of GetBitmap  */
  799.  
  800. /**************************************************************************
  801.  *
  802.  *  Name       : Initialize
  803.  *
  804.  *  Description: initialize the PM interface,
  805.  *               create an application message queue and a
  806.  *               standard frame window
  807.  *
  808.  *  Concepts   :
  809.  *
  810.  *  API's      : WinLoadString
  811.  *               WinRegisterClass
  812.  *               WinSetPointer
  813.  *               WinQuerySysPointer
  814.  *               WinCreateStdWindow
  815.  *               WinQueryWIndowText
  816.  *               WinSetWindowText
  817.  *
  818.  *  Parameters : [none]
  819.  *
  820.  *  Return     : TRUE = successful initialization
  821.  *               FALSE = error occurred
  822.  *
  823.  *************************************************************************/
  824. BOOL Initialize()
  825. {
  826.    ULONG flCreate;
  827.    BOOL  fErrTmp=FALSE;
  828.  
  829.    fErrMem = (BOOL)!WinLoadString(habMain,
  830.                                 (HMODULE)0L,
  831.                                 (USHORT)TERMINATE,
  832.                                 (SHORT)CCHMAXSTRING,
  833.                                 (PSZ)szTerminate
  834.                                 );
  835.    fErrTmp = (BOOL)!WinLoadString(habMain,
  836.                                 (HMODULE)0L,
  837.                                 (USHORT)HELPPANEL,
  838.                                 (SHORT)CCHMAXSTRING,
  839.                                 (PSZ)szHelp
  840.                                 );
  841.    if (fErrMem || fErrTmp)
  842.       return(FALSE);
  843.  
  844.    if (!WinRegisterClass(habMain,
  845.                          (PSZ)"My Class",
  846.                          (PFNWP)ClientWndProc,
  847.                          CS_SIZEREDRAW,
  848.                          0))
  849.  
  850.       return(FALSE);
  851.  
  852.    WinSetPointer(HWND_DESKTOP,
  853.                 WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE));
  854.  
  855.    flCreate = FCF_STANDARD;
  856.    hwndFrame = WinCreateStdWindow(HWND_DESKTOP,
  857.                                  WS_VISIBLE,
  858.                                  &flCreate,
  859.                                  (PSZ)"My Class",
  860.                                  (PSZ)NULL,
  861.                                  WS_VISIBLE,
  862.                                  (HMODULE)0L,
  863.                                  AMENU,
  864.                                  &hwndClient
  865.                                  );
  866.  
  867.    WinSetWindowText(hwndFrame, "CLIPBOARD SAMPLE");
  868.  
  869.    WinSetPointer(HWND_DESKTOP,
  870.                 WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE));
  871.  
  872.    if (hwndFrame == (HWND)0L)
  873.    {
  874.       return(FALSE);
  875.    } /* endif */
  876.  
  877.   /*
  878.    * Get the window title given to the window by the system
  879.    */
  880.    WinQueryWindowText(hwndFrame, CCHMAXSTRING, (PSZ)szTitleBar);
  881.  
  882.    return(TRUE);
  883. }  /*  end of Initialize  */
  884.  
  885. /**************************************************************************
  886.  *
  887.  *  Name       : MenuInitialization
  888.  *
  889.  *  Description: set beginning attributes (enabled or not) of menu items
  890.  *
  891.  *  Concepts   : menu
  892.  *
  893.  *  API's      : WinIsRectEmpty
  894.  *               WinSendMsg
  895.  *               WinOpenClipbrd
  896.  *               WinQueryClipbrdData
  897.  *               WinCloseClipbrd
  898.  *
  899.  *  Parameters : mp1 = first message parameter
  900.  *               mp2 = second message parameter
  901.  *
  902.  *  Return     : [none]
  903.  *
  904.  *************************************************************************/
  905. VOID MenuInitialization(MPARAM mp1, MPARAM mp2)
  906. {
  907.    BOOL    fEmptyRect;
  908.     /*
  909.      * Menu items in the Edit pull-down may need to be grayed, depending on
  910.      * the presence of a rectangle and the contents of the clipboard.
  911.      */
  912.    if (LOUSHORT(mp1) == SM_CLIPBRD)
  913.    {
  914.       fEmptyRect = WinIsRectEmpty(habMain, &tiStruct.rclTrack);
  915.       WinSendMsg((HWND)mp2,
  916.                     MM_SETITEMATTR,
  917.                     MPFROM2SHORT(MENU_COPY, TRUE),
  918.                     MPFROM2SHORT(MIA_DISABLED,
  919.                                  fEmptyRect ? MIA_DISABLED : ~MIA_DISABLED)
  920.                                 );
  921.       WinSendMsg((HWND)mp2,
  922.                     MM_SETITEMATTR,
  923.                     MPFROM2SHORT(MENU_CUT, TRUE),
  924.                     MPFROM2SHORT(MIA_DISABLED,
  925.                                  fEmptyRect ? MIA_DISABLED : ~MIA_DISABLED)
  926.                                 );
  927.       WinSendMsg((HWND)mp2,
  928.                     MM_SETITEMATTR,
  929.                     MPFROM2SHORT(MENU_CLEAR, TRUE),
  930.                     MPFROM2SHORT(MIA_DISABLED,
  931.                                  fEmptyRect ? MIA_DISABLED : ~MIA_DISABLED)
  932.                                 );
  933.  
  934.       WinOpenClipbrd(habMain);
  935.  
  936.       if ((HBITMAP)WinQueryClipbrdData(habMain, CF_BITMAP) != (HBITMAP)0L &&
  937.             !fEmptyRect)
  938.       {
  939.          fEmptyRect = TRUE;
  940.       }
  941.       else
  942.       {
  943.          fEmptyRect = FALSE;
  944.       }
  945.       WinSendMsg((HWND)mp2,
  946.                  MM_SETITEMATTR,
  947.                  MPFROM2SHORT(MENU_PASTE, TRUE),
  948.                  MPFROM2SHORT(MIA_DISABLED,
  949.                  fEmptyRect ? ~MIA_DISABLED : MIA_DISABLED)
  950.                            );
  951.       WinCloseClipbrd(habMain);
  952.    }
  953. }   /*  end of MenuInitialization  */
  954.  
  955. /**************************************************************************
  956.  *
  957.  *  Name       : MouseButtonDown
  958.  *
  959.  *  Description: process the mouse button interface
  960.  *
  961.  *  Concepts   : rectangle tracking
  962.  *
  963.  *  API's      : WinSetFocus
  964.  *               WinIsRectEmpty
  965.  *               WinSetRect
  966.  *               WinQueryWindowRect
  967.  *               WinTrackRect
  968.  *
  969.  *  Parameters : hwnd = window handle
  970.  *               mp1 = message parameter
  971.  *
  972.  *  Return     : [none]
  973.  *
  974.  *************************************************************************/
  975. VOID MouseButtonDown(HWND hwnd, MPARAM mp1)
  976. {
  977.     /*
  978.      * As the application is handling the button message, set the focus
  979.      * to the frame window.
  980.      */
  981.    WinSetFocus(HWND_DESKTOP,hwndClient);
  982.  
  983.     /*
  984.      * Clear an existing rectangle from the screen, and set the process into
  985.      * track rectangle mode loop, after setting up the required parameters.
  986.      */
  987.    if(!WinIsRectEmpty(habMain, &tiStruct.rclTrack))
  988.    {
  989.       RemoveRect();
  990.       WinSetRect(habMain, &tiStruct.rclTrack, 0, 0, 0, 0);
  991.    } /* endif */
  992.  
  993.    tiStruct.cxBorder = 1;
  994.    tiStruct.cyBorder = 1;
  995.    tiStruct.cxGrid = 0;
  996.    tiStruct.cyGrid = 0;
  997.    WinSetRect(habMain, &tiStruct.rclTrack,
  998.              LOUSHORT(mp1),
  999.              HIUSHORT(mp1),
  1000.              LOUSHORT(mp1),
  1001.              HIUSHORT(mp1));
  1002.    WinQueryWindowRect(hwnd, &tiStruct.rclBoundary);
  1003.    tiStruct.ptlMinTrackSize.x = 1;
  1004.    tiStruct.ptlMinTrackSize.y = 1;
  1005.    tiStruct.ptlMaxTrackSize.x = ++tiStruct.rclBoundary.xRight;
  1006.    tiStruct.ptlMaxTrackSize.y = ++tiStruct.rclBoundary.yTop;
  1007.    tiStruct.fs  = TF_STANDARD | TF_ALLINBOUNDARY | TF_RIGHT | TF_BOTTOM;
  1008.    WinTrackRect(hwnd, (HPS)0L, &tiStruct);
  1009.    if((tiStruct.rclTrack.xRight - tiStruct.rclTrack.xLeft) > 2 &&
  1010.        (tiStruct.rclTrack.yTop - tiStruct.rclTrack.yBottom) > 2)
  1011.    {
  1012.       DrawRect();
  1013.    }
  1014.    else
  1015.    {
  1016.       WinSetRect(habMain, &tiStruct.rclTrack, 0, 0, 0, 0);
  1017.    } /* endif */
  1018. }    /*  end of MouseButtonDown  */
  1019.  
  1020. /**************************************************************************
  1021.  *
  1022.  *  Name       : PaintRoutine
  1023.  *
  1024.  *  Description: display bits in the window
  1025.  *
  1026.  *  Concepts   :
  1027.  *
  1028.  *  API's      : WinQueryUpdateRect
  1029.  *               GpiBitBlt
  1030.  *               WinInvalidateRect
  1031.  *               WinIsRectEmpty
  1032.  *
  1033.  *
  1034.  *  Parameters : hwnd = window handle
  1035.  *
  1036.  *  Return     : [none]
  1037.  *
  1038.  *************************************************************************/
  1039. VOID PaintRoutine(HWND hwnd)
  1040. {
  1041.    RECTL   rclUpdt;
  1042.    BOOL    RC;
  1043.      /*
  1044.       * If we are in a position to update the window, get the invalidated
  1045.       * rectangle and use this to copy from the memory bit map to the screen,
  1046.       * using a BitBlt. Finally, validate the updated rectangle.
  1047.       */
  1048.    if (fPaintable)
  1049.    {
  1050.        WinQueryUpdateRect(hwnd, &rclUpdt);
  1051.    /*
  1052.     * Want the top & right-hand side, so increase by one, since the
  1053.     * rectangles used for the BitBlt are non-inclusive (the bottom
  1054.     * and left are included, but not the top and right).
  1055.     */
  1056.        aptlCorners[0].x = rclUpdt.xLeft;
  1057.        aptlCorners[0].y = rclUpdt.yBottom;
  1058.        aptlCorners[1].x = rclUpdt.xRight+1;
  1059.        aptlCorners[1].y = rclUpdt.yTop+1;
  1060.    /*
  1061.     * Want the top & right-hand side as well, so increase by one, since the
  1062.     * rectangles used for the BitBlt are non-inclusive (the bottom
  1063.     * and left are included, but not the top and right).
  1064.     */
  1065.        aptlCorners[2].x = rclUpdt.xLeft;
  1066.        aptlCorners[2].y = rclUpdt.yBottom;
  1067.        aptlCorners[3].x = rclUpdt.xRight+1;
  1068.        aptlCorners[3].y = rclUpdt.yTop+1;
  1069.        GpiBitBlt(hpsClient,
  1070.                  hpsMemory,
  1071.                  4L,
  1072.                  aptlCorners,
  1073.                  ROP_SRCCOPY,
  1074.                  BBO_IGNORE
  1075.                 );
  1076.        RC = WinValidateRect(hwnd, &rclUpdt, FALSE);
  1077.        if (!WinIsRectEmpty(habMain, &tiStruct.rclTrack))
  1078.            DrawRect();
  1079.    }
  1080. }  /*  end of PaintRoutine  */
  1081.  
  1082. /**************************************************************************
  1083.  *
  1084.  *  Name       : PasteRoutine
  1085.  *
  1086.  *  Description: display a rectangle from the clipboard
  1087.  *
  1088.  *  Concepts   :
  1089.  *
  1090.  *  API's      : WinIsRectEmpty
  1091.  *               WinOpenClipbrd
  1092.  *               WinQueryClipbrdData
  1093.  *               GpiQueryBitmapParameters
  1094.  *               DevOpenDC
  1095.  *               GpiCreatePS
  1096.  *               GpiSetBitmap
  1097.  *               WinSetPointer
  1098.  *               GpiBitBlt
  1099.  *               GpiAssociate
  1100.  *               GpiDestroyPS
  1101.  *               DevCloseDC
  1102.  *               WinCloseClipbrd
  1103.  *               WinSetRect
  1104.  *
  1105.  *  Parameters : [none]
  1106.  *
  1107.  *  Return     : [none]
  1108.  *
  1109.  *************************************************************************/
  1110. VOID PasteRoutine()
  1111. {
  1112.    HDC     hdcTempMem;
  1113.    HBITMAP bmapTempMem;
  1114.    HPS     hpsTempMem;
  1115.    BITMAPINFOHEADER bmpTemp;
  1116.    SIZEL   sizlWork;
  1117.      /*
  1118.       * If a bounding rectangle has been defined, open the clipboard and
  1119.       * see if it contains a bit map. If one exists, create temporary DCs
  1120.       * and GPI PSs to enable the clipboard bit map to be BitBlted into
  1121.       * the memory bit map and from there onto the screen. Destroy all the
  1122.       * temporary resources, close the clipboard and clear the
  1123.       * bounding rectangle.
  1124.       */
  1125.    if (!WinIsRectEmpty(habMain, &tiStruct.rclTrack))
  1126.    {
  1127.       WinOpenClipbrd(habMain);
  1128.       bmapTempMem = (HBITMAP)WinQueryClipbrdData(habMain, CF_BITMAP);
  1129.       if(bmapTempMem != (HBITMAP)0L)
  1130.       {
  1131.          GpiQueryBitmapParameters(bmapTempMem,
  1132.                                   &bmpTemp
  1133.                                   );
  1134.           /*
  1135.            * Want to paste inside the bounding rect. So increase the
  1136.            * left & bottom by one but leave the top & right since the
  1137.            * rectangles used for the BitBlt are non-inclusive (the
  1138.            * bottom and left are included, but not the top and right).
  1139.            */
  1140.           aptlCorners[0].x = tiStruct.rclTrack.xLeft+1;
  1141.           aptlCorners[0].y = tiStruct.rclTrack.yBottom+1;
  1142.           aptlCorners[1].x = tiStruct.rclTrack.xRight;
  1143.           aptlCorners[1].y = tiStruct.rclTrack.yTop;
  1144.           /*
  1145.            * No adjustments to the top & right top (using lengths)
  1146.            * since the rectangles used for the BitBlt are
  1147.            * non-inclusive (the bottom and left are included,
  1148.            * but not the top and right).
  1149.            */
  1150.           aptlCorners[2].x = 0;
  1151.           aptlCorners[2].y = 0;
  1152.           aptlCorners[3].x = bmpTemp.cx;
  1153.           aptlCorners[3].y = bmpTemp.cy;
  1154.           hdcTempMem = DevOpenDC(habMain,
  1155.                                  OD_MEMORY,
  1156.                                 (PSZ)"*",
  1157.                                  8L,
  1158.                                 (PDEVOPENDATA)&dcdatablk,
  1159.                                 (HDC)0L
  1160.                                 );
  1161.           sizlWork.cx = bmpTemp.cx;
  1162.           sizlWork.cy = bmpTemp.cy;
  1163.           hpsTempMem = GpiCreatePS(habMain,
  1164.                                    hdcTempMem,
  1165.                                    &sizlWork,
  1166.                                    GPIA_ASSOC | PU_PELS
  1167.                                   );
  1168.           GpiSetBitmap(hpsTempMem, bmapTempMem);
  1169.           WinSetPointer(HWND_DESKTOP,
  1170.                         WinQuerySysPointer(HWND_DESKTOP,
  1171.                                            SPTR_WAIT,
  1172.                                            FALSE)
  1173.                        );
  1174.           GpiBitBlt(hpsMemory,
  1175.                     hpsTempMem,
  1176.                     4L,
  1177.                     aptlCorners,
  1178.                     ROP_SRCCOPY,
  1179.                     BBO_IGNORE
  1180.                    );
  1181.           /*
  1182.            * Want a slightly bigger rectangle for the screen because
  1183.            * we need to remove the bounding rectangle as well as do
  1184.            * the paste.
  1185.            */
  1186.           aptlCorners[2].x =  (--aptlCorners[0].x);
  1187.           aptlCorners[2].y =  (--aptlCorners[0].y);
  1188.           aptlCorners[3].x =  (++aptlCorners[1].x);
  1189.           aptlCorners[3].y =  (++aptlCorners[1].y);
  1190.           GpiBitBlt(hpsClient,
  1191.                     hpsMemory,
  1192.                     4L,
  1193.                     aptlCorners,
  1194.                     ROP_SRCCOPY,
  1195.                     BBO_IGNORE
  1196.                    );
  1197.           WinSetPointer(HWND_DESKTOP,
  1198.                         WinQuerySysPointer(HWND_DESKTOP,
  1199.                                            SPTR_ARROW,
  1200.                                            FALSE)
  1201.                        );
  1202.  
  1203.           GpiSetBitmap(hpsTempMem, (HBITMAP)0L);
  1204.           GpiAssociate(hpsTempMem, (HDC)0L);
  1205.           GpiDestroyPS(hpsTempMem);
  1206.           DevCloseDC(hdcTempMem);
  1207.       } /* endif */
  1208.       WinCloseClipbrd(habMain);
  1209.       WinSetRect(habMain, &tiStruct.rclTrack, 0, 0, 0, 0);
  1210.    } /* endif */
  1211. }   /* end of PasteRoutine  */
  1212.  
  1213. /**************************************************************************
  1214.  *
  1215.  *  Name       : RemoveRect
  1216.  *
  1217.  *  Description: Update the screen from the memory bitmap, thus erasing
  1218.  *               the rectangle
  1219.  *
  1220.  *  Concepts   :  bitblt
  1221.  *
  1222.  *  API's      : GpiBitBlt
  1223.  *               WinSetRect
  1224.  *
  1225.  *  Parameters : [none]
  1226.  *
  1227.  *  Return     : [none]
  1228.  *
  1229.  *************************************************************************/
  1230. VOID RemoveRect()
  1231. {
  1232.   /*
  1233.    * Want the top & right-hand side as well, so increase by one since the
  1234.    * rectangles used for the BitBlt are non-inclusive (the
  1235.    * bottom and left are included, but not the top and right).
  1236.    */
  1237.    aptlCorners[0].x = tiStruct.rclTrack.xLeft;
  1238.    aptlCorners[0].y = tiStruct.rclTrack.yBottom;
  1239.    aptlCorners[1].x = tiStruct.rclTrack.xRight+1;
  1240.    aptlCorners[1].y = tiStruct.rclTrack.yTop+1;
  1241.  
  1242.   /*
  1243.    * Want the top & right-hand side as well, so increase by one since the
  1244.    * rectangles used for the BitBlt are non-inclusive (the
  1245.    * bottom and left are included, but not the top and right).
  1246.    */
  1247.    aptlCorners[2].x = tiStruct.rclTrack.xLeft;
  1248.    aptlCorners[2].y = tiStruct.rclTrack.yBottom;
  1249.    aptlCorners[3].x = tiStruct.rclTrack.xRight+1;
  1250.    aptlCorners[3].y = tiStruct.rclTrack.yTop+1;
  1251.    GpiBitBlt(hpsClient,
  1252.              hpsMemory,
  1253.              4L,
  1254.              aptlCorners,
  1255.              ROP_SRCCOPY,
  1256.              BBO_IGNORE
  1257.             );
  1258.  
  1259.  
  1260.    WinSetRect(habMain, &tiStruct.rclTrack, 0, 0, 0, 0);
  1261. }  /* end of RemoveRect */
  1262.  
  1263. /**************************************************************************
  1264.  *
  1265.  *  Name       : Report_Error
  1266.  *
  1267.  *  Description: Display a particular system error message, the latest one
  1268.  *               for the required thread.  No resources can be loaded in
  1269.  *               case of memory error.
  1270.  *
  1271.  *  Concepts   :
  1272.  *
  1273.  *  API's      : WinGetErrorInfo
  1274.  *               WinMessageBox
  1275.  *               WinFreeErrorInfo
  1276.  *
  1277.  *  Parameters : hab = anchor block handle
  1278.  *
  1279.  *  Return     : [none]
  1280.  *
  1281.  *************************************************************************/
  1282. VOID Report_Error(HAB hab)
  1283. {
  1284.    PERRINFO  perriBlk;
  1285.    PSZ       pszErrMsg;
  1286.    PSZ       pszOffSet;
  1287.  
  1288.    if (!fErrMem)
  1289.    {
  1290.       if((perriBlk = WinGetErrorInfo(hab)) != (PERRINFO)NULL)
  1291.       {
  1292.          pszOffSet = ((PSZ)perriBlk) + perriBlk->offaoffszMsg;
  1293.          pszErrMsg = ((PSZ)perriBlk) + *((PUSHORT)pszOffSet);
  1294.  
  1295.          WinMessageBox(HWND_DESKTOP,
  1296.                         hwndFrame,
  1297.                        (PSZ)(pszErrMsg),
  1298.                        (PSZ)szTitleBar,
  1299.                         0,
  1300.                         MB_MOVEABLE | MB_CUACRITICAL | MB_CANCEL );
  1301.           WinFreeErrorInfo(perriBlk);
  1302.           return;
  1303.       }
  1304.    } /* endif */
  1305.    WinMessageBox(HWND_DESKTOP,
  1306.                  hwndFrame,
  1307.                  (PSZ)"ERROR - Out Of Memory",
  1308.                  (PSZ)szTitleBar,
  1309.                  0,
  1310.                  MB_MOVEABLE | MB_CUACRITICAL | MB_CANCEL);
  1311. }  /* end of Report_Error */
  1312.  
  1313. /**************************************************************************
  1314.  *
  1315.  *  Name       : WindowDestroy
  1316.  *
  1317.  *  Description: destroy particular window data
  1318.  *
  1319.  *  Concepts   :
  1320.  *
  1321.  *  API's      : GpiSetBitmap
  1322.  *               GpiDeleteBitmap
  1323.  *               GpiAssociate
  1324.  *               GpiDestroyPS
  1325.  *               DevCloseDC
  1326.  *
  1327.  *  Parameters : [none]
  1328.  *
  1329.  *  Return     : [none]
  1330.  *
  1331.  *************************************************************************/
  1332. VOID WindowDestroy()
  1333. {
  1334.     /*
  1335.      * Deselect the bit map from the screen-compatible device context, and
  1336.      * delete the bit map. Disassociate the two GPI PSs from their respective
  1337.      * DCs and destroy the PSs. Finally destroy the memory DC.
  1338.      */
  1339.  
  1340.    GpiSetBitmap(hpsMemory, (HBITMAP)0L);
  1341.    GpiDeleteBitmap(bmapMemory);
  1342.    GpiAssociate(hpsClient, (HDC)0L);
  1343.    GpiDestroyPS(hpsClient);
  1344.    GpiAssociate(hpsMemory, (HDC)0L);
  1345.    GpiDestroyPS(hpsMemory);
  1346.    DevCloseDC(hdcMemory);
  1347.    return;
  1348. }   /*  end of WindowDestroy  */
  1349.  
  1350. /**************************************************************************
  1351.  *
  1352.  *  Name       : WindowInitialization
  1353.  *
  1354.  *  Description: create window information
  1355.  *
  1356.  *  Concepts   :
  1357.  *
  1358.  *  API's      : WinQuerySysValue
  1359.  *               WinOpenWindowDC
  1360.  *               GpiCreatePS
  1361.  *               DevOpenDC
  1362.  *               GpiSetBitmap
  1363.  *               GpiLoadBitmap
  1364.  *               GpiSetRect
  1365.  *
  1366.  *  Parameters : [none]
  1367.  *
  1368.  *  Return     : [none]
  1369.  *
  1370.  *************************************************************************/
  1371. VOID WindowInitialization(HWND hwnd)
  1372. {
  1373.    SIZEL   sizlWork;
  1374.  
  1375.     /*
  1376.      * Get the maximum client area size. Create a window DC for the client
  1377.      * area and a normal GPI Presentation Space and associate the two. The
  1378.      * GPI PS will be the maximum client area size in pels. Create a
  1379.      * memory DC compatible with the screen, create a GPI PS and associate it
  1380.      * with the screen compatible DC. Load a bit map from the resource
  1381.      * file, and select the bit map into the screen-compatible DC.
  1382.      * Initialize the rectangle tracking and set a flag to enable window
  1383.      * painting.
  1384.      */
  1385.    sizlWork.cx = WinQuerySysValue(HWND_DESKTOP, SV_CXFULLSCREEN);
  1386.    sizlWork.cy = WinQuerySysValue(HWND_DESKTOP, SV_CYFULLSCREEN);
  1387.  
  1388.    hdcClient = WinOpenWindowDC(hwnd);
  1389.    hpsClient = GpiCreatePS(habMain,
  1390.                            hdcClient,
  1391.                            &sizlWork,
  1392.                            GPIA_ASSOC | PU_PELS
  1393.                           );
  1394.  
  1395.    dcdatablk.driver_data = (PSZ)&drvdata;
  1396.    hdcMemory = DevOpenDC(habMain,
  1397.                          OD_MEMORY,
  1398.                         (PSZ)"*",
  1399.                          8L,
  1400.                         (PDEVOPENDATA)&dcdatablk,
  1401.                         (HDC)0L
  1402.                         );
  1403.  
  1404.    hpsMemory = GpiCreatePS(habMain,
  1405.                            hdcMemory,
  1406.                            &sizlWork,
  1407.                            GPIA_ASSOC | PU_PELS
  1408.                           );
  1409.  
  1410.    bmapMemory = GpiLoadBitmap( hpsMemory
  1411.                              , (HMODULE)0L
  1412.                              , (USHORT)ID_BITMAP
  1413.                              , sizlWork.cx
  1414.                              , sizlWork.cy
  1415.                              );
  1416.  
  1417.    GpiSetBitmap(hpsMemory, bmapMemory);
  1418.    WinSetRect(habMain, &tiStruct.rclTrack, 0, 0, 0, 0);
  1419.  
  1420.    fPaintable = TRUE;
  1421.    return;
  1422. }   /*  end of WindowInitialization  */
  1423.  
  1424. /**************************************************************************
  1425.  *
  1426.  *  Name       : ReportAPIError
  1427.  *
  1428.  *  Description: display an error message returned from an API call
  1429.  *
  1430.  *  Concepts   :
  1431.  *
  1432.  *  API's      : WinGetErrorInfo
  1433.  *               WinMessageBox
  1434.  *               WinPostMsg
  1435.  *
  1436.  *  Parameters : what = message string
  1437.  *
  1438.  *  Return     : [none]
  1439.  *
  1440.  *************************************************************************/
  1441. VOID ReportAPIError(PSZ what)
  1442. {
  1443.    PERRINFO  pErrInfoBlk;
  1444.    PSZ       pszErrMsg;
  1445.    PSZ       pszOffSet;
  1446.    char      ErrorMsg[CCHMAXSTRING];                          /* error text buffer */
  1447.  
  1448.    pszErrMsg = &szDefErrMesg[0];               /* set default in case no err */
  1449.    strcpy(ErrorMsg, what);                     /* init message string        */
  1450.    strcat(ErrorMsg, "\n\n");                   /* double space for neatness  */
  1451.    if ((pErrInfoBlk = WinGetErrorInfo(habMain)) != (PERRINFO)NULL)
  1452.    {
  1453.        pszOffSet = ((PSZ)pErrInfoBlk) + pErrInfoBlk->offaoffszMsg;
  1454.        pszErrMsg = ((PSZ)pErrInfoBlk) + *((PUSHORT)pszOffSet);
  1455.  
  1456.        WinFreeErrorInfo(pErrInfoBlk);
  1457.    } /*  if ((pErrInfoBlk = WinGetErrorInfo(hab)) != (PCH)NULL) */
  1458.    strcat(ErrorMsg, pszErrMsg);                 /* combine specific text     */
  1459.    WinMessageBox(HWND_DESKTOP,                  /* parent window is desk top */
  1460.                  hwndFrame,                     /* owner window is our frame */
  1461.                 (PSZ)&ErrorMsg[0],              /* text for message          */
  1462.                 (PSZ)szApiErrTitle,             /* title is API error        */
  1463.                  0,                             /* null window id            */
  1464.                  MB_MOVEABLE | MB_CUACRITICAL | MB_CANCEL ); /* flags        */
  1465.    Status = ERRORX;
  1466.    WinPostMsg(hwndClient, WM_QUIT, (ULONG)0, (ULONG)0);
  1467.    return;
  1468. }  /* end of ReportAPIError  */
  1469.  
  1470. /**************************************************************************
  1471.  *
  1472.  *  Name       :  ProductInfoDlgProc(hwnd, msg, mp1, mp2)
  1473.  *
  1474.  *  Description:  Processes all messages sent to the Product
  1475.  *                information dialog
  1476.  *
  1477.  *  Concepts   :  Called for each message sent to the Product information
  1478.  *                dialog box.
  1479.  *
  1480.  *                the Product information dialog has only a button control, so this
  1481.  *                routine processes only WM_COMMAND messages.  Any
  1482.  *                WM_COMMAND posted must have come from the OK
  1483.  *                button, so we dismiss the dialog upon receiving it.
  1484.  *
  1485.  *  API's      :  WinDefDlgProc
  1486.  *
  1487.  *  Parameters :  [none]
  1488.  *
  1489.  *  Return     :  dependent on message sent
  1490.  *
  1491.  *************************************************************************/
  1492. MRESULT EXPENTRY ProductInfoDlgProc(HWND hwnd,ULONG msg, MPARAM mp1, MPARAM mp2)
  1493. {
  1494.    switch (msg)
  1495.    {
  1496.    case WM_INITDLG:
  1497.       SetSysMenu(hwnd);       /* system menu for this dialog  */
  1498.          return (MRESULT)NULL;
  1499.  
  1500.    default:
  1501.       return WinDefDlgProc(hwnd, msg, mp1, mp2);
  1502.    }
  1503.    return (MRESULT)NULL;
  1504. }   /*  End of ProductInfoDlgProc  */
  1505.  
  1506. /**************************************************************************
  1507.  *
  1508.  *  Name       :  HelpProductInfo(hwndMain)
  1509.  *
  1510.  *  Description: Processes the Product information choice from the Help
  1511.  *               pulldown
  1512.  *
  1513.  *  Concepts   : Processes the WM_COMMAND message posted by the
  1514.  *               Product information item of the Help menu
  1515.  *               Called from MainCommand when the Product information
  1516.  *               menu item is selected
  1517.  *               Calls WinDlgBox to display the Product information
  1518.  *               dialog.
  1519.  *
  1520.  *  API's      :  WinDlgBox
  1521.  *
  1522.  *  Parameters :  hwndMain = main window handle
  1523.  *
  1524.  *  Return     :  [none]
  1525.  *
  1526.  *************************************************************************/
  1527. VOID  HelpProductInfo(HWND hwndMain)
  1528. {
  1529.     /* display the Product Information dialog. */
  1530.    if(DID_ERROR == WinDlgBox(HWND_DESKTOP,
  1531.                              hwndMain,
  1532.                              (PFNWP)ProductInfoDlgProc,
  1533.                              0,
  1534.                              IDD_PRODUCTINFO,
  1535.                              (PVOID)NULL))
  1536.       ReportAPIError("Can't start dialog");
  1537.    return;
  1538. }   /*  End of HelpProductInfo   */
  1539.  
  1540. /**************************************************************************
  1541.  *
  1542.  *  Name       :  SetSysMenu(hDlg)
  1543.  *
  1544.  *  Description:  Enables only the Move and Close items in the
  1545.  *                system menu pulldown for any dialog
  1546.  *
  1547.  *  Concepts   :
  1548.  *
  1549.  *  API's      :  WinWindowFromID
  1550.  *                WinSendMsg
  1551.  *
  1552.  *  Parameters :  hDlg = dialog handle
  1553.  *
  1554.  *  Return     :  [none]
  1555.  *
  1556.  *************************************************************************/
  1557. VOID SetSysMenu(HWND hDlg)
  1558. {
  1559.    HWND     hSysMenu;
  1560.    MENUITEM Mi;
  1561.    SHORT    Pos;
  1562.    SHORT    Id;
  1563.    SHORT    cItems;
  1564.  
  1565.    /*
  1566.     *  We only want Move and Close in the system menu.
  1567.     */
  1568.    hSysMenu = WinWindowFromID(hDlg, FID_SYSMENU);
  1569.    WinSendMsg( hSysMenu, MM_QUERYITEM
  1570.              , MPFROM2SHORT(SC_SYSMENU, FALSE), MPFROMP((PCH) & Mi));
  1571.    Pos = 0;
  1572.    cItems = (SHORT)WinSendMsg( Mi.hwndSubMenu, MM_QUERYITEMCOUNT,
  1573.                                (MPARAM)NULL, (MPARAM)NULL);
  1574.    while (cItems--)
  1575.    {
  1576.       Id = SHORT1FROMMR(WinSendMsg( Mi.hwndSubMenu, MM_ITEMIDFROMPOSITION
  1577.                          , MPFROM2SHORT(Pos, TRUE), (MPARAM)NULL));
  1578.       switch (Id)
  1579.       {
  1580.       case SC_MOVE:
  1581.       case SC_CLOSE:
  1582.          Pos++;  /* Don't delete that one. */
  1583.          break;
  1584.       default:
  1585.          WinSendMsg( Mi.hwndSubMenu, MM_DELETEITEM
  1586.                      , MPFROM2SHORT(Id, TRUE), (MPARAM)NULL);
  1587.       }
  1588.    }
  1589. } /*  End of SetSysMenu  */
  1590. /***************************  End of clipbrd.c  **************************/
  1591.