mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1511 lines
43 KiB
1511 lines
43 KiB
/****************************Module*Header******************************\
|
|
* Module Name: newpick.c *
|
|
* *
|
|
* *
|
|
* *
|
|
* Created: 1989 *
|
|
* *
|
|
* Copyright (c) 1987 - 1991 Microsoft Corporation *
|
|
* *
|
|
\***********************************************************************/
|
|
|
|
#include <windows.h>
|
|
#include <port1632.h>
|
|
|
|
#include "oleglue.h"
|
|
#include "pbrush.h"
|
|
|
|
#ifndef CBM_CREATEDIB
|
|
# define CBM_CREATEDIB 0x02L /* create DIB bitmap */
|
|
#endif
|
|
|
|
extern HWND pbrushWnd[];
|
|
extern int pickWid, pickHgt;
|
|
extern int imagePlanes, imagePixels;
|
|
extern HDC pickDC, saveDC, monoDC, tempDC;
|
|
extern HBITMAP pickBM, saveBM, monoBM;
|
|
extern HPALETTE hPalette;
|
|
extern DWORD *rgbColor;
|
|
extern int theBackg;
|
|
extern RECT pickRect;
|
|
extern POINT polyPts[];
|
|
extern int numPts;
|
|
extern int theTool;
|
|
extern DPPROC DrawProc;
|
|
extern LPTSTR DrawCursor;
|
|
extern BOOL TerminateKill;
|
|
extern RECT imageView;
|
|
|
|
extern BOOL bExchanged;
|
|
extern RECT rDirty;
|
|
|
|
/* define raster ops needed for MyMaskBlt */
|
|
#define DSa 0x008800C6L
|
|
#define DSna 0x00220326L
|
|
|
|
static POINT OldPos, CurPos;
|
|
static BOOL bPickSwept;
|
|
|
|
short nPickMode;
|
|
|
|
HBITMAP MapBitmapColors( HDC hdcMem, HPALETTE hpalDst, HBITMAP hbmSrc,
|
|
HPALETTE hpalSrc );
|
|
|
|
void EnablePickMenu(BOOL bEnable)
|
|
{
|
|
EnableMenuBarItemByPos(MENUPOS_PICK, bEnable ? MF_ENABLED : MF_GRAYED);
|
|
DrawFrameMenuBar();
|
|
}
|
|
|
|
int AlocPick(HDC hDC)
|
|
{
|
|
if (pickBM = CreateBitmap(pickWid, pickHgt, (BYTE) imagePlanes,
|
|
(BYTE) imagePixels, 0L))
|
|
{
|
|
if (pickDC = CreateCompatibleDC(hDC))
|
|
SelectObject(pickDC, pickBM);
|
|
}
|
|
|
|
if (saveBM = CreateBitmap(pickWid, pickHgt, (BYTE) imagePlanes,
|
|
(BYTE) imagePixels, 0L))
|
|
{
|
|
if (saveDC = CreateCompatibleDC(hDC))
|
|
SelectObject(saveDC, saveBM);
|
|
}
|
|
|
|
if (monoBM = CreateBitmap(pickWid, pickHgt, 1, 1, 0L))
|
|
{
|
|
if (monoDC = CreateCompatibleDC(hDC))
|
|
SelectObject(monoDC, monoBM);
|
|
}
|
|
|
|
if(pickBM && pickDC && saveBM && saveDC && monoBM && monoDC) {
|
|
if (hPalette) {
|
|
SelectPalette(pickDC, hPalette, 0);
|
|
SelectPalette(saveDC, hPalette, 0);
|
|
RealizePalette(pickDC);
|
|
RealizePalette(saveDC);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* something was not built */
|
|
FreePick();
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/* Build an opaque/transparent mask for bitmap contained in pickDC
|
|
**
|
|
** The mask is 0 when the destination should remain unchanged (transparent)
|
|
** The mask is 1 when the source should be copied to destination (opaque)
|
|
*/
|
|
void BuildMask(int mode)
|
|
{
|
|
DWORD rgbOldBk;
|
|
DWORD dwROP;
|
|
|
|
/* Since we change lots of things just do global save of monoDC */
|
|
SaveDC(monoDC);
|
|
|
|
/* Start with everything transparent */
|
|
PatBlt(monoDC, 0, 0, pickWid, pickHgt, BLACKNESS);
|
|
|
|
/* Set window origin of monoDC so we don't have to transform points */
|
|
MSetWindowOrg(monoDC, pickRect.left, pickRect.top);
|
|
|
|
/* make our interior/exterior white */
|
|
SelectObject(monoDC, GetStockObject(WHITE_PEN));
|
|
SelectObject(monoDC, GetStockObject(WHITE_BRUSH));
|
|
|
|
/* fill the interior */
|
|
SetPolyFillMode(monoDC, ALTERNATE);
|
|
Polygon(monoDC, polyPts, numPts);
|
|
|
|
if (mode == TRANSPARENT) {
|
|
/* set background to transparent color */
|
|
|
|
DB_OUTF((acDbgBfr, TEXT("Bkgd = %lx\r\n"), rgbColor[theBackg]));
|
|
|
|
rgbOldBk = SetBkColor(pickDC, rgbColor[theBackg]);
|
|
|
|
dwROP = DSna;
|
|
if (imagePlanes == 1 && imagePixels == 1 &&
|
|
!PBGetNearestColor(monoDC, rgbColor[theBackg]))
|
|
dwROP = DSa;
|
|
|
|
BitBlt(monoDC, pickRect.left, pickRect.top, pickWid, pickHgt,
|
|
pickDC, 0, 0,
|
|
dwROP);
|
|
|
|
/* restore pickDC's background color */
|
|
SetBkColor(pickDC, rgbOldBk);
|
|
}
|
|
|
|
/* throw out the clipping region, reset window origin to (0,0) */
|
|
RestoreDC(monoDC, -1);
|
|
|
|
}
|
|
|
|
static RECT rcPaint;
|
|
|
|
LONG APIENTRY DrawDotRect(HDC dstDC, LPRECT lprBounds, WPARAM wParam)
|
|
{
|
|
RECT rcTemp;
|
|
|
|
rcTemp = *lprBounds;
|
|
ConstrainRect(&rcTemp, &rcPaint, wParam);
|
|
|
|
DotRect(dstDC, rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
LONG APIENTRY DrawShrGroRect(HDC dstDC, LPRECT lprBounds, WPARAM wParam)
|
|
{
|
|
int dx, dy;
|
|
BOOL bFinal;
|
|
RECT r;
|
|
|
|
bFinal = (GetROP2(dstDC) == R2_COPYPEN);
|
|
|
|
if (wParam & MK_SHIFT) {
|
|
dx = abs(lprBounds->right - lprBounds->left);
|
|
dy = abs(lprBounds->bottom - lprBounds->top);
|
|
|
|
if (pickHgt < pickWid) {
|
|
dy = (int) (((long) dx * pickHgt) / pickWid);
|
|
} else {
|
|
dx = (int) (((long) dy * pickWid) / pickHgt);
|
|
}
|
|
} else {
|
|
dx = lprBounds->right - lprBounds->left;
|
|
dy = lprBounds->bottom - lprBounds->top;
|
|
}
|
|
|
|
if (bFinal) {
|
|
r.left = lprBounds->left;
|
|
r.top = lprBounds->top;
|
|
r.right = lprBounds->left + dx;
|
|
r.bottom = lprBounds->top + dy;
|
|
*lprBounds = r;
|
|
} else {
|
|
DotRect(dstDC, lprBounds->left, lprBounds->top,
|
|
lprBounds->left + dx, lprBounds->top + dy);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
LONG APIENTRY DrawDotPoly(HDC dstDC, LPRECT lprBounds, WPARAM wParam)
|
|
{
|
|
static int xLast = -1, yLast = -1;
|
|
|
|
/* do nothing if we already have all of our points */
|
|
if (numPts == MAXpts - 1 || (GetROP2(dstDC) == R2_COPYPEN))
|
|
return TRUE;
|
|
|
|
if (xLast != lprBounds->right || yLast != lprBounds->bottom) {
|
|
polyPts[numPts].x = xLast = lprBounds->right;
|
|
polyPts[numPts].y = yLast = lprBounds->bottom;
|
|
++numPts;
|
|
|
|
if (numPts > 1)
|
|
LineTo(dstDC, xLast, yLast);
|
|
else
|
|
MMoveTo(dstDC, xLast, yLast);
|
|
}
|
|
|
|
/* if we are terminating reset last points back to -1 */
|
|
if (GetROP2(dstDC) == R2_COPYPEN)
|
|
xLast = yLast = -1;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*static*/ LONG PRIVATE TrackPick(HWND hWnd, LPRECT rcReturn, WPARAM *wParam)
|
|
{
|
|
WORD w;
|
|
|
|
if (theTool == PICKtool || DrawProc == ShrGroDP) {
|
|
GetClientRect(hWnd, &rcPaint);
|
|
w = TrackTool(hWnd, DrawDotRect, rcReturn, wParam, NULL);
|
|
} else
|
|
w = TrackTool(hWnd, DrawDotPoly, rcReturn, wParam, NULL);
|
|
return w;
|
|
}
|
|
|
|
extern int cntr;
|
|
|
|
LONG APIENTRY DragProc(HDC dstDC, LPRECT lprBounds, WPARAM wParam)
|
|
{
|
|
static int dx = -32768, dy = -32768;
|
|
|
|
UINT OldROP;
|
|
RECT rcOld, rcNew, rcTemp;
|
|
int unionWid, unionHgt;
|
|
BOOL bUseRadMouse;
|
|
|
|
if (GetROP2(dstDC) == R2_COPYPEN) {
|
|
dx = dy = -32768;
|
|
} else {
|
|
if (dx == -32768) {
|
|
cntr = 0;
|
|
dx = lprBounds->right - CurPos.x;
|
|
dy = lprBounds->bottom - CurPos.y;
|
|
}
|
|
if(01&cntr++)
|
|
return(FALSE);
|
|
|
|
OldROP = SetROP2(dstDC, R2_COPYPEN);
|
|
|
|
/* compute old/new rectangles */
|
|
rcOld.left = CurPos.x;
|
|
rcOld.top = CurPos.y;
|
|
rcOld.right = rcOld.left + pickWid - 1;
|
|
rcOld.bottom = rcOld.top + pickHgt - 1;
|
|
rcNew.left = lprBounds->right - dx;
|
|
rcNew.top = lprBounds->bottom - dy;
|
|
rcNew.right = rcNew.left + pickWid - 1;
|
|
rcNew.bottom = rcNew.top + pickHgt - 1;
|
|
|
|
bUseRadMouse = IntersectRect(&rcTemp, &rcOld, &rcNew) ? TRUE
|
|
: FALSE;
|
|
/* compute union rect */
|
|
UnionRect(&rcTemp, &rcOld, &rcNew);
|
|
rcTemp.right++;
|
|
rcTemp.bottom++;
|
|
unionWid = rcTemp.right - rcTemp.left;
|
|
unionHgt = rcTemp.bottom - rcTemp.top;
|
|
|
|
|
|
if (bUseRadMouse) {
|
|
/* restore old area if we aren't sweeping */
|
|
if (!(wParam & MK_SHIFT)) {
|
|
// EDH: change to SHIFT for sweep
|
|
BitBlt(hdcWork, rcOld.left+imageView.left,
|
|
rcOld.top+imageView.top,
|
|
pickWid, pickHgt,
|
|
saveDC, 0, 0, SRCCOPY);
|
|
} else
|
|
bPickSwept = TRUE;
|
|
|
|
/* Save area under new pick */
|
|
BitBlt(saveDC, 0, 0, pickWid, pickHgt,
|
|
hdcWork, rcNew.left+imageView.left,
|
|
rcNew.top+imageView.top,
|
|
SRCCOPY);
|
|
|
|
/* draw pick */
|
|
MaskBlt(hdcWork, rcNew.left+imageView.left,
|
|
rcNew.top+imageView.top,
|
|
pickWid, pickHgt,
|
|
pickDC, 0, 0,monoBM, 0, 0,MASKROP(SRCCOPY,0x00aa0000));
|
|
|
|
/* transfer result to screen */
|
|
|
|
/* Reset window origion */
|
|
} else {
|
|
if (!(wParam & MK_SHIFT)) {
|
|
// EDH: change to SHIFT for sweep
|
|
BitBlt(hdcWork, rcOld.left + imageView.left,
|
|
rcOld.top + imageView.top,
|
|
pickWid, pickHgt,
|
|
saveDC, 0, 0, SRCCOPY);
|
|
} else
|
|
bPickSwept = TRUE;
|
|
|
|
BitBlt(saveDC, 0, 0, pickWid, pickHgt,
|
|
hdcWork, rcNew.left + imageView.left,
|
|
rcNew.top + imageView.top,
|
|
SRCCOPY);
|
|
MaskBlt(hdcWork, rcNew.left + imageView.left,
|
|
rcNew.top + imageView.top,
|
|
pickWid, pickHgt,
|
|
pickDC, 0, 0,monoBM, 0, 0,MASKROP(SRCCOPY,0x00aa0000));
|
|
}
|
|
|
|
rcTemp.left += imageView.left;
|
|
rcTemp.right += imageView.left;
|
|
rcTemp.top += imageView.top;
|
|
rcTemp.bottom += imageView.top;
|
|
|
|
BitBlt(dstDC, rcTemp.left - imageView.left,
|
|
rcTemp.top - imageView.top,
|
|
unionWid, unionHgt,
|
|
hdcWork, rcTemp.left, rcTemp.top,
|
|
SRCCOPY);
|
|
|
|
UnionWithRect(&rDirty,&rcTemp);
|
|
|
|
AdviseDataChange();
|
|
|
|
SetROP2(dstDC, OldROP);
|
|
|
|
CurPos.x = rcNew.left;
|
|
CurPos.y = rcNew.top;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void EnableOutline(BOOL bEnable)
|
|
{
|
|
static BOOL bPickStatus = FALSE;
|
|
static BOOL bScissorStatus = FALSE;
|
|
|
|
HDC hDC;
|
|
|
|
if (!(hDC = GetDisplayDC(pbrushWnd[PAINTid])))
|
|
return;
|
|
|
|
switch (theTool) {
|
|
case PICKtool:
|
|
if (bPickStatus == bEnable)
|
|
break;
|
|
|
|
DotRect(hDC, pickRect.left, pickRect.top,
|
|
pickRect.right, pickRect.bottom);
|
|
bPickStatus = bEnable;
|
|
break;
|
|
|
|
case SCISSORStool:
|
|
if (bScissorStatus == bEnable)
|
|
break;
|
|
|
|
DotPoly(hDC, polyPts, numPts);
|
|
bScissorStatus = bEnable;
|
|
break;
|
|
}
|
|
|
|
ReleaseDC(pbrushWnd[PAINTid], hDC);
|
|
}
|
|
|
|
BOOL IsInSelection(POINT pt)
|
|
{
|
|
int x = pt.x - CurPos.x;
|
|
int y = pt.y - CurPos.y;
|
|
|
|
if (!monoDC ||
|
|
!PtInRect(&pickRect, pt) ||
|
|
GetPixel(monoDC, x, y) == RGB(0,0,0))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void FillBkgd(HDC hDC, int x, int y, int dx, int dy)
|
|
{
|
|
HBRUSH hBrush, hOldBrush;
|
|
|
|
if (hBrush = CreateSolidBrush(rgbColor[theBackg]))
|
|
hOldBrush = SelectObject(hDC, hBrush);
|
|
|
|
PatBlt(hDC, x, y, dx, dy, PATCOPY);
|
|
|
|
if (hBrush) {
|
|
if (hOldBrush)
|
|
SelectObject(hDC, hOldBrush);
|
|
DeleteObject(hBrush);
|
|
}
|
|
}
|
|
|
|
void FillInCutoutOrigin(void)
|
|
{
|
|
HDC dstDC;
|
|
HBRUSH hBrush, hOldBrush;
|
|
RECT tempRect;
|
|
|
|
tempRect.left = pickRect.left + imageView.left;
|
|
tempRect.right = pickRect.right + imageView.left;
|
|
tempRect.top = pickRect.top + imageView.top;
|
|
tempRect.bottom = pickRect.bottom + imageView.top;
|
|
|
|
dstDC = GetDisplayDC(pbrushWnd[PAINTid]);
|
|
|
|
BitBlt(saveDC, 0, 0, pickWid, pickHgt,
|
|
pickDC, 0, 0, SRCCOPY);
|
|
|
|
MSetBrushOrg(saveDC, -imageView.left-pickRect.left,
|
|
-imageView.top-pickRect.top);
|
|
if (hBrush = CreateSolidBrush(rgbColor[theBackg]))
|
|
hOldBrush = SelectObject(saveDC, hBrush);
|
|
|
|
BitBlt(saveDC, 0, 0, pickWid, pickHgt,
|
|
monoDC, 0, 0, ROP_DSPDxax);
|
|
|
|
if (hBrush) {
|
|
if(hOldBrush)
|
|
SelectObject(saveDC, hOldBrush);
|
|
DeleteObject(hBrush);
|
|
}
|
|
|
|
/* copy save area to work image */
|
|
BitBlt(hdcWork, tempRect.left, tempRect.top, pickWid, pickHgt,
|
|
saveDC, 0, 0, SRCCOPY);
|
|
|
|
UnionWithRect(&rDirty,&tempRect);
|
|
|
|
AdviseDataChange();
|
|
|
|
BitBlt(dstDC, pickRect.left, pickRect.top, pickWid, pickHgt,
|
|
pickDC, 0, 0, SRCCOPY);
|
|
|
|
ReleaseDC(pbrushWnd[PAINTid], dstDC);
|
|
}
|
|
|
|
|
|
void ClearPickArea(void)
|
|
{
|
|
HDC dstDC;
|
|
RECT rect1;
|
|
|
|
dstDC = GetDisplayDC(pbrushWnd[PAINTid]);
|
|
|
|
if (!dstDC)
|
|
return;
|
|
|
|
EnableOutline(FALSE);
|
|
|
|
BuildMask(OPAQUE);
|
|
|
|
BitBlt(hdcWork, CurPos.x + imageView.left,
|
|
CurPos.y + imageView.top, pickWid, pickHgt,
|
|
saveDC, 0, 0,
|
|
SRCCOPY);
|
|
FillBkgd(hdcWork, CurPos.x + imageView.left,
|
|
CurPos.y + imageView.top, pickWid, pickHgt);
|
|
BitBlt(dstDC, CurPos.x, CurPos.y, pickWid, pickHgt,
|
|
hdcWork, CurPos.x + imageView.left,
|
|
CurPos.y + imageView.top,
|
|
SRCCOPY);
|
|
|
|
rect1.left = CurPos.x + imageView.left;
|
|
rect1.right = rect1.left + pickWid;
|
|
rect1.top = CurPos.y + imageView.top;
|
|
rect1.bottom = rect1.top + pickHgt;
|
|
|
|
UnionWithRect(&rDirty,&rect1);
|
|
|
|
AdviseDataChange();
|
|
|
|
ReleaseDC(pbrushWnd[PAINTid], dstDC);
|
|
}
|
|
|
|
void PastePict(HWND hWnd, HDC dstDC, HBITMAP hClipBM, HANDLE hMF, HPALETTE hpalClip)
|
|
{
|
|
HBITMAP hOldBM = NULL;
|
|
BITMAP bm;
|
|
HDC hClipDC;
|
|
RECT rc1;
|
|
|
|
DOUTR(L"In PastePict");
|
|
|
|
if (!IsRectEmpty(&pickRect)) {
|
|
DOUTR(L"PastePict: Sending WM_TERMINATE" );
|
|
SendMessage(hWnd, WM_TERMINATE, 0, 0L);
|
|
}
|
|
|
|
/* get dimensions of the bitmap to be pasted */
|
|
if (hClipBM)
|
|
{
|
|
GetObject(hClipBM, sizeof(BITMAP), (LPVOID) &bm);
|
|
pickWid = bm.bmWidth;
|
|
pickHgt = bm.bmHeight;
|
|
}
|
|
else /* metafile on clipboard, compute its dimensions */
|
|
{
|
|
if (!GetMFDimensions(hMF, hdcWork, &pickWid, &pickHgt))
|
|
return;
|
|
}
|
|
|
|
/* fill polyPts with rect coords */
|
|
numPts = 4;
|
|
polyPts[0].x = polyPts[3].x = polyPts[0].y = polyPts[1].y = pickRect.left = pickRect.top = 0;
|
|
polyPts[1].x = polyPts[2].x = pickRect.right = pickWid - 1;
|
|
polyPts[2].y = polyPts[3].y = pickRect.bottom = pickHgt - 1;
|
|
|
|
/* Allocate offscreen bitmaps for pick operations */
|
|
if (AlocPick(hdcWork))
|
|
{
|
|
/* copy bitmap into pickDC */
|
|
if (hClipBM && (hClipDC = CreateCompatibleDC(hdcWork)))
|
|
{
|
|
HBITMAP hbmTmp = NULL;
|
|
if (hPalette != NULL)
|
|
{
|
|
hbmTmp = MapBitmapColors( hClipDC, hPalette, hClipBM, hpalClip );
|
|
}
|
|
else if (hpalClip != NULL)
|
|
{
|
|
HPALETTE hpalNew;
|
|
/*
|
|
* We're pasting a paletized bitmap and we don't already
|
|
* have a palette selected. Adopt the one from the
|
|
* clipboard
|
|
*/
|
|
DOUTR( L"PastePict: adopting clipbrd palette" );
|
|
hpalNew = CopyPalette( hpalClip );
|
|
SelectPalette(hdcWork, hpalNew, 0);
|
|
RealizePalette(hdcWork);
|
|
SelectPalette(hdcImage, hpalNew, 0);
|
|
RealizePalette(hdcImage);
|
|
|
|
hPalette = hpalNew;
|
|
}
|
|
|
|
hOldBM = SelectObject(hClipDC, hbmTmp != NULL ? hbmTmp : hClipBM);
|
|
BitBlt(pickDC, 0, 0, pickWid, pickHgt, hClipDC, 0, 0, SRCCOPY);
|
|
SelectObject(hClipDC, hOldBM);
|
|
DeleteDC(hClipDC);
|
|
|
|
if (hbmTmp != NULL) {
|
|
DeleteObject(hbmTmp);
|
|
}
|
|
|
|
}
|
|
else if (hMF) /* play metafile into the pickDC */
|
|
{
|
|
RECT Rect;
|
|
|
|
Rect.left = Rect.top = 0;
|
|
Rect.right = pickWid; Rect.bottom = pickHgt;
|
|
PlayMetafileIntoDC(hMF, &Rect, pickDC);
|
|
}
|
|
|
|
/* Initialize saveDC to ULC of workDC */
|
|
BitBlt(saveDC, 0, 0, pickWid, pickHgt,
|
|
hdcWork, pickRect.left + imageView.left,
|
|
pickRect.top + imageView.top,
|
|
SRCCOPY);
|
|
|
|
/* make an opaque mask to use for hit testing */
|
|
BuildMask(nPickMode = OPAQUE);
|
|
|
|
/* draw pick on screen */
|
|
rc1.left = pickRect.left + imageView.left;
|
|
rc1.top = pickRect.top + imageView.top;
|
|
rc1.right = rc1.left + pickWid;
|
|
rc1.bottom = rc1.top + pickHgt;
|
|
|
|
MaskBlt(hdcWork, rc1.left, rc1.top, pickWid, pickHgt,
|
|
pickDC, 0, 0, monoBM, 0, 0,MASKROP(SRCCOPY,0x00aa0000));
|
|
|
|
UnionWithRect(&rDirty,&rc1);
|
|
AdviseDataChange();
|
|
BitBlt(dstDC, pickRect.left,
|
|
pickRect.top,
|
|
pickWid, pickHgt,
|
|
hdcWork, rc1.left,
|
|
rc1.top,
|
|
SRCCOPY);
|
|
|
|
/* draw the dotted outline */
|
|
EnableOutline(TRUE);
|
|
|
|
/* Save current/old position */
|
|
OldPos.x = CurPos.x = pickRect.left;
|
|
OldPos.y = CurPos.y = pickRect.top;
|
|
|
|
/* Enable Pick Menu */
|
|
EnablePickMenu(TRUE);
|
|
|
|
/* Enable Copy options in edit menu */
|
|
ChangeCutCopy(ghMenuFrame, MF_ENABLED);
|
|
}
|
|
else
|
|
{
|
|
SimpleMessage(IDSNoMemAvail, NULL, MB_OK | MB_ICONEXCLAMATION);
|
|
}
|
|
}
|
|
|
|
void
|
|
PastePictFromOle(HWND hWnd)
|
|
{
|
|
CLIPFORMAT cf = CF_BITMAP;
|
|
HGLOBAL hGlob = NULL;
|
|
HANDLE hMF = NULL;
|
|
HBITMAP hClipBM = NULL;
|
|
HPALETTE hpalClip = NULL;
|
|
HDC dstDC = GetDisplayDC(hWnd);
|
|
if(dstDC == NULL)
|
|
return;
|
|
|
|
if(ghGlobalToPaste != NULL)
|
|
{
|
|
DOUTR( L"PstPicFmOle: ghGlobalToPaste != NULL" );
|
|
switch(gcfToPaste)
|
|
{
|
|
case CF_BITMAP:
|
|
hClipBM = (HBITMAP)ghGlobalToPaste;
|
|
break;
|
|
case CF_METAFILEPICT:
|
|
hMF = (HANDLE)ghGlobalToPaste;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cf = CF_METAFILEPICT;
|
|
if(GetTypedHGlobalFromOleClipboard(cf, &hGlob))
|
|
{
|
|
hMF = (HANDLE)hGlob;
|
|
DOUTR( L"PstPicFmOle: Got Metafile from OLE clipbrd" );
|
|
}
|
|
else
|
|
{
|
|
cf = CF_BITMAP;
|
|
if(GetTypedHGlobalFromOleClipboard(cf, &hGlob)) {
|
|
hClipBM = (HBITMAP)hGlob;
|
|
DOUTR( L"PstPicFmOle: Got Metafile from OLE clipbrd" );
|
|
}
|
|
}
|
|
}
|
|
|
|
if (cf == CF_BITMAP && hClipBM != NULL) {
|
|
// Get the palette for this bitmap if one exists
|
|
HGLOBAL hgPal;
|
|
|
|
DOUTR( L"PstPicFmOle: attempting to get palette from OLE clipbrd" );
|
|
|
|
if (GetTypedHGlobalFromOleClipboard(CF_PALETTE, &hgPal)) {
|
|
hpalClip = (HPALETTE)hgPal;
|
|
DOUTR( L"PstPicFmOle: Got Palette from OLE clipbrd" );
|
|
}
|
|
}
|
|
|
|
PastePict(hWnd, dstDC, hClipBM, hMF, hpalClip);
|
|
|
|
if(hGlob != NULL)
|
|
{
|
|
switch(cf)
|
|
{
|
|
case CF_BITMAP:
|
|
DeleteObject(hGlob);
|
|
if (hpalClip != NULL) {
|
|
DeleteObject(hpalClip);
|
|
}
|
|
break;
|
|
case CF_METAFILEPICT:
|
|
{
|
|
LPMETAFILEPICT pMF = GlobalLock(hGlob);
|
|
DeleteMetaFile(pMF->hMF);
|
|
GlobalUnlock(hGlob);
|
|
GlobalFree(hGlob);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if(dstDC != NULL)
|
|
ReleaseDC(hWnd, dstDC);
|
|
}
|
|
|
|
void
|
|
PastePictFromClipboard(HWND hWnd)
|
|
{
|
|
HDC dstDC = NULL;
|
|
HANDLE hMF = NULL;
|
|
HBITMAP hClipBM;
|
|
HANDLE hDIB;
|
|
LPBITMAPINFO lpDIB;
|
|
LPBITMAPINFOHEADER bmHdr;
|
|
HPALETTE hpalClip = NULL;
|
|
|
|
if (!OpenClipboard(hWnd)) /* can't open the clipboard */
|
|
return;
|
|
|
|
if ((!((hClipBM = GetClipboardData(CF_BITMAP)) ||
|
|
(hClipBM = GetClipboardData(CF_DIB))) && /* if no bitmap/metafile */
|
|
!(hMF = GetClipboardData(CF_METAFILEPICT))) ||
|
|
!(dstDC = GetDisplayDC(hWnd))) /* failed to get a DC */
|
|
{
|
|
goto Exit1;
|
|
}
|
|
|
|
/* If this is a DIB, we need to convert it */
|
|
if (hDIB = GetClipboardData(CF_DIB))
|
|
{
|
|
UINT nOffset;
|
|
lpDIB = GlobalLock (hDIB);
|
|
bmHdr = (LPBITMAPINFOHEADER) lpDIB;
|
|
|
|
// calculate the offset to the bits based on the format
|
|
// of the DIB (1,4,8,or 24bpp)
|
|
if( bmHdr->biBitCount == 24 )
|
|
nOffset = 0;
|
|
else
|
|
nOffset = ( bmHdr->biClrUsed ) ?
|
|
bmHdr->biClrUsed * sizeof( RGBQUAD ) :
|
|
( sizeof( RGBQUAD ) << bmHdr->biBitCount );
|
|
if ((hClipBM = CreateDIBitmap (dstDC,
|
|
(LPBITMAPINFOHEADER) lpDIB,
|
|
CBM_INIT, ( BYTE * )( lpDIB ) + bmHdr->biSize + nOffset,
|
|
lpDIB, DIB_RGB_COLORS)) == NULL)
|
|
{
|
|
GlobalUnlock(hDIB);
|
|
goto Exit1;
|
|
}
|
|
|
|
GlobalUnlock( hDIB );
|
|
}
|
|
else if (IsClipboardFormatAvailable(CF_PALETTE))
|
|
{
|
|
hpalClip = GetClipboardData(CF_PALETTE);
|
|
}
|
|
|
|
PastePict(hWnd, dstDC, hClipBM, hMF, hpalClip);
|
|
|
|
if(dstDC != NULL)
|
|
ReleaseDC(hWnd, dstDC);
|
|
|
|
Exit1:
|
|
CloseClipboard();
|
|
}
|
|
|
|
BOOL
|
|
PickDP(HWND hWnd, UINT code, WPARAM wParam, LONG lParam)
|
|
{
|
|
static BOOL bFirstDrag = FALSE, bDragging = FALSE;
|
|
static BOOL bCrossh = TRUE;
|
|
|
|
POINT newPt;
|
|
RECT rcBounds;
|
|
BOOL bCancel = FALSE;
|
|
HDC dstDC;
|
|
POINT OldPos;
|
|
LPPAINTSTRUCT lpps;
|
|
HCURSOR oldcsr;
|
|
RECT rc1;
|
|
|
|
LONG2POINT(lParam,newPt);
|
|
dstDC = NULL;
|
|
switch (code) {
|
|
case WM_PAINT:
|
|
lpps = (LPPAINTSTRUCT) lParam;
|
|
if (IsRectEmpty(&pickRect))
|
|
break;
|
|
|
|
BitBlt(lpps->hdc, CurPos.x, CurPos.y, pickWid, pickHgt,
|
|
saveDC, 0, 0,
|
|
SRCCOPY);
|
|
MaskBlt(lpps->hdc, CurPos.x, CurPos.y, pickWid, pickHgt,
|
|
pickDC, 0, 0,monoBM, 0, 0,MASKROP(SRCCOPY,0x00aa0000));
|
|
break;
|
|
|
|
case WM_LBUTTONDOWN:
|
|
if(bExchanged)
|
|
{
|
|
PasteDownRect(rDirty.left, rDirty.top,
|
|
rDirty.right-rDirty.left, rDirty.bottom-rDirty.top);
|
|
}
|
|
|
|
if (!IsInSelection(newPt)) {
|
|
DOUTR(L"newpick: Sending WM_TERMINATE for button up" );
|
|
SendMessage(hWnd, WM_TERMINATE, 0, 0L);
|
|
UpdatImg();
|
|
|
|
rcBounds.left = rcBounds.right = newPt.x;
|
|
rcBounds.top = rcBounds.bottom = newPt.y;
|
|
bCancel = TrackPick(hWnd, &rcBounds, &wParam) == WM_RBUTTONDOWN;
|
|
|
|
case WM_OUTLINE:
|
|
if (code == WM_OUTLINE) {
|
|
GetClientRect(hWnd, &rcPaint);
|
|
rcBounds = pickRect;
|
|
}
|
|
|
|
dstDC = GetDisplayDC(hWnd);
|
|
if (!dstDC)
|
|
bCancel = TRUE;
|
|
else {
|
|
/* Get final coordinates */
|
|
ConstrainRect(&rcBounds, &rcPaint, wParam);
|
|
|
|
if (theTool == PICKtool) {
|
|
numPts = 4;
|
|
polyPts[0].x = polyPts[3].x = rcBounds.left;
|
|
polyPts[0].y = polyPts[1].y = rcBounds.top;
|
|
polyPts[1].x = polyPts[2].x = rcBounds.right;
|
|
polyPts[2].y = polyPts[3].y = rcBounds.bottom;
|
|
} else {
|
|
SetROP2(dstDC, R2_XORPEN);
|
|
SelectObject(dstDC, GetStockObject(WHITE_PEN));
|
|
Polyline(dstDC, polyPts, numPts);
|
|
SetROP2(dstDC, R2_COPYPEN);
|
|
PolyRect(polyPts, numPts, &rcBounds);
|
|
}
|
|
}
|
|
|
|
/* if bounding rect is empty then just cancel operation */
|
|
if (IsRectEmpty(&rcBounds))
|
|
{
|
|
bCancel = TRUE;
|
|
EnablePickMenu(FALSE);
|
|
ChangeCutCopy(ghMenuFrame, MF_GRAYED);
|
|
}
|
|
|
|
if (!bCancel) {
|
|
|
|
/* get bounding rect and its width/height */
|
|
pickRect = rcBounds;
|
|
pickWid = pickRect.right - pickRect.left + 1;
|
|
pickHgt = pickRect.bottom - pickRect.top + 1;
|
|
|
|
/* Allocate offscreen bitmaps for pick operations */
|
|
if (!AlocPick(hdcWork)) {
|
|
SimpleMessage(IDSNoMemAvail, NULL,
|
|
MB_OK | MB_ICONEXCLAMATION);
|
|
bCancel = TRUE;
|
|
} else {
|
|
/* copy pick into pickDC */
|
|
BitBlt(pickDC, 0, 0, pickWid, pickHgt,
|
|
hdcWork, pickRect.left + imageView.left,
|
|
pickRect.top + imageView.top,
|
|
SRCCOPY);
|
|
|
|
|
|
/* Initialize saveDC to screen contents */
|
|
BitBlt(saveDC, 0, 0, pickWid, pickHgt,
|
|
hdcWork, pickRect.left + imageView.left,
|
|
pickRect.top + imageView.top,
|
|
SRCCOPY);
|
|
|
|
|
|
/* make an opaque mask to use for hit testing */
|
|
BuildMask(nPickMode = OPAQUE);
|
|
|
|
|
|
/* draw the dotted outline */
|
|
EnableOutline(TRUE);
|
|
|
|
/* Save current/old position */
|
|
OldPos.x = CurPos.x = pickRect.left;
|
|
OldPos.y = CurPos.y = pickRect.top;
|
|
|
|
/* Enable Pick Menu */
|
|
EnablePickMenu(TRUE);
|
|
|
|
/* Enable Copy options in edit menu */
|
|
ChangeCutCopy(ghMenuFrame, MF_ENABLED);
|
|
}
|
|
}
|
|
|
|
if (bCancel) {
|
|
DOUTR(L"newpick: Sending WM_TERMINATE WM_OUTLINE" );
|
|
SendMessage(hWnd, WM_TERMINATE, 0, 0L);
|
|
}
|
|
|
|
if (dstDC)
|
|
ReleaseDC(hWnd, dstDC);
|
|
|
|
break;
|
|
}
|
|
|
|
/* Note: If left button down pressed inside selection then
|
|
** FALL THROUGH to the right button down message to begin
|
|
** movement processing.
|
|
*/
|
|
|
|
case WM_RBUTTONDOWN:
|
|
if (IsRectEmpty(&pickRect) || !IsInSelection(newPt))
|
|
break;
|
|
|
|
/* remove outline */
|
|
EnableOutline(FALSE);
|
|
|
|
/* if left button down then make transparent mask */
|
|
if (code == WM_LBUTTONDOWN)
|
|
BuildMask(nPickMode = TRANSPARENT);
|
|
|
|
dstDC = GetDisplayDC(hWnd);
|
|
|
|
/* if shift key down make save area same as pick */
|
|
if ((wParam & MK_CONTROL) && dstDC) { // EDH: change to CTRL for copy
|
|
rc1.left = pickRect.left + imageView.left;
|
|
rc1.right = rc1.left + pickWid;
|
|
rc1.top = pickRect.top + imageView.top;
|
|
rc1.bottom = rc1.top + pickHgt;
|
|
|
|
BitBlt(saveDC, 0, 0, pickWid, pickHgt,
|
|
hdcWork, rc1.left, rc1.top,
|
|
SRCCOPY);
|
|
|
|
UnionWithRect(&rDirty, &rc1);
|
|
|
|
AdviseDataChange();
|
|
|
|
UpdFlag(TRUE);
|
|
|
|
} else if (bFirstDrag)
|
|
FillInCutoutOrigin();
|
|
|
|
bFirstDrag = FALSE;
|
|
bPickSwept = FALSE;
|
|
|
|
/***** Allocate work memory for dragging *****/
|
|
|
|
OldPos = CurPos;
|
|
|
|
rcBounds.left = rcBounds.right = newPt.x;
|
|
rcBounds.top = rcBounds.bottom = newPt.y;
|
|
|
|
bDragging = TRUE;
|
|
TrackTool(hWnd, DragProc, &rcBounds, &wParam, NULL);
|
|
bDragging = FALSE;
|
|
|
|
/* reset track tool */
|
|
if (dstDC) {
|
|
DragProc(dstDC, &rcBounds, wParam);
|
|
ReleaseDC(hWnd, dstDC);
|
|
}
|
|
|
|
/* get rid of temporary storage */
|
|
|
|
/* user swept, so just copy entire area to work buffer */
|
|
if (bPickSwept) {
|
|
rDirty.left = 0;
|
|
rDirty.top = 0;
|
|
rDirty.right = nNewImageWidth;
|
|
rDirty.bottom = nNewImageHeight;
|
|
|
|
AdviseDataChange();
|
|
|
|
UpdFlag(TRUE);
|
|
}
|
|
|
|
/* move pickRect and polyPts to new position */
|
|
OffsetRect(&pickRect, CurPos.x - OldPos.x, CurPos.y - OldPos.y);
|
|
OffsetPoly(polyPts, numPts, CurPos.x - OldPos.x,
|
|
CurPos.y - OldPos.y);
|
|
|
|
BuildMask(nPickMode = OPAQUE);
|
|
EnableOutline(TRUE);
|
|
break;
|
|
|
|
case WM_MOUSEMOVE:
|
|
if (bDragging || IsInSelection(newPt)) {
|
|
if (bCrossh) {
|
|
PbSetCursor(szPbCursor(HANDtool));
|
|
bCrossh = FALSE;
|
|
}
|
|
} else {
|
|
if (!bCrossh) {
|
|
PbSetCursor(DrawCursor);
|
|
bCrossh = TRUE;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_TERMINATE:
|
|
EnableOutline(FALSE);
|
|
|
|
if (!IsRectEmpty(&pickRect) && gfDirty) {
|
|
rc1.left = pickRect.left + imageView.left;
|
|
rc1.right = rc1.left + pickWid;
|
|
rc1.top = pickRect.top + imageView.top;
|
|
rc1.bottom = rc1.top + pickHgt;
|
|
|
|
UnionWithRect(&rDirty, &rc1);
|
|
|
|
AdviseDataChange();
|
|
|
|
UpdFlag(TRUE);
|
|
}
|
|
|
|
numPts = 0;
|
|
SetRectEmpty(&pickRect);
|
|
bFirstDrag = TRUE;
|
|
|
|
ChangeCutCopy(ghMenuFrame, MF_GRAYED);
|
|
EnablePickMenu(FALSE);
|
|
|
|
/* tell DotRect to delete its local objects */
|
|
DotRect(NULL, 0, 0, 0, 0);
|
|
FreePick();
|
|
break;
|
|
|
|
case WM_PICKFLIPH:
|
|
oldcsr = SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
if (dstDC = GetDisplayDC(hWnd)) {
|
|
EnableOutline(FALSE);
|
|
|
|
|
|
if (bFirstDrag) {
|
|
FillInCutoutOrigin();
|
|
bFirstDrag = FALSE;
|
|
}
|
|
|
|
StretchBlt(pickDC, pickWid-1, 0, -pickWid, pickHgt,
|
|
pickDC, 0, 0, pickWid, pickHgt,
|
|
SRCCOPY);
|
|
|
|
|
|
StretchBlt(monoDC, pickWid-1, 0, -pickWid, pickHgt,
|
|
monoDC, 0, 0, pickWid, pickHgt,
|
|
SRCCOPY);
|
|
|
|
|
|
BitBlt(hdcWork, CurPos.x + imageView.left,
|
|
CurPos.y + imageView.top,
|
|
pickWid, pickHgt,
|
|
saveDC, 0, 0,
|
|
SRCCOPY);
|
|
|
|
MaskBlt(hdcWork, CurPos.x + imageView.left,
|
|
CurPos.y + imageView.top,
|
|
pickWid, pickHgt,
|
|
pickDC, 0, 0,monoBM, 0, 0,MASKROP(SRCCOPY,0x00aa0000));
|
|
|
|
|
|
BitBlt(dstDC, CurPos.x, CurPos.y, pickWid, pickHgt,
|
|
hdcWork, CurPos.x + imageView.left,
|
|
CurPos.y + imageView.top,
|
|
SRCCOPY);
|
|
|
|
rc1.left = CurPos.x + imageView.left;
|
|
rc1.top = CurPos.y + imageView.top;
|
|
rc1.right = rc1.left + pickWid;
|
|
rc1.bottom = rc1.top + pickHgt;
|
|
|
|
UnionWithRect(&rDirty,&rc1);
|
|
|
|
AdviseDataChange();
|
|
|
|
FlipPoly(polyPts, numPts, FLIPh, &pickRect);
|
|
EnableOutline(TRUE);
|
|
|
|
ReleaseDC(hWnd, dstDC);
|
|
}
|
|
SetCursor(oldcsr);
|
|
break;
|
|
|
|
case WM_PICKFLIPV:
|
|
oldcsr = SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
if (dstDC = GetDisplayDC(hWnd)) {
|
|
EnableOutline(FALSE);
|
|
|
|
|
|
if (bFirstDrag) {
|
|
FillInCutoutOrigin();
|
|
bFirstDrag = FALSE;
|
|
}
|
|
|
|
StretchBlt(pickDC, 0, pickHgt-1, pickWid, -pickHgt,
|
|
pickDC, 0, 0, pickWid, pickHgt,
|
|
SRCCOPY);
|
|
|
|
|
|
StretchBlt(monoDC, 0, pickHgt-1, pickWid, -pickHgt,
|
|
monoDC, 0, 0, pickWid, pickHgt,
|
|
SRCCOPY);
|
|
|
|
|
|
BitBlt(hdcWork, CurPos.x + imageView.left,
|
|
CurPos.y + imageView.top,
|
|
pickWid, pickHgt,
|
|
saveDC, 0, 0,
|
|
SRCCOPY);
|
|
|
|
MaskBlt(hdcWork, CurPos.x + imageView.left,
|
|
CurPos.y + imageView.top,
|
|
pickWid, pickHgt,
|
|
pickDC, 0, 0,monoBM, 0, 0,MASKROP(SRCCOPY,0x00aa0000));
|
|
|
|
BitBlt(dstDC, CurPos.x, CurPos.y, pickWid, pickHgt,
|
|
hdcWork, CurPos.x + imageView.left,
|
|
CurPos.y + imageView.top,
|
|
SRCCOPY);
|
|
|
|
rc1.left = CurPos.x + imageView.left;
|
|
rc1.top = CurPos.y + imageView.top;
|
|
rc1.right = rc1.left + pickWid;
|
|
rc1.bottom = rc1.top + pickHgt;
|
|
|
|
UnionWithRect(&rDirty,&rc1);
|
|
|
|
AdviseDataChange();
|
|
|
|
FlipPoly(polyPts, numPts, FLIPv, &pickRect);
|
|
EnableOutline(TRUE);
|
|
|
|
ReleaseDC(hWnd, dstDC);
|
|
}
|
|
SetCursor(oldcsr);
|
|
break;
|
|
|
|
case WM_PICKINVERT:
|
|
if (dstDC = GetDisplayDC(hWnd)) {
|
|
EnableOutline(FALSE);
|
|
|
|
PatBlt(pickDC, 0, 0, pickWid, pickHgt, DSTINVERT);
|
|
|
|
BuildMask(OPAQUE);
|
|
|
|
BitBlt(hdcWork, CurPos.x + imageView.left,
|
|
CurPos.y + imageView.top,
|
|
pickWid, pickHgt,
|
|
saveDC, 0, 0,
|
|
SRCCOPY);
|
|
|
|
MaskBlt(hdcWork, CurPos.x + imageView.left,
|
|
CurPos.y + imageView.top,
|
|
pickWid, pickHgt,
|
|
pickDC,0, 0, monoBM, 0, 0,MASKROP(SRCCOPY,0x00aa0000));
|
|
|
|
|
|
BitBlt(dstDC, CurPos.x, CurPos.y, pickWid, pickHgt,
|
|
hdcWork, CurPos.x + imageView.left,
|
|
CurPos.y + imageView.top,
|
|
SRCCOPY);
|
|
|
|
rc1.left = CurPos.x + imageView.left;
|
|
rc1.top = CurPos.y + imageView.top;
|
|
rc1.right = rc1.left + pickWid;
|
|
rc1.bottom = rc1.top + pickHgt;
|
|
|
|
UnionWithRect(&rDirty,&rc1);
|
|
|
|
AdviseDataChange();
|
|
|
|
EnableOutline(TRUE);
|
|
|
|
ReleaseDC(hWnd, dstDC);
|
|
}
|
|
break;
|
|
|
|
case WM_PICKSG:
|
|
if (IsRectEmpty((LPRECT) &pickRect))
|
|
break;
|
|
|
|
EnableOutline(FALSE);
|
|
DrawProc = ShrGroDP;
|
|
CheckMenuItem(ghMenuFrame, PICKsg, MF_CHECKED);
|
|
ChangeCutCopy(ghMenuFrame, MF_GRAYED);
|
|
break;
|
|
|
|
case WM_PICKTILT:
|
|
if (IsRectEmpty((LPRECT)&pickRect))
|
|
break;
|
|
|
|
EnableOutline(FALSE);
|
|
DrawProc = TiltDP;
|
|
CheckMenuItem(ghMenuFrame, PICKtilt, MF_CHECKED);
|
|
break;
|
|
|
|
case WM_COPYTO:
|
|
if (!IsRectEmpty(&pickRect)) {
|
|
int result;
|
|
|
|
EnableOutline(FALSE);
|
|
TerminateKill = FALSE;
|
|
result = DoFileDialog(SAVEBOX, pbrushWnd[PARENTid]);
|
|
if (result)
|
|
SaveClip(pickDC, pickBM, pickWid, pickHgt);
|
|
TerminateKill = TRUE;
|
|
UpdateWindow(pbrushWnd[PARENTid]);
|
|
EnableOutline(TRUE);
|
|
}
|
|
break;
|
|
|
|
case WM_CUT:
|
|
case WM_COPY:
|
|
if (!IsRectEmpty(&pickRect)) {
|
|
HDC tempDC = NULL;
|
|
HBITMAP tempBM = NULL;
|
|
|
|
EnableOutline(FALSE);
|
|
|
|
tempDC = CreateCompatibleDC(NULL);
|
|
tempBM = CreateBitmap(pickWid, pickHgt, (BYTE) imagePlanes,
|
|
(BYTE) imagePixels, 0L);
|
|
if (tempDC && tempBM) {
|
|
if (SelectObject(tempDC, tempBM)) {
|
|
RECT rcFix = pickRect;
|
|
|
|
++rcFix.right;
|
|
++rcFix.bottom;
|
|
|
|
FillBkgd(tempDC, 0, 0, pickWid, pickHgt);
|
|
MaskBlt(tempDC, 0, 0, pickWid, pickHgt,
|
|
gfWholeHog ? hdcWork : pickDC,
|
|
0, 0, monoBM, 0, 0, MASKROP(SRCCOPY,0x00aa0000));
|
|
//bCancel = DumpBitmapToClipboard(tempDC, code, rcFix);
|
|
bCancel = SnapshotBitmap(tempDC, rcFix);
|
|
UpdateWindow(hWnd);
|
|
}
|
|
}
|
|
|
|
if (tempDC)
|
|
DeleteDC(tempDC);
|
|
tempDC = NULL;
|
|
if (tempBM)
|
|
DeleteObject(tempBM);
|
|
tempBM = NULL;
|
|
|
|
if (bCancel && code == WM_CUT) {
|
|
if(bFirstDrag) {
|
|
// Set the image changed flag
|
|
gfDirty = TRUE;
|
|
ClearPickArea();
|
|
} else {
|
|
dstDC = GetDisplayDC(pbrushWnd[PAINTid]);
|
|
|
|
BitBlt(hdcWork, CurPos.x + imageView.left,
|
|
CurPos.y + imageView.top,
|
|
pickWid, pickHgt,
|
|
saveDC, 0, 0,
|
|
SRCCOPY);
|
|
BitBlt(dstDC, CurPos.x, CurPos.y, pickWid, pickHgt,
|
|
hdcWork, CurPos.x + imageView.left,
|
|
CurPos.y + imageView.top,
|
|
SRCCOPY);
|
|
|
|
ReleaseDC(pbrushWnd[PAINTid], dstDC);
|
|
}
|
|
|
|
DOUTR(L"newpick: sending WM_TERMINATE for CUT/COPY");
|
|
SendMessage(hWnd, WM_TERMINATE, 0, 0L);
|
|
} else
|
|
EnableOutline(TRUE);
|
|
|
|
//
|
|
// Offer our OLE data-transfer object...
|
|
//
|
|
TransferToClipboard();
|
|
}
|
|
break;
|
|
|
|
case WM_PASTE:
|
|
//PastePictFromClipboard(hWnd);
|
|
PastePictFromOle(hWnd);
|
|
bFirstDrag = FALSE; // make sure screen preserved on drag
|
|
break;
|
|
|
|
case WM_PASTEFROM:
|
|
if (!pickDC)
|
|
break;
|
|
|
|
/* fill polyPts with rect coords */
|
|
numPts = 4;
|
|
polyPts[0].x = polyPts[3].x =
|
|
polyPts[0].y = polyPts[1].y =
|
|
pickRect.left = pickRect.top = 0;
|
|
polyPts[1].x = polyPts[2].x = pickRect.right = pickWid - 1;
|
|
polyPts[2].y = polyPts[3].y = pickRect.bottom = pickHgt - 1;
|
|
|
|
dstDC = GetDisplayDC(hWnd);
|
|
if (dstDC) {
|
|
/* Initialize saveDC to ULC of screen */
|
|
BitBlt(saveDC, 0, 0, pickWid, pickHgt,
|
|
hdcWork, pickRect.left + imageView.left,
|
|
pickRect.top + imageView.top,
|
|
SRCCOPY);
|
|
|
|
/* make an opaque mask to use for hit testing */
|
|
BuildMask(nPickMode = OPAQUE);
|
|
|
|
/* draw pick on screen */
|
|
rc1.left = pickRect.left + imageView.left;
|
|
rc1.top = pickRect.top + imageView.top;
|
|
rc1.right = rc1.left + pickWid;
|
|
rc1.bottom = rc1.top + pickHgt;
|
|
|
|
MaskBlt(hdcWork, rc1.left, rc1.top, pickWid, pickHgt,
|
|
pickDC, 0, 0,monoBM, 0, 0,MASKROP(SRCCOPY,0x00aa0000));
|
|
|
|
UnionWithRect(&rDirty,&rc1);
|
|
AdviseDataChange();
|
|
BitBlt(dstDC, pickRect.left,
|
|
pickRect.top,
|
|
pickWid, pickHgt,
|
|
hdcWork, rc1.left,
|
|
rc1.top,
|
|
SRCCOPY);
|
|
|
|
/* draw the dotted outline */
|
|
EnableOutline(TRUE);
|
|
|
|
/* Save current/old position */
|
|
OldPos.x = CurPos.x = pickRect.left;
|
|
OldPos.y = CurPos.y = pickRect.top;
|
|
|
|
/* Enable Pick Menu */
|
|
EnablePickMenu(TRUE);
|
|
|
|
/* Enable Copy options in edit menu */
|
|
ChangeCutCopy(ghMenuFrame, MF_ENABLED);
|
|
ReleaseDC(hWnd, dstDC);
|
|
|
|
bFirstDrag = FALSE; /* make sure screen preserved on drag */
|
|
UpdFlag(TRUE);
|
|
} else {
|
|
DOUTR(L"newpick: sending WM_TERMINATE from PASTEFROM");
|
|
SendMessage(hWnd, WM_TERMINATE, 0, 0L);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
void FAR ChangeCutCopy(HMENU hMenu, WORD wEnable) {
|
|
EnableMenuItem(hMenu, EDITcutpict, wEnable);
|
|
EnableMenuItem(hMenu, EDITcopyTo, wEnable);
|
|
EnableMenuItem(hMenu, EDITcopypict, wEnable);
|
|
}
|
|
|
|
#if 0
|
|
|
|
#pragma message( __FILE__ "(1342) : warning @@@@ : remove this debug code" )
|
|
|
|
#define JONP 0x504e4f4aL
|
|
#define NCSU 0x5543534eL
|
|
|
|
#define MsgBox( szTxt, szTitle ) \
|
|
MessageBox( GetDesktopWindow(), szTxt, szTitle, MB_OK )
|
|
|
|
HLOCAL AllocLPTR(UINT cbBytes ) {
|
|
LPDWORD pdw;
|
|
UINT cb;
|
|
|
|
cb = ((cbBytes + 3) & ~3);
|
|
|
|
pdw = LocalAlloc( LPTR, cb + sizeof(DWORD) * 3 );
|
|
|
|
if (pdw != NULL ) {
|
|
*pdw++ = (DWORD)cbBytes;
|
|
*pdw++ = JONP;
|
|
pdw[cb/4] = NCSU;
|
|
}
|
|
|
|
return (LPBYTE)pdw;
|
|
}
|
|
|
|
HLOCAL FreeLPTR( HLOCAL hpb, LPTSTR szName ) {
|
|
LPDWORD pdw;
|
|
DWORD cb;
|
|
LPBYTE pb = (LPBYTE)hpb;
|
|
|
|
pdw = (LPDWORD)pb;
|
|
|
|
if ( *--pdw != JONP )
|
|
MsgBox( szName, TEXT("Under Write on pointer") );
|
|
|
|
pdw--;
|
|
cb = *pdw;
|
|
|
|
cb = ((cb + 3) & ~3);
|
|
if ( ((LPDWORD)pb)[cb/4] != NCSU )
|
|
MsgBox( szName, TEXT("OverWrite on pointer") );
|
|
|
|
return LocalFree( pdw );
|
|
}
|
|
|
|
#else
|
|
# define AllocLPTR( cb ) LocalAlloc( LPTR, cb )
|
|
# define FreeLPTR(pb, sz) LocalFree( pb )
|
|
# define MsgBox( s1, s2 ) /* nothing */
|
|
#endif
|
|
|
|
#if DBG
|
|
# pragma message("newpick.c(1483): warning $$$$ : Debug build of newpick.c" )
|
|
#endif
|
|
|
|
HBITMAP MapBitmapColors( HDC hdcMem, HPALETTE hpalDst, HBITMAP hbmSrc,
|
|
HPALETTE hpalSrc ) {
|
|
|
|
WORD cColors;
|
|
LPBITMAPINFO lpbmi = NULL;
|
|
BITMAPINFO bmi;
|
|
HPALETTE hpalOld;
|
|
LPVOID lpBits = NULL;
|
|
HBITMAP hbmNew = NULL;
|
|
|
|
DOUTR(L"In MapBMClrs");
|
|
|
|
if (hpalSrc == NULL)
|
|
return NULL;
|
|
|
|
DOUTR(L"MapBMClrs: hpalSrc != NULL, continuing");
|
|
|
|
hpalOld = SelectPalette(hdcMem, hpalSrc, FALSE);
|
|
RealizePalette(hdcMem);
|
|
|
|
#if DBG
|
|
if (hpalOld == NULL ) {
|
|
TCHAR szBuf[50];
|
|
wsprintf( szBuf, L"MapBMClrs: sel palSrc failed %ld\n", GetLastError());
|
|
DOUT(szBuf);
|
|
}
|
|
#endif
|
|
|
|
ZeroMemory( &(bmi.bmiHeader), sizeof(bmi.bmiHeader) );
|
|
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
|
|
|
|
if (GetDIBits( hdcMem, hbmSrc, 0, 0, NULL, &bmi, DIB_RGB_COLORS ) == 0) {
|
|
MsgBox( L"GetDIBits1 failed", NULL );
|
|
goto MBCExit;
|
|
}
|
|
|
|
cColors = 1 << (bmi.bmiHeader.biPlanes * bmi.bmiHeader.biBitCount);
|
|
|
|
lpbmi = AllocLPTR( sizeof(BITMAPINFO) + (sizeof(RGBQUAD) * cColors) );
|
|
|
|
if (lpbmi == NULL)
|
|
goto MBCExit;
|
|
|
|
CopyMemory( lpbmi, &bmi, sizeof(bmi) );
|
|
|
|
lpbmi->bmiHeader.biSize = sizeof(lpbmi->bmiHeader);
|
|
|
|
lpBits = AllocLPTR( lpbmi->bmiHeader.biHeight *
|
|
((lpbmi->bmiHeader.biWidth * lpbmi->bmiHeader.biPlanes *
|
|
lpbmi->bmiHeader.biBitCount + 31) & ~31) / 8);
|
|
|
|
|
|
if (lpBits == NULL) {
|
|
MsgBox(L"LocalAllocs failed", NULL);
|
|
goto MBCExit;
|
|
}
|
|
|
|
if (GetDIBits( hdcMem, hbmSrc, 0, lpbmi->bmiHeader.biHeight, lpBits, lpbmi,
|
|
DIB_RGB_COLORS ) == 0) {
|
|
MsgBox( L"GetDIBits2 failed", NULL );
|
|
goto MBCExit;
|
|
}
|
|
|
|
#if DBG
|
|
if( SelectPalette( hdcMem, hpalDst, FALSE ) == NULL ) {
|
|
TCHAR szBuf[50];
|
|
wsprintf( szBuf, L"MapBMClrs: sel palDst failed %ld\n", GetLastError());
|
|
DOUT(szBuf);
|
|
}
|
|
#else
|
|
SelectPalette( hdcMem, hpalDst, FALSE );
|
|
#endif
|
|
|
|
RealizePalette(hdcMem);
|
|
|
|
if ( (hbmNew = CreateDIBitmap( hdcMem, NULL, CBM_INIT | CBM_CREATEDIB,
|
|
lpBits, lpbmi, DIB_RGB_COLORS )) == NULL) {
|
|
MsgBox(L"SetDIBits failed", NULL);
|
|
}
|
|
|
|
MBCExit:
|
|
if (lpbmi != NULL)
|
|
FreeLPTR(lpbmi, TEXT("lpbmi"));
|
|
|
|
if (lpBits != NULL)
|
|
FreeLPTR(lpBits, TEXT("lpBits") );
|
|
|
|
SelectPalette(hdcMem, hpalOld, FALSE);
|
|
|
|
return hbmNew;
|
|
}
|