home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / SAMPLES / DIBVIEW / CLIPBRD.C_ / CLIPBRD.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  11.1 KB  |  413 lines

  1. /*************************************************************************
  2.  
  3.       File:  CLIPBRD.C
  4.  
  5.    Purpose:  Contains routines related to cutting/pasting bitmaps to/from
  6.              the clipboard.
  7.  
  8.  Functions:  CopyHandle
  9.              CropBitmap
  10.              RenderFormat
  11.              HandleCopyClipboard
  12.              HandlePasteClipboard
  13.  
  14.   Comments:
  15.  
  16.    History:   Date      Reason
  17.              6/ 1/91     Created
  18.  
  19. *************************************************************************/
  20.  
  21. #include "master.h"
  22.  
  23. RECT  grcClip     = {0,0,0,0};    // Clipboard rectangle at time of copy.
  24.  
  25.  
  26.  
  27. //---------------------------------------------------------------------
  28. //
  29. // Function:   CopyHandle
  30. //
  31. // Purpose:    Makes a copy of the given global memory block.  Returns
  32. //             a handle to the new memory block (NULL on error).
  33. //
  34. //             Routine stolen verbatim out of ShowDIB.
  35. //
  36. // Parms:      h == Handle to global memory to duplicate.
  37. //
  38. // Returns:    Handle to new global memory block.
  39. //
  40. // History:   Date      Reason
  41. //             ???      Created
  42. //
  43. //---------------------------------------------------------------------
  44.  
  45. HANDLE CopyHandle (HANDLE h)
  46. {
  47.    BYTE huge *lpCopy;
  48.    BYTE huge *lp;
  49.    HANDLE     hCopy;
  50.    DWORD      dwLen;
  51.  
  52.    if (!h)
  53.       return NULL;
  54.  
  55.    dwLen = GlobalSize (h);
  56.  
  57.    if (hCopy = GlobalAlloc (GHND, dwLen))
  58.       {
  59.       lpCopy = (BYTE huge *)GlobalLock (hCopy);
  60.       lp     = (BYTE huge *)GlobalLock (h);
  61.  
  62.       while (dwLen--)
  63.          *lpCopy++ = *lp++;
  64.  
  65.       GlobalUnlock (hCopy);
  66.       GlobalUnlock (h);
  67.       }
  68.  
  69.    return hCopy;
  70. }
  71.  
  72.  
  73.  
  74.  
  75.  
  76. //---------------------------------------------------------------------
  77. //
  78. // Function:   CropBitmap
  79. //
  80. // Purpose:    Crops a bitmap to a new size specified by the lpRect
  81. //             parameter.  The lpptSize parameter is used to determine
  82. //             how much to stretch/compress the bitmap.  Returns a
  83. //             handle to a new bitmap.  If lpRect is empty, copies the
  84. //             bitmap to a new one.
  85. //
  86. //             Stolen almost verbatim out of ShowDIB.
  87. //
  88. // Parms:      hbm      == Handle to device dependent bitmap to crop.
  89. //             hPal     == Palette to use in cropping (NULL for default pal.)
  90. //             lpRect   == New bitmap's size (size we're cropping to).
  91. //             lpptSize == A scaling factor scale by the proportion:
  92. //                              Bitmap Width / lpptSize->x horizontally,
  93. //                              Bitmap Height / lpptSize->y horizontally.
  94. //                           Note that if lpptSize is set to the bitmap's
  95. //                           dimensions, no scaling occurs.
  96. //
  97. //
  98. // History:   Date      Reason
  99. //            6/15/91   Stolen from ShowDIB
  100. //
  101. //---------------------------------------------------------------------
  102.  
  103. HBITMAP CropBitmap (HBITMAP hbm,
  104.                    HPALETTE hPal,
  105.                      LPRECT lpRect,
  106.                     LPPOINT lpptSize)
  107. {
  108.    HDC      hMemDCsrc;
  109.    HDC      hMemDCdst;
  110.    HBITMAP  hNewBm = NULL;
  111.    BITMAP   bm;
  112.    int      dxDst,dyDst, dxSrc, dySrc;
  113.    double   cxScale, cyScale;
  114.    HPALETTE hOldPal1 = NULL;
  115.    HPALETTE hOldPal2 = NULL;
  116.  
  117.    if (!hbm)
  118.       return NULL;
  119.  
  120.    GetObject (hbm, sizeof(BITMAP), (LPSTR)&bm);
  121.  
  122.    hMemDCsrc = CreateCompatibleDC (NULL);
  123.    hMemDCdst = CreateCompatibleDC (NULL);
  124.  
  125.    if (hPal)
  126.       {
  127.       hOldPal1 = SelectPalette (hMemDCsrc, hPal, FALSE);
  128.       hOldPal2 = SelectPalette (hMemDCdst, hPal, FALSE);
  129.       RealizePalette (hMemDCdst);
  130.       }
  131.  
  132.    dxDst     = lpRect->right  - lpRect->left;
  133.    dyDst     = lpRect->bottom - lpRect->top;
  134.    cxScale   = (double) bm.bmWidth  / lpptSize->x;
  135.    cyScale   = (double) bm.bmHeight / lpptSize->y;
  136.    dxSrc     = (int) ((lpRect->right - lpRect->left) * cxScale);
  137.    dySrc     = (int) ((lpRect->bottom - lpRect->top) * cyScale);
  138.  
  139.    if (dxDst == 0 || dyDst == 0)
  140.       {
  141.       dxDst = bm.bmWidth;
  142.       dyDst = bm.bmHeight;
  143.       }
  144.  
  145.    if (dxSrc == 0)
  146.       dxSrc = 1;
  147.  
  148.    if (dySrc == 0)
  149.       dySrc = 1;
  150.  
  151.    hNewBm = CreateBitmap (dxDst, dyDst, bm.bmPlanes, bm.bmBitsPixel, NULL);
  152.  
  153.    if (hNewBm)
  154.       {
  155.       HBITMAP hOldBitmap1, hOldBitmap2;
  156.  
  157.       hOldBitmap1 = SelectObject (hMemDCsrc, hbm);
  158.       hOldBitmap2 = SelectObject (hMemDCdst, hNewBm);
  159.  
  160.       StretchBlt (hMemDCdst,
  161.                   0,
  162.                   0,
  163.                   dxDst,
  164.                   dyDst,
  165.                   hMemDCsrc,
  166.                   (int) (lpRect->left * cxScale),
  167.                   (int) (lpRect->top  * cyScale),
  168.                   dxSrc,
  169.                   dySrc,
  170.                   SRCCOPY);
  171.  
  172.       SelectObject (hMemDCsrc, hOldBitmap1);
  173.       SelectObject (hMemDCdst, hOldBitmap2);
  174.       }
  175.  
  176.    if (hOldPal1)
  177.       SelectPalette (hMemDCsrc, hOldPal1, FALSE);
  178.  
  179.    if (hOldPal2)
  180.       SelectPalette (hMemDCdst, hOldPal1, FALSE);
  181.  
  182.    DeleteDC (hMemDCsrc);
  183.    DeleteDC (hMemDCdst);
  184.  
  185.    return hNewBm;
  186. }
  187.  
  188.  
  189.  
  190. //---------------------------------------------------------------------
  191. //
  192. // Function:   RenderFormat
  193. //
  194. // Purpose:    Renders an object for the clipboard.  The format is
  195. //             specified in the "cf" variable (either CF_BITMAP,
  196. //             CF_DIB, or CF_PALETTE).
  197. //
  198. //             Stolen almost verbatim out of ShowDIB.
  199. //
  200. // Parms:      hWndClip == Window clipboard belongs to, and where our
  201. //                         image is stored).
  202. //             cf       == Format to render (CF_BITMAP, CF_DIB, CF_PALETTE)
  203. //             ptDIBSize== Size of the DIB in the given window.
  204. //
  205. // History:   Date      Reason
  206. //             ???      Created
  207. //
  208. //---------------------------------------------------------------------
  209.  
  210. HANDLE RenderFormat (HWND hWndClip, int cf, POINT ptDIBSize)
  211. {
  212.    HANDLE    h = NULL;
  213.    HBITMAP   hBitmap;
  214.    HANDLE    hDIB;
  215.    HANDLE    hDIBInfo;
  216.    LPDIBINFO lpDIBInfo;
  217.    HPALETTE  hPalette;        // Handle to the bitmap's palette.
  218.  
  219.  
  220.    if (!hWndClip)
  221.       return NULL;
  222.  
  223.    hDIBInfo = GetWindowWord (hWndClip, WW_DIB_HINFO);
  224.  
  225.    if (!hDIBInfo)
  226.       return NULL;
  227.  
  228.    lpDIBInfo    = (LPDIBINFO) GlobalLock (hDIBInfo);
  229.    hDIB         = lpDIBInfo->hDIB;
  230.    hPalette     = lpDIBInfo->hPal;
  231.    hBitmap      = lpDIBInfo->hBitmap;
  232.    GlobalUnlock (hDIBInfo);
  233.  
  234.    switch (cf)
  235.       {
  236.       case CF_BITMAP:
  237.          h = CropBitmap (hBitmap, hPalette, &grcClip, &ptDIBSize);
  238.          break;
  239.  
  240.  
  241.       case CF_DIB:
  242.          {
  243.          HBITMAP hbm;
  244.  
  245.             // NOTE:  For simplicity, we use the display device to crop
  246.             //        the bitmap.  This means that we may lose color
  247.             //        precision (if the display device has less color
  248.             //        precision than the DIB).  This isn't usually a
  249.             //        problem, as users shouldn't really be editting
  250.             //        images on devices that can't display them.
  251.  
  252.          hbm = RenderFormat (hWndClip, CF_BITMAP, ptDIBSize);
  253.  
  254.          if (hbm)
  255.             {
  256.             h = BitmapToDIB (hbm, hPalette);
  257.             DeleteObject (hbm);
  258.             }
  259.          break;
  260.          }
  261.  
  262.  
  263.       case CF_PALETTE:
  264.          if (hPalette)
  265.             h = CopyPaletteChangingFlags (hPalette, 0);
  266.          break;
  267.    }
  268.  
  269.    return h;
  270. }
  271.  
  272.  
  273.  
  274.  
  275. //---------------------------------------------------------------------
  276. //
  277. // Function:   HandleCopyClipboard
  278. //
  279. // Purpose:    User wants to copy the current DIB to the clipboard.
  280. //             Tell the clipboard we can render a DIB, DDB, and a
  281. //             palette (defer rendering until we get a WM_RENDERFORMAT
  282. //             in our MDI child window procedure in CHILD.C).
  283. //
  284. // Parms:      None
  285. //
  286. //
  287. // History:   Date      Reason
  288. //            6/1/91    Created
  289. //           11/4/91    Init grcClip to full DIB size if
  290. //                      it is currently empty.
  291. //
  292. //---------------------------------------------------------------------
  293.  
  294. void HandleCopyClipboard (void)
  295. {
  296.    HWND    hDIBWnd;
  297.  
  298.    hDIBWnd = GetCurrentMDIWnd ();
  299.  
  300.    if (!hDIBWnd)
  301.       {
  302.       DIBError (ERR_NOCLIPWINDOW);
  303.       return;
  304.       }
  305.  
  306.       // Clean clipboard of contents, and tell it we can render
  307.       //  a DIB, a DDB, and/or a palette.
  308.  
  309.    if (OpenClipboard (hDIBWnd))
  310.       {
  311.       EmptyClipboard ();
  312.       SetClipboardData (CF_DIB ,NULL);
  313.       SetClipboardData (CF_BITMAP  ,NULL);
  314.       SetClipboardData (CF_PALETTE ,NULL);
  315.       CloseClipboard ();
  316.  
  317.  
  318.          // Set our globals to tell our app which child window
  319.          //  owns the clipboard, and the clipping rectangle at
  320.          //  the time of the copy.  If the clipping rectangle is
  321.          //  empty, then use the entire DIB window.
  322.  
  323.       hWndClip   = hDIBWnd;
  324.       grcClip    = GetCurrentClipRect (hWndClip);
  325.       ptClipSize = GetCurrentDIBSize (hWndClip);
  326.  
  327.       if (IsRectEmpty (&grcClip))
  328.          {
  329.          grcClip.left   = 0;
  330.          grcClip.top    = 0;
  331.          grcClip.right  = ptClipSize.x;
  332.          grcClip.bottom = ptClipSize.y;
  333.          }
  334.       }
  335.    else
  336.       DIBError (ERR_CLIPBUSY);
  337. }
  338.  
  339.  
  340.  
  341. //---------------------------------------------------------------------
  342. //
  343. // Function:   HandlePasteClipboard
  344. //
  345. // Purpose:    User wants to paste the clipboard's contents to our
  346. //             app.  Open a new DIB window with the bitmap in the
  347. //             clipboard.
  348. //
  349. // Parms:      None
  350. //
  351. // History:   Date      Reason
  352. //            6/1/91    Created
  353. //
  354. //---------------------------------------------------------------------
  355.  
  356. void HandlePasteClipboard (void)
  357. {
  358.    HANDLE     hDIB;
  359.    HBITMAP    hBitmap;
  360.    HPALETTE   hPal;
  361.    char       szTitle [20];
  362.    static int nPasteNum = 1;     // For window title
  363.  
  364.       // Open up the clipboard.  This routine assumes our app has
  365.       //  the focus (which it should, as the user just picked the
  366.       //  paste operation off the menu, and Windows is a non-preemptive
  367.       //  system.  First we try for a DIB; if that's not available go
  368.       //  for a bitmap (and a palette if one can be had).  Whatever
  369.       //  format's available, we have to copy immediately (since the
  370.       //  handle returned by GetClipboardData() belongs to the clipboard.
  371.       //  Finally, go create the new MDI child window.
  372.  
  373.    if (OpenClipboard (GetFocus ()))
  374.       {
  375.       if (IsClipboardFormatAvailable (CF_DIB))
  376.          {
  377.          hDIB = CopyHandle (GetClipboardData (CF_DIB));
  378.          }
  379.  
  380.       else if (IsClipboardFormatAvailable (CF_BITMAP))
  381.          {
  382.          hBitmap = GetClipboardData (CF_BITMAP);
  383.  
  384.          if (IsClipboardFormatAvailable (CF_PALETTE))
  385.             hPal = GetClipboardData (hPal);
  386.          else
  387.             hPal = GetStockObject (DEFAULT_PALETTE);
  388.  
  389.          hDIB = BitmapToDIB (hBitmap, hPal);
  390.          }
  391.  
  392.       else
  393.          DIBError (ERR_NOCLIPFORMATS);
  394.  
  395.       CloseClipboard ();
  396.  
  397.  
  398.          // The window title is of the form: "Clipboard1".  The
  399.          //  number in the title is changed for each paste operation.
  400.  
  401.       wsprintf (szTitle, "Paste%d", nPasteNum++);
  402.  
  403.  
  404.          // Perform the actual window opening.
  405.  
  406.       OpenDIBWindow (hDIB, szTitle);
  407.       }
  408.    else
  409.       DIBError (ERR_CLIPBUSY);
  410. }
  411.  
  412.  
  413.