home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / WIN_NT / MASK2.ZIP / MASKBLT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-03  |  28.5 KB  |  833 lines

  1. /**************************************************************************\
  2. *  maskblt.c -- sample program demonstrating MaskBlt()
  3. *
  4. *         Steve Firebaugh
  5. *         Microsoft Developer Support
  6. *         Copyright (c) 1992, 1993 Microsoft Corporation
  7. *
  8. *  design:  There is one main window with one dialog box maskblted to fill
  9. *   the top of it.  The parameters for the MaskBlt() are stored in the
  10. *   entry fields of this dialog box.  The user may change these values and
  11. *   see the effect on the blt.  The top dialog also offers a chance to
  12. *   select from standard raster operations.
  13. *
  14. *  other modules:  track.c  bitmap.c
  15. *   (these other 2 modules are the same for all of the XBlt samples,
  16. *   i.e. STREBLT, PLGBLT, ...)
  17. *
  18. \**************************************************************************/
  19.  
  20. #include <windows.h>
  21. #include <commdlg.h>
  22. #include <math.h>
  23. #include <stdio.h>
  24. #include "maskblt.h"
  25. #include "track.h"
  26. #include "bitmap.h"
  27.  
  28.  
  29. /* Global variables */
  30. HANDLE hInst;
  31. HWND   hwndMain, hwndDlg;
  32.  
  33. PTrackObject ptoSrc, ptoDest, ptoMask = NULL;
  34. HDC          hdcSrc, hdcDest, hdcMask;
  35. HBITMAP      hbmSrc = NULL;
  36. HBITMAP      hbmMask = NULL;
  37.  
  38. #define NONE -1
  39. int iPatternBrush = NONE;
  40.  
  41.  
  42.  
  43. /**************************************************************************\
  44. *
  45. *  function:  WinMain()
  46. *
  47. *  input parameters:  c.f. generic sample
  48. *
  49. \**************************************************************************/
  50. int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  51.                      LPSTR lpCmdLine, int nCmdShow)
  52. {
  53.     MSG   msg;
  54.     RECT rect;
  55.     HANDLE haccel;
  56.  
  57.  
  58.     UNREFERENCED_PARAMETER( lpCmdLine );
  59.  
  60.  
  61.     /* Check for previous instance.  If none, then register class. */
  62.     if (!hPrevInstance) {
  63.         WNDCLASS  wc;
  64.  
  65.         wc.style = 0;
  66.         wc.lpfnWndProc = (WNDPROC)MainWndProc;
  67.  
  68.         wc.cbClsExtra = 0;
  69.         wc.cbWndExtra = 0;
  70.         wc.hInstance = hInstance;
  71.         wc.hIcon = LoadIcon(hInstance, "MaskBltIcon");
  72.         wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  73.         wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
  74.         wc.lpszMenuName =  NULL;
  75.         wc.lpszClassName = "MaskBlt";
  76.  
  77.         if (!RegisterClass(&wc)) return (FALSE);
  78.     }  /* class registered o.k. */
  79.  
  80.  
  81.     /* Create the main window.  Return false if CreateWindow() fails */
  82.     hInst = hInstance;
  83.  
  84.     hwndMain = CreateWindow(
  85.         "MaskBlt",
  86.         "MaskBlt",
  87.         WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  88.         CW_USEDEFAULT,
  89.         CW_USEDEFAULT,
  90.         CW_USEDEFAULT,
  91.         CW_USEDEFAULT,
  92.         NULL,
  93.         NULL,
  94.         hInstance,
  95.         NULL);
  96.  
  97.     if (!hwndMain) return (FALSE);
  98.  
  99.  
  100.     /* create the top dialog as a child of the main window. */
  101.     hwndDlg = CreateDialog (hInst, "maskbltDlg", hwndMain, (DLGPROC)DlgProc);
  102.  
  103.     /* Send main window a WM_SIZE message so that it will size the top
  104.      *  dialog correctly.
  105.      */
  106.     GetClientRect (hwndMain, &rect);
  107.     SendMessage (hwndMain, WM_SIZE, 0, (rect.right - rect.left));
  108.     ShowWindow (hwndDlg, SW_SHOW);
  109.     ShowWindow(hwndMain, nCmdShow);
  110.  
  111.  
  112.     /* Load the accelerator table that provides clipboard support. */
  113.     haccel = LoadAccelerators (hInst, "bltAccel");
  114.  
  115.  
  116.     /* Loop getting messages and dispatching them. */
  117.     while (GetMessage(&msg,NULL, 0,0)) {
  118.       if (!TranslateAccelerator(hwndMain, haccel, &msg))
  119.       if (!IsDialogMessage (hwndDlg, &msg)){
  120.         DispatchMessage(&msg);
  121.       }
  122.     }
  123.  
  124.     /* Return the value from PostQuitMessage */
  125.     return (msg.wParam);
  126. }
  127.  
  128.  
  129.  
  130.  
  131. /**************************************************************************\
  132. *
  133. *  function:  MainWndProc()
  134. *
  135. *  input parameters:  normal window procedure parameters.
  136. *
  137. *  There are 6 different HDCs used for the main window (in addition to the
  138. *   temporary one returned from BeginPaint).  There are two for each of the
  139. *   three thirds of the window.  The first one contains the bitmap.  The
  140. *   second one is for the track object and is stored in the TRACKOBJECT
  141. *   structure.
  142. *
  143. *  global variables:
  144. *   hwndDlg - dialog with entry fields containing parameters.
  145. *   ptoDest, ptoSrc, ptoMask - pointers to the direct manipulation objects
  146. *   hdcDest, hdcSrc, hdcMask - HDCs for the 3 sub regions of the window.
  147. *   hbmSrc, hbmMask          - bitmap handles for source and mask.
  148. *   iPatternBrush - Selection from combo box, set into the hdc.
  149. \**************************************************************************/
  150. LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  151. {
  152. static int miniWidth;
  153. static RECT rect;
  154. static HANDLE hPenGrid, hPenSeparator;
  155.  
  156.   switch (message) {
  157.  
  158.     /**********************************************************************\
  159.     *  WM_CREATE
  160.     *
  161.     * Get three new HDCs, then create three new track objects.
  162.     *  Each track object has different allowed tracking modes.
  163.     *  Finally create two pens for drawing later on.
  164.     \**********************************************************************/
  165.     case WM_CREATE:
  166.         hdcSrc  = GetDC (hwnd);
  167.         hdcDest = GetDC (hwnd);
  168.         hdcMask = GetDC (hwnd);
  169.  
  170.         ptoDest = doTrackObject (NULL, TROB_NEW, hwnd,0);
  171.         ptoDest->allowedModes = TMMOVE | TMSIZEXY;
  172.         ptoSrc  = doTrackObject (NULL, TROB_NEW, hwnd,0);
  173.         ptoSrc->allowedModes = TMMOVE;
  174.         ptoMask = doTrackObject (NULL, TROB_NEW, hwnd,0);
  175.         ptoMask->allowedModes = TMMOVE;
  176.  
  177.         hPenGrid      = CreatePen (PS_SOLID, 1, GRIDCOLOR);
  178.         hPenSeparator = CreatePen (PS_SOLID, 2*SEPARATORWIDTH, (COLORREF) 0x01000000);
  179.     break;
  180.  
  181.  
  182.     /**********************************************************************\
  183.     *  WM_DESTROY
  184.     *
  185.     * Complement of WM_CREATE.  Free up all of the HDCs, send all of the
  186.     *  track objects their delete messages, delete the pens,
  187.     *  then call PostQuitMessage.
  188.     \**********************************************************************/
  189.     case WM_DESTROY:
  190.         ReleaseDC (hwnd, hdcSrc );
  191.         ReleaseDC (hwnd, hdcDest);
  192.         ReleaseDC (hwnd, hdcMask);
  193.         doTrackObject (ptoDest, TROB_DELETE, hwnd,0);
  194.         doTrackObject (ptoSrc , TROB_DELETE, hwnd,0);
  195.         doTrackObject (ptoMask, TROB_DELETE, hwnd,0);
  196.  
  197.         DeleteObject(hPenGrid);
  198.         DeleteObject(hPenSeparator);
  199.  
  200.         PostQuitMessage(0);
  201.     break;
  202.  
  203.  
  204.  
  205.     /**********************************************************************\
  206.     *  WM_SIZE
  207.     *
  208.     * Stretch the top dialog to fill the width of the main window.
  209.     * Adjust the viewport origins of the 6 HDCs.
  210.     * Set the clip regions of the 6 HDCs.
  211.     \**********************************************************************/
  212.     case WM_SIZE: {
  213.         HRGN hrgn;
  214.  
  215.         SetWindowPos (hwndDlg, NULL, 0,0, LOWORD(lParam), DIALOGHEIGHT, 0);
  216.  
  217.         GetClientRect (hwndMain, &rect);
  218.         miniWidth = rect.right/3;
  219.  
  220.         SetViewportOrgEx (hdcDest,      0,           DIALOGHEIGHT, NULL);
  221.         SetViewportOrgEx (ptoDest->hdc, 0,           DIALOGHEIGHT, NULL);
  222.         SetViewportOrgEx (hdcSrc,       miniWidth,   DIALOGHEIGHT, NULL);
  223.         SetViewportOrgEx (ptoSrc->hdc,  miniWidth,   DIALOGHEIGHT, NULL);
  224.         SetViewportOrgEx (hdcMask,      2*miniWidth, DIALOGHEIGHT, NULL);
  225.         SetViewportOrgEx (ptoMask->hdc, 2*miniWidth, DIALOGHEIGHT, NULL);
  226.  
  227.         ptoDest->rectClip.left    = 0;
  228.         ptoDest->rectClip.top     = DIALOGHEIGHT;
  229.         ptoDest->rectClip.right   = miniWidth-2*SEPARATORWIDTH;
  230.         ptoDest->rectClip.bottom  = rect.bottom;
  231.         hrgn = CreateRectRgnIndirect (&ptoDest->rectClip);
  232.         SelectClipRgn (hdcDest,      hrgn);
  233.         SelectClipRgn (ptoDest->hdc, hrgn);
  234.         DeleteObject (hrgn);
  235.  
  236.         ptoSrc->rectClip.left    = miniWidth;
  237.         ptoSrc->rectClip.top     = DIALOGHEIGHT;
  238.         ptoSrc->rectClip.right   = 2*miniWidth-2*SEPARATORWIDTH;
  239.         ptoSrc->rectClip.bottom  = rect.bottom;
  240.         hrgn = CreateRectRgnIndirect (&ptoSrc->rectClip);
  241.         SelectClipRgn (hdcSrc,       hrgn);
  242.         SelectClipRgn (ptoSrc->hdc,  hrgn);
  243.         DeleteObject (hrgn);
  244.  
  245.         ptoMask->rectClip.left    = 2*miniWidth;
  246.         ptoMask->rectClip.top     = DIALOGHEIGHT;
  247.         ptoMask->rectClip.right   = 3*miniWidth;
  248.         ptoMask->rectClip.bottom  = rect.bottom;
  249.         hrgn = CreateRectRgnIndirect (&ptoMask->rectClip);
  250.         SelectClipRgn (hdcMask,      hrgn);
  251.         SelectClipRgn (ptoMask->hdc, hrgn);
  252.         DeleteObject (hrgn);
  253.  
  254.         SendMessage (hwndDlg, WM_PUTUPDESTRECT, (DWORD)hdcDest, (LONG)ptoDest);
  255.         SendMessage (hwndDlg, WM_PUTUPSRCRECT,  (DWORD)hdcSrc,  (LONG)ptoSrc);
  256.         SendMessage (hwndDlg, WM_PUTUPMASKPT,   (DWORD)hdcMask, (LONG)ptoMask);
  257.  
  258.         /* repaint the whole window. */
  259.         InvalidateRect (hwnd, NULL, TRUE);
  260.     } break;
  261.  
  262.  
  263.  
  264.     /**********************************************************************\
  265.     *  WM_PAINT
  266.     *
  267.     * miniWidth, rect -- set by WM_SIZE message.
  268.     *
  269.     * First shift the viewport origin down so that 0,0 is the top left
  270.     *  most visible point (out from underneath the top dialog).  Second,
  271.     *  draw the grid with wider lines on the axes.  Finally, read the
  272.     *  values out of the top dialog, do elementary validation, and then
  273.     *  try to call MaskBlt() with the values.
  274.     \**********************************************************************/
  275.      case WM_PAINT: {
  276.         HDC hdc;
  277.         PAINTSTRUCT ps;
  278.  
  279.         hdc = BeginPaint(hwnd, &ps);
  280.  
  281.         /* Draw Separator lines for the three miniareas */
  282.         SelectObject(hdc, hPenSeparator);
  283.         MoveToEx (hdc,   miniWidth-SEPARATORWIDTH,0, NULL);
  284.         LineTo   (hdc,   miniWidth-SEPARATORWIDTH, rect.bottom);
  285.         MoveToEx (hdc, 2*miniWidth-SEPARATORWIDTH,0, NULL);
  286.         LineTo   (hdc, 2*miniWidth-SEPARATORWIDTH, rect.bottom);
  287.  
  288.         /* Grid the HDCs */
  289.         SelectObject(hdcSrc, hPenGrid);
  290.         DrawGrids (hdcSrc, miniWidth, rect.bottom);
  291.         SelectObject(hdcMask, hPenGrid);
  292.         DrawGrids (hdcMask, miniWidth, rect.bottom);
  293.  
  294.         /* Draw bitmaps if any, then draw track objects over them. */
  295.         if (hbmSrc)  DrawBitmap (hdcSrc, hbmSrc);
  296.         if (hbmMask) DrawBitmap (hdcMask, hbmMask);
  297.         doTrackObject (ptoSrc , TROB_PAINT, hwnd, 0);
  298.         doTrackObject (ptoMask, TROB_PAINT, hwnd, 0);
  299.  
  300.         /* paint the left third of the window. */
  301.         SendMessage (hwnd, WM_MASKBLT, 0,0);
  302.  
  303.         EndPaint (hwnd, &ps);
  304.     } return FALSE;
  305.  
  306.  
  307.  
  308.     /**********************************************************************\
  309.     *  WM_MASKBLT
  310.     *
  311.     * WM_USER message.  This paints the left third of the window.  It
  312.     *  is called on the WM_PAINT message.  It is separated out here because
  313.     *  it is common for just the MaskBlt() to need to be called and not the
  314.     *  whole window painted.
  315.     \**********************************************************************/
  316.     case WM_MASKBLT: {
  317.         int X, Y, nWidth, nHeight;
  318.         int XSrc, YSrc, XMask, YMask;
  319.         DWORD rop, ropByte;
  320.         char buffer[MAXCHARS];
  321.  
  322.         BOOL success;
  323.         RECT cliprect;
  324.  
  325.         doTrackObject (ptoSrc , TROB_PAINT, hwnd, 0);
  326.         doTrackObject (ptoMask, TROB_PAINT, hwnd, 0);
  327.  
  328.         GetClipBox (hdcDest, &cliprect);
  329.         FillRect (hdcDest, &cliprect,
  330.                   (HBRUSH) GetClassLong (hwnd, GCL_HBRBACKGROUND));
  331.         SelectObject(hdcDest, hPenGrid);
  332.  
  333.         DrawGrids (hdcDest, miniWidth, rect.bottom);
  334.         if (IsWindow(hwndDlg)) {
  335.  
  336.           /* Grab points out of the dialog entry fields. */
  337.           X =      GetDlgItemInt(hwndDlg, DID_X,      &success, TRUE);
  338.           Y =      GetDlgItemInt(hwndDlg, DID_Y,      &success, TRUE);
  339.           nWidth = GetDlgItemInt(hwndDlg, DID_WIDTH,  &success, TRUE);
  340.           nHeight= GetDlgItemInt(hwndDlg, DID_HEIGHT, &success, TRUE);
  341.  
  342.           XSrc =   GetDlgItemInt(hwndDlg, DID_XSRC,   &success, TRUE);
  343.           YSrc =   GetDlgItemInt(hwndDlg, DID_YSRC,   &success, TRUE);
  344.           XMask =  GetDlgItemInt(hwndDlg, DID_XMASK,  &success, TRUE);
  345.           YMask =  GetDlgItemInt(hwndDlg, DID_YMASK,  &success, TRUE);
  346.  
  347.           /* get high order ROP byte and shift left by two bytes. */
  348.           GetDlgItemText(hwndDlg, DID_ROP0, buffer, MAXCHARS);
  349.           sscanf (buffer, "%lx", &ropByte);
  350.           rop = ropByte * 256 * 256 * 256;
  351.  
  352.           /* get the next ROP byte and shift left by one byte. */
  353.           GetDlgItemText(hwndDlg, DID_ROP1, buffer, MAXCHARS);
  354.           sscanf (buffer, "%lx", &ropByte);
  355.           rop += ropByte * 256 * 256;
  356.  
  357.           /* get the next ROP byte and shift left by one byte. */
  358.           GetDlgItemText(hwndDlg, DID_ROP2, buffer, MAXCHARS);
  359.           sscanf (buffer, "%lx", &ropByte);
  360.           rop += ropByte * 256;
  361.  
  362.           /* finally, get the low order ROP byte. */
  363.           GetDlgItemText(hwndDlg, DID_ROP3, buffer, MAXCHARS);
  364.           sscanf (buffer, "%lx", &ropByte);
  365.           rop += ropByte;
  366.  
  367.           /* select the pattern brush.  (user selects via combo box.) */
  368.           if (iPatternBrush != NONE)
  369.             SelectObject (hdcDest, GetStockObject (iPatternBrush));
  370.  
  371.  
  372.           /**********************************************************/
  373.           /**********************************************************/
  374.           MaskBlt (hdcDest, X, Y, nWidth, nHeight,
  375.                   hdcSrc, XSrc, YSrc,
  376.                   hbmMask, XMask, YMask, rop);
  377.           /**********************************************************/
  378.           /**********************************************************/
  379.         }
  380.         doTrackObject (ptoSrc , TROB_PAINT, hwnd, 0);
  381.         doTrackObject (ptoMask, TROB_PAINT, hwnd, 0);
  382.     } break;
  383.  
  384.  
  385.  
  386.     /**********************************************************************\
  387.     *  WM_LBUTTONDOWN & WM_RBUTTONDOWN
  388.     * On button down messages, hittest on the track object, and if
  389.     *  it returns true, then send these messages to the track object.
  390.     \**********************************************************************/
  391.     case WM_RBUTTONDOWN:
  392.     case WM_LBUTTONDOWN:
  393.       if (doTrackObject(ptoDest, TROB_HITTEST, hwnd, lParam))
  394.          doTrackObject(ptoDest, message, hwnd, lParam);
  395.       else if (doTrackObject(ptoSrc, TROB_HITTEST, hwnd, lParam))
  396.          doTrackObject(ptoSrc, message, hwnd, lParam);
  397.       else if (doTrackObject(ptoMask, TROB_HITTEST, hwnd, lParam))
  398.          doTrackObject(ptoMask, message, hwnd, lParam);
  399.     break;
  400.  
  401.  
  402.  
  403.     /**********************************************************************\
  404.     *  WM_LBUTTONUP & WM_RBUTTONDOWN & MW_MOUSEMOVE
  405.     * If the track object is in a "tracking mode" then send it these messages.
  406.     *  If the transform dialog is not minimized, fill it with numbers.
  407.     *  If the mouse dialog is not minimized, fill it with numbers.
  408.     \**********************************************************************/
  409.     case WM_RBUTTONUP:
  410.     case WM_LBUTTONUP:
  411.       /* user action complete.  Force MaskBlt() update. */
  412.       PostMessage (hwndMain, WM_MASKBLT, 0,0);
  413.     case WM_MOUSEMOVE:
  414.       if (ptoDest->Mode) {
  415.         doTrackObject(ptoDest, message, hwnd, lParam);
  416.         SendMessage (hwndDlg, WM_PUTUPDESTRECT, (DWORD) hdcDest, (LONG) ptoDest);
  417.       }
  418.       if (ptoSrc->Mode) {
  419.         doTrackObject(ptoSrc, message, hwnd, lParam);
  420.         SendMessage (hwndDlg, WM_PUTUPSRCRECT, (DWORD) hdcSrc, (LONG) ptoSrc);
  421.       }
  422.  
  423.       if (ptoMask->Mode) {
  424.         doTrackObject(ptoMask, message, hwnd, lParam);
  425.         SendMessage (hwndDlg, WM_PUTUPMASKPT, (DWORD) hdcMask, (LONG) ptoMask);
  426.       }
  427.  
  428.     break;
  429.  
  430.  
  431.  
  432.     /**********************************************************************\
  433.     *  Accelerator & clipboard support.
  434.     *
  435.     * Certain key strokes (c.f. *.rc) will cause the following WM_COMMAND
  436.     *  messages.  In response the app will copy a bitmap into the clipboard
  437.     *  or paste down from it.  In both cases, it is necessary to create a
  438.     *  new bitmap since a bitmap in the clipboard belongs to the clipboard
  439.     *  and not to the application.
  440.     \**********************************************************************/
  441.     case WM_COMMAND:
  442.       switch (LOWORD(wParam)) {
  443.         HBITMAP hbmCompat, hbmOld;
  444.         HDC hdcCompat;
  445.  
  446.         /******************************************************************\
  447.         *  WM_COMMAND, AID_COPY
  448.         *
  449.         * Create a new bitmap, copy the destination HDC bits into it,
  450.         *  and send the new bitmap to the clipboard.
  451.         \******************************************************************/
  452.         case AID_COPY: {
  453.           int X,Y, nWidth, nHeight;
  454.           BOOL success;
  455.  
  456.           X = GetDlgItemInt(hwndDlg, DID_X, &success, TRUE);
  457.           Y = GetDlgItemInt(hwndDlg, DID_Y, &success, TRUE);
  458.           nWidth = GetDlgItemInt(hwndDlg, DID_WIDTH, &success, TRUE);
  459.           nHeight = GetDlgItemInt(hwndDlg, DID_HEIGHT, &success, TRUE);
  460.  
  461.  
  462.           hdcCompat = CreateCompatibleDC(hdcDest);
  463.           hbmCompat = CreateCompatibleBitmap (hdcDest, nWidth, nHeight);
  464.           hbmOld = SelectObject(hdcCompat,hbmCompat);
  465.  
  466.           BitBlt (hdcCompat, 0,0,nWidth, nHeight, hdcDest, X,Y, SRCCOPY );
  467.  
  468.           SelectObject(hdcCompat,hbmOld);
  469.           DeleteDC(hdcCompat);
  470.  
  471.           OpenClipboard (hwnd);
  472.           SetClipboardData (CF_BITMAP,hbmCompat);
  473.           CloseClipboard ();
  474.  
  475.           DeleteObject (hbmCompat);
  476.  
  477.         } break;
  478.  
  479.  
  480.         /******************************************************************\
  481.         *  WM_COMMAND, AID_PASTE
  482.         *
  483.         * Get bitmap handle from clipboard, create a new bitmap, draw
  484.         *  the clipboard bitmap into the new one, and store the new
  485.         *  handle in the global hbmSrc.
  486.         \******************************************************************/
  487.         case AID_PASTE: {
  488.           HBITMAP hbm;
  489.           BITMAP bm;
  490.  
  491.           OpenClipboard (hwnd);
  492.           if ( hbm = GetClipboardData (CF_BITMAP)) {
  493.             DeleteObject (hbmSrc);
  494.  
  495.             GetObject (hbm, sizeof(BITMAP), &bm);
  496.  
  497.             hdcCompat = CreateCompatibleDC(hdcDest);
  498.             hbmCompat = CreateCompatibleBitmap (hdcDest, bm.bmWidth, bm.bmHeight);
  499.             hbmOld = SelectObject(hdcCompat,hbmCompat);
  500.  
  501.             DrawBitmap (hdcCompat, hbm);
  502.  
  503.             SelectObject(hdcCompat,hbmOld);
  504.             DeleteDC(hdcCompat);
  505.  
  506.             hbmSrc = hbmCompat;
  507.  
  508.             InvalidateRect (hwnd, &ptoSrc->rectClip, TRUE);
  509.             InvalidateRect (hwnd, &ptoDest->rectClip, TRUE);
  510.           }
  511.           CloseClipboard ();
  512.         } break;
  513.  
  514.         /******************************************************************\
  515.         *  WM_COMMAND, AID_CYCLE
  516.         *
  517.         * Post a COPY and PASTE command message to this window so that with
  518.         *  one key stroke the user can copy the DEST image into the clipboard,
  519.         *  paste it down into the SRC hdc and cause the blt.
  520.         \******************************************************************/
  521.         case AID_CYCLE:
  522.           PostMessage (hwnd, WM_COMMAND, MAKELONG (AID_COPY , 1), 0);
  523.           PostMessage (hwnd, WM_COMMAND, MAKELONG (AID_PASTE, 1), 0);
  524.         break;
  525.       }  /* end switch */
  526.  
  527.     break;  /* end wm_command */
  528.  
  529.  
  530.  
  531.   } /* end switch */
  532.   return (DefWindowProc(hwnd, message, wParam, lParam));
  533. }
  534.  
  535.  
  536.  
  537.  
  538. /**************************************************************************\
  539. *
  540. *  function:  DlgProc()
  541. *
  542. *  input parameters:  normal window procedure parameters.
  543. *
  544. *  Respond to user button presses by getting new bitmaps or by sending
  545. *   the main window a WM_MASKBLT message.  Also handle special user messages
  546. *   for updating the entry fields with the contents of the direct manipulation
  547. *   objects.
  548. *
  549. *  global variables:
  550. *   hwndMain - the main window.  also the parent of this dialog
  551. *   ptoDest, ptoSrc, ptoMask - pointers to the direct manipulation objects
  552. *   hdcDest, hdcSrc, hdcMask - HDCs for the 3 sub regions of the window.
  553. *   hbmSrc, hbmMask          - bitmap handles for source and mask.
  554. \**************************************************************************/
  555. LRESULT CALLBACK DlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  556. {
  557. char buffer[MAXCHARS];
  558. HBITMAP hbm;
  559.  
  560.  
  561.   switch (message) {
  562.     /**********************************************************************\
  563.     *  WM_INITDIALOG
  564.     *
  565.     * Fill the entry fields with sensible original values.
  566.     \**********************************************************************/
  567.     case WM_INITDIALOG: {
  568.       int i;
  569.  
  570.       for (i = DID_X; i<=  DID_YMASK; i++)
  571.         SetDlgItemText(hwnd, i, "0");
  572.  
  573.       /* these are the three bytes from SRCCOPY */
  574.       SetDlgItemText(hwnd, DID_ROP0  , "00");
  575.       SetDlgItemText(hwnd, DID_ROP1  , "cc");
  576.       SetDlgItemText(hwnd, DID_ROP2  , "00");
  577.       SetDlgItemText(hwnd, DID_ROP3  , "20");
  578.  
  579.       for (i = 0; i< NROPS; i++)
  580.         SendDlgItemMessage (hwnd, DID_CB_ROPS, CB_INSERTSTRING,
  581.                             (DWORD) -1, (LONG)StandardROPs[i].String);
  582.  
  583.       for (i = 0; i< NPATTERNS; i++)
  584.         SendDlgItemMessage (hwnd, DID_CB_PATTERN, CB_INSERTSTRING,
  585.                             (DWORD) -1, (LONG)Patterns[i].String);
  586.  
  587.  
  588.     } return TRUE;
  589.  
  590.  
  591.  
  592.  
  593.     /**********************************************************************\
  594.     *  WM_PUTUPDESTRECT
  595.     *
  596.     * wParam -  HDC with the needed world transform.
  597.     * lParam -  Pointer to the track object.
  598.     *
  599.     * Fill the entry fields for the destination rectangle points.
  600.     *  Conditionally change <x,y> or <width,height> depending on tracking mode.
  601.     \**********************************************************************/
  602.     case WM_PUTUPDESTRECT: {
  603.         POINT p1,p2, origin;
  604.         PTrackObject pto;
  605.         HDC hdc;
  606.  
  607.         hdc = (HDC) wParam;
  608.         pto = (PTrackObject) lParam;
  609.         GetViewportOrgEx (hdc, &origin);
  610.  
  611.         p1.x = pto->rect.left;
  612.         p1.y = pto->rect.top;
  613.         LPtoDP (pto->hdc, &p1, 1);
  614.  
  615.         p2.x = pto->rect.right;
  616.         p2.y = pto->rect.bottom;
  617.         LPtoDP (pto->hdc, &p2, 1);
  618.         p2.x -= p1.x; p2.y -= p1.y;
  619.  
  620.         p1.x -= origin.x; p1.y -= origin.y;
  621.  
  622.         if (!(pto->Mode & TMSIZEXY)) {
  623.           SetDlgItemInt(hwnd, DID_X, p1.x, TRUE);
  624.           SetDlgItemInt(hwnd, DID_Y, p1.y, TRUE);
  625.         }
  626.  
  627.         if (!(pto->Mode & TMMOVE)) {
  628.           SetDlgItemInt(hwnd, DID_WIDTH,  p2.x, TRUE);
  629.           SetDlgItemInt(hwnd, DID_HEIGHT, p2.y, TRUE);
  630.         }
  631.     } return FALSE;
  632.  
  633.  
  634.  
  635.  
  636.     /**********************************************************************\
  637.     *  WM_PUTUPSRCRECT
  638.     *
  639.     * wParam -  HDC with the needed world transform.
  640.     * lParam -  Pointer to the track object.
  641.     *
  642.     * Fill the entry fields for the source location point.
  643.     \**********************************************************************/
  644.     case WM_PUTUPSRCRECT: {
  645.         POINT p1, origin;
  646.         PTrackObject pto;
  647.         HDC hdc;
  648.  
  649.         hdc = (HDC) wParam;
  650.         pto = (PTrackObject) lParam;
  651.         GetViewportOrgEx (hdc, &origin);
  652.  
  653.         p1.x = pto->rect.left;
  654.         p1.y = pto->rect.top;
  655.         LPtoDP (pto->hdc, &p1, 1);
  656.  
  657.         p1.x -= origin.x; p1.y -= origin.y;
  658.  
  659.         SetDlgItemInt(hwnd, DID_XSRC, p1.x, TRUE);
  660.         SetDlgItemInt(hwnd, DID_YSRC, p1.y, TRUE);
  661.  
  662.     } return FALSE;
  663.  
  664.  
  665.  
  666.     /**********************************************************************\
  667.     *  WM_PUTUPMASKPT
  668.     *
  669.     * wParam -  HDC with the needed world transform.
  670.     * lParam -  Pointer to the track object.
  671.     *
  672.     * Fill the entry fields for the mask location point.
  673.     \**********************************************************************/
  674.     case WM_PUTUPMASKPT: {
  675.         POINT p1, origin;
  676.         PTrackObject pto;
  677.         HDC hdc;
  678.  
  679.         hdc = (HDC) wParam;
  680.         pto = (PTrackObject) lParam;
  681.         GetViewportOrgEx (hdc, &origin);
  682.  
  683.         p1.x = pto->rect.left;
  684.         p1.y = pto->rect.top;
  685.         LPtoDP (pto->hdc, &p1, 1);
  686.         p1.x -= origin.x; p1.y -= origin.y;
  687.  
  688.         SetDlgItemInt(hwnd, DID_XMASK, p1.x, TRUE);
  689.         SetDlgItemInt(hwnd, DID_YMASK, p1.y, TRUE);
  690.  
  691.     } return FALSE;
  692.  
  693.  
  694.  
  695.  
  696.  
  697.     case WM_COMMAND:
  698.       switch (LOWORD(wParam)) {
  699.  
  700.         /******************************************************************\
  701.         *  WM_COMMAND, DID_DRAW
  702.         *
  703.         * Draw button hit - send main window message to call MaskBlt().
  704.         \******************************************************************/
  705.         case DID_DRAW:
  706.           SendMessage (hwndMain, WM_MASKBLT, 0,0);
  707.         break;
  708.  
  709.  
  710.  
  711.  
  712.         /**********************************************************************\
  713.         *  WM_COMMAND, DID_NEWSRC
  714.         *
  715.         * Try to get a new source bitmap.  Then
  716.         *  invalidate two sub windows so that we force a repaint.
  717.         \**********************************************************************/
  718.         case DID_NEWSRC:
  719.           if ( hbm = GetBitmap (hdcSrc, hInst, FALSE)) {
  720.             DeleteObject (hbmSrc);
  721.             hbmSrc = hbm;
  722.             InvalidateRect (hwndMain, &ptoSrc->rectClip, TRUE);
  723.             InvalidateRect (hwndMain, &ptoDest->rectClip, TRUE);
  724.           }
  725.         break;
  726.  
  727.         /**********************************************************************\
  728.         *  WM_COMMAND, DID_NEWMASK
  729.         *
  730.         * Try to get a new mask bitmap.  Then
  731.         *  invalidate two sub windows so that we force a repaint.
  732.         \**********************************************************************/
  733.         case DID_NEWMASK:
  734.           if ( hbm = GetBitmap (hdcMask, hInst, TRUE)) {
  735.             DeleteObject (hbmMask);
  736.             hbmMask = hbm;
  737.             InvalidateRect (hwndMain, &ptoMask->rectClip, TRUE);
  738.             InvalidateRect (hwndMain, &ptoDest->rectClip, TRUE);
  739.           }
  740.         break;
  741.  
  742.  
  743.  
  744.         /******************************************************************\
  745.         *  WM_COMMAND, DID_CB_ROPS
  746.         *
  747.         * A new standard rop entry was selected.  Lookup the value,
  748.         *  then break it into three parts, convert to hex, and put
  749.         *  it in the proper entry fields.
  750.         \******************************************************************/
  751.         case DID_CB_ROPS:
  752.           if (HIWORD (wParam) == CBN_SELCHANGE) {
  753.             int iSel, rop;
  754.  
  755.             iSel = SendMessage ((HWND) lParam, CB_GETCURSEL, 0,0);
  756.             rop = StandardROPs[iSel].Value;
  757.             sprintf (buffer, "%2x", (rop & 0x000000ff));
  758.             SetDlgItemText(hwnd, DID_ROP3, buffer);
  759.             rop /= 256;
  760.             sprintf (buffer, "%2x", (rop & 0x000000ff));
  761.             SetDlgItemText(hwnd, DID_ROP2, buffer);
  762.             rop /= 256;
  763.             sprintf (buffer, "%2x", (rop & 0x000000ff));
  764.             SetDlgItemText(hwnd, DID_ROP1, buffer);
  765.  
  766.             SendMessage (hwndMain, WM_MASKBLT, 0,0);
  767.           }
  768.         break;
  769.  
  770.  
  771.         /******************************************************************\
  772.         *  WM_COMMAND, DID_CB_PATTERN
  773.         *
  774.         * A new pattern brush was selected.  Look up the value, store it
  775.         *  in a global variable (iPatternBrush), then force a new StretchBlt
  776.         \******************************************************************/
  777.         case DID_CB_PATTERN:
  778.           if (HIWORD (wParam) == CBN_SELCHANGE) {
  779.             int iSel;
  780.  
  781.             iSel = SendMessage ((HWND) lParam, CB_GETCURSEL, 0,0);
  782.             iPatternBrush = Patterns[iSel].Value;
  783.  
  784.             SendMessage (hwndMain, WM_MASKBLT, 0,0);
  785.           }
  786.         break;
  787.  
  788.  
  789.  
  790.       } return FALSE; /* end WM_COMMAND switch*/
  791.  
  792.   } /* end switch */
  793.   return 0;
  794. }
  795.  
  796.  
  797.  
  798. #define TICKSPACE     20
  799.  
  800. /**************************************************************************\
  801. *
  802. *  function:  DrawGrids()
  803. *
  804. *  input parameters:
  805. *   hdc - Device context to draw into.
  806. *   width, height - size of the rectangle to fill with grids.
  807. *
  808. *  global variables:  none.
  809. *
  810. \**************************************************************************/
  811. VOID DrawGrids (HDC hdc, int width, int height)
  812. {
  813. int i;
  814.  
  815.     /* Draw vertical lines. Double at the axis */
  816.     for (i = 0; i<= width; i+=TICKSPACE){
  817.       MoveToEx (hdc, i, 0, NULL);
  818.       LineTo (hdc, i, height);
  819.     }
  820.     MoveToEx (hdc, 1, 0, NULL);
  821.     LineTo (hdc, 1, height);
  822.  
  823.     /* Draw horizontal lines. Double at the axis */
  824.     for (i = 0; i<= height; i+=TICKSPACE){
  825.       MoveToEx (hdc, 0,i, NULL);
  826.       LineTo (hdc, width,i);
  827.     }
  828.     MoveToEx (hdc, 0, 1, NULL);
  829.     LineTo (hdc, width,1);
  830.  
  831.   return;
  832. }
  833.