home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / os2sdk / os2sdk11 / petzold / chap15 / blowup.c next >
Encoding:
C/C++ Source or Header  |  1989-02-20  |  12.1 KB  |  350 lines

  1. /*------------------------------------
  2.    BLOWUP.C -- Screen Capture Program
  3.   ------------------------------------*/
  4.  
  5. #define INCL_WIN
  6. #define INCL_GPI
  7. #include <os2.h>
  8. #include "blowup.h"
  9.  
  10. MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
  11.  
  12. CHAR szClientClass [] = "BlowUp" ;
  13. HAB  hab ;
  14.  
  15. int main (void)
  16.      {
  17.      static ULONG flFrameFlags = FCF_TITLEBAR      | FCF_SYSMENU  |
  18.                                  FCF_SIZEBORDER    | FCF_MINMAX   |
  19.                                  FCF_SHELLPOSITION | FCF_TASKLIST |
  20.                                  FCF_MENU          | FCF_ACCELTABLE ;
  21.      HMQ          hmq ;
  22.      HWND         hwndFrame, hwndClient ;
  23.      QMSG         qmsg ;
  24.  
  25.      hab = WinInitialize (0) ;
  26.      hmq = WinCreateMsgQueue (hab, 0) ;
  27.  
  28.      WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0) ;
  29.  
  30.      hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE,
  31.                                      &flFrameFlags, szClientClass, NULL,
  32.                                      0L, NULL, ID_RESOURCE, &hwndClient) ;
  33.  
  34.      WinSendMsg (hwndFrame, WM_SETICON,
  35.                  WinQuerySysPointer (HWND_DESKTOP, SPTR_APPICON, FALSE),
  36.                  NULL) ;
  37.  
  38.      while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
  39.           WinDispatchMsg (hab, &qmsg) ;
  40.  
  41.      WinDestroyWindow (hwndFrame) ;
  42.      WinDestroyMsgQueue (hmq) ;
  43.      WinTerminate (hab) ;
  44.      return 0 ;
  45.      }
  46.  
  47. BOOL BeginTracking (RECTL *prclTrack)
  48.      {
  49.      LONG      cxScreen, cyScreen, cxPointer, cyPointer ;
  50.      TRACKINFO ti ;
  51.  
  52.      cxScreen  = WinQuerySysValue (HWND_DESKTOP, SV_CXSCREEN) ;
  53.      cyScreen  = WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN) ;
  54.      cxPointer = WinQuerySysValue (HWND_DESKTOP, SV_CXPOINTER) ;
  55.      cyPointer = WinQuerySysValue (HWND_DESKTOP, SV_CYPOINTER) ;
  56.  
  57.                                    // Set up track rectangle for moving
  58.  
  59.      ti.cxBorder = 1 ;                       // Border width
  60.      ti.cyBorder = 1 ;
  61.      ti.cxGrid = 0 ;                         // Not used
  62.      ti.cyGrid = 0 ;
  63.      ti.cxKeyboard = 4 ;                     // Pixel increment for keyboard
  64.      ti.cyKeyboard = 4 ;
  65.  
  66.      ti.rclBoundary.xLeft   = 0 ;            // Area for tracking rectangle
  67.      ti.rclBoundary.yBottom = 0 ;
  68.      ti.rclBoundary.xRight  = cxScreen ;
  69.      ti.rclBoundary.yTop    = cyScreen ;
  70.  
  71.      ti.ptlMinTrackSize.x = 1 ;              // Minimum rectangle size
  72.      ti.ptlMinTrackSize.y = 1 ;
  73.  
  74.      ti.ptlMaxTrackSize.x = cxScreen ;       // Maximum rectangle size
  75.      ti.ptlMaxTrackSize.y = cyScreen ;
  76.                                              // Initial position
  77.  
  78.      ti.rclTrack.xLeft   = (cxScreen - cxPointer) / 2 ;
  79.      ti.rclTrack.yBottom = (cyScreen - cyPointer) / 2 ;
  80.      ti.rclTrack.xRight  = (cxScreen + cxPointer) / 2 ;
  81.      ti.rclTrack.yTop    = (cyScreen + cyPointer) / 2 ;
  82.  
  83.      ti.fs = TF_MOVE | TF_STANDARD | TF_SETPOINTERPOS ;     // Flags
  84.  
  85.      if (!WinTrackRect (HWND_DESKTOP, NULL, &ti))
  86.           return FALSE ;
  87.                                    // Switch to "sizing" pointer
  88.      WinSetPointer (HWND_DESKTOP,
  89.                WinQuerySysPointer (HWND_DESKTOP, SPTR_SIZENESW, FALSE)) ;
  90.  
  91.                                    // Track rectangle for sizing
  92.  
  93.      ti.fs = TF_RIGHT | TF_TOP | TF_STANDARD | TF_SETPOINTERPOS ;
  94.  
  95.      if (!WinTrackRect (HWND_DESKTOP, NULL, &ti))
  96.           return FALSE ;
  97.  
  98.      *prclTrack = ti.rclTrack ;    // Final rectangle
  99.  
  100.      return TRUE ;
  101.      }
  102.  
  103. HBITMAP CopyScreenToBitmap (RECTL *prclTrack)
  104.      {
  105.      BITMAPINFOHEADER bmp ;
  106.      HBITMAP          hbm ;
  107.      HDC              hdcMemory ;
  108.      HPS              hps, hpsMemory ;
  109.      LONG             alBmpFormats[2] ;
  110.      POINTL           aptl[3] ;
  111.      SIZEL            sizl ;
  112.                                    // Create memory DC and PS
  113.  
  114.      hdcMemory = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ;
  115.  
  116.      sizl.cx = sizl.cy = 0 ;
  117.      hpsMemory = GpiCreatePS (hab, hdcMemory, &sizl,
  118.                               PU_PELS    | GPIF_DEFAULT |
  119.                               GPIT_MICRO | GPIA_ASSOC) ;
  120.  
  121.                                    // Create bitmap for destination
  122.  
  123.      GpiQueryDeviceBitmapFormats (hpsMemory, 2L, alBmpFormats) ;
  124.  
  125.      bmp.cbFix     = sizeof bmp ;
  126.      bmp.cx        = (USHORT) (prclTrack->xRight - prclTrack->xLeft) ;
  127.      bmp.cy        = (USHORT) (prclTrack->yTop   - prclTrack->yBottom) ;
  128.      bmp.cPlanes   = (USHORT) alBmpFormats[0] ;
  129.      bmp.cBitCount = (USHORT) alBmpFormats[1] ;
  130.  
  131.      hbm = GpiCreateBitmap (hpsMemory, &bmp, 0L, NULL, NULL) ;
  132.  
  133.                                    // Copy from screen to bitmap
  134.      if (hbm != NULL)
  135.           {
  136.           GpiSetBitmap (hpsMemory, hbm) ;
  137.           hps = WinGetScreenPS (HWND_DESKTOP) ;
  138.  
  139.           aptl[0].x = 0 ;
  140.           aptl[0].y = 0 ;
  141.           aptl[1].x = bmp.cx ;
  142.           aptl[1].y = bmp.cy ;
  143.           aptl[2].x = prclTrack->xLeft ;
  144.           aptl[2].y = prclTrack->yBottom ;
  145.  
  146.           WinLockVisRegions (HWND_DESKTOP, TRUE) ;
  147.  
  148.           GpiBitBlt (hpsMemory, hps, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE);
  149.  
  150.           WinLockVisRegions (HWND_DESKTOP, FALSE) ;
  151.  
  152.           WinReleasePS (hps) ;
  153.           }
  154.                                    // Clean up
  155.      GpiDestroyPS (hpsMemory) ;
  156.      DevCloseDC (hdcMemory) ;
  157.  
  158.      return hbm ;
  159.      }
  160.  
  161. HBITMAP CopyBitmap (HBITMAP hbmSrc)
  162.      {
  163.      BITMAPINFOHEADER bmp ;
  164.      HBITMAP          hbmDst ;
  165.      HDC              hdcSrc, hdcDst ;
  166.      HPS              hpsSrc, hpsDst ;
  167.      POINTL           aptl[3] ;
  168.      SIZEL            sizl ;
  169.  
  170.                                    // Create memory DC's and PS's
  171.  
  172.      hdcSrc = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ;
  173.      hdcDst = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ;
  174.  
  175.      sizl.cx = sizl.cy = 0 ;
  176.      hpsSrc = GpiCreatePS (hab, hdcSrc, &sizl, PU_PELS    | GPIF_DEFAULT |
  177.                                                GPIT_MICRO | GPIA_ASSOC) ;
  178.  
  179.      hpsDst = GpiCreatePS (hab, hdcDst, &sizl, PU_PELS    | GPIF_DEFAULT |
  180.                                                GPIT_MICRO | GPIA_ASSOC) ;
  181.  
  182.                                    // Create bitmap
  183.  
  184.      GpiQueryBitmapParameters (hbmSrc, &bmp) ;
  185.      hbmDst = GpiCreateBitmap (hpsDst, &bmp, 0L, NULL, NULL) ;
  186.  
  187.                                    // Copy from source to destination
  188.  
  189.      if (hbmDst != NULL)
  190.           {
  191.           GpiSetBitmap (hpsSrc, hbmSrc) ;
  192.           GpiSetBitmap (hpsDst, hbmDst) ;
  193.  
  194.           aptl[0].x = aptl[0].y = 0 ;
  195.           aptl[1].x = bmp.cx ;
  196.           aptl[1].y = bmp.cy ;
  197.           aptl[2]   = aptl[0] ;
  198.  
  199.           GpiBitBlt (hpsDst, hpsSrc, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE) ;
  200.           }
  201.                                    // Clean up
  202.      GpiDestroyPS (hpsSrc) ;
  203.      GpiDestroyPS (hpsDst) ;
  204.      DevCloseDC (hdcSrc) ;
  205.      DevCloseDC (hdcDst) ;
  206.  
  207.      return hbmDst ;
  208.      }
  209.  
  210. VOID BitmapCreationError (HWND hwnd)
  211.      {
  212.      WinMessageBox (HWND_DESKTOP, hwnd, "Cannot create bitmap.",
  213.                     szClientClass, 0, MB_OK | MB_ICONEXCLAMATION) ;
  214.      }
  215.  
  216. MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  217.      {
  218.      static HBITMAP   hbm ;
  219.      static HWND      hwndMenu ;
  220.      static SHORT     sDisplay = IDM_ACTUAL ;
  221.      HBITMAP          hbmClip ;
  222.      HPS              hps ;
  223.      RECTL            rclTrack, rclClient ;
  224.      USHORT           usfInfo ;
  225.  
  226.      switch (msg)
  227.           {
  228.           case WM_CREATE:
  229.                hwndMenu = WinWindowFromID (
  230.                                WinQueryWindow (hwnd, QW_PARENT, FALSE),
  231.                                FID_MENU) ;
  232.                return 0 ;
  233.  
  234.           case WM_INITMENU:
  235.                switch (SHORT1FROMMP (mp1))
  236.                     {
  237.                     case IDM_EDIT:
  238.                          WinSendMsg (hwndMenu, MM_SETITEMATTR,
  239.                                      MPFROM2SHORT (IDM_COPY, TRUE),
  240.                                      MPFROM2SHORT (MIA_DISABLED,
  241.                                           hbm != NULL ? 0 : MIA_DISABLED)) ;
  242.  
  243.                          WinSendMsg (hwndMenu, MM_SETITEMATTR,
  244.                                      MPFROM2SHORT (IDM_PASTE, TRUE),
  245.                                      MPFROM2SHORT (MIA_DISABLED,
  246.                               WinQueryClipbrdFmtInfo (hab, CF_BITMAP, &usfInfo)
  247.                                         ? 0 : MIA_DISABLED)) ;
  248.                          return 0 ;
  249.                     }
  250.                break ;
  251.  
  252.           case WM_COMMAND:
  253.                switch (COMMANDMSG(&msg)->cmd)
  254.                     {
  255.                     case IDM_COPY:
  256.                                         // Make copy of stored bitmap
  257.  
  258.                          hbmClip = CopyBitmap (hbm) ;
  259.  
  260.                                         // Set clipboard data to copy of bitmap
  261.  
  262.                          if (hbmClip != NULL)
  263.                               {
  264.                               WinOpenClipbrd (hab) ;
  265.                               WinEmptyClipbrd (hab) ;
  266.                               WinSetClipbrdData (hab, (ULONG) hbmClip,
  267.                                                  CF_BITMAP, CFI_HANDLE) ;
  268.                               WinCloseClipbrd (hab) ;
  269.                               }
  270.                          else
  271.                               BitmapCreationError (hwnd) ;
  272.                          return 0 ;
  273.  
  274.                     case IDM_PASTE:
  275.                                          // Get bitmap from clipboard
  276.  
  277.                          WinOpenClipbrd (hab) ;
  278.                          hbmClip = WinQueryClipbrdData (hab, CF_BITMAP) ;
  279.  
  280.                          if (hbmClip != NULL)
  281.                               {
  282.                               if (hbm != NULL)
  283.                                    GpiDeleteBitmap (hbm) ;
  284.  
  285.                                         // Make copy of it
  286.  
  287.                               hbm = CopyBitmap (hbmClip) ;
  288.  
  289.                               if (hbm == NULL)
  290.                                    BitmapCreationError (hwnd) ;
  291.                               }
  292.                          WinCloseClipbrd (hab) ;
  293.                          WinInvalidateRect (hwnd, NULL, FALSE) ;
  294.                          return 0 ;
  295.  
  296.                     case IDM_CAPTURE:
  297.                          if (BeginTracking (&rclTrack))
  298.                               {
  299.                               if (hbm != NULL)
  300.                                    GpiDeleteBitmap (hbm) ;
  301.  
  302.                               hbm = CopyScreenToBitmap (&rclTrack) ;
  303.  
  304.                               if (hbm == NULL)
  305.                                    BitmapCreationError (hwnd) ;
  306.  
  307.                               WinInvalidateRect (hwnd, NULL, FALSE) ;
  308.                               }
  309.                          return 0 ;
  310.  
  311.                     case IDM_ACTUAL:
  312.                     case IDM_STRETCH:
  313.                          WinSendMsg (hwndMenu, MM_SETITEMATTR,
  314.                                      MPFROM2SHORT (sDisplay, TRUE),
  315.                                      MPFROM2SHORT (MIA_CHECKED, 0)) ;
  316.  
  317.                          sDisplay = COMMANDMSG(&msg)->cmd ;
  318.  
  319.                          WinSendMsg (hwndMenu, MM_SETITEMATTR,
  320.                                      MPFROM2SHORT (sDisplay, TRUE),
  321.                                      MPFROM2SHORT (MIA_CHECKED, MIA_CHECKED)) ;
  322.  
  323.                          WinInvalidateRect (hwnd, NULL, FALSE) ;
  324.                          return 0 ;
  325.                     }
  326.  
  327.           case WM_PAINT:
  328.                hps = WinBeginPaint (hwnd, NULL, NULL) ;
  329.                GpiErase (hps) ;
  330.  
  331.                if (hbm != NULL)
  332.                     {
  333.                     WinQueryWindowRect (hwnd, &rclClient) ;
  334.  
  335.                     WinDrawBitmap (hps, hbm, NULL, (PPOINTL) &rclClient,
  336.                                    CLR_NEUTRAL, CLR_BACKGROUND,
  337.                                    sDisplay == IDM_STRETCH ?
  338.                                         DBM_STRETCH : DBM_NORMAL) ;
  339.                     }
  340.                WinEndPaint (hps) ;
  341.                return 0 ;
  342.  
  343.           case WM_DESTROY:
  344.                if (hbm != NULL)
  345.                     GpiDeleteBitmap (hbm) ;
  346.                return 0 ;
  347.           }
  348.      return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
  349.      }
  350.