Solved

Copying a bitmap to the clipboard

Posted on 1999-01-04
5
466 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
Comment Utility
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
Comment Utility
cool :-)
0
 

Author Comment

by:amnav
Comment Utility
Not clear enogh
0
 
LVL 13

Expert Comment

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

Accepted Solution

by:
Mirkwood earned 100 total points
Comment Utility
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
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 pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

728 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

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now