|
|
1.1 root 1: /**************************************************************************\
2: * streblt.c -- sample program demonstrating StretchBlt()
3: *
4: * written Feb 92 by Steve Firebaugh
5: *
6: * design: There is one main window with one dialog box streblted to fill
7: * the top of it. The parameters for the StretchBlt() are stored in the
8: * entry fields of this dialog box. The user may change these values and
9: * see the effect on the blt. The top dialog also offers a chance to set
10: * the streblt blt mode, to select pattern brushes for the hdc, and to
11: * select from standard raster operations
12: \**************************************************************************/
13:
14:
15: #include <windows.h>
16: #include <commdlg.h>
17: #include <math.h>
18: #include <string.h>
19: #include <stdio.h>
20: #include "streblt.h"
21: #include "track.h"
22: #include "bitmap.h"
23:
24:
25: /* Global variables */
26: HANDLE hInst;
27: HWND hwndMain, hwndDlg;
28:
29: PTrackObject ptoSrc, ptoDest = NULL;
30: HDC hdcSrc, hdcDest;
31: HBITMAP hbmSrc = NULL;
32:
33: #define NONE -1
34: int strebltMode = NONE;
35: int iPatternBrush = NONE;
36:
37:
38:
39:
40:
41: /**************************************************************************\
42: *
43: * function: WinMain()
44: *
45: * input parameters: c.f. generic sample
46: *
47: \**************************************************************************/
48: int APIENTRY WinMain(HANDLE hInstance, HANDLE hPrevInstance,
49: LPSTR lpCmdLine, int nCmdShow)
50: {
51: MSG msg;
52: RECT rect;
53: HANDLE haccel;
54:
55: UNREFERENCED_PARAMETER( lpCmdLine );
56:
57:
58: /* Check for previous instance. If none, then register class. */
59: if (!hPrevInstance) {
60: WNDCLASS wc;
61:
62: wc.style = NULL;
63: wc.lpfnWndProc = (WNDPROC)MainWndProc;
64:
65: wc.cbClsExtra = 0;
66: wc.cbWndExtra = 0;
67: wc.hInstance = hInstance;
68: wc.hIcon = LoadIcon(hInstance, "strebltIcon");
69: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
70: wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
71: wc.lpszMenuName = NULL;
72: wc.lpszClassName = "streblt";
73:
74: if (!RegisterClass(&wc)) return (FALSE);
75: } /* class registered o.k. */
76:
77:
78: /* Create the main window. Return false if CreateWindow() fails */
79: hInst = hInstance;
80:
81: hwndMain = CreateWindow(
82: "streblt",
83: "StretchBlt()",
84: WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
85: CW_USEDEFAULT,
86: CW_USEDEFAULT,
87: CW_USEDEFAULT,
88: CW_USEDEFAULT,
89: NULL,
90: NULL,
91: hInstance,
92: NULL);
93:
94: if (!hwndMain) return (FALSE);
95:
96:
97: /* create the top dialog as a child of the main window. */
1.1.1.2 ! root 98: hwndDlg = CreateDialog (hInst, "strebltDlg", hwndMain, (DLGPROC)DlgProc);
1.1 root 99:
100: /* Send main window a WM_SIZE message so that it will size the top
101: * dialog correctly. Also, force a repaint of the main window
102: * now that the dialog is there and we can draw the arc.
103: */
104: GetClientRect (hwndMain, &rect);
105: SendMessage (hwndMain, WM_SIZE, 0, (rect.right - rect.left));
106: ShowWindow (hwndDlg, SW_SHOW);
107: ShowWindow(hwndMain, nCmdShow);
108:
109:
110: /* Load the accelerator table that provides clipboard support. */
111: haccel = LoadAccelerators (hInst, "bltAccel");
112:
113:
114: /* Loop getting messages and dispatching them. */
115: while (GetMessage(&msg,NULL, NULL, NULL)) {
116: if (!TranslateAccelerator(hwndMain, haccel, &msg))
117: if (!IsDialogMessage (hwndDlg, &msg)) {
118: DispatchMessage(&msg);
119: }
120: }
121:
122: return (msg.wParam); /* Returns the value from PostQuitMessage */
123: }
124:
125:
126:
127:
128: /**************************************************************************\
129: *
130: * function: MainWndProc()
131: *
132: * input parameters: normal window procedure parameters.
133: *
134: * This is the main window window procedure. Allocate needed structures
135: * at create time and free them at destroy time. Pass the mouse messages
136: * down to the track objects when appropriate. Size the top dialog on
137: * size messages. The window is painted in two halfs. One for the source
138: * region and one for the destination region. The StretchBlt() call is
139: * separated out as a user message so that the call can be made without
140: * erasing the whole window.
141: *
142: * global variables:
143: * hwndDlg - dialog with entry fields containing arc parameters.
144: * ptoSrc - pointer to the source track object
145: * hdcSrc - device context for the right half the window.
146: * ptoDest - pointer to the destination track object
147: * hdcDest - device context for the left half the window.
148: * hbmSrc - bitmap handle for the source bitmap.
149: *
150: * strebltMode - Selection from combo box, to be used in SetStretchBltMode()
151: * iPatternBrush - Selection from combo box, set into the hdc.
152: \**************************************************************************/
153: LONG APIENTRY MainWndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
154: {
155: static int miniWidth;
156: static RECT rect;
157: char buffer[MAXCHARS];
158: static HANDLE hPenGrid, hPenSeparator;
159:
160:
161: switch (message) {
162:
163: /**********************************************************************\
164: * WM_CREATE
165: *
166: * Get the two hdc's for this window, allocate two track objects,
167: * and then create two pens to be used when painting the windows.
168: \**********************************************************************/
169: case WM_CREATE:
170: hdcSrc = GetDC (hwnd);
171: hdcDest = GetDC (hwnd);
172:
173: ptoDest = doTrackObject (NULL, TROB_NEW, hwnd,NULL);
174: ptoSrc = doTrackObject (NULL, TROB_NEW, hwnd,NULL);
175:
176: hPenGrid = CreatePen (PS_SOLID, 1, GRIDCOLOR);
177: hPenSeparator = CreatePen (PS_SOLID, 2*SEPARATORWIDTH, (COLORREF) 0x01000000);
178: break;
179:
180:
181: /**********************************************************************\
182: * WM_DESTROY
183: *
184: * Complement of WM_CREATE. Free up all of the HDCs, send all of the
185: * track objects their delete messages, then call PostQuitMessage.
186: \**********************************************************************/
187: case WM_DESTROY:
188: ReleaseDC (hwnd, hdcSrc );
189: ReleaseDC (hwnd, hdcDest);
190: doTrackObject (ptoDest, TROB_DELETE, hwnd,NULL);
191: doTrackObject (ptoSrc , TROB_DELETE, hwnd,NULL);
192:
193: DeleteObject(hPenGrid);
194: DeleteObject(hPenSeparator);
195:
196: PostQuitMessage(0);
197: break;
198:
199:
200:
201: /**********************************************************************\
202: * WM_SIZE
203: *
204: * streblt the top dialog to fill the width of the main window.
205: * Adjust the viewport origins of the 4 HDCs.
206: * Set the clip regions of the 4 HDCs.
207: \**********************************************************************/
208: case WM_SIZE: {
209: HRGN hrgn;
210:
211: SetWindowPos (hwndDlg, NULL, 0,0, LOWORD(lParam), DIALOGHEIGHT, NULL);
212:
213: GetClientRect (hwndMain, &rect);
214: miniWidth = rect.right/2;
215:
216: SetViewportOrgEx (hdcDest, 0, DIALOGHEIGHT, NULL);
217: SetViewportOrgEx (ptoDest->hdc, 0, DIALOGHEIGHT, NULL);
218: SetViewportOrgEx (hdcSrc, miniWidth, DIALOGHEIGHT, NULL);
219: SetViewportOrgEx (ptoSrc->hdc, miniWidth, DIALOGHEIGHT, NULL);
220:
221: ptoDest->rectClip.left = 0;
222: ptoDest->rectClip.top = DIALOGHEIGHT;
223: ptoDest->rectClip.right = miniWidth-2*SEPARATORWIDTH;
224: ptoDest->rectClip.bottom = rect.bottom;
225: hrgn = CreateRectRgnIndirect (&ptoDest->rectClip);
226: SelectClipRgn (hdcDest, hrgn);
227: SelectClipRgn (ptoDest->hdc, hrgn);
228: DeleteObject (hrgn);
229:
230: ptoSrc->rectClip.left = miniWidth;
231: ptoSrc->rectClip.top = DIALOGHEIGHT;
232: ptoSrc->rectClip.right = 2*miniWidth;
233: ptoSrc->rectClip.bottom = rect.bottom;
234: hrgn = CreateRectRgnIndirect (&ptoSrc->rectClip);
235: SelectClipRgn (hdcSrc, hrgn);
236: SelectClipRgn (ptoSrc->hdc, hrgn);
237: DeleteObject (hrgn);
238:
239: SendMessage (hwndDlg, WM_PUTUPDESTRECT, (DWORD)hdcDest, (LONG)ptoDest);
240: SendMessage (hwndDlg, WM_PUTUPSRCRECT, (DWORD)hdcSrc, (LONG)ptoSrc);
241:
242: InvalidateRect (hwnd, NULL, TRUE);
243: } break;
244:
245:
246:
247: /**********************************************************************\
248: * WM_PAINT
249: *
250: * miniWidth, rect -- set by WM_SIZE message.
251: *
252: * First shift the viewport origin down so that 0,0 is the top left
253: * most visible point (out from underneath the top dialog). Second,
254: * draw the grid with wider lines on the axes. Finally, read the
255: * values out of the top dialog, do elementary validation, and then
256: * try to call StretchBlt() with the values.
257: \**********************************************************************/
258: case WM_PAINT: {
259: HDC hdc;
260: PAINTSTRUCT ps;
261:
262: hdc = BeginPaint(hwnd, &ps);
263:
264: /* Draw Separator lines for the three miniareas */
265: SelectObject(hdc, hPenSeparator);
266: MoveToEx (hdc, miniWidth-SEPARATORWIDTH,0, NULL);
267: LineTo (hdc, miniWidth-SEPARATORWIDTH , rect.bottom);
268:
269: /* Grid the 2 HDCs */
270: SelectObject (hdcSrc, hPenGrid);
271: DrawGrids (hdcSrc, miniWidth, rect.bottom);
272: SelectObject (hdcDest, hPenGrid);
273: DrawGrids (hdcDest, miniWidth, rect.bottom);
274:
275: /* if a source bitmap has been selected, draw it. */
276: if (hbmSrc) DrawBitmap (hdcSrc, hbmSrc);
277:
278: /* paint the source track object on top of the bitmap */
279: doTrackObject (ptoSrc , TROB_PAINT, hwnd, NULL);
280:
281: /* make the call to StretchBlt() for the left half the window */
282: SendMessage (hwnd, WM_STRETCHBLT, 0,0);
283:
284: EndPaint (hwnd, &ps);
285: } return FALSE;
286:
287:
288:
289: /**********************************************************************\
290: * WM_STRETCHBLT
291: *
292: * Separate out the StretchBlt() call from the rest of the WM_PAINT
293: * case in this user message. In this way, we can blt() without erasing
294: * and/or repaint all of the rest of the window. Send this message when
295: * only the blt() should be done. Invalidate the left half of the window
296: * when it should be erased, re-grided, and then blt()ed.
297: \**********************************************************************/
298: case WM_STRETCHBLT: {
299: int X, Y, nWidth, nHeight,
300: XSrc, YSrc, nSrcWidth, nSrcHeight;
301: LONG rop, ropByte;
302: BOOL success;
303:
304: /* erase source track object, or top left sides will show up in blt. */
305: doTrackObject (ptoSrc , TROB_PAINT, hwnd, NULL);
306:
307: /* Get the parameters out of the top dialog box and call StretchBlt */
308: if (IsWindow(hwndDlg)) {
309:
310: X = GetDlgItemInt(hwndDlg, DID_X, &success, TRUE);
311: Y = GetDlgItemInt(hwndDlg, DID_Y, &success, TRUE);
312: nWidth = GetDlgItemInt(hwndDlg, DID_WIDTH, &success, TRUE);
313: nHeight = GetDlgItemInt(hwndDlg, DID_HEIGHT, &success, TRUE);
314: XSrc = GetDlgItemInt(hwndDlg, DID_XSRC, &success, TRUE);
315: YSrc = GetDlgItemInt(hwndDlg, DID_YSRC, &success, TRUE);
316: nSrcWidth = GetDlgItemInt(hwndDlg, DID_SRCWIDTH, &success, TRUE);
317: nSrcHeight = GetDlgItemInt(hwndDlg, DID_SRCHEIGHT, &success, TRUE);
318:
319: /* get high order ROP byte and shift left by two bytes. */
320: GetDlgItemText(hwndDlg, DID_ROP0, buffer, MAXCHARS);
321: sscanf (buffer, "%lx", &ropByte);
322: rop = ropByte * 256 * 256;
323:
324: /* get the next ROP byte and shift left by one byte. */
325: GetDlgItemText(hwndDlg, DID_ROP1, buffer, MAXCHARS);
326: sscanf (buffer, "%lx", &ropByte);
327: rop += ropByte * 256;
328:
329: /* finally, get the low order ROP byte. */
330: GetDlgItemText(hwndDlg, DID_ROP2, buffer, MAXCHARS);
331: sscanf (buffer, "%lx", &ropByte);
332: rop += ropByte;
333:
334: /* set streblt mode. (user selects via combo box.) */
335: if (strebltMode != NONE)
336: SetStretchBltMode (hdcDest, strebltMode);
337:
338: /* select the pattern brush. (user selects via combo box.) */
339: if (iPatternBrush != NONE)
340: SelectObject (hdcDest, GetStockObject (iPatternBrush));
341:
342: /**********************************************************/
343: /**********************************************************/
344: StretchBlt (hdcDest, X, Y, nWidth, nHeight,
345: hdcSrc, XSrc, YSrc, nSrcWidth, nSrcHeight, rop);
346: /**********************************************************/
347: /**********************************************************/
348: }
349:
350: /* redraw source track object which was erased temporarily. */
351: doTrackObject (ptoSrc , TROB_PAINT, hwnd, NULL);
352: } break;
353:
354:
355:
356: /**********************************************************************\
357: * WM_LBUTTONDOWN
358: * On button down messages, hittest on the track object, and if
359: * it returns true, then send these messages to the track object.
360: \**********************************************************************/
361: case WM_LBUTTONDOWN:
362: if (doTrackObject(ptoDest, TROB_HITTEST, hwnd, lParam))
363: doTrackObject(ptoDest, message, hwnd, lParam);
364: else if (doTrackObject(ptoSrc, TROB_HITTEST, hwnd, lParam))
365: doTrackObject(ptoSrc, message, hwnd, lParam);
366: break;
367:
368:
369:
370: /**********************************************************************\
371: * WM_LBUTTONUP
372: * If the track object is in a "tracking mode" then send it this message.
373: * For the source track object, just send a STRETCHBLT message.
374: * For the dest. track object, invalidate the left half causing erase.
375: \**********************************************************************/
376: case WM_LBUTTONUP:
377: if (ptoDest->Mode) {
378: doTrackObject(ptoDest, message, hwnd, lParam);
379: SendMessage (hwndDlg, WM_PUTUPDESTRECT, (DWORD) hdcDest, (LONG) ptoDest);
380: InvalidateRect (hwndMain, &ptoSrc->rectClip, TRUE);
381: InvalidateRect (hwndMain, &ptoDest->rectClip, TRUE);
382: }
383: if (ptoSrc->Mode) {
384: doTrackObject(ptoSrc, message, hwnd, lParam);
385: SendMessage (hwndDlg, WM_PUTUPSRCRECT, (DWORD) hdcSrc, (LONG) ptoSrc);
386: PostMessage (hwndMain, WM_STRETCHBLT, 0,0);
387: }
388: break;
389:
390:
391: /**********************************************************************\
392: * MW_MOUSEMOVE
393: * If the track object is in a "tracking mode" then send it these messages.
394: * Also, update the coordinates in the top dialog box.
395: \**********************************************************************/
396: case WM_MOUSEMOVE:
397: if (ptoDest->Mode) {
398: doTrackObject(ptoDest, message, hwnd, lParam);
399: SendMessage (hwndDlg, WM_PUTUPDESTRECT, (DWORD) hdcDest, (LONG) ptoDest);
400: }
401: if (ptoSrc->Mode) {
402: doTrackObject(ptoSrc, message, hwnd, lParam);
403: SendMessage (hwndDlg, WM_PUTUPSRCRECT, (DWORD) hdcSrc, (LONG) ptoSrc);
404: }
405: break;
406:
407:
408:
409:
410:
411: /**********************************************************************\
412: * Accelerator & clipboard support.
413: *
414: * Certain key strokes (c.f. *.rc) will cause the following WM_COMMAND
415: * messages. In response the app will copy a bitmap into the clipboard
416: * or paste down from it. In both cases, it is necessary to create a
417: * new bitmap since a bitmap in the clipboard belongs to the clipboard
418: * and not to the application.
419: \**********************************************************************/
420: case WM_COMMAND:
421: switch (LOWORD(wParam)) {
422: HBITMAP hbmCompat, hbmOld;
423: HDC hdcCompat;
424:
425: /******************************************************************\
426: * WM_COMMAND, AID_COPY
427: *
428: * Create a new bitmap, copy the destination HDC bits into it,
429: * and send the new bitmap to the clipboard.
430: \******************************************************************/
431: case AID_COPY: {
432: int X,Y, nWidth, nHeight;
433: BOOL success;
434:
435: X = GetDlgItemInt(hwndDlg, DID_X, &success, TRUE);
436: Y = GetDlgItemInt(hwndDlg, DID_Y, &success, TRUE);
437: nWidth = GetDlgItemInt(hwndDlg, DID_WIDTH, &success, TRUE);
438: nHeight = GetDlgItemInt(hwndDlg, DID_HEIGHT, &success, TRUE);
439:
440:
441: hdcCompat = CreateCompatibleDC(hdcDest);
442: hbmCompat = CreateCompatibleBitmap (hdcDest, nWidth, nHeight);
443: hbmOld = SelectObject(hdcCompat,hbmCompat);
444:
445: BitBlt (hdcCompat, 0,0,nWidth, nHeight, hdcDest, X,Y, SRCCOPY );
446:
447: SelectObject(hdcCompat,hbmOld);
448: DeleteDC(hdcCompat);
449:
450: OpenClipboard (hwnd);
451: SetClipboardData (CF_BITMAP,hbmCompat);
452: CloseClipboard ();
453:
454: DeleteObject (hbmCompat);
455:
456: } break;
457:
458:
459: /******************************************************************\
460: * WM_COMMAND, AID_PASTE
461: *
462: * Get bitmap handle from clipboard, create a new bitmap, draw
463: * the clipboard bitmap into the new one, and store the new
464: * handle in the global hbmSrc.
465: \******************************************************************/
466: case AID_PASTE: {
467: HBITMAP hbm;
468: BITMAP bm;
469:
470: OpenClipboard (hwnd);
471: if ( hbm = GetClipboardData (CF_BITMAP)) {
472: DeleteObject (hbmSrc);
473:
474: GetObject (hbm, sizeof(BITMAP), &bm);
475:
476: hdcCompat = CreateCompatibleDC(hdcDest);
477: hbmCompat = CreateCompatibleBitmap (hdcDest, bm.bmWidth, bm.bmHeight);
478: hbmOld = SelectObject(hdcCompat,hbmCompat);
479:
480: DrawBitmap (hdcCompat, hbm);
481:
482: SelectObject(hdcCompat,hbmOld);
483: DeleteDC(hdcCompat);
484:
485: hbmSrc = hbmCompat;
486:
487: InvalidateRect (hwnd, &ptoSrc->rectClip, TRUE);
488: InvalidateRect (hwnd, &ptoDest->rectClip, TRUE);
489: }
490: CloseClipboard ();
491: } break;
492:
493: /******************************************************************\
494: * WM_COMMAND, AID_CYCLE
495: *
496: * Post a COPY and PASTE command message to this window so that with
497: * one key stroke the user can copy the DEST image into the clipboard,
498: * paste it down into the SRC hdc and cause the blt.
499: \******************************************************************/
500: case AID_CYCLE:
501: PostMessage (hwnd, WM_COMMAND, MAKELONG (AID_COPY , 1), 0);
502: PostMessage (hwnd, WM_COMMAND, MAKELONG (AID_PASTE, 1), 0);
503: break;
504: } /* end switch */
505:
506: break; /* end wm_command */
507:
508:
509:
510: default:
511: return (DefWindowProc(hwnd, message, wParam, lParam));
512: }
513: return (NULL);
514: }
515:
516:
517:
518:
519:
520:
521: /**************************************************************************\
522: *
523: * function: DlgProc()
524: *
525: * input parameters: normal window procedure parameters.
526: *
527: * This is the dialog that sits on top of the window (it is streblted on the
528: * WM_SIZE message of the main window). In this window procedure, handle
529: * the command messages that arise as the user selects buttons on this
530: * dialog. Also handle user messages for filling in entry field values.
531: *
532: * global variables:
533: * hwndMain - the main window. also the parent of this dialog
534: * ptoSrc - pointer to the source track object
535: * hdcSrc - device context for the right half the window.
536: * ptoDest - pointer to the destination track object
537: * hdcDest - device context for the left half the window.
538: * hbmSrc - bitmap handle for the source bitmap.
539: *
540: * strebltMode - Selection from combo box, to be used in SetStretchMode()
541: * iPatternBrush - Selection from combo box, set into the hdc.
542: \**************************************************************************/
543: LONG APIENTRY DlgProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
544: {
545: char buffer[MAXCHARS];
546:
547: UNREFERENCED_PARAMETER(lParam);
548:
549: switch (message) {
550: /**********************************************************************\
551: * WM_INITDIALOG
552: *
553: * Fill the entry fields with sensible original values.
554: * Also fill the combo boxes with the text entries from lookup tables.
555: \**********************************************************************/
556: case WM_INITDIALOG: {
557: int i;
558:
559: for ( i = DID_X; i<= DID_SRCHEIGHT; i++)
560: SetDlgItemText(hwnd, i , "0");
561:
562: SetDlgItemText(hwnd, DID_ROP0 , "cc");
563: SetDlgItemText(hwnd, DID_ROP1 , "00");
564: SetDlgItemText(hwnd, DID_ROP2 , "20");
565:
566: for (i = 0; i< NMODES; i++)
567: SendDlgItemMessage (hwnd, DID_CB_MODE, CB_INSERTSTRING,
568: (DWORD) -1, (LONG)strebltModes[i].String);
569:
570: for (i = 0; i< NPATTERNS; i++)
571: SendDlgItemMessage (hwnd, DID_CB_PATTERN, CB_INSERTSTRING,
572: (DWORD) -1, (LONG)Patterns[i].String);
573:
574: for (i = 0; i< NROPS; i++)
575: SendDlgItemMessage (hwnd, DID_CB_ROPS, CB_INSERTSTRING,
576: (DWORD) -1, (LONG)StandardROPs[i].String);
577:
578:
579: } return TRUE;
580:
581:
582: /**********************************************************************\
583: * WM_PUTUPDESTRECT
584: *
585: * wParam - HDC with the needed world transform.
586: * lParam - Pointer to the track object.
587: *
588: * Fill the entry fields for the destination rectangle points.
589: * Conditionally change <x,y> or <width,height> depending on tracking mode.
590: \**********************************************************************/
591: case WM_PUTUPDESTRECT: {
592: POINT p1,p2, origin;
593: PTrackObject pto;
594: HDC hdc;
595:
596: hdc = (HDC) wParam;
597: pto = (PTrackObject) lParam;
598: GetViewportOrgEx (hdc, &origin);
599:
600: p1.x = pto->rect.left;
601: p1.y = pto->rect.top;
602: LPtoDP (pto->hdc, &p1, 1);
603:
604: p2.x = pto->rect.right;
605: p2.y = pto->rect.bottom;
606: LPtoDP (pto->hdc, &p2, 1);
607: p2.x -= p1.x; p2.y -= p1.y;
608:
609: p1.x -= origin.x; p1.y -= origin.y;
610:
611: if (!(pto->Mode & TMSIZEXY)) {
612: SetDlgItemInt(hwnd, DID_X, p1.x, TRUE);
613: SetDlgItemInt(hwnd, DID_Y, p1.y, TRUE);
614: }
615:
616: if (!(pto->Mode & TMMOVE)) {
617: SetDlgItemInt(hwnd, DID_WIDTH, p2.x, TRUE);
618: SetDlgItemInt(hwnd, DID_HEIGHT, p2.y, TRUE);
619: }
620: } return FALSE;
621:
622:
623:
624:
625: /**********************************************************************\
626: * WM_PUTUPSRCRECT
627: *
628: * wParam - HDC with the needed world transform.
629: * lParam - Pointer to the track object.
630: *
631: * Fill the entry fields for the source rectangle points.
632: * Conditionally change <x,y> or <width,height> depending on tracking mode.
633: \**********************************************************************/
634: case WM_PUTUPSRCRECT: {
635: POINT p1,p2, origin;
636: PTrackObject pto;
637: HDC hdc;
638:
639: hdc = (HDC) wParam;
640: pto = (PTrackObject) lParam;
641: GetViewportOrgEx (hdc, &origin);
642:
643: p1.x = pto->rect.left;
644: p1.y = pto->rect.top;
645: LPtoDP (pto->hdc, &p1, 1);
646:
647: p2.x = pto->rect.right;
648: p2.y = pto->rect.bottom;
649: LPtoDP (pto->hdc, &p2, 1);
650: p2.x -= p1.x; p2.y -= p1.y;
651:
652: p1.x -= origin.x; p1.y -= origin.y;
653:
654: if (!(pto->Mode & TMSIZEXY)) {
655: SetDlgItemInt(hwnd, DID_XSRC, p1.x, TRUE);
656: SetDlgItemInt(hwnd, DID_YSRC, p1.y, TRUE);
657: }
658:
659: if (!(pto->Mode & TMMOVE)) {
660: SetDlgItemInt(hwnd, DID_SRCWIDTH, p2.x, TRUE);
661: SetDlgItemInt(hwnd, DID_SRCHEIGHT, p2.y, TRUE);
662: }
663: } return FALSE;
664:
665:
666:
667:
668: case WM_COMMAND:
669:
670: switch (LOWORD(wParam)) {
671:
672: /******************************************************************\
673: * WM_COMMAND, DID_DRAW
674: *
675: * Draw button hit - send main window message to call StretchBlt().
676: \******************************************************************/
677: case DID_DRAW:
678: SendMessage (hwndMain, WM_STRETCHBLT, 0,0);
679: break;
680:
681:
682: /******************************************************************\
683: * WM_COMMAND, DID_NEWSRC
684: *
685: * Try to get a new source bitmap. If successful, store it in the
686: * global handle (hbmSrc) then invalidate two sub windows so that
687: * we force a complete repaint in both.
688: \******************************************************************/
689: case DID_NEWSRC: {
690: HBITMAP hbm;
691: if ( hbm = GetBitmap (hdcSrc, hInst, FALSE)) {
692: DeleteObject (hbmSrc);
693: hbmSrc = hbm;
694: InvalidateRect (hwndMain, &ptoSrc->rectClip, TRUE);
695: InvalidateRect (hwndMain, &ptoDest->rectClip, TRUE);
696: }
697:
698: } break;
699:
700:
701: /******************************************************************\
702: * WM_COMMAND, DID_CB_MODE
703: *
704: * A new streblt mode was selected. Look up the value, store it
705: * in a global variable (strebltMode), then force a new StretchBlt
706: \******************************************************************/
707: case DID_CB_MODE:
708: if (HIWORD (wParam) == CBN_SELCHANGE) {
709: int iSel;
710:
711: iSel = SendMessage ((HWND) lParam, CB_GETCURSEL, 0,0);
712: strebltMode = strebltModes[iSel].Value;
713:
714: SendMessage (hwndMain, WM_STRETCHBLT, 0,0);
715: }
716: break;
717:
718:
719: /******************************************************************\
720: * WM_COMMAND, DID_CB_PATTERN
721: *
722: * A new pattern brush was selected. Look up the value, store it
723: * in a global variable (iPatternBrush), then force a new StretchBlt
724: \******************************************************************/
725: case DID_CB_PATTERN:
726: if (HIWORD (wParam) == CBN_SELCHANGE) {
727: int iSel;
728:
729: iSel = SendMessage ((HWND) lParam, CB_GETCURSEL, 0,0);
730: iPatternBrush = Patterns[iSel].Value;
731:
732: SendMessage (hwndMain, WM_STRETCHBLT, 0,0);
733: }
734: break;
735:
736:
737:
738: /******************************************************************\
739: * WM_COMMAND, DID_CB_ROPS
740: *
741: * A new standard rop entry was selected. Lookup the value,
742: * then break it into three parts, convert to hex, and put
743: * it in the proper entry fields.
744: \******************************************************************/
745: case DID_CB_ROPS:
746: if (HIWORD (wParam) == CBN_SELCHANGE) {
747: int iSel, rop;
748:
749: iSel = SendMessage ((HWND) lParam, CB_GETCURSEL, 0,0);
750: rop = StandardROPs[iSel].Value;
751: sprintf (buffer, "%2x", (rop & 0x000000ff));
752: SetDlgItemText(hwnd, DID_ROP2, buffer);
753: rop /= 256;
754: sprintf (buffer, "%2x", (rop & 0x000000ff));
755: SetDlgItemText(hwnd, DID_ROP1, buffer);
756: rop /= 256;
757: sprintf (buffer, "%2x", (rop & 0x000000ff));
758: SetDlgItemText(hwnd, DID_ROP0, buffer);
759:
760: SendMessage (hwndMain, WM_STRETCHBLT, 0,0);
761: }
762: break;
763:
764:
765:
766:
767: } /* end switch */
768:
769:
770: return FALSE; /* end WM_COMMAND */
771:
772:
773: } /* end switch */
774: return (NULL);
775: }
776:
777:
778: #define TICKSPACE 20
779:
780: /**************************************************************************\
781: *
782: * function: DrawGrids()
783: *
784: * input parameters:
785: * hdc - Device context to draw into.
786: * width, height - size of the rectangle to fill with grids.
787: *
788: * global variables: none.
789: *
790: \**************************************************************************/
791: VOID DrawGrids (HDC hdc, int width, int height)
792: {
793: int i;
794:
795: /* Draw vertical lines. Double at the axis */
796: for (i = 0; i<= width; i+=TICKSPACE){
797: MoveToEx (hdc, i, 0, NULL);
798: LineTo (hdc, i, height);
799: }
800: MoveToEx (hdc, 1, 0, NULL);
801: LineTo (hdc, 1, height);
802:
803: /* Draw horizontal lines. Double at the axis */
804: for (i = 0; i<= height; i+=TICKSPACE){
805: MoveToEx (hdc, 0,i, NULL);
806: LineTo (hdc, width,i);
807: }
808: MoveToEx (hdc, 0, 1, NULL);
809: LineTo (hdc, width,1);
810:
811: return;
812: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.