Solved

Copying a bitmap to the clipboard

Posted on 1999-01-04
5
487 Views
Last Modified: 2011-10-03
Hi,

I'm working with VC++ (without using MFC).
I'm trying to pass a bitmap ,that I created, to the clipboard, so other application (VB application) can present it.

Any idea how to do that ?


Many thanks?
0
Comment
Question by:amnav
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
5 Comments
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1181472
fROM THE msDN

ICCLIP.C
/***************************************************************************      *                                                                         *      *  MODULE      : ICClip.C                                                 *      *                                                                         *      *  DESCRIPTION : Clipboard functions for ImagEdit                         *      *                                                                         *      *  FUNCTIONS   : CopyImageClip ()  - Copies selected portion of image to  *      *                                    the clipboard.                       *      *                                                                         *      *                PasteImageClip () - Pastes the clipboard image to        *      *                                    selected portion of edit image.      *      *                                                                         *      *                                                                         *      *  HISTORY     : 6/21/89 - created by LR                                  *      *                                                                         *      ***************************************************************************/          #include "imagedit.h"     #include "dialogs.h"     #include "iehelp.h"       #include <windowsx.h>          /*==========================================================================       |ImagEdit's clipboard data is in two formats:                              |       |        a) a standard CF_BITMAP format  and                               |       |        b) a private ImagEdit format described below.                     |       |                                                                          |       |The private ImagEdit format data consists of:                             |       |   1.  a DWORD describing screen color when image was sent to clipboard   |       |       followed by...                                                     |       |   2.  the DIB bits of the monochrome AND image (in ghdcANDMask).         |       |                                                                          |       |The CF_BITMAP format consists of the image bitmap (the combined XOR and   |       |AND images in ghdcImage for icons and cursors).                           |       |                                                                          |       |This information is sufficient to re-create the image correctly during    |       |paste even if the screen viewing color is subsequently changed.           |       |                                                                          |       |Both formats are created if the image being edited is an icon or a cursor.|       |Only the CF_BITMAP format is created if a bitmap is being edited.         |       ==========================================================================*/          /****************************************************************************      *                                                                          *      *  FUNCTION   : BOOL PASCAL CopyImageClip(fBitmap)                         *      *                                                                          *      *  PURPOSE    : Copies the information from the selected area of image to  *      *               the clipboard.                                             *      *                                                                          *      *  SIDE EFFECTS: may change contents of the clipboard. The "pick" or clip  *      *                rectangle is reset to cover the entire image.             *      *                                                                          *      ****************************************************************************/          BOOL CopyImageClip(VOID)     {         HCURSOR hcurOld;         HBITMAP hStdBitmap;         HBITMAP hPrivBitmap;         HDC hStdDC;         HDC hPrivDC;         HANDLE hOldSObj;         HANDLE hOldPObj;         HANDLE hPriv;         LPSTR lpPriv;              hcurOld = SetCursor(hcurWait);              /* create a temp. bitmap and DC for the standard clipboard format          * along the same lines as the image bitmap          */         hStdDC = CreateCompatibleDC(ghdcImage);         hStdBitmap = MyCreateBitmap(ghdcImage, gcxPick, gcyPick, 16);         hOldSObj = SelectObject(hStdDC, hStdBitmap);              /* blt the image bits into standard format DC */         BitBlt(hStdDC, 0, 0, gcxPick, gcyPick, ghdcImage,                 grcPick.left, grcPick.top, SRCCOPY);         SelectObject(hStdDC, hOldSObj);              if (giType != FT_BITMAP) {             /* for icons and cursors, create a temp. DC and bitmap for the AND             * mask and blt the mask bits into it.             */             hPrivDC = CreateCompatibleDC(ghdcANDMask);             hPrivBitmap = CreateCompatibleBitmap(ghdcANDMask, gcxPick, gcyPick);             hOldPObj = SelectObject(hPrivDC, hPrivBitmap);             BitBlt(hPrivDC, 0, 0, gcxPick, gcyPick, ghdcANDMask,                     grcPick.left, grcPick.top, SRCCOPY);                  /* Allocate a buffer for the private ImagEdit format */             hPriv = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,                     (DWORD)((gcxPick + 31) >> 3) * gcyPick + sizeof(DWORD));             if (!hPriv) {                 DeleteDC(hStdDC);                 DeleteObject(hStdBitmap);                 DeleteDC(hPrivDC);                 DeleteObject(hPrivBitmap);                 return FALSE;             }                  lpPriv = (LPSTR)GlobalLock(hPriv);                  /* Fill in the first DWORD with the screen color information */             *((DWORD FAR *)lpPriv) = grgbScreen;                  /* Get the mask bits into the buffer */             GetBitmapBits(hPrivBitmap, (DWORD)((gcxPick + 31) >> 3) * gcyPick,                     (LPSTR)lpPriv + sizeof(DWORD));                  SelectObject(hPrivDC, hOldPObj);             DeleteObject(hPrivBitmap);             DeleteDC(hPrivDC);         }              /* Open clipboard and clear it of it's contents */         if (!OpenClipboard(ghwndMain)) {             DeleteDC(hStdDC);             return(FALSE);         }         EmptyClipboard();              if (giType != FT_BITMAP) {             /* set the private ImagEdit format data into the clipboard */             if (!SetClipboardData(ClipboardFormat, hPriv)) {                 DeleteDC(hStdDC);                 GlobalUnlock(hPriv);                 GlobalFree(hPriv);                 CloseClipboard();                 return(FALSE);             }             GlobalUnlock(hPriv);         }         /* set the standard CF_BITMAP format data in the clipboard */         if (!SetClipboardData(CF_BITMAP, hStdBitmap)) {             DeleteDC(hStdDC);             GlobalFree(hPriv);  //   hPriv may not have been initialized (if giType == BITMAP).             CloseClipboard();             return(FALSE);         }              CloseClipboard();         DeleteDC(hStdDC);              /*          * Reset pick rectangle to cover entire image.          */         PickSetRect(0, 0, gcxImage - 1, gcyImage - 1);              /*          * Erase the drag rectangle.          */         WorkUpdate();              SetCursor(hcurOld);              return TRUE;     }                    /************************************************************************     * PasteImageClip     *     * Pastes an image from the clipboard to the current image.     *     * It is assumed that this routine will not be called unless an     * image is currently being edited.     *     * The pick rectangle is reset to cover the entire image if the     * paste is successful.     *     * Basic outline of how Paste is done in ImagEdit.     *     * Find out what format is available in the clipboard:     *    a. CF_BITMAP only     *       --------------     *       case 1: Pasting to an icon or cursor     *                 * We don't have any screen color information.     *                   Make the mask bits opaque and blt. the bitmap to     *                   ghdcImage.     *     *       case 2: Pasting to a bitmap     *                 * Blt the bitmap to the image DC.     *     *    b. both ImagEdit and CF_BITMAP     *       ---------------------------     *       case 1: Pasting to an icon or cursor     *                 * Recover the image from the AND and screen color     *                   data (in ImagEdit) and the combined image bitmap     *                   (in CF_BITMAP). Use the information to make the     *                   neccessary changes if the screen viewing color was     *                   changed between Copy and Paste.     *     *       case 2: Pasting to a bitmap     *                 * Blt the CF_BITMAP data to the image DC.     *     * If the destination image differs in dimensions from     * source image, the source image is stretched or clipped to that of     * destination, depending on preference     *     * History:     *     ************************************************************************/          BOOL PasteImageClip(VOID)     {         HCURSOR hcurOld;         INT cxClip;         INT cyClip;         INT cxTarget;         INT cyTarget;         INT cxSource;         INT cySource;         DWORD rgbClipScreen;         BOOL fIEFormatFound;         HANDLE hClipData;         LPSTR lpClipData;         BITMAP bmClip;         HDC hdcClip;         HBITMAP hbmClip;         HBITMAP hbmClipOld;         HDC hdcClipAND;         HBITMAP hbmClipAND;         HBITMAP hbmClipANDOld;         HDC hdcClipAND16;         HBITMAP hbmClipAND16;         HBITMAP hbmClipAND16Old;         HDC hdcTarget;         HBITMAP hbmTarget;         HBITMAP hbmTargetOld;         HDC hdcTargetAND16;         HBITMAP hbmTargetAND16;         HBITMAP hbmTargetAND16Old;         HDC hdcTargetAND;         HBITMAP hbmTargetAND;         HBITMAP hbmTargetANDOld;              hcurOld = SetCursor(hcurWait);              if (!OpenClipboard(ghwndMain)) {             Message(MSG_NOCLIPBOARD);             goto Error1;         }              if (!(hbmClip = GetClipboardData(CF_BITMAP))) {             Message(MSG_NOCLIPBOARDFORMAT);             goto Error2;         }              GetObject(hbmClip, sizeof(BITMAP), (LPSTR)&bmClip);         cxClip = (INT)bmClip.bmWidth;         cyClip = (INT)bmClip.bmHeight;              /*          * If the dimensions of the current pick rectangle don't match          * the bitmap being pasted, ask the user if they want to stretch          * or clip the pasted image.          */         cxTarget = gcxPick;         cyTarget = gcyPick;         cxSource = cxClip;         cySource = cyClip;         if (gcxPick != cxClip || gcyPick != cyClip) {             if (DlgBox(DID_PASTEOPTIONS, (WNDPROC)PasteOptionsDlgProc) == IDCANCEL) {                 goto Error2;             }                  /*              * If clipping and the clipboard dimensions differ from the              * selected pick rectangle, then either the target dimensions              * or the source dimensions need to be sized down.              */             if (!fStretchClipboardData) {                 if (cxClip < gcxPick)                     cxTarget = cxClip;                 else                     cxSource = gcxPick;                      if (cyClip < gcyPick)                     cyTarget = cyClip;                 else                     cySource = gcyPick;             }         }              /*          * Update the undo buffer now that we are committed to the paste.          */         ImageUpdateUndo();              /*          * Determine if the private ImagEdit clipboard format is available.          */         fIEFormatFound = IsClipboardFormatAvailable(ClipboardFormat);              if (giType != FT_BITMAP && fIEFormatFound) {             /*              * Get the AND mask bitmap and the old screen color out of              * the private format.              */             hClipData = GetClipboardData(ClipboardFormat);             lpClipData = (LPSTR)GlobalLock(hClipData);             rgbClipScreen = *((DWORD FAR *)lpClipData);             hdcClipAND = CreateCompatibleDC(ghdcImage);             hbmClipAND = CreateBitmap(cxClip, cyClip, (BYTE)1, (BYTE)1,                     (LPSTR)lpClipData + sizeof(DWORD));             hbmClipANDOld = SelectObject(hdcClipAND, hbmClipAND);                  /*              * Create a color bitmap for temporary use.              */             hdcClipAND16 = CreateCompatibleDC(ghdcImage);             hbmClipAND16 = MyCreateBitmap(ghdcImage, cxSource, cySource, 16);             hbmClipAND16Old = SelectObject(hdcClipAND16, hbmClipAND16);                  /*              * Blt the AND mask onto the color bitmap.              */             BitBlt(hdcClipAND16, 0, 0, cxSource, cySource, hdcClipAND,                     0, 0, SRCCOPY);                  /*              * Create the color target AND mask bitmap.              */             hdcTargetAND16 = CreateCompatibleDC(ghdcImage);             hbmTargetAND16 = MyCreateBitmap(ghdcImage, cxTarget, cyTarget, 16);             hbmTargetAND16Old = SelectObject(hdcTargetAND16, hbmTargetAND16);                  /*              * StretchBlt from the color AND mask bitmap to the color target              * AND mask bitmap.  The blt must be done from a color bitmap to              * a color bitmap, and the stretch blt mode must be set to              * COLORONCOLOR.  All this is necessary so that the AND mask              * stays exactly in sync with the stretch blt of the color              * (XOR) mask.  If these steps are not done correctly, shrinking              * an image with screen colored pixels in it can cause problems,              * because the stretch blt will use a slightly different              * algorithm to compress the monochrome AND mask and the color              * XOR mask.              */             SetStretchBltMode(hdcTargetAND16, COLORONCOLOR);             SetStretchBltMode(hdcClipAND16, COLORONCOLOR);     //             StretchBlt(hdcTargetAND16, 0, 0, cxTarget, cyTarget, hdcClipAND16,                     0, 0, cxSource, cySource, SRCCOPY);                  /*              * Create the monochrome target AND mask bitmap.              */             hdcTargetAND = CreateCompatibleDC(ghdcImage);             hbmTargetAND = MyCreateBitmap(ghdcImage, cxTarget, cyTarget, 2);             hbmTargetANDOld = SelectObject(hdcTargetAND, hbmTargetAND);                  /*              * Blt the color AND mask onto the monochrome AND mask.              * The monochrome AND mask is the one that we will use              * later.  It must be monochrome or the ImageDCSeparate              * and ImageDCCombine functions will not work properly.              */             BitBlt(hdcTargetAND, 0, 0, cxTarget, cyTarget, hdcTargetAND16,                     0, 0, SRCCOPY);                  /*              * Cleanup.              */             SelectObject(hdcTargetAND16, hbmTargetAND16Old);             DeleteObject(hbmTargetAND16);             DeleteDC(hdcTargetAND16);             SelectObject(hdcClipAND16, hbmClipAND16Old);             DeleteObject(hbmClipAND16);             DeleteDC(hdcClipAND16);             SelectObject(hdcClipAND, hbmClipANDOld);             DeleteObject(hbmClipAND);             DeleteDC(hdcClipAND);             GlobalUnlock(hClipData);         }              /*          * Get the clipboard bitmap into a DC.          */         hdcClip = CreateCompatibleDC(ghdcImage);         hbmClipOld = SelectObject(hdcClip, hbmClip);              /*          * Create the target bitmap.          */         hdcTarget = CreateCompatibleDC(ghdcImage);         hbmTarget = MyCreateBitmap(ghdcImage, cxTarget, cyTarget, 16);         hbmTargetOld = SelectObject(hdcTarget, hbmTarget);              /*          * StretchBlt the bitmap onto the target.          */         SetStretchBltMode(hdcTarget, COLORONCOLOR);         SetStretchBltMode(hdcClip, COLORONCOLOR);     //         StretchBlt(hdcTarget, 0, 0, cxTarget, cyTarget, hdcClip, 0, 0,                 cxSource, cySource, SRCCOPY);              /*          * Handle some special cases.          */         if (giType == FT_BITMAP || !fIEFormatFound) {             /*              * The image we are pasting into is either a bitmap, or              * there does not exist an AND mask in the clipboard.              */             if (gnColors == 2) {                 /*                  * We are pasting to a mono image.  We must convert the                  * colors in the clipboard bitmap into monochrome.                  */                 ImageDCMonoBlt(hdcTarget, cxTarget, cyTarget);             }         }         else {             /*              * We are pasting into an icon or cursor image and we have              * available an AND mask.  Is the current image monochrome?              */             if (gnColors == 2) {                 /*                  * Remove the old screen/inverse colors from the image,                  * convert it to monochrome, then put back in the                  * current screen/inverse colors.                  */                 ImageDCSeparate(hdcTarget, cxTarget, cyTarget, hdcTargetAND,                         rgbClipScreen);                 ImageDCMonoBlt(hdcTarget, cxTarget, cyTarget);                 ImageDCCombine(hdcTarget, cxTarget, cyTarget, hdcTargetAND);             }             /*              * Does the screen color specified in the clipboard              * differ from the current screen color?              */             else if (rgbClipScreen != grgbScreen) {                 /*                  * Remove the old screen/inverse colors, then put back                  * in the current ones.                  */                 ImageDCSeparate(hdcTarget, cxTarget, cyTarget, hdcTargetAND,                         rgbClipScreen);                 ImageDCCombine(hdcTarget, cxTarget, cyTarget, hdcTargetAND);             }         }              /*          * Blt the clipboard image to the proper rectangle in the current image.          */         BitBlt(ghdcImage, grcPick.left, grcPick.top,                 cxTarget, cyTarget, hdcTarget, 0, 0, SRCCOPY);              /*          * If the current image is an icon or cursor, we must take care          * of the AND mask also.          */         if (giType != FT_BITMAP) {             /*              * Is there an AND mask in the clipboard to use?              */             if (fIEFormatFound) {                 /*                  * Blt it into the current image's AND mask.                  */                 BitBlt(ghdcANDMask, grcPick.left, grcPick.top,                         cxTarget, cyTarget, hdcTargetAND, 0, 0, SRCCOPY);             }             else {                 /*                  * Make the AND mask opaque, because there is no                  * screen color information.                  */                 PatBlt(ghdcANDMask, grcPick.left, grcPick.top,                         cxTarget, cyTarget, BLACKNESS);             }         }              /*          * Cleanup.          */         SelectObject(hdcTarget, hbmTargetOld);         DeleteObject(hbmTarget);         DeleteDC(hdcTarget);              if (giType != FT_BITMAP && fIEFormatFound) {             SelectObject(hdcTargetAND, hbmTargetANDOld);             DeleteObject(hbmTargetAND);             DeleteDC(hdcTargetAND);         }              SelectObject(hdcClip, hbmClipOld);         DeleteDC(hdcClip);              CloseClipboard();              /*          * Update the View and workspace windows.          */         ViewUpdate();              /*          * Reset pick rectangle to cover entire image.          */         PickSetRect(0, 0, gcxImage - 1, gcyImage - 1);              fImageDirty = TRUE;              SetCursor(hcurOld);              return TRUE;          Error2:         CloseClipboard();          Error1:         SetCursor(hcurOld);              return FALSE;     }                    /************************************************************************     * PasteOptionsDlgProc     *     * Proc for the dialog that asks the user whether they want to clip     * or stretch the bitmap being pasted in.     *     * Upon return with an IDOK value, the fStretchClipboardData global     * will be TRUE if they want to stretch, or FALSE if they want to clip.     *     * History:     *     ************************************************************************/          DIALOGPROC PasteOptionsDlgProc(         HWND hwnd,         UINT msg,         WPARAM wParam,         LPARAM lParam)     {         switch (msg) {             case WM_INITDIALOG:                 CheckRadioButton(hwnd, DID_PASTEOPTIONSSTRETCH,                         DID_PASTEOPTIONSCLIP,                         fStretchClipboardData ?                         DID_PASTEOPTIONSSTRETCH : DID_PASTEOPTIONSCLIP);                      CenterWindow(hwnd);                      break;                  case WM_COMMAND:                 switch (GET_WM_COMMAND_ID(wParam, lParam)) {                     case IDOK :                         if (IsDlgButtonChecked(hwnd, DID_PASTEOPTIONSSTRETCH))                             fStretchClipboardData = TRUE;                         else                             fStretchClipboardData = FALSE;                              EndDialog(hwnd, IDOK);                         break;                          case IDCANCEL:                         EndDialog(hwnd, IDCANCEL);                         break;                          case IDHELP:                         WinHelp(ghwndMain, gszHelpFile, HELP_CONTEXT,                                 HELPID_PASTEOPTIONS);                         break;                 }                      break;                  default:                 return FALSE;         }              return TRUE;     }                    /************************************************************************     * PickSetRect     *     * Sets the globals for the picking rectangle size.  This affects     * what is copied into the clipboard.     *     * Arguments:     *     * History:     *     ************************************************************************/          VOID PickSetRect(         INT xLeft,         INT yTop,         INT xRight,         INT yBottom)     {         SetRect(&grcPick, xLeft, yTop, xRight, yBottom);         gcxPick = (grcPick.right - grcPick.left) + 1;         gcyPick = (grcPick.bottom - grcPick.top) + 1;     }
 

