Windows NT 4.0 source code leak
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

/****************************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;
}