Solved

Copying a bitmap to the clipboard

Posted on 1999-01-04
5
479 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
  • 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

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

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

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

770 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