0
 
LVL 4

Expert Comment

by:nil_dib
ID: 1181473
cool :-)
0
 

Author Comment

by:amnav
ID: 1181474
Not clear enogh
0
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1181475
Please post an email adres so I can send it to you
0
 
LVL 13

Accepted Solution

by:
Mirkwood earned 100 total points
ID: 1181476
Retry
ICCLIP.C
/***********************************************************************
     *  MODULE      : ICClip.C                                                 *
     *                                                                         *
     *  DESCRIPTION : Clipboard functions for ImagEdit                         *
     *                                                                         *
     *  FUNCTIONS   : CopyImageClip ()  - Copies selected portion of image to  *
     *                                    the clipboard.                       *
     *                                                                         *
     *                PasteImageClip () - Pastes the clipboard image to        *
     *                                    selected portion of edit image.      *
     *                                                                         *
     *                                                                         *
     *  HISTORY     : 6/21/89 - created by LR                                  *
     *                                                                         *
     ***************************************************************************/
     
    #include "imagedit.h"
    #include "dialogs.h"
    #include "iehelp.h"
     
 #include <windowsx.h>
     
    /*==========================================================================
      |ImagEdit's clipboard data is in two formats:                              |
      |        a) a standard CF_BITMAP format  and                               |
      |        b) a private ImagEdit format described below.                     |
      |                                                                          |
      |The private ImagEdit format data consists of:                             |
      |   1.  a DWORD describing screen color when image was sent to clipboard   |
      |       followed by...                                                     |
      |   2.  the DIB bits of the monochrome AND image (in ghdcANDMask).         |
      |                                                                          |
      |The CF_BITMAP format consists of the image bitmap (the combined XOR and   |
      |AND images in ghdcImage for icons and cursors).                           |
      |                                                                          |
      |This information is sufficient to re-create the image correctly during    |
      |paste even if the screen viewing color is subsequently changed.           |
      |                                                                          |
      |Both formats are created if the image being edited is an icon or a cursor.|
      |Only the CF_BITMAP format is created if a bitmap is being edited.         |
      ==========================================================================*/
     
    /****************************************************************************
     *                                                                          *
     *  FUNCTION   : BOOL PASCAL CopyImageClip(fBitmap)                         *
     *                                                                          *
     *  PURPOSE    : Copies the information from the selected area of image to  *
     *               the clipboard.                                             *
     *                                                                          *
     *  SIDE EFFECTS: may change contents of the clipboard. The "pick" or clip  *
     *                rectangle is reset to cover the entire image.             *
     *                                                                          *
     ****************************************************************************/
     
    BOOL CopyImageClip(VOID)
    {
        HCURSOR hcurOld;
        HBITMAP hStdBitmap;
        HBITMAP hPrivBitmap;
        HDC hStdDC;
        HDC hPrivDC;
        HANDLE hOldSObj;
        HANDLE hOldPObj;
        HANDLE hPriv;
        LPSTR lpPriv;
     
        hcurOld = SetCursor(hcurWait);
     
        /* create a temp. bitmap and DC for the standard clipboard format
         * along the same lines as the image bitmap
         */
        hStdDC = CreateCompatibleDC(ghdcImage);
        hStdBitmap = MyCreateBitmap(ghdcImage, gcxPick, gcyPick, 16);
        hOldSObj = SelectObject(hStdDC, hStdBitmap);
     
        /* blt the image bits into standard format DC */
        BitBlt(hStdDC, 0, 0, gcxPick, gcyPick, ghdcImage,
                grcPick.left, grcPick.top, SRCCOPY);
        SelectObject(hStdDC, hOldSObj);
     
        if (giType != FT_BITMAP) {
            /* for icons and cursors, create a temp. DC and bitmap for the AND
            * mask and blt the mask bits into it.
            */
            hPrivDC = CreateCompatibleDC(ghdcANDMask);
            hPrivBitmap = CreateCompatibleBitmap(ghdcANDMask, gcxPick, gcyPick);
            hOldPObj = SelectObject(hPrivDC, hPrivBitmap);
            BitBlt(hPrivDC, 0, 0, gcxPick, gcyPick, ghdcANDMask,
                    grcPick.left, grcPick.top, SRCCOPY);
     
            /* Allocate a buffer for the private ImagEdit format */
            hPriv = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
                    (DWORD)((gcxPick + 31) >> 3) * gcyPick + sizeof(DWORD));
            if (!hPriv) {
                DeleteDC(hStdDC);
                DeleteObject(hStdBitmap);
                DeleteDC(hPrivDC);
                DeleteObject(hPrivBitmap);
                return FALSE;
            }
     
            lpPriv = (LPSTR)GlobalLock(hPriv);
     
            /* Fill in the first DWORD with the screen color information */
            *((DWORD FAR *)lpPriv) = grgbScreen;
     
            /* Get the mask bits into the buffer */
            GetBitmapBits(hPrivBitmap, (DWORD)((gcxPick + 31) >> 3) * gcyPick,
                    (LPSTR)lpPriv + sizeof(DWORD));
     
            SelectObject(hPrivDC, hOldPObj);
            DeleteObject(hPrivBitmap);
            DeleteDC(hPrivDC);
        }
     
        /* Open clipboard and clear it of it's contents */
        if (!OpenClipboard(ghwndMain)) {
            DeleteDC(hStdDC);
            return(FALSE);
        }
        EmptyClipboard();
     
        if (giType != FT_BITMAP) {
            /* set the private ImagEdit format data into the clipboard */
            if (!SetClipboardData(ClipboardFormat, hPriv)) {
                DeleteDC(hStdDC);
                GlobalUnlock(hPriv);
                GlobalFree(hPriv);
                CloseClipboard();
                return(FALSE);
            }
            GlobalUnlock(hPriv);
        }
        /* set the standard CF_BITMAP format data in the clipboard */
        if (!SetClipboardData(CF_BITMAP, hStdBitmap)) {
            DeleteDC(hStdDC);
            GlobalFree(hPriv);  //   hPriv may not have been initialized (if giType == BITMAP).
            CloseClipboard();
            return(FALSE);
        }
     
        CloseClipboard();
        DeleteDC(hStdDC);
     
        /*
         * Reset pick rectangle to cover entire image.
         */
        PickSetRect(0, 0, gcxImage - 1, gcyImage - 1);
     
        /*
         * Erase the drag rectangle.
         */
        WorkUpdate();
     
        SetCursor(hcurOld);
     
        return TRUE;
    }
     
     
     
    /************************************************************************
    * PasteImageClip
    *
    * Pastes an image from the clipboard to the current image.
    *
    * It is assumed that this routine will not be called unless an
    * image is currently being edited.
    *
    * The pick rectangle is reset to cover the entire image if the
    * paste is successful.
    *
    * Basic outline of how Paste is done in ImagEdit.
    *
    * Find out what format is available in the clipboard:
    *    a. CF_BITMAP only
    *       --------------
    *       case 1: Pasting to an icon or cursor
    *                 * We don't have any screen color information.
    *                   Make the mask bits opaque and blt. the bitmap to
    *                   ghdcImage.
    *
    *       case 2: Pasting to a bitmap
    *                 * Blt the bitmap to the image DC.
    *
    *    b. both ImagEdit and CF_BITMAP
    *       ---------------------------
    *       case 1: Pasting to an icon or cursor
    *                 * Recover the image from the AND and screen color
    *                   data (in ImagEdit) and the combined image bitmap
    *                   (in CF_BITMAP). Use the information to make the
    *                   neccessary changes if the screen viewing color was
    *                   changed between Copy and Paste.
    *
    *       case 2: Pasting to a bitmap
    *                 * Blt the CF_BITMAP data to the image DC.
    *
    * If the destination image differs in dimensions from
    * source image, the source image is stretched or clipped to that of
    * destination, depending on preference
    *
    * History:
    *
    ************************************************************************/
     
    BOOL PasteImageClip(VOID)
    {
        HCURSOR hcurOld;
        INT cxClip;
        INT cyClip;
        INT cxTarget;
        INT cyTarget;
        INT cxSource;
        INT cySource;
        DWORD rgbClipScreen;
        BOOL fIEFormatFound;
        HANDLE hClipData;
        LPSTR lpClipData;
        BITMAP bmClip;
        HDC hdcClip;
        HBITMAP hbmClip;
        HBITMAP hbmClipOld;
        HDC hdcClipAND;
        HBITMAP hbmClipAND;
        HBITMAP hbmClipANDOld;
        HDC hdcClipAND16;
        HBITMAP hbmClipAND16;
        HBITMAP hbmClipAND16Old;
        HDC hdcTarget;
        HBITMAP hbmTarget;
        HBITMAP hbmTargetOld;
        HDC hdcTargetAND16;
        HBITMAP hbmTargetAND16;
        HBITMAP hbmTargetAND16Old;
        HDC hdcTargetAND;
        HBITMAP hbmTargetAND;
        HBITMAP hbmTargetANDOld;
     
        hcurOld = SetCursor(hcurWait);
     
        if (!OpenClipboard(ghwndMain)) {
            Message(MSG_NOCLIPBOARD);
            goto Error1;
        }
     
        if (!(hbmClip = GetClipboardData(CF_BITMAP))) {
            Message(MSG_NOCLIPBOARDFORMAT);
            goto Error2;
        }
     
        GetObject(hbmClip, sizeof(BITMAP), (LPSTR)&bmClip);
        cxClip = (INT)bmClip.bmWidth;
        cyClip = (INT)bmClip.bmHeight;
     
        /*
         * If the dimensions of the current pick rectangle don't match
         * the bitmap being pasted, ask the user if they want to stretch
         * or clip the pasted image.
         */
        cxTarget = gcxPick;
        cyTarget = gcyPick;
        cxSource = cxClip;
        cySource = cyClip;
        if (gcxPick != cxClip || gcyPick != cyClip) {
            if (DlgBox(DID_PASTEOPTIONS, (WNDPROC)PasteOptionsDlgProc) == IDCANCEL) {
                goto Error2;
            }
     
            /*
             * If clipping and the clipboard dimensions differ from the
             * selected pick rectangle, then either the target dimensions
             * or the source dimensions need to be sized down.
             */
            if (!fStretchClipboardData) {
                if (cxClip < gcxPick)
                    cxTarget = cxClip;
                else
                    cxSource = gcxPick;
     
                if (cyClip < gcyPick)
                    cyTarget = cyClip;
                else
                    cySource = gcyPick;
            }
        }
     
        /*
         * Update the undo buffer now that we are committed to the paste.
         */
        ImageUpdateUndo();
     
        /*
         * Determine if the private ImagEdit clipboard format is available.
         */
        fIEFormatFound = IsClipboardFormatAvailable(ClipboardFormat);
     
        if (giType != FT_BITMAP && fIEFormatFound) {
            /*
             * Get the AND mask bitmap and the old screen color out of
             * the private format.
             */
            hClipData = GetClipboardData(ClipboardFormat);
            lpClipData = (LPSTR)GlobalLock(hClipData);
            rgbClipScreen = *((DWORD FAR *)lpClipData);
            hdcClipAND = CreateCompatibleDC(ghdcImage);
            hbmClipAND = CreateBitmap(cxClip, cyClip, (BYTE)1, (BYTE)1,
                    (LPSTR)lpClipData + sizeof(DWORD));
            hbmClipANDOld = SelectObject(hdcClipAND, hbmClipAND);
     
            /*
             * Create a color bitmap for temporary use.
             */
            hdcClipAND16 = CreateCompatibleDC(ghdcImage);
            hbmClipAND16 = MyCreateBitmap(ghdcImage, cxSource, cySource, 16);
            hbmClipAND16Old = SelectObject(hdcClipAND16, hbmClipAND16);
     
            /*
             * Blt the AND mask onto the color bitmap.
             */
            BitBlt(hdcClipAND16, 0, 0, cxSource, cySource, hdcClipAND,
                    0, 0, SRCCOPY);
     
            /*
             * Create the color target AND mask bitmap.
             */
            hdcTargetAND16 = CreateCompatibleDC(ghdcImage);
            hbmTargetAND16 = MyCreateBitmap(ghdcImage, cxTarget, cyTarget, 16);
            hbmTargetAND16Old = SelectObject(hdcTargetAND16, hbmTargetAND16);
     
            /*
             * StretchBlt from the color AND mask bitmap to the color target
             * AND mask bitmap.  The blt must be done from a color bitmap to
             * a color bitmap, and the stretch blt mode must be set to
             * COLORONCOLOR.  All this is necessary so that the AND mask
             * stays exactly in sync with the stretch blt of the color
             * (XOR) mask.  If these steps are not done correctly, shrinking
             * an image with screen colored pixels in it can cause problems,
             * because the stretch blt will use a slightly different
             * algorithm to compress the monochrome AND mask and the color
             * XOR mask.
             */
            SetStretchBltMode(hdcTargetAND16, COLORONCOLOR);
            SetStretchBltMode(hdcClipAND16, COLORONCOLOR);     //
            StretchBlt(hdcTargetAND16, 0, 0, cxTarget, cyTarget, hdcClipAND16,
                    0, 0, cxSource, cySource, SRCCOPY);
     
            /*
             * Create the monochrome target AND mask bitmap.
             */
            hdcTargetAND = CreateCompatibleDC(ghdcImage);
            hbmTargetAND = MyCreateBitmap(ghdcImage, cxTarget, cyTarget, 2);
            hbmTargetANDOld = SelectObject(hdcTargetAND, hbmTargetAND);
     
            /*
             * Blt the color AND mask onto the monochrome AND mask.
             * The monochrome AND mask is the one that we will use
             * later.  It must be monochrome or the ImageDCSeparate
             * and ImageDCCombine functions will not work properly.
             */
            BitBlt(hdcTargetAND, 0, 0, cxTarget, cyTarget, hdcTargetAND16,
                    0, 0, SRCCOPY);
     
            /*
             * Cleanup.
             */
            SelectObject(hdcTargetAND16, hbmTargetAND16Old);
            DeleteObject(hbmTargetAND16);
            DeleteDC(hdcTargetAND16);
            SelectObject(hdcClipAND16, hbmClipAND16Old);
            DeleteObject(hbmClipAND16);
            DeleteDC(hdcClipAND16);
            SelectObject(hdcClipAND, hbmClipANDOld);
            DeleteObject(hbmClipAND);
            DeleteDC(hdcClipAND);
            GlobalUnlock(hClipData);
        }
     
        /*
         * Get the clipboard bitmap into a DC.
         */
        hdcClip = CreateCompatibleDC(ghdcImage);
        hbmClipOld = SelectObject(hdcClip, hbmClip);
     
        /*
         * Create the target bitmap.
         */
        hdcTarget = CreateCompatibleDC(ghdcImage);
        hbmTarget = MyCreateBitmap(ghdcImage, cxTarget, cyTarget, 16);
        hbmTargetOld = SelectObject(hdcTarget, hbmTarget);
     
        /*
         * StretchBlt the bitmap onto the target.
         */
        SetStretchBltMode(hdcTarget, COLORONCOLOR);
        SetStretchBltMode(hdcClip, COLORONCOLOR);     //
        StretchBlt(hdcTarget, 0, 0, cxTarget, cyTarget, hdcClip, 0, 0,
                cxSource, cySource, SRCCOPY);
     
        /*
         * Handle some special cases.
         */
        if (giType == FT_BITMAP || !fIEFormatFound) {
            /*
             * The image we are pasting into is either a bitmap, or
             * there does not exist an AND mask in the clipboard.
             */
            if (gnColors == 2) {
                /*
                 * We are pasting to a mono image.  We must convert the
                 * colors in the clipboard bitmap into monochrome.
                 */
                ImageDCMonoBlt(hdcTarget, cxTarget, cyTarget);
            }
        }
        else {
            /*
             * We are pasting into an icon or cursor image and we have
             * available an AND mask.  Is the current image monochrome?
             */
            if (gnColors == 2) {
                /*
                 * Remove the old screen/inverse colors from the image,
                 * convert it to monochrome, then put back in the
                 * current screen/inverse colors.
                 */
                ImageDCSeparate(hdcTarget, cxTarget, cyTarget, hdcTargetAND,
                        rgbClipScreen);
                ImageDCMonoBlt(hdcTarget, cxTarget, cyTarget);
                ImageDCCombine(hdcTarget, cxTarget, cyTarget, hdcTargetAND);
            }
            /*
             * Does the screen color specified in the clipboard
             * differ from the current screen color?
             */
            else if (rgbClipScreen != grgbScreen) {
                /*
                 * Remove the old screen/inverse colors, then put back
                 * in the current ones.
                 */
                ImageDCSeparate(hdcTarget, cxTarget, cyTarget, hdcTargetAND,
                        rgbClipScreen);
                ImageDCCombine(hdcTarget, cxTarget, cyTarget, hdcTargetAND);
            }
        }
     
        /*
         * Blt the clipboard image to the proper rectangle in the current image.
         */
        BitBlt(ghdcImage, grcPick.left, grcPick.top,
                cxTarget, cyTarget, hdcTarget, 0, 0, SRCCOPY);
     
        /*
         * If the current image is an icon or cursor, we must take care
         * of the AND mask also.
         */
        if (giType != FT_BITMAP) {
            /*
             * Is there an AND mask in the clipboard to use?
             */
            if (fIEFormatFound) {
                /*
                 * Blt it into the current image's AND mask.
                 */
                BitBlt(ghdcANDMask, grcPick.left, grcPick.top,
                        cxTarget, cyTarget, hdcTargetAND, 0, 0, SRCCOPY);
            }
            else {
                /*
                 * Make the AND mask opaque, because there is no
                 * screen color information.
                 */
                PatBlt(ghdcANDMask, grcPick.left, grcPick.top,
                        cxTarget, cyTarget, BLACKNESS);
            }
        }
     
        /*
         * Cleanup.
         */
        SelectObject(hdcTarget, hbmTargetOld);
        DeleteObject(hbmTarget);
        DeleteDC(hdcTarget);
     
        if (giType != FT_BITMAP && fIEFormatFound) {
            SelectObject(hdcTargetAND, hbmTargetANDOld);
            DeleteObject(hbmTargetAND);
            DeleteDC(hdcTargetAND);
        }
     
        SelectObject(hdcClip, hbmClipOld);
        DeleteDC(hdcClip);
     
        CloseClipboard();
     
        /*
         * Update the View and workspace windows.
         */
        ViewUpdate();
     
        /*
         * Reset pick rectangle to cover entire image.
         */
        PickSetRect(0, 0, gcxImage - 1, gcyImage - 1);
     
        fImageDirty = TRUE;
     
        SetCursor(hcurOld);
     
        return TRUE;
     
    Error2:
        CloseClipboard();
     
    Error1:
        SetCursor(hcurOld);
     
        return FALSE;
    }
     
     
     
    /************************************************************************
    * PasteOptionsDlgProc
    *
    * Proc for the dialog that asks the user whether they want to clip
    * or stretch the bitmap being pasted in.
    *
    * Upon return with an IDOK value, the fStretchClipboardData global
    * will be TRUE if they want to stretch, or FALSE if they want to clip.
    *
    * History:
    *
    ************************************************************************/
     
    DIALOGPROC PasteOptionsDlgProc(
        HWND hwnd,
        UINT msg,
        WPARAM wParam,
        LPARAM lParam)
    {
        switch (msg) {
            case WM_INITDIALOG:
                CheckRadioButton(hwnd, DID_PASTEOPTIONSSTRETCH,
                        DID_PASTEOPTIONSCLIP,
                        fStretchClipboardData ?
                        DID_PASTEOPTIONSSTRETCH : DID_PASTEOPTIONSCLIP);
     
                CenterWindow(hwnd);
     
                break;
     
            case WM_COMMAND:
                switch (GET_WM_COMMAND_ID(wParam, lParam)) {
                    case IDOK :
                        if (IsDlgButtonChecked(hwnd, DID_PASTEOPTIONSSTRETCH))
                            fStretchClipboardData = TRUE;
                        else
                            fStretchClipboardData = FALSE;
     
                        EndDialog(hwnd, IDOK);
                        break;
     
                    case IDCANCEL:
                        EndDialog(hwnd, IDCANCEL);
                        break;
     
                    case IDHELP:
                        WinHelp(ghwndMain, gszHelpFile, HELP_CONTEXT,
                                HELPID_PASTEOPTIONS);
                        break;
                }
     
                break;
     
            default:
                return FALSE;
        }
     
        return TRUE;
    }
     
     
     
    /************************************************************************
    * PickSetRect
    *
    * Sets the globals for the picking rectangle size.  This affects
    * what is copied into the clipboard.
    *
    * Arguments:
    *
    * History:
    *
    ************************************************************************/
     
    VOID PickSetRect(
        INT xLeft,
        INT yTop,
        INT xRight,
        INT yBottom)
    {
        SetRect(&grcPick, xLeft, yTop, xRight, yBottom);
        gcxPick = (grcPick.right - grcPick.left) + 1;
        gcyPick = (grcPick.bottom - grcPick.top) + 1;
    }

0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
C++ standard library based binary archive format 6 108
I could not build boost code, 10 107
Using Diagnostic tools in VS2015: Unresoved allocations 19 125
visual C++ 1 9
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question