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