|
|
1.1.1.3 ! root 1: ! 2: /******************************************************************************\ ! 3: * This is a part of the Microsoft Source Code Samples. ! 4: * Copyright (C) 1993 Microsoft Corporation. ! 5: * All rights reserved. ! 6: * This source code is only intended as a supplement to ! 7: * Microsoft Development Tools and/or WinHelp documentation. ! 8: * See these sources for detailed information regarding the ! 9: * Microsoft samples programs. ! 10: \******************************************************************************/ ! 11: 1.1 root 12: /**************************************************************************\ 13: * plgblt.c -- sample program demonstrating the new PlgBlt() API. 14: * 15: * design: There is one main window with one dialog box stretched to fill 16: * the top of it. The parameters for the plgblt painted into the main 17: * window are stored in the entry fields of this dialog box. The user 18: * may change these values and see the effect on the blt. 19: \**************************************************************************/ 20: 21: #include <windows.h> 22: #include <commdlg.h> 23: #include <math.h> 24: #include <stdio.h> 25: #include "plgblt.h" 26: #include "track.h" 27: #include "bitmap.h" 28: 29: 30: 31: /* global variables. */ 32: PTrackObject ptoDest, ptoSrc, ptoMask = NULL; 33: HDC hdcDest, hdcSrc, hdcMask; 34: HBITMAP hbmSrc, hbmMask = NULL; 35: 36: HANDLE hInst; 37: HWND hwndMain, hwndDlg; 38: 1.1.1.2 root 39: int nSpin; 40: 41: 42: #define BACKGROUNDBRUSH GetStockObject(LTGRAY_BRUSH) 1.1 root 43: 44: 45: 46: /**************************************************************************\ 47: * 48: * function: WinMain() 49: * 50: * input parameters: c.f. generic sample 51: * 52: \**************************************************************************/ 53: int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 54: LPSTR lpCmdLine, int nCmdShow) 55: { 56: MSG msg; 57: RECT rect; 58: HANDLE haccel; 59: 60: UNREFERENCED_PARAMETER( lpCmdLine ); 61: 62: 63: /* Check for previous instance. If none, then register class. */ 64: if (!hPrevInstance) { 65: WNDCLASS wc; 66: 1.1.1.3 ! root 67: wc.style = 0; 1.1 root 68: wc.lpfnWndProc = (WNDPROC)MainWndProc; 69: 70: wc.cbClsExtra = 0; 71: wc.cbWndExtra = 0; 72: wc.hInstance = hInstance; 73: wc.hIcon = LoadIcon(hInstance, "plgbltIcon"); 74: wc.hCursor = LoadCursor(NULL, IDC_ARROW); 1.1.1.2 root 75: wc.hbrBackground = BACKGROUNDBRUSH; 76: wc.lpszMenuName = "plgbltMenu"; 1.1 root 77: wc.lpszClassName = "plgblt"; 78: 79: if (!RegisterClass(&wc)) return (FALSE); 80: } /* class registered o.k. */ 81: 82: 83: /* Create the main window. Return false if CreateWindow() fails */ 84: hInst = hInstance; 85: 86: hwndMain = CreateWindow( 87: "plgblt", 88: "plgblt", 89: WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, 90: CW_USEDEFAULT, 91: CW_USEDEFAULT, 92: CW_USEDEFAULT, 93: CW_USEDEFAULT, 94: NULL, 95: NULL, 96: hInstance, 97: NULL); 98: 99: if (!hwndMain) return (FALSE); 100: 101: 102: /* create the top dialog as a child of the main window. */ 103: hwndDlg = CreateDialog (hInst, "plgbltDlg", hwndMain, (DLGPROC)DlgProc); 104: 105: /* Send main window a WM_SIZE message so that it will size the top 106: * dialog correctly. 107: */ 108: GetClientRect (hwndMain, &rect); 109: SendMessage (hwndMain, WM_SIZE, 0, (rect.right - rect.left)); 110: ShowWindow (hwndDlg, SW_SHOW); 111: ShowWindow(hwndMain, nCmdShow); 112: 113: 1.1.1.2 root 114: /* get global handle to the menu */ 115: 1.1 root 116: /* Load the accelerator table that provides clipboard support. */ 117: haccel = LoadAccelerators (hInst, "bltAccel"); 118: 119: 120: 121: /* Loop getting messages and dispatching them. */ 1.1.1.3 ! root 122: while (GetMessage(&msg,NULL, 0,0)) { 1.1 root 123: if (!TranslateAccelerator(hwndMain, haccel, &msg)) 124: if (!IsDialogMessage (hwndDlg, &msg)){ 125: DispatchMessage(&msg); 126: } 1.1.1.2 root 127: 128: /* if no messages, and we are spinning, then post spin message. */ 129: if (!PeekMessage (&msg, hwndMain, 0,0, PM_NOREMOVE) && nSpin) 130: PostMessage (hwndMain, WM_SPIN, 0,0); 1.1 root 131: } 132: 133: /* Return the value from PostQuitMessage */ 134: return (msg.wParam); 135: } 136: 137: 138: 139: 140: /**************************************************************************\ 141: * 142: * function: MainWndProc() 143: * 144: * input parameters: normal window procedure parameters. 145: * 146: * There are 6 different HDCs used for the main window (in addition to the 147: * temporary one returned from BeginPaint). There are two for each of the 148: * three thirds of the window. The first one contains the bitmap. The 149: * second one is for the track object and is stored in the TRACKOBJECT 150: * structure. 151: * 152: * global variables: 153: * hwndDlg - dialog with entry fields containing parameters. 154: * ptoDest, ptoSrc, ptoMask - pointers to the direct manipulation objects 155: * hdcDest, hdcSrc, hdcMask - HDCs for the 3 sub regions of the window. 156: * hbmSrc, hbmMask - bitmap handles for source and mask. 157: \**************************************************************************/ 1.1.1.2 root 158: LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 1.1 root 159: { 160: static int miniWidth; 161: static RECT rect; 162: static HANDLE hPenGrid, hPenSeparator; 163: 164: switch (message) { 165: 166: /**********************************************************************\ 167: * WM_CREATE 168: * 169: * Get three new HDCs, then create three new track objects. 170: * Each track object has different allowed tracking modes. 171: * Finally create two pens for drawing later on. 172: \**********************************************************************/ 173: case WM_CREATE: 174: hdcSrc = GetDC (hwnd); 175: hdcDest = GetDC (hwnd); 176: hdcMask = GetDC (hwnd); 177: 1.1.1.3 ! root 178: ptoDest = doTrackObject (NULL, TROB_NEW, hwnd,0); 1.1 root 179: ptoDest->allowedModes = TMALL; 1.1.1.3 ! root 180: ptoSrc = doTrackObject (NULL, TROB_NEW, hwnd,0); 1.1 root 181: ptoSrc->allowedModes = TMMOVE | TMSIZEXY; 1.1.1.3 ! root 182: ptoMask = doTrackObject (NULL, TROB_NEW, hwnd,0); 1.1 root 183: ptoMask->allowedModes = TMMOVE; 184: 185: hPenGrid = CreatePen (PS_SOLID, 1, GRIDCOLOR); 186: hPenSeparator = CreatePen (PS_SOLID, 2*SEPARATORWIDTH, (COLORREF) 0x01000000); 1.1.1.2 root 187: 188: { HMENU hMenu; 189: hMenu = GetMenu (hwnd); 190: CheckMenuItem(hMenu, IDM_SPINTOPLEFT, MF_CHECKED); 191: CheckMenuItem(hMenu, IDM_SPINOFF , MF_CHECKED); 192: nSpin = FALSE; 193: } 194: 1.1 root 195: break; 196: 197: 198: /**********************************************************************\ 199: * WM_DESTROY 200: * 201: * Complement of WM_CREATE. Free up all of the HDCs, send all of the 202: * track objects their delete messages, delete the pens, 203: * then call PostQuitMessage. 204: \**********************************************************************/ 205: case WM_DESTROY: 206: ReleaseDC (hwnd, hdcSrc ); 207: ReleaseDC (hwnd, hdcDest); 208: ReleaseDC (hwnd, hdcMask); 1.1.1.3 ! root 209: doTrackObject (ptoDest, TROB_DELETE, hwnd,0); ! 210: doTrackObject (ptoSrc , TROB_DELETE, hwnd,0); ! 211: doTrackObject (ptoMask, TROB_DELETE, hwnd,0); 1.1 root 212: 213: DeleteObject(hPenGrid); 214: DeleteObject(hPenSeparator); 215: 216: PostQuitMessage(0); 217: break; 218: 219: 220: 221: /**********************************************************************\ 222: * WM_SIZE 223: * 224: * Stretch the top dialog to fill the width of the main window. 225: * Adjust the viewport origins of the 6 HDCs. 226: * Set the clip regions of the 6 HDCs. 227: \**********************************************************************/ 228: case WM_SIZE: { 229: HRGN hrgn; 230: 1.1.1.3 ! root 231: SetWindowPos (hwndDlg, NULL, 0,0, LOWORD(lParam), DIALOGHEIGHT, 0); 1.1 root 232: 233: GetClientRect (hwndMain, &rect); 234: miniWidth = rect.right/3; 235: 236: SetViewportOrgEx (hdcDest, 0, DIALOGHEIGHT, NULL); 237: SetViewportOrgEx (ptoDest->hdc, 0, DIALOGHEIGHT, NULL); 238: SetViewportOrgEx (hdcSrc, miniWidth, DIALOGHEIGHT, NULL); 239: SetViewportOrgEx (ptoSrc->hdc, miniWidth, DIALOGHEIGHT, NULL); 240: SetViewportOrgEx (hdcMask, 2*miniWidth, DIALOGHEIGHT, NULL); 241: SetViewportOrgEx (ptoMask->hdc, 2*miniWidth, DIALOGHEIGHT, NULL); 242: 243: ptoDest->rectClip.left = 0; 244: ptoDest->rectClip.top = DIALOGHEIGHT; 245: ptoDest->rectClip.right = miniWidth-2*SEPARATORWIDTH; 246: ptoDest->rectClip.bottom = rect.bottom; 247: hrgn = CreateRectRgnIndirect (&ptoDest->rectClip); 248: SelectClipRgn (hdcDest, hrgn); 249: SelectClipRgn (ptoDest->hdc, hrgn); 250: DeleteObject (hrgn); 251: 252: ptoSrc->rectClip.left = miniWidth; 253: ptoSrc->rectClip.top = DIALOGHEIGHT; 254: ptoSrc->rectClip.right = 2*miniWidth-2*SEPARATORWIDTH; 255: ptoSrc->rectClip.bottom = rect.bottom; 256: hrgn = CreateRectRgnIndirect (&ptoSrc->rectClip); 257: SelectClipRgn (hdcSrc, hrgn); 258: SelectClipRgn (ptoSrc->hdc, hrgn); 259: DeleteObject (hrgn); 260: 261: ptoMask->rectClip.left = 2*miniWidth; 262: ptoMask->rectClip.top = DIALOGHEIGHT; 263: ptoMask->rectClip.right = 3*miniWidth; 264: ptoMask->rectClip.bottom = rect.bottom; 265: hrgn = CreateRectRgnIndirect (&ptoMask->rectClip); 266: SelectClipRgn (hdcMask, hrgn); 267: SelectClipRgn (ptoMask->hdc, hrgn); 268: DeleteObject (hrgn); 269: 270: SendMessage (hwndDlg, WM_PUTUPLPOINTS, (DWORD)hdcDest, (LONG)ptoDest); 271: SendMessage (hwndDlg, WM_PUTUPSRCRECT, (DWORD)hdcSrc, (LONG)ptoSrc); 272: SendMessage (hwndDlg, WM_PUTUPMASKPT, (DWORD)hdcMask, (LONG)ptoMask); 273: 274: /* repaint the whole window. */ 275: InvalidateRect (hwnd, NULL, TRUE); 276: } break; 277: 278: 279: 280: /**********************************************************************\ 281: * WM_PAINT 282: * 283: * miniWidth, rect -- set by WM_SIZE message. 284: * 285: * First shift the viewport origin down so that 0,0 is the top left 286: * most visible point (out from underneath the top dialog). Second, 287: * draw the grid with wider lines on the axes. Finally, read the 288: * values out of the top dialog, do elementary validation, and then 289: * try to call plgblt() with the values. 290: \**********************************************************************/ 291: case WM_PAINT: { 292: HDC hdc; 293: PAINTSTRUCT ps; 294: 295: hdc = BeginPaint(hwnd, &ps); 296: 297: /* Draw Separator lines for the three miniareas */ 298: SelectObject(hdc, hPenSeparator); 299: MoveToEx (hdc, miniWidth-SEPARATORWIDTH,0, NULL); 300: LineTo (hdc, miniWidth-SEPARATORWIDTH, rect.bottom); 301: MoveToEx (hdc, 2*miniWidth-SEPARATORWIDTH,0, NULL); 302: LineTo (hdc, 2*miniWidth-SEPARATORWIDTH, rect.bottom); 303: 304: /* Grid the HDCs */ 305: SelectObject(hdcSrc, hPenGrid); 306: DrawGrids (hdcSrc, miniWidth, rect.bottom); 307: SelectObject(hdcMask, hPenGrid); 308: DrawGrids (hdcMask, miniWidth, rect.bottom); 309: 310: /* Draw bitmaps if any, then draw track objects over them. */ 311: if (hbmSrc) DrawBitmap (hdcSrc, hbmSrc); 312: if (hbmMask) DrawBitmap (hdcMask, hbmMask); 1.1.1.3 ! root 313: doTrackObject (ptoSrc , TROB_PAINT, hwnd, 0); ! 314: doTrackObject (ptoMask, TROB_PAINT, hwnd, 0); 1.1 root 315: 316: /* paint the left third of the window. */ 317: SendMessage (hwnd, WM_PLGBLT, 0,0); 318: 319: EndPaint (hwnd, &ps); 320: } return FALSE; 321: 322: 323: 324: /**********************************************************************\ 325: * WM_PLGBLT 326: * 327: * WM_USER message. This paints the left third of the window. It 328: * is called on the WM_PAINT message. It is separated out here because 329: * it is common for just the plgblt() to need to be called and not the 330: * whole window painted. 331: \**********************************************************************/ 332: case WM_PLGBLT: { 333: POINT lpPoint[3]; 334: int XSrc, YSrc, nWidth, nHeight, XMask, YMask; 335: BOOL success; 336: RECT cliprect; 337: 1.1.1.3 ! root 338: doTrackObject (ptoSrc , TROB_PAINT, hwnd, 0); ! 339: doTrackObject (ptoMask, TROB_PAINT, hwnd, 0); 1.1 root 340: 341: GetClipBox (hdcDest, &cliprect); 342: FillRect (hdcDest, &cliprect, 343: (HBRUSH) GetClassLong (hwnd, GCL_HBRBACKGROUND)); 344: SelectObject(hdcDest, hPenGrid); 345: 346: DrawGrids (hdcDest, miniWidth, rect.bottom); 347: if (IsWindow(hwndDlg)) { 348: 349: /* Grab points out of the dialog entry fields. */ 350: lpPoint[0].x = GetDlgItemInt(hwndDlg, DID_P1X, &success, TRUE); 351: lpPoint[0].y = GetDlgItemInt(hwndDlg, DID_P1Y, &success, TRUE); 352: lpPoint[1].x = GetDlgItemInt(hwndDlg, DID_P2X, &success, TRUE); 353: lpPoint[1].y = GetDlgItemInt(hwndDlg, DID_P2Y, &success, TRUE); 354: lpPoint[2].x = GetDlgItemInt(hwndDlg, DID_P3X, &success, TRUE); 355: lpPoint[2].y = GetDlgItemInt(hwndDlg, DID_P3Y, &success, TRUE); 356: XSrc = GetDlgItemInt(hwndDlg, DID_XSRC, &success, TRUE); 357: YSrc = GetDlgItemInt(hwndDlg, DID_YSRC, &success, TRUE); 358: nWidth = GetDlgItemInt(hwndDlg, DID_WIDTH, &success, TRUE); 359: nHeight = GetDlgItemInt(hwndDlg, DID_HEIGHT, &success, TRUE); 360: XMask = GetDlgItemInt(hwndDlg, DID_XMASK, &success, TRUE); 361: YMask = GetDlgItemInt(hwndDlg, DID_YMASK, &success, TRUE); 362: 363: 364: /**********************************************************/ 365: /**********************************************************/ 366: PlgBlt (hdcDest, lpPoint, 367: hdcSrc, XSrc, YSrc, nWidth, nHeight, 368: hbmMask, XMask, YMask); 369: /**********************************************************/ 370: /**********************************************************/ 371: } 1.1.1.3 ! root 372: doTrackObject (ptoSrc , TROB_PAINT, hwnd, 0); ! 373: doTrackObject (ptoMask, TROB_PAINT, hwnd, 0); 1.1 root 374: } break; 375: 376: 377: 378: /**********************************************************************\ 379: * WM_LBUTTONDOWN & WM_RBUTTONDOWN 380: * On button down messages, hittest on the track object, and if 381: * it returns true, then send these messages to the track object. 382: \**********************************************************************/ 383: case WM_RBUTTONDOWN: 384: case WM_LBUTTONDOWN: 385: if (doTrackObject(ptoDest, TROB_HITTEST, hwnd, lParam)) 386: doTrackObject(ptoDest, message, hwnd, lParam); 387: else if (doTrackObject(ptoSrc, TROB_HITTEST, hwnd, lParam)) 388: doTrackObject(ptoSrc, message, hwnd, lParam); 389: else if (doTrackObject(ptoMask, TROB_HITTEST, hwnd, lParam)) 390: doTrackObject(ptoMask, message, hwnd, lParam); 391: break; 392: 393: 394: 395: /**********************************************************************\ 396: * WM_LBUTTONUP & WM_RBUTTONDOWN & MW_MOUSEMOVE 397: * If the track object is in a "tracking mode" then send it these messages. 398: * If the transform dialog is not minimized, fill it with numbers. 399: * If the mouse dialog is not minimized, fill it with numbers. 400: \**********************************************************************/ 401: case WM_RBUTTONUP: 402: case WM_LBUTTONUP: 403: /* user action complete. Force plgblt() update. */ 404: PostMessage (hwndMain, WM_PLGBLT, 0,0); 405: case WM_MOUSEMOVE: 406: if (ptoDest->Mode) { 407: doTrackObject(ptoDest, message, hwnd, lParam); 408: SendMessage (hwndDlg, WM_PUTUPLPOINTS, (DWORD) hdcDest, (LONG) ptoDest); 409: } 410: if (ptoSrc->Mode) { 411: doTrackObject(ptoSrc, message, hwnd, lParam); 412: SendMessage (hwndDlg, WM_PUTUPSRCRECT, (DWORD) hdcSrc, (LONG) ptoSrc); 413: } 414: 415: if (ptoMask->Mode) { 416: doTrackObject(ptoMask, message, hwnd, lParam); 417: SendMessage (hwndDlg, WM_PUTUPMASKPT, (DWORD) hdcMask, (LONG) ptoMask); 418: } 419: 420: break; 421: 422: 423: 424: /**********************************************************************\ 1.1.1.2 root 425: * WM_SETFOCUS 426: * 427: * The main window should never have the focus. Set it back 428: * to the top dialog. 429: \**********************************************************************/ 430: case WM_SETFOCUS: SetFocus (hwndDlg); 1.1.1.3 ! root 431: return 0; 1.1.1.2 root 432: 433: 434: 435: /**********************************************************************\ 436: * Menu item support. 1.1 root 437: * 438: \**********************************************************************/ 439: case WM_COMMAND: 440: switch (LOWORD(wParam)) { 441: HBITMAP hbmCompat, hbmOld; 442: HDC hdcCompat; 443: 444: /******************************************************************\ 1.1.1.2 root 445: * WM_COMMAND, IDM_COPY 1.1 root 446: * 447: * Create a new bitmap, copy the destination HDC bits into it, 448: * and send the new bitmap to the clipboard. 449: \******************************************************************/ 1.1.1.2 root 450: case IDM_COPY: { 1.1 root 451: int X[4],Y[4]; 452: int nWidth, nHeight; 453: int Xmin, Ymin, Xmax, Ymax; 454: BOOL success; 455: int i; 456: 457: for (i = 0; i<3 ; i++) { 458: X[i] = GetDlgItemInt(hwndDlg, DID_P1X + 2*i, &success, TRUE); 459: Y[i] = GetDlgItemInt(hwndDlg, DID_P1Y + 2*i, &success, TRUE); 460: } 461: 462: X[3] = (X[1] - X[0]) + X[2]; 463: Y[3] = (Y[2] - Y[0]) + Y[1]; 464: 465: Xmin = Xmax = X[0]; 466: Ymin = Ymax = Y[0]; 467: 468: for (i = 1; i<4 ; i++) { 469: Xmin = (X[i] < Xmin) ? X[i] : Xmin; 470: Ymin = (Y[i] < Ymin) ? Y[i] : Ymin; 471: Xmax = (X[i] > Xmax) ? X[i] : Xmax; 472: Ymax = (Y[i] > Ymax) ? Y[i] : Ymax; 473: } 474: 475: nWidth = Xmax - Xmin; 476: nHeight = Ymax - Ymin; 477: 478: hdcCompat = CreateCompatibleDC(hdcDest); 479: hbmCompat = CreateCompatibleBitmap (hdcDest, nWidth, nHeight); 480: hbmOld = SelectObject(hdcCompat,hbmCompat); 481: 482: BitBlt (hdcCompat, 0,0,nWidth, nHeight, hdcDest, Xmin,Ymin, SRCCOPY ); 483: 484: SelectObject(hdcCompat,hbmOld); 485: DeleteDC(hdcCompat); 486: 487: OpenClipboard (hwnd); 488: SetClipboardData (CF_BITMAP,hbmCompat); 489: CloseClipboard (); 490: 491: DeleteObject (hbmCompat); 492: 493: } break; 494: 495: 496: /******************************************************************\ 1.1.1.2 root 497: * WM_COMMAND, IDM_PASTE 1.1 root 498: * 499: * Get bitmap handle from clipboard, create a new bitmap, draw 500: * the clipboard bitmap into the new one, and store the new 501: * handle in the global hbmSrc. 502: \******************************************************************/ 1.1.1.2 root 503: case IDM_PASTE: { 1.1 root 504: HBITMAP hbm; 505: BITMAP bm; 506: 507: OpenClipboard (hwnd); 508: if ( hbm = GetClipboardData (CF_BITMAP)) { 509: DeleteObject (hbmSrc); 510: 511: GetObject (hbm, sizeof(BITMAP), &bm); 512: 513: hdcCompat = CreateCompatibleDC(hdcDest); 514: hbmCompat = CreateCompatibleBitmap (hdcDest, bm.bmWidth, bm.bmHeight); 515: hbmOld = SelectObject(hdcCompat,hbmCompat); 516: 517: DrawBitmap (hdcCompat, hbm); 518: 519: SelectObject(hdcCompat,hbmOld); 520: DeleteDC(hdcCompat); 521: 522: hbmSrc = hbmCompat; 523: 524: InvalidateRect (hwnd, &ptoSrc->rectClip, TRUE); 525: InvalidateRect (hwnd, &ptoDest->rectClip, TRUE); 526: } 527: CloseClipboard (); 528: } break; 529: 530: /******************************************************************\ 1.1.1.2 root 531: * WM_COMMAND, IDM_BOTH 1.1 root 532: * 533: * Post a COPY and PASTE command message to this window so that with 534: * one key stroke the user can copy the DEST image into the clipboard, 535: * paste it down into the SRC hdc and cause the blt. 536: \******************************************************************/ 1.1.1.2 root 537: case IDM_BOTH: 538: 539: PostMessage (hwnd, WM_COMMAND, MAKELONG (IDM_COPY , 1), 0); 540: PostMessage (hwnd, WM_COMMAND, MAKELONG (IDM_PASTE, 1), 0); 541: 1.1 root 542: break; 1.1.1.2 root 543: 544: 545: 546: /******************************************************************\ 547: * WM_COMMAND, IDM_MODE_* 548: * 549: * manage mutually exclusive menu. 550: * call SetStretchBltMode() for the global destination hdc. 551: \******************************************************************/ 552: case IDM_MODE_BLACKONWHITE: 553: { HMENU hMenu; 554: hMenu = GetMenu (hwnd); 555: 556: CheckMenuItem(hMenu, IDM_MODE_BLACKONWHITE, MF_CHECKED); 557: CheckMenuItem(hMenu, IDM_MODE_COLORONCOLOR, MF_UNCHECKED); 558: CheckMenuItem(hMenu, IDM_MODE_WHITEONBLACK, MF_UNCHECKED); 559: CheckMenuItem(hMenu, IDM_MODE_HALFTONE , MF_UNCHECKED); 560: 561: SetStretchBltMode (hdcDest,BLACKONWHITE); 562: SendMessage (hwndMain, WM_PLGBLT, 0,0); 563: 1.1.1.3 ! root 564: } return 0; 1.1.1.2 root 565: 566: case IDM_MODE_COLORONCOLOR: 567: { HMENU hMenu; 568: hMenu = GetMenu (hwnd); 569: 570: CheckMenuItem(hMenu, IDM_MODE_BLACKONWHITE, MF_UNCHECKED); 571: CheckMenuItem(hMenu, IDM_MODE_COLORONCOLOR, MF_CHECKED); 572: CheckMenuItem(hMenu, IDM_MODE_WHITEONBLACK, MF_UNCHECKED); 573: CheckMenuItem(hMenu, IDM_MODE_HALFTONE , MF_UNCHECKED); 574: 575: SetStretchBltMode (hdcDest,COLORONCOLOR); 576: SendMessage (hwndMain, WM_PLGBLT, 0,0); 577: 1.1.1.3 ! root 578: } return 0; 1.1.1.2 root 579: 580: case IDM_MODE_WHITEONBLACK: 581: { HMENU hMenu; 582: hMenu = GetMenu (hwnd); 583: 584: CheckMenuItem(hMenu, IDM_MODE_BLACKONWHITE, MF_UNCHECKED); 585: CheckMenuItem(hMenu, IDM_MODE_COLORONCOLOR, MF_UNCHECKED); 586: CheckMenuItem(hMenu, IDM_MODE_WHITEONBLACK, MF_CHECKED); 587: CheckMenuItem(hMenu, IDM_MODE_HALFTONE , MF_UNCHECKED); 588: 589: SetStretchBltMode (hdcDest,WHITEONBLACK); 590: SendMessage (hwndMain, WM_PLGBLT, 0,0); 591: 1.1.1.3 ! root 592: } return 0; 1.1.1.2 root 593: 594: case IDM_MODE_HALFTONE : 595: { HMENU hMenu; 596: hMenu = GetMenu (hwnd); 597: 598: CheckMenuItem(hMenu, IDM_MODE_BLACKONWHITE, MF_UNCHECKED); 599: CheckMenuItem(hMenu, IDM_MODE_COLORONCOLOR, MF_UNCHECKED); 600: CheckMenuItem(hMenu, IDM_MODE_WHITEONBLACK, MF_UNCHECKED); 601: CheckMenuItem(hMenu, IDM_MODE_HALFTONE , MF_CHECKED); 602: 603: SetStretchBltMode (hdcDest,HALFTONE); 604: SendMessage (hwndMain, WM_PLGBLT, 0,0); 605: 1.1.1.3 ! root 606: } return 0; 1.1.1.2 root 607: 608: 609: 610: 611: 612: /******************************************************************\ 613: * WM_COMMAND, IDM_SPIN* 614: * 615: * manage mutually exclusive menu. 616: * 617: \******************************************************************/ 618: case IDM_SPINOFF: 619: { HMENU hMenu; 620: hMenu = GetMenu (hwnd); 621: 622: CheckMenuItem(hMenu, IDM_SPINOFF, MF_CHECKED); 623: CheckMenuItem(hMenu, IDM_SPIN5 , MF_UNCHECKED); 624: CheckMenuItem(hMenu, IDM_SPIN10 , MF_UNCHECKED); 625: CheckMenuItem(hMenu, IDM_SPIN30 , MF_UNCHECKED); 626: CheckMenuItem(hMenu, IDM_SPIN60 , MF_UNCHECKED); 627: CheckMenuItem(hMenu, IDM_SPIN90 , MF_UNCHECKED); 628: 629: nSpin = FALSE; 630: SendMessage (hwndMain, WM_PLGBLT, 0,0); 631: 1.1.1.3 ! root 632: } return 0; 1.1.1.2 root 633: 634: case IDM_SPIN5 : 635: { HMENU hMenu; 636: hMenu = GetMenu (hwnd); 637: 638: CheckMenuItem(hMenu, IDM_SPINOFF, MF_UNCHECKED); 639: CheckMenuItem(hMenu, IDM_SPIN5 , MF_CHECKED); 640: CheckMenuItem(hMenu, IDM_SPIN10 , MF_UNCHECKED); 641: CheckMenuItem(hMenu, IDM_SPIN30 , MF_UNCHECKED); 642: CheckMenuItem(hMenu, IDM_SPIN60 , MF_UNCHECKED); 643: CheckMenuItem(hMenu, IDM_SPIN90 , MF_UNCHECKED); 644: 645: nSpin = 5; 646: 1.1.1.3 ! root 647: } return 0; 1.1.1.2 root 648: 649: case IDM_SPIN10: 650: { HMENU hMenu; 651: hMenu = GetMenu (hwnd); 652: 653: CheckMenuItem(hMenu, IDM_SPINOFF, MF_UNCHECKED); 654: CheckMenuItem(hMenu, IDM_SPIN5 , MF_UNCHECKED); 655: CheckMenuItem(hMenu, IDM_SPIN10 , MF_CHECKED); 656: CheckMenuItem(hMenu, IDM_SPIN30 , MF_UNCHECKED); 657: CheckMenuItem(hMenu, IDM_SPIN60 , MF_UNCHECKED); 658: CheckMenuItem(hMenu, IDM_SPIN90 , MF_UNCHECKED); 659: 660: nSpin = 10; 661: 1.1.1.3 ! root 662: } return 0; 1.1.1.2 root 663: 664: case IDM_SPIN30: 665: { HMENU hMenu; 666: hMenu = GetMenu (hwnd); 667: 668: CheckMenuItem(hMenu, IDM_SPINOFF, MF_UNCHECKED); 669: CheckMenuItem(hMenu, IDM_SPIN5 , MF_UNCHECKED); 670: CheckMenuItem(hMenu, IDM_SPIN10 , MF_UNCHECKED); 671: CheckMenuItem(hMenu, IDM_SPIN30 , MF_CHECKED); 672: CheckMenuItem(hMenu, IDM_SPIN60 , MF_UNCHECKED); 673: CheckMenuItem(hMenu, IDM_SPIN90 , MF_UNCHECKED); 674: 675: nSpin = 30; 676: 1.1.1.3 ! root 677: } return 0; 1.1.1.2 root 678: 679: case IDM_SPIN60: 680: { HMENU hMenu; 681: hMenu = GetMenu (hwnd); 682: 683: CheckMenuItem(hMenu, IDM_SPINOFF, MF_UNCHECKED); 684: CheckMenuItem(hMenu, IDM_SPIN5 , MF_UNCHECKED); 685: CheckMenuItem(hMenu, IDM_SPIN10 , MF_UNCHECKED); 686: CheckMenuItem(hMenu, IDM_SPIN30 , MF_UNCHECKED); 687: CheckMenuItem(hMenu, IDM_SPIN60 , MF_CHECKED); 688: CheckMenuItem(hMenu, IDM_SPIN90 , MF_UNCHECKED); 689: 690: nSpin = 60; 691: 1.1.1.3 ! root 692: } return 0; 1.1.1.2 root 693: 694: case IDM_SPIN90: 695: { HMENU hMenu; 696: hMenu = GetMenu (hwnd); 697: 698: CheckMenuItem(hMenu, IDM_SPINOFF, MF_UNCHECKED); 699: CheckMenuItem(hMenu, IDM_SPIN5 , MF_UNCHECKED); 700: CheckMenuItem(hMenu, IDM_SPIN10 , MF_UNCHECKED); 701: CheckMenuItem(hMenu, IDM_SPIN30 , MF_UNCHECKED); 702: CheckMenuItem(hMenu, IDM_SPIN60 , MF_UNCHECKED); 703: CheckMenuItem(hMenu, IDM_SPIN90 , MF_CHECKED); 704: 705: nSpin = 90; 706: 1.1.1.3 ! root 707: } return 0; 1.1.1.2 root 708: 709: 710: case IDM_FLIPONCE: 711: nSpin = 90; 712: SendMessage (hwndMain, WM_SPIN, 0,0); 713: nSpin = FALSE; 1.1.1.3 ! root 714: return 0; 1.1.1.2 root 715: 716: 717: 718: case IDM_SPINTOPLEFT: 719: { HMENU hMenu; 720: hMenu = GetMenu (hwnd); 721: 722: CheckMenuItem(hMenu, IDM_SPINTOPLEFT, MF_CHECKED); 723: CheckMenuItem(hMenu, IDM_SPINCENTER , MF_UNCHECKED); 724: 1.1.1.3 ! root 725: } return 0; 1.1.1.2 root 726: 727: case IDM_SPINCENTER: 728: { HMENU hMenu; 729: hMenu = GetMenu (hwnd); 730: 731: CheckMenuItem(hMenu, IDM_SPINTOPLEFT, MF_UNCHECKED); 732: CheckMenuItem(hMenu, IDM_SPINCENTER , MF_CHECKED); 733: 1.1.1.3 ! root 734: } return 0; 1.1.1.2 root 735: 736: 737: /******************************************************************\ 738: * WM_COMMAND, DID_NEW* 739: * 740: * menu equivalents for buttons on top dialog. Just pass along 741: * WM_COMMAND messages to the dialog. 742: * 743: \******************************************************************/ 744: case DID_NEWSRC: 745: case DID_NEWMASK: 746: SendMessage (hwndDlg, message, wParam, lParam); 1.1.1.3 ! root 747: return 0; 1.1.1.2 root 748: 749: 750: /******************************************************************\ 751: * WM_COMMAND, IDM_ABOUT 752: * 753: \******************************************************************/ 754: case IDM_ABOUT: 755: DialogBox (hInst, "aboutBox", hwnd, (DLGPROC)About); 1.1.1.3 ! root 756: return 0; 1.1.1.2 root 757: 758: 759: 760: 1.1 root 761: } /* end switch */ 762: 763: break; /* end wm_command */ 764: 765: 766: 1.1.1.2 root 767: /******************************************************************\ 768: * WM_SPIN 769: * 770: * Set up a transform to modify the destination points. 771: * (Note that the transform in hdcDest remains the identity.) 772: * Loop through, reblitting to the transformed points. 773: * Erase behind the old bitmap by keeping track of the region uncovered. 774: * 775: \******************************************************************/ 776: case WM_SPIN: { 777: 778: XFORM x; 779: HDC hdc; 780: float M11, M12, M21, M22; 781: int nSteps, i; 782: 783: POINT pivot; 784: POINT lpPoint[3]; 785: POINT lpRgnErase[4], lpRgnBmp[4]; 786: HRGN hrgnErase, hrgnBmp; 787: HMENU hMenu; 788: int XSrc, YSrc, nWidth, nHeight, XMask, YMask; 789: BOOL success; 790: 791: /* validate the dialog on top with the parameters in it. */ 1.1.1.3 ! root 792: if (!IsWindow(hwndDlg)) return 0; 1.1.1.2 root 793: 794: /* Grab points out of the dialog entry fields. */ 795: lpPoint[0].x = GetDlgItemInt(hwndDlg, DID_P1X, &success, TRUE); 796: lpPoint[0].y = GetDlgItemInt(hwndDlg, DID_P1Y, &success, TRUE); 797: lpPoint[1].x = GetDlgItemInt(hwndDlg, DID_P2X, &success, TRUE); 798: lpPoint[1].y = GetDlgItemInt(hwndDlg, DID_P2Y, &success, TRUE); 799: lpPoint[2].x = GetDlgItemInt(hwndDlg, DID_P3X, &success, TRUE); 800: lpPoint[2].y = GetDlgItemInt(hwndDlg, DID_P3Y, &success, TRUE); 801: XSrc = GetDlgItemInt(hwndDlg, DID_XSRC, &success, TRUE); 802: YSrc = GetDlgItemInt(hwndDlg, DID_YSRC, &success, TRUE); 803: nWidth = GetDlgItemInt(hwndDlg, DID_WIDTH, &success, TRUE); 804: nHeight = GetDlgItemInt(hwndDlg, DID_HEIGHT, &success, TRUE); 805: XMask = GetDlgItemInt(hwndDlg, DID_XMASK, &success, TRUE); 806: YMask = GetDlgItemInt(hwndDlg, DID_YMASK, &success, TRUE); 807: 808: 809: /* get an HDC we can use to play with transforms. */ 810: hdc = GetDC (hwnd); 1.1.1.3 ! root 811: SetGraphicsMode (hdc, GM_ADVANCED); 1.1.1.2 root 812: 813: 814: 815: /* check menu check to pivot on top-left corner, or pivot on center. */ 816: hMenu = GetMenu (hwnd); 817: 818: if (GetMenuState(hMenu, IDM_SPINCENTER, MF_BYCOMMAND) & MF_CHECKED) { 819: pivot.x = (lpPoint[1].x +lpPoint[2].x)/2; 820: pivot.y = (lpPoint[1].y +lpPoint[2].y)/2; 821: } else { 822: pivot.x = lpPoint[0].x; 823: pivot.y = lpPoint[0].y; 824: } 1.1 root 825: 1.1.1.2 root 826: /* nSpin contains values reflecting the number of degrees per step. 827: * fill in the number of steps required (360 / nSpin), and fill in 828: * the precomputed transformation matrices. 829: */ 830: switch (nSpin) { 831: 832: case 5: 833: nSteps = 72; 834: M11 = M22 = (float)0.9961946980917; 835: M12 = (float)-0.08715574274766; M21 = (float)0.08715574274766; 836: break; 837: case 10: 838: nSteps = 36; 839: M11 = M22 = (float)0.984808; 840: M12 = (float)-0.173648; M21 = (float)0.173648; 841: break; 842: case 30: 843: nSteps = 12; 844: M11 = M22 = (float)0.866025; 845: M12 = (float)-0.5 ; M21 = (float)0.5; 846: break; 847: case 60: 848: nSteps = 6; 849: M11 = M22 = (float)0.5 ; 850: M12 = (float)-0.866025; M21 = (float)0.866025; 851: break; 852: case 90: 853: nSteps = 4; 854: M11 = M22 = (float)0.0; 855: M12 = (float)-1.0 ; M21 = (float)1.0; 856: break; 857: default: 858: MessageBox (hwnd, "nSpin invalid.", "Internal app error.", MB_ICONHAND); 1.1.1.3 ! root 859: return 0; 1.1.1.2 root 860: 861: } /* end switch nSpin */ 862: 863: 864: 865: 866: /* translate objects from pivot point to origin. */ 867: x.eM11 = (float)1.0; 868: x.eM12 = (float)0.0; 869: x.eM21 = (float)0.0; 870: x.eM22 = (float)1.0; 871: x.eDx = (float)-pivot.x; 872: x.eDy = (float)-pivot.y; 873: ModifyWorldTransform (hdc, &x, MWT_RIGHTMULTIPLY); 874: 875: /* rotate object about origin. */ 876: x.eM11 = M11; 877: x.eM12 = M12; 878: x.eM21 = M21; 879: x.eM22 = M22; 880: x.eDx = (float)0.0; 881: x.eDy = (float)0.0; 882: ModifyWorldTransform (hdc, &x, MWT_RIGHTMULTIPLY); 883: 884: /* translate objects back to pivot point. */ 885: x.eM11 = (float)1.0; 886: x.eM12 = (float)0.0; 887: x.eM21 = (float)0.0; 888: x.eM22 = (float)1.0; 889: x.eDx = (float)pivot.x; 890: x.eDy = (float)pivot.y; 891: ModifyWorldTransform (hdc, &x, MWT_RIGHTMULTIPLY); 892: 893: 894: 895: /* fill in initial region for erasure... the region containing bmp */ 896: lpRgnErase[0] = lpPoint[0]; 897: lpRgnErase[1] = lpPoint[1]; 898: lpRgnErase[3] = lpPoint[2]; 899: lpRgnErase[2].x = lpPoint[1].x - lpPoint[0].x; 900: lpRgnErase[2].x += lpPoint[2].x - lpPoint[0].x; 901: lpRgnErase[2].x += lpPoint[0].x; 902: lpRgnErase[2].y = lpPoint[1].y - lpPoint[0].y; 903: lpRgnErase[2].y += lpPoint[2].y - lpPoint[0].y; 904: lpRgnErase[2].y += lpPoint[0].y; 905: 906: 907: 908: /* loop through transforming the points on each step. */ 909: for (i= 0; i<nSteps; i++) { 910: 911: 912: hrgnErase = CreatePolygonRgn (lpRgnErase, 4, ALTERNATE); 913: 914: /* TRANSFORM the lpPoint[] destination extent points */ 915: LPtoDP (hdc, lpPoint, 3); 916: 917: /* create a region containing the new bitmap extents */ 918: lpRgnBmp[0] = lpPoint[0]; 919: lpRgnBmp[1] = lpPoint[1]; 920: lpRgnBmp[3] = lpPoint[2]; 921: lpRgnBmp[2].x = lpPoint[1].x - lpPoint[0].x; 922: lpRgnBmp[2].x += lpPoint[2].x - lpPoint[0].x; 923: lpRgnBmp[2].x += lpPoint[0].x; 924: lpRgnBmp[2].y = lpPoint[1].y - lpPoint[0].y; 925: lpRgnBmp[2].y += lpPoint[2].y - lpPoint[0].y; 926: lpRgnBmp[2].y += lpPoint[0].y; 927: hrgnBmp = CreatePolygonRgn (lpRgnBmp, 4, ALTERNATE); 928: 929: /* subtract the new bitmap extents region from the erasure region. */ 930: CombineRgn (hrgnErase, hrgnErase, hrgnBmp, RGN_DIFF); 931: 932: 933: 934: /* while we are here, get points ready for the next loop erasure */ 935: lpRgnErase[0] = lpPoint[0]; 936: lpRgnErase[1] = lpPoint[1]; 937: lpRgnErase[3] = lpPoint[2]; 938: lpRgnErase[2].x = lpPoint[1].x - lpPoint[0].x; 939: lpRgnErase[2].x += lpPoint[2].x - lpPoint[0].x; 940: lpRgnErase[2].x += lpPoint[0].x; 941: lpRgnErase[2].y = lpPoint[1].y - lpPoint[0].y; 942: lpRgnErase[2].y += lpPoint[2].y - lpPoint[0].y; 943: lpRgnErase[2].y += lpPoint[0].y; 944: 945: 946: 947: /**********************************************************/ 948: PlgBlt (hdcDest, lpPoint, 949: hdcSrc, XSrc, YSrc, nWidth, nHeight, 950: hbmMask, XMask, YMask); 951: /**********************************************************/ 952: 953: /* need to flush graphics buffer, or regions are erased 954: * before the bitmap is drawn. 955: */ 956: GdiFlush(); 957: 958: /* erase the newly uncovered region. */ 959: FillRgn (hdcDest, hrgnErase, BACKGROUNDBRUSH ); 960: DeleteObject (hrgnErase); 961: DeleteObject (hrgnBmp); 962: } /* end for loop */ 963: 964: 965: /* because of roundoff error, the 'nSteps'th rotation will not 966: * always bring the parallelogram around to the 0th position. 967: * So we special case the last position, and do one more erase. 968: * Try commenting this out, and see the little glitches left 969: * on the screen if this comment is unclear. 970: */ 971: lpRgnErase[0] = lpPoint[0]; 972: lpRgnErase[1] = lpPoint[1]; 973: lpRgnErase[3] = lpPoint[2]; 974: lpRgnErase[2].x = lpPoint[1].x - lpPoint[0].x; 975: lpRgnErase[2].x += lpPoint[2].x - lpPoint[0].x; 976: lpRgnErase[2].x += lpPoint[0].x; 977: lpRgnErase[2].y = lpPoint[1].y - lpPoint[0].y; 978: lpRgnErase[2].y += lpPoint[2].y - lpPoint[0].y; 979: lpRgnErase[2].y += lpPoint[0].y; 980: hrgnErase = CreatePolygonRgn (lpRgnErase, 4, ALTERNATE); 981: lpPoint[0].x = GetDlgItemInt(hwndDlg, DID_P1X, &success, TRUE); 982: lpPoint[0].y = GetDlgItemInt(hwndDlg, DID_P1Y, &success, TRUE); 983: lpPoint[1].x = GetDlgItemInt(hwndDlg, DID_P2X, &success, TRUE); 984: lpPoint[1].y = GetDlgItemInt(hwndDlg, DID_P2Y, &success, TRUE); 985: lpPoint[2].x = GetDlgItemInt(hwndDlg, DID_P3X, &success, TRUE); 986: lpPoint[2].y = GetDlgItemInt(hwndDlg, DID_P3Y, &success, TRUE); 987: lpRgnBmp[0] = lpPoint[0]; 988: lpRgnBmp[1] = lpPoint[1]; 989: lpRgnBmp[3] = lpPoint[2]; 990: lpRgnBmp[2].x = lpPoint[1].x - lpPoint[0].x; 991: lpRgnBmp[2].x += lpPoint[2].x - lpPoint[0].x; 992: lpRgnBmp[2].x += lpPoint[0].x; 993: lpRgnBmp[2].y = lpPoint[1].y - lpPoint[0].y; 994: lpRgnBmp[2].y += lpPoint[2].y - lpPoint[0].y; 995: lpRgnBmp[2].y += lpPoint[0].y; 996: hrgnBmp = CreatePolygonRgn (lpRgnBmp, 4, ALTERNATE); 997: CombineRgn (hrgnErase, hrgnErase, hrgnBmp, RGN_DIFF); 998: FillRgn (hdcDest, hrgnErase, BACKGROUNDBRUSH ); 999: DeleteObject (hrgnErase); 1000: DeleteObject (hrgnBmp); 1.1 root 1001: 1002: 1003: 1004: 1005: 1006: 1007: 1.1.1.2 root 1008: ReleaseDC (hwnd, hdc); 1009: 1010: 1.1.1.3 ! root 1011: } return 0; /* end WM_SPIN message */ 1.1 root 1012: 1013: 1.1.1.3 ! root 1014: } /* end switch */ ! 1015: return (DefWindowProc(hwnd, message, wParam, lParam)); 1.1 root 1016: } 1017: 1018: 1019: 1020: 1021: /**************************************************************************\ 1022: * 1023: * function: DlgProc() 1024: * 1025: * input parameters: normal window procedure parameters. 1026: * 1027: * Respond to user button presses by getting new bitmaps or by sending 1028: * the main window a WM_PLGBLT message. Also handle special user messages 1029: * for updating the entry fields with the contents of the direct manipulation 1030: * objects. 1031: * 1032: * global variables: 1033: * hwndMain - the main window. also the parent of this dialog 1034: * ptoDest, ptoSrc, ptoMask - pointers to the direct manipulation objects 1035: * hdcDest, hdcSrc, hdcMask - HDCs for the 3 sub regions of the window. 1036: * hbmSrc, hbmMask - bitmap handles for source and mask. 1037: \**************************************************************************/ 1.1.1.2 root 1038: LRESULT CALLBACK DlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 1.1 root 1039: { 1040: 1041: switch (message) { 1042: /**********************************************************************\ 1043: * WM_INITDIALOG 1044: * 1045: * Fill the entry fields with sensible original values. 1046: \**********************************************************************/ 1047: case WM_INITDIALOG: 1048: SetDlgItemText(hwnd, DID_P1X , "0"); 1049: SetDlgItemText(hwnd, DID_P1Y , "0"); 1050: SetDlgItemText(hwnd, DID_P2X , "0"); 1051: SetDlgItemText(hwnd, DID_P2Y , "0"); 1052: SetDlgItemText(hwnd, DID_P3X , "0"); 1053: SetDlgItemText(hwnd, DID_P3Y , "0"); 1054: SetDlgItemText(hwnd, DID_XSRC , "0"); 1055: SetDlgItemText(hwnd, DID_YSRC , "0"); 1056: SetDlgItemText(hwnd, DID_WIDTH , "0"); 1057: SetDlgItemText(hwnd, DID_HEIGHT , "0"); 1058: SetDlgItemText(hwnd, DID_XMASK , "0"); 1059: SetDlgItemText(hwnd, DID_YMASK , "0"); 1060: return TRUE; 1061: 1062: 1063: 1064: /**********************************************************************\ 1065: * WM_PUTUPLPOINTS 1066: * 1067: * wParam - HDC with the needed world transform. 1068: * lParam - Pointer to the track object. 1069: * 1070: * Fill the entry fields for the array of 3 dest parallelogram points. 1071: * Conditionally change the first point depending on tracking mode. 1072: \**********************************************************************/ 1073: case WM_PUTUPLPOINTS: { 1074: POINT p, origin; 1075: PTrackObject pto; 1076: HDC hdc; 1077: 1078: hdc = (HDC) wParam; 1079: pto = (PTrackObject) lParam; 1080: GetViewportOrgEx (hdc, &origin); 1081: 1082: if (pto->Mode & TMMOVE) { 1083: p.x = pto->rect.left; 1084: p.y = pto->rect.top; 1085: LPtoDP (pto->hdc, &p, 1); 1086: p.x -= origin.x; p.y -= origin.y; 1087: 1088: SetDlgItemInt(hwnd, DID_P1X, p.x, TRUE); 1089: SetDlgItemInt(hwnd, DID_P1Y, p.y, TRUE); 1090: 1091: } 1092: 1093: p.x = pto->rect.right; 1094: p.y = pto->rect.top; 1095: LPtoDP (pto->hdc, &p, 1); 1096: p.x -= origin.x; p.y -= origin.y; 1097: 1098: SetDlgItemInt(hwnd, DID_P2X, p.x, TRUE); 1099: SetDlgItemInt(hwnd, DID_P2Y, p.y, TRUE); 1100: 1101: p.x = pto->rect.left; 1102: p.y = pto->rect.bottom; 1103: LPtoDP (pto->hdc, &p, 1); 1104: p.x -= origin.x; p.y -= origin.y; 1105: SetDlgItemInt(hwnd, DID_P3X, p.x, TRUE); 1106: SetDlgItemInt(hwnd, DID_P3Y, p.y, TRUE); 1107: 1108: } return FALSE; 1109: 1110: 1111: 1112: 1113: /**********************************************************************\ 1114: * WM_PUTUPSRCRECT 1115: * 1116: * wParam - HDC with the needed world transform. 1117: * lParam - Pointer to the track object. 1118: * 1119: * Fill the entry fields for the source rectangle points. 1120: * Conditionally change <x,y> or <width,height> depending on tracking mode. 1121: \**********************************************************************/ 1122: case WM_PUTUPSRCRECT: { 1123: POINT p1,p2, origin; 1124: PTrackObject pto; 1125: HDC hdc; 1126: 1127: hdc = (HDC) wParam; 1128: pto = (PTrackObject) lParam; 1129: GetViewportOrgEx (hdc, &origin); 1130: 1131: p1.x = pto->rect.left; 1132: p1.y = pto->rect.top; 1133: LPtoDP (pto->hdc, &p1, 1); 1134: 1135: p2.x = pto->rect.right; 1136: p2.y = pto->rect.bottom; 1137: LPtoDP (pto->hdc, &p2, 1); 1138: p2.x -= p1.x; p2.y -= p1.y; 1139: 1140: p1.x -= origin.x; p1.y -= origin.y; 1141: 1142: if (!(pto->Mode & TMSIZEXY)) { 1143: SetDlgItemInt(hwnd, DID_XSRC, p1.x, TRUE); 1144: SetDlgItemInt(hwnd, DID_YSRC, p1.y, TRUE); 1145: } 1146: 1147: if (!(pto->Mode & TMMOVE)) { 1148: SetDlgItemInt(hwnd, DID_WIDTH, p2.x, TRUE); 1149: SetDlgItemInt(hwnd, DID_HEIGHT, p2.y, TRUE); 1150: } 1151: } return FALSE; 1152: 1153: 1154: 1155: /**********************************************************************\ 1156: * WM_PUTUPMASKPT 1157: * 1158: * wParam - HDC with the needed world transform. 1159: * lParam - Pointer to the track object. 1160: * 1161: * Fill the entry fields for the mask location point. 1162: \**********************************************************************/ 1163: case WM_PUTUPMASKPT: { 1164: POINT p1, origin; 1165: PTrackObject pto; 1166: HDC hdc; 1167: 1168: hdc = (HDC) wParam; 1169: pto = (PTrackObject) lParam; 1170: GetViewportOrgEx (hdc, &origin); 1171: 1172: p1.x = pto->rect.left; 1173: p1.y = pto->rect.top; 1174: LPtoDP (pto->hdc, &p1, 1); 1175: p1.x -= origin.x; p1.y -= origin.y; 1176: 1177: SetDlgItemInt(hwnd, DID_XMASK, p1.x, TRUE); 1178: SetDlgItemInt(hwnd, DID_YMASK, p1.y, TRUE); 1179: 1180: } return FALSE; 1181: 1182: 1183: 1184: 1185: /**********************************************************************\ 1186: * WM_COMMAND, DID_DRAW 1187: * 1188: * Draw button hit - send main window message to call PlgBlt(). 1189: \**********************************************************************/ 1190: case WM_COMMAND: { 1191: HBITMAP hbm; 1192: 1193: if (LOWORD(wParam) == DID_DRAW) { 1194: SendMessage (hwndMain, WM_PLGBLT, 0,0); 1195: 1196: 1197: /**********************************************************************\ 1198: * WM_COMMAND, DID_NEWSRC 1199: * 1200: * Try to get a new source bitmap. Then 1201: * invalidate two sub windows so that we force a repaint. 1202: \**********************************************************************/ 1203: } else if (LOWORD(wParam) == DID_NEWSRC) { 1204: if ( hbm = GetBitmap (hdcSrc, hInst, FALSE)) { 1205: DeleteObject (hbmSrc); 1206: hbmSrc = hbm; 1207: InvalidateRect (hwndMain, &ptoSrc->rectClip, TRUE); 1208: InvalidateRect (hwndMain, &ptoDest->rectClip, TRUE); 1209: } 1210: 1211: /**********************************************************************\ 1212: * WM_COMMAND, DID_Mask 1213: * 1214: * Try to get a new mask bitmap. Then 1215: * invalidate two sub windows so that we force a repaint. 1216: \**********************************************************************/ 1217: } else if (LOWORD(wParam) == DID_NEWMASK) { 1218: if ( hbm = GetBitmap (hdcMask, hInst, TRUE)) { 1219: DeleteObject (hbmMask); 1220: hbmMask = hbm; 1221: InvalidateRect (hwndMain, &ptoMask->rectClip, TRUE); 1222: InvalidateRect (hwndMain, &ptoDest->rectClip, TRUE); 1223: } 1224: } 1225: 1226: } return FALSE; /* end WM_COMMAND */ 1227: 1228: 1.1.1.3 ! root 1229: } /* end switch */ ! 1230: return 0; 1.1 root 1231: } 1232: 1233: 1234: 1235: #define TICKSPACE 20 1236: 1237: /**************************************************************************\ 1238: * 1239: * function: DrawGrids() 1240: * 1241: * input parameters: 1242: * hdc - Device context to draw into. 1243: * width, height - size of the rectangle to fill with grids. 1244: * 1245: * global variables: none. 1246: * 1247: \**************************************************************************/ 1248: VOID DrawGrids (HDC hdc, int width, int height) 1249: { 1250: int i; 1251: 1252: /* Draw vertical lines. Double at the axis */ 1253: for (i = 0; i<= width; i+=TICKSPACE){ 1254: MoveToEx (hdc, i, 0, NULL); 1255: LineTo (hdc, i, height); 1256: } 1257: MoveToEx (hdc, 1, 0, NULL); 1258: LineTo (hdc, 1, height); 1259: 1260: /* Draw horizontal lines. Double at the axis */ 1261: for (i = 0; i<= height; i+=TICKSPACE){ 1262: MoveToEx (hdc, 0,i, NULL); 1263: LineTo (hdc, width,i); 1264: } 1265: MoveToEx (hdc, 0, 1, NULL); 1266: LineTo (hdc, width,1); 1267: 1268: return; 1269: } 1.1.1.2 root 1270: 1271: 1272: 1273: 1274: /**************************************************************************** 1275: FUNCTION: About 1276: ****************************************************************************/ 1277: LRESULT CALLBACK About(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 1278: { 1279: if ((message == WM_COMMAND) && (LOWORD(wParam) == IDOK)) { 1280: EndDialog (hwnd, TRUE); 1281: return TRUE; 1282: } 1283: if ((message == WM_SYSCOMMAND) && (wParam == SC_CLOSE)) { 1284: EndDialog (hwnd, TRUE); 1285: return TRUE; 1286: } 1287: return FALSE; 1288: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.