ICCLIP.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:23k
源码类别:
Windows编程
开发平台:
Visual 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;
- }