|
|
1.1 root 1: /******************************Module*Header*******************************\
2: * Module Name: julia.c
3: *
4: * Main module for the Mandelbrot Dream
5: * contains almost everything; windows procedure + misc stuff
6: *
7: * Created: 24-Oct-1991 18:34:08
8: * Author: Petrus Wong
9: *
10: * Copyright (c) 1990 Microsoft Corporation
11: *
12: * The Mandelbrot Dream serves to demonstrate the GDI and USER
13: * functionalities in the setting of fractals.
14: *
15: * The Mandelbrot Dream provides the following functions:
16: * 1. Drawing the Mandelbrot set and the corresponding julia set
17: * 2. Zooming into any of the set
18: * 3. MDI fractal drawing windows
19: * 4. Floating Point Math/Fix Point Math
20: * 5. Shifting color table entries
21: * 6. Changing palette entries and animating palatte aka color cycling
22: * 7. Loading/Saving bitmap created with special effect
23: * 8. Changing bitmap color with flood fill
24: * 9. Boundary tracing and creating a clip region out of it for
25: * creating special effect
26: * 10. Enumerate printers for printing
27: *
28: * Dependencies:
29: *
30: * none
31: *
32: \**************************************************************************/
33: #include <windows.h>
34: #include <stdlib.h>
35: #include <commdlg.h>
36: #include <stdarg.h>
37: #include <math.h>
38: #include <stdio.h>
39: #include "julia.h"
40:
41: //#define CYCLETHRD
42: #define PRTTHRD
43: #define NEWPRTAPI
44:
45: //#define DEBUG
46:
47: #ifndef DEBUG
48: #undef OutputDebugString
49: #define OutputDebugString(LPCSTR)
50: #endif
51:
52:
53:
54: //
55: // Forward declarations.
56: //
57: BOOL InitializeApp (INT*);
58: LONG MainWndProc (HWND, UINT, DWORD, LONG);
59: LONG ChildWndProc (HWND, UINT, DWORD, LONG);
60: LONG About (HWND, UINT, DWORD, LONG);
61: LONG TextWndProc (HWND, UINT, DWORD, LONG);
62: LONG JuliaWndProc (HWND, UINT, DWORD, LONG);
63: LONG DrawWndProc (HWND, UINT, DWORD, LONG);
64: BOOL APIENTRY SuspendDrawThrd (HWND, LONG);
65: BOOL APIENTRY ResumeDrawThrd (HWND, LONG);
66: BOOL StartDraw (PINFO);
67: BOOL StartDrawFix (PINFO);
68: BOOL StartDraw2 (PINFO);
69: BOOL StartMandelbrot (PINFO);
70: BOOL StartMandelbrotFix (PINFO);
71: HBITMAP SaveBitmap (HWND);
72: void DrawBitmap (HDC, PINFO, int, int, int, int);
73: LONG lMul(LONG, LONG);
74: LONG lDiv(LONG, LONG);
75: PINFO pGetInfoData(HWND);
76: BOOL bReleaseInfoData(HWND);
77: BOOL bCheckMutexMenuItem(HMENU, UINT);
78: BOOL bInitInfo(PINFO);
79: BOOL bResetGlobal(VOID);
80: HBRUSH hBrCreateBrush(HDC, DWORD);
81: BOOL bPrintBmp(PPRTDATA);
82: extern BOOL bCycle(HWND);
83: extern BOOL bCleanupPrinter(VOID);
84: extern INT iCreatePenFrPal(HDC, PVOID *);
85:
86: /******************************Public*Routine******************************\
87: *
88: * WinMain
89: *
90: * History:
91: * 13-Jun-1992 -by- Petrus Wong Creates an array of pens
92: * 17-Apr-1991 -by- Petrus Wong
93: * Wrote it.
94: \**************************************************************************/
95:
96: int APIENTRY WinMain(
97: HINSTANCE hInstance,
98: HINSTANCE hPrevInstance,
99: LPSTR lpCmdLine,
100: int nShowCmd)
101: {
102: MSG msg;
103: INT i;
104:
105: ghModule = GetModuleHandle(NULL);
106: if (!InitializeApp(&giPen)) {
107: MessageBox(ghwndMain, "memory: InitializeApp failure!", "Error", MB_OK);
108: return 0;
109: }
110:
111: if (!(ghAccel = LoadAccelerators (ghModule, MAKEINTRESOURCE(ACCEL_ID))))
112: MessageBox(ghwndMain, "memory: Load Accel failure!", "Error", MB_OK);
113:
114:
115: while (GetMessage(&msg, NULL, 0, 0)) {
116: if (!TranslateAccelerator( ghwndMain, ghAccel, &msg) &&
117: !TranslateMDISysAccel( ghwndClient, &msg) ) {
118: TranslateMessage(&msg);
119: DispatchMessage(&msg);
120: }
121: }
122:
123: //
124: // Delete all the pens created and free the array of hPens;
125: // The pens and the array of hPens was created and allocated respectively
126: // in InitializeApp
127: //
128: if (gprghPen != NULL) {
129: for (i = 0; i <= giPen; i++) {
130: DeleteObject((HPEN) gprghPen[i]);
131: }
132: GlobalFree(gprghPen);
133: }
134:
135:
136: return 1;
137:
138: UNREFERENCED_PARAMETER(lpCmdLine);
139: UNREFERENCED_PARAMETER(nShowCmd);
140: UNREFERENCED_PARAMETER(hInstance);
141: UNREFERENCED_PARAMETER(hPrevInstance);
142: }
143:
144:
145: /***************************************************************************\
146: * InitializeApp
147: *
148: * History:
149: * 13-Jun-1992 Petrus Wong creates pens
150: * 29-May-1992 Petrus Wong check if device supports palette for cycling
151: * 09-09-91 Petrus Wong Created.
152: \***************************************************************************/
153:
154: BOOL InitializeApp(INT *piPen)
155: {
156: WNDCLASS wc;
157: HDC hDC;
158: INT iNumClr;
159:
160: wc.style = CS_OWNDC;
161: wc.lpfnWndProc = (WNDPROC)MainWndProc;
162: wc.cbClsExtra = 0;
163: wc.cbWndExtra = sizeof(LONG);
164: wc.hInstance = ghModule;
165: wc.hIcon = LoadIcon(ghModule, MAKEINTRESOURCE(APPICON));
166: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
167: wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE);
168: wc.lpszMenuName = "MainMenu";
169: wc.lpszClassName = "MandelClass";
170:
171: if (!RegisterClass(&wc))
172: return FALSE;
173:
174: wc.lpfnWndProc = (WNDPROC)ChildWndProc;
175: wc.hIcon = LoadIcon(ghModule, MAKEINTRESOURCE(APPICON));
176: wc.lpszMenuName = NULL;
177: wc.lpszClassName = "ChildClass";
178:
179: if (!RegisterClass(&wc))
180: return FALSE;
181:
182: wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
183: wc.lpfnWndProc = (WNDPROC)TextWndProc;
184: wc.hIcon = NULL;
185: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
186: wc.hbrBackground = (HBRUSH)(COLOR_BTNSHADOW);
187: wc.lpszMenuName = NULL;
188: wc.lpszClassName = "Text";
189:
190: if (!RegisterClass(&wc))
191: return FALSE;
192:
193: wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
194: wc.lpfnWndProc = (WNDPROC)JuliaWndProc;
195: wc.hIcon = NULL;
196:
197: //
198: // Nope. Can't have this, screw up my Paint Can cursor
199: //
200: //wc.hCursor = LoadCursor(NULL, IDC_ARROW);
201:
202: wc.hCursor = NULL;
203: wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
204: wc.lpszMenuName = NULL;
205: wc.lpszClassName = "Julia";
206:
207: if (!RegisterClass(&wc))
208: return FALSE;
209:
210:
211: //
212: // Notice, submenu is zero-based
213: //
214: hMenu = LoadMenu(ghModule, "MainMenu");
215: hChildMenu = LoadMenu(ghModule, "ChildMenu");
216: hSubMenuOne = GetSubMenu(hMenu, 1);
217: hSubMenuThree = GetSubMenu(hChildMenu, 8);
218: hPrinterMenu = GetSubMenu(hChildMenu, 7);
219:
220: //
221: // Disable color-cycling for display devices that does not support
222: // palette like the VGA. As as 29-May-1992, the MIPS display driver
223: // is the only one that supports palette
224: //
225: hDC = GetDC(NULL);
226: if (!((GetDeviceCaps(hDC, RASTERCAPS)) & RC_PALETTE)) {
227: EnableMenuItem(hChildMenu, MM_CYCLE, MF_GRAYED);
228: }
229:
230: if ((iNumClr = iCreatePenFrPal(hDC, NULL)) != 0) {
231: sprintf( gtext,"iNumClr = %d\n", iNumClr);
232: OutputDebugString( gtext);
233:
234: if ((gprghPen = (PVOID*) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(HPEN)*iNumClr)) == NULL) {
235: MessageBox(ghwndMain, "Failed in Memory Allocation for gprghPen!", "Error", MB_OK);
236: } else {
237: if ((*piPen = iCreatePenFrPal(hDC, gprghPen)) == 0)
238: MessageBox(ghwndMain, "Failed in creating pen!", "Error", MB_OK);
239: }
240: }
241:
242: ReleaseDC(NULL, hDC);
243:
244: ghwndMain = CreateWindowEx(0L, "MandelClass", "Mandelbrot Dream",
245: WS_OVERLAPPED | WS_CAPTION | WS_BORDER |
246: WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX |
247: WS_CLIPCHILDREN | WS_VISIBLE | WS_SYSMENU,
248: 80, 70, 550, 550,
249: NULL, hMenu, ghModule, NULL);
250:
251: if (ghwndMain == NULL)
252: return FALSE;
253:
254: bInitPrinter(ghwndMain);
255:
256: SetWindowLong(ghwndMain, GWL_USERDATA, 0L);
257:
258: SetFocus(ghwndMain); /* set initial focus */
259:
260: return TRUE;
261: }
262:
263:
264: /******************************Public*Routine******************************\
265: *
266: * MainWndProc
267: *
268: * History:
269: * 09-Sept-1991 -by- Petrus Wong
270: * Wrote it.
271: \**************************************************************************/
272:
273: long MainWndProc(
274: HWND hwnd,
275: UINT message,
276: DWORD wParam,
277: LONG lParam)
278: {
279: static int iJuliaCount=1;
280: static int iMandelCount=1;
281: CLIENTCREATESTRUCT clientcreate;
282: HWND hwndChildWindow;
283: static FARPROC lpfnSuspendThrd, lpfnResumeThrd;
284:
285:
286: switch (message) {
287:
288: case WM_CREATE:
289: SetWindowLong(hwnd, 0, (LONG)NULL);
290:
291: clientcreate.hWindowMenu = hSubMenuOne;
292: clientcreate.idFirstChild = 1;
293:
294: ghwndClient = CreateWindow("MDICLIENT", NULL,
295: WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
296: 0,0,0,0,
297: hwnd, NULL, ghModule, (LPVOID)&clientcreate);
298: lpfnSuspendThrd = (FARPROC)MakeProcInstance (SuspendDrawThrd, ghModule);
299: lpfnResumeThrd = (FARPROC)MakeProcInstance (ResumeDrawThrd, ghModule);
300: return 0L;
301:
302: case WM_DESTROY: {
303: bCleanupPrinter();
304: PostQuitMessage(0);
305: return 0L;
306: }
307:
308: //
309: // Wait! User is going to zero out our app's visible region. This
310: // is going to mess up our drawing (we are not keeping any shadow
311: // bitmap in this version yet.) So, let's suspend our drawing thread
312: // first before user does that. We will resume after user is done.
313: //
314: case WM_SYSCOMMAND: {
315: LONG lResult;
316:
317: //
318: // We'll enumerate our children and suspend their drawing thread.
319: //
320: EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnSuspendThrd, lParam);
321:
322: //
323: // Now, let user does it supposed to do
324: //
325: lResult = DefFrameProc(hwnd, ghwndClient, message, wParam, lParam);
326:
327: //
328: // User's done, we'll resume the suspended threads in our children
329: //
330: EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnResumeThrd, lParam);
331:
332: return lResult;
333: break;
334: }
335: #if 0
336: //
337: // Our window's size is going to change, we'll make sure the new
338: // window is a square.
339: //
340: case WM_WINDOWPOSCHANGING: {
341: PWINDOWPOS pWndPos;
342: RECT rect;
343: LONG lcx, lcy;
344:
345: GetWindowRect(hwnd, &rect);
346: lcx = rect.right-rect.left;
347: lcy = rect.bottom-rect.top;
348: pWndPos = (PWINDOWPOS)lParam;
349: if ((pWndPos->cy > lcy) || (pWndPos->cx > lcx))
350: pWndPos->cx = pWndPos->cy =
351: ((pWndPos->cx > pWndPos->cy) ? pWndPos->cy : pWndPos->cx);
352: else if ((pWndPos->cy < lcy) || (pWndPos->cx < lcx))
353: pWndPos->cx = pWndPos->cy =
354: ((pWndPos->cx > pWndPos->cy) ? pWndPos->cy : pWndPos->cx);
355: break;
356: }
357: #endif
358: case WM_COMMAND:
359:
360: switch (LOWORD(wParam)) {
361: case IDM_TILE:
362: SendMessage(ghwndClient, WM_MDITILE, 0L, 0L);
363: return 0L;
364: case IDM_CASCADE:
365: SendMessage(ghwndClient, WM_MDICASCADE, 0L, 0L);
366: return 0L;
367: case IDM_ARRANGE:
368: SendMessage(ghwndClient, WM_MDIICONARRANGE, 0L, 0L);
369: return 0L;
370:
371: //
372: // Create Julia or Mandelbrot set
373: //
374: case MM_JULIA:
375: case MM_MANDEL: {
376: HANDLE hInfo;
377: PINFO pInfo;
378: MDICREATESTRUCT mdicreate;
379:
380: hInfo = LocalAlloc(LHND, (WORD) sizeof(INFO));
381: if (hInfo == NULL) {
382: MessageBox(ghwndMain, "Failed to Allocate Info!", "Error", MB_OK);
383: return 0L;
384: }
385: if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) {
386: MessageBox(ghwndMain, "Failed in LocalLock, hInfo", "Error", MB_OK);
387: return 0L;
388: }
389:
390: bInitInfo(pInfo);
391: wsprintf((LPSTR) &(pInfo->CaptionBarText),
392: (LOWORD(wParam) == MM_JULIA) ? "Julia %d" : "Mandelbrot %d",
393: (LOWORD(wParam) == MM_JULIA) ? iJuliaCount : iMandelCount );
394: if (LOWORD(wParam) == MM_JULIA) {
395: c1 = 0.360284;
396: c2 = 0.100376;
397: lc1 = 738; //.3603515
398: lc2 = 206; //.1005859
399: pInfo->bMandel = FALSE;
400: } else {
401: pInfo->bMandel = TRUE;
402: }
403:
404: //
405: // Fill in the MDICREATE structure for MDI child creation
406: //
407: mdicreate.szClass = "ChildClass";
408: mdicreate.szTitle = (LPTSTR)&(pInfo->CaptionBarText);
409: mdicreate.hOwner = ghModule;
410: mdicreate.x =
411: mdicreate.y = CW_USEDEFAULT;
412: mdicreate.cx = 300;
413: mdicreate.cy = 300;
414: mdicreate.style = 0L;
415: mdicreate.lParam = (LONG) hInfo;
416:
417: /*Create Child Window*/
418: hwndChildWindow =
419: (HANDLE) SendMessage(ghwndClient, WM_MDICREATE,
420: 0L,
421: (LONG)(LPMDICREATESTRUCT)&mdicreate);
422:
423: if (hwndChildWindow == NULL) {
424: MessageBox(ghwndMain, "Failed in Creating Child Window", "Error", MB_OK);
425: return 0L;
426: }
427:
428: (LOWORD(wParam) == MM_JULIA) ? iJuliaCount++ : iMandelCount++ ;
429: LocalUnlock(hInfo);
430: return ((LONG)hwndChildWindow);
431: }
432:
433: case MM_ABOUT:
434: if (DialogBox(ghModule, "AboutBox", ghwndMain, (DLGPROC)About) == -1)
435: MessageBox(ghwndMain, "DEMO: About Dialog Creation Error!", "Error", MB_OK);
436: return 0L;
437:
438: //
439: // Only my children know how to deal with these messages, so
440: // pass these to children for processing
441: //
442: case MM_CREATE_JULIA_THREAD:
443: case MM_SET_XFORM_ATTR:
444: case MM_CREATE_MANDEL_THREAD:
445: case MM_OPT_4: // currently not used
446: case MM_DRAW_SET:
447: case MM_SETDIB2DEVICE:
448: case MM_BW:
449: case MM_SHIFT:
450: case MM_CUSTOM:
451: case MM_CYCLE:
452: case MM_FLOAT:
453: case MM_FIX:
454: case MM_ITERATION_TEN:
455: case MM_ITERATION_TWENTY:
456: case MM_ITERATION_THIRTY:
457: case MM_ITERATION_FIFTY:
458: case MM_ITERATION_DOUBLE:
459: case MM_STEP_ONE:
460: case MM_STEP_TWO:
461: case MM_STEP_THREE:
462: case MM_SAVE:
463: case MM_SAVE_MONO:
464: case MM_LOAD:
465: case MM_STRETCHBLT:
466: case MM_BITBLT:
467: case MM_BLACKONWHITE:
468: case MM_COLORONCOLOR:
469: case MM_WHITEONBLACK:
470: case MM_HALFTONE:
471: case MM_CLIP:
472: case MM_RM_CLIP:
473: case MM_ERASE:
474: case MM_PORTRAIT:
475: case MM_LANDSCAPE:
476: case MM_PRINTER:
477: case MM_PRINTER + 1:
478: case MM_PRINTER + 2:
479: case MM_PRINTER + 3:
480: case MM_PRINTER + 4:
481: case MM_PRINTER + 5:
482: case MM_PRINTER + 6:
483: case MM_PRINTER + 7:
484: case MM_PRINTER + 8:
485: case MM_PRINTER + 9:
486: {
487: HWND hActiveChild;
488:
489: hActiveChild = (HANDLE) SendMessage(ghwndClient, WM_MDIGETACTIVE, 0L, 0L);
490: if (hActiveChild)
491: SendMessage(hActiveChild, WM_COMMAND, wParam, lParam);
492: return 0L;
493: }
494:
495: default:
496: return DefFrameProc(hwnd, ghwndClient, message, wParam, lParam);
497: }
498: default:
499:
500: return DefFrameProc(hwnd, ghwndClient, message, wParam, lParam);
501: }
502: }
503:
504: /***************************************************************************\
505: * ChildWndProc
506: *
507: * History:
508: * 04-17-91 ???? Created.
509: * 09-09-91 Petrus Wong Rewrote.
510: \***************************************************************************/
511:
512: long ChildWndProc(
513: HWND hwnd,
514: UINT message,
515: DWORD wParam,
516: LONG lParam)
517: {
518: static FARPROC lpfnSuspendThrd, lpfnResumeThrd;
519: static BOOL bDIB2Device = FALSE;
520:
521: sprintf( gtext,"message = %lx\n", message);
522: OutputDebugString( gtext);
523:
524: switch (message) {
525:
526: case WM_COMMAND: {
527: PINFO pInfo;
528: HWND hTextWnd;
529:
530: switch (LOWORD(wParam)) {
531: //
532: // Create a Julia drawing thread
533: //
534: case MM_CREATE_JULIA_THREAD: {
535: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
536: return 0L;
537: }
538:
539: hTextWnd = pInfo->hTextWnd;
540: sprintf( gtext,"(%g, %g) <-> (%g, %g)", pInfo->xFrom, pInfo->yFrom, pInfo->xTo, pInfo->yTo);
541: SetWindowText(hTextWnd, gtext);
542: sprintf( gtext,"(c1 = %g, c2 = %g)\n\n", pInfo->c1, pInfo->c2);
543: OutputDebugString( gtext );
544:
545: pInfo->hThrd = CreateThread(NULL, 0,
546: (gFloat ? (LPTHREAD_START_ROUTINE)StartDraw : (LPTHREAD_START_ROUTINE)StartDrawFix),
547: pInfo,
548: STANDARD_RIGHTS_REQUIRED,
549: &pInfo->dwThreadId );
550:
551: bReleaseInfoData(hwnd);
552: return 0L;
553: }
554:
555: //
556: // Reset pInfo reflecting new transformation
557: //
558: case MM_SET_XFORM_ATTR: {
559: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
560: return 0L;
561: }
562:
563: hTextWnd = pInfo->hTextWnd;
564: SetWindowText(hTextWnd, "Click here for viewing info");
565:
566: pInfo->xFrom = xFrom;
567: pInfo->xTo = xTo;
568: pInfo->yFrom = yFrom;
569: pInfo->yTo = yTo;
570: pInfo->c1 = c1;
571: pInfo->c2 = c2;
572: pInfo->lxFrom = lxFrom;
573: pInfo->lxTo = lxTo;
574: pInfo->lyFrom = lyFrom;
575: pInfo->lyTo = lyTo;
576: pInfo->lc1 = lc1;
577: pInfo->lc2 = lc2;
578:
579: bReleaseInfoData(hwnd);
580: return 0L;
581: }
582:
583: //
584: // Create a Mandelbrot drawing thread
585: //
586: case MM_CREATE_MANDEL_THREAD: {
587: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
588: return 0L;
589: }
590:
591: hTextWnd = pInfo->hTextWnd;
592: sprintf( gtext,"(%g, %g) <-> (%g, %g)", pInfo->xFrom, pInfo->yFrom, pInfo->xTo, pInfo->yTo);
593: SetWindowText(hTextWnd, gtext);
594: sprintf( gtext,"(c1 = %g, c2 = %g)\n\n", pInfo->c1, pInfo->c2);
595: OutputDebugString( gtext );
596:
597: pInfo->hThrd = CreateThread(NULL, 0,
598: (gFloat ? (LPTHREAD_START_ROUTINE)StartMandelbrot : (LPTHREAD_START_ROUTINE)StartMandelbrotFix),
599: pInfo,
600: STANDARD_RIGHTS_REQUIRED,
601: &pInfo->dwThreadId );
602: bReleaseInfoData(hwnd);
603: return 0L;
604: }
605:
606: //
607: // Create a Julia drawing thread using algorithm StartDraw2
608: // Currently not used
609: //
610: case MM_OPT_4: {
611: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
612: return 0L;
613: }
614:
615: hTextWnd = pInfo->hTextWnd;
616: SetWindowText(hTextWnd, "MM_OPT_4");
617:
618: sprintf( gtext,"xFrom = %g, xTo = %g, yFrom = %g, yTo = %g\n", pInfo->xFrom, pInfo->xTo, pInfo->yFrom, pInfo->yTo);
619: OutputDebugString( gtext );
620:
621: pInfo->hThrd = CreateThread(NULL, 0,
622: (LPTHREAD_START_ROUTINE)StartDraw2,
623: pInfo,
624: STANDARD_RIGHTS_REQUIRED,
625: &pInfo->dwThreadId );
626:
627: bReleaseInfoData(hwnd);
628: return 0L;
629: }
630:
631: case MM_DRAW_SET: {
632: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
633: return 0L;
634: }
635:
636: PostMessage(hwnd, WM_COMMAND,
637: pInfo->bMandel ? (DWORD)((WORD)MM_CREATE_MANDEL_THREAD) : (DWORD)((WORD)MM_CREATE_JULIA_THREAD),
638: (LONG)0L);
639:
640: bReleaseInfoData(hwnd);
641: return 0L;
642: }
643:
644: case MM_FLOAT: {
645: bCheckMutexMenuItem(hChildMenu, MM_FLOAT);
646: DrawMenuBar(GetParent(GetParent(hwnd))) ;
647: gFloat = TRUE;
648: return 0L;
649: }
650: case MM_FIX: {
651: bCheckMutexMenuItem(hChildMenu, MM_FIX);
652: DrawMenuBar(GetParent(GetParent(hwnd))) ;
653: gFloat = FALSE;
654: return 0L;
655: }
656: case MM_ITERATION_TEN: {
657: bCheckMutexMenuItem(hChildMenu, MM_ITERATION_TEN);
658: DrawMenuBar(GetParent(GetParent(hwnd))) ;
659: gIteration = 10;
660: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
661: return 0L;
662: }
663: pInfo->iIteration = 10;
664:
665: bReleaseInfoData(hwnd);
666: return 0L;
667: }
668: case MM_ITERATION_TWENTY: {
669: bCheckMutexMenuItem(hChildMenu, MM_ITERATION_TWENTY);
670: DrawMenuBar(GetParent(GetParent(hwnd))) ;
671: gIteration = 20;
672: if ((pInfo = pGetInfoData(hwnd)) == NULL){
673: return 0L;
674: }
675:
676: pInfo->iIteration = 20;
677:
678: bReleaseInfoData(hwnd);
679: return 0L;
680: }
681: case MM_ITERATION_THIRTY: {
682: bCheckMutexMenuItem(hChildMenu, MM_ITERATION_THIRTY);
683: DrawMenuBar(GetParent(GetParent(hwnd))) ;
684: gIteration = 30;
685: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
686: return 0L;
687: }
688: pInfo->iIteration = 30;
689:
690: bReleaseInfoData(hwnd);
691: return 0L;
692: }
693: case MM_ITERATION_FIFTY: {
694: bCheckMutexMenuItem(hChildMenu, MM_ITERATION_FIFTY);
695: DrawMenuBar(GetParent(GetParent(hwnd))) ;
696: gIteration = 50;
697: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
698: return 0L;
699: }
700: pInfo->iIteration = 50;
701:
702: bReleaseInfoData(hwnd);
703: return 0L;
704: }
705: case MM_ITERATION_DOUBLE: {
706: bCheckMutexMenuItem(hChildMenu, MM_ITERATION_DOUBLE);
707: DrawMenuBar(GetParent(GetParent(hwnd))) ;
708: gIteration *= 2;
709: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
710: return 0L;
711: }
712: pInfo->iIteration = gIteration;
713:
714: bReleaseInfoData(hwnd);
715: return 0L;
716: }
717: case MM_STEP_ONE: {
718: bCheckMutexMenuItem(hChildMenu, MM_STEP_ONE);
719: DrawMenuBar(GetParent(GetParent(hwnd))) ;
720: gStep = 1;
721: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
722: return 0L;
723: }
724: pInfo->iStep = 1;
725:
726: bReleaseInfoData(hwnd);
727: return 0L;
728: }
729: case MM_STEP_TWO: {
730: bCheckMutexMenuItem(hChildMenu, MM_STEP_TWO);
731: DrawMenuBar(GetParent(GetParent(hwnd))) ;
732: gStep = 2;
733: if ((pInfo = pGetInfoData(hwnd)) == NULL){
734: return 0L;
735: }
736: pInfo->iStep = 2;
737:
738: bReleaseInfoData(hwnd);
739: return 0L;
740: }
741: case MM_STEP_THREE: {
742: bCheckMutexMenuItem(hChildMenu, MM_STEP_THREE);
743: DrawMenuBar(GetParent(GetParent(hwnd))) ;
744: gStep = 3;
745: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
746: return 0L;
747: }
748: pInfo->iStep = 3;
749:
750: bReleaseInfoData(hwnd);
751: return 0L;
752: }
753:
754: case MM_LOAD: {
755: HDC hDC;
756: OPENFILENAME ofn;
757: char szDirName[256];
758: char szFile[256], szFileTitle[256];
759: static char *szFilter;
760: RECT rc;
761:
762: szFilter =
763: "DIB files (*.bmp)\0*.bmp\0RLE files (*.rle)\0*.rle\0\0";
764:
765: GetSystemDirectory((LPSTR) szDirName, 256);
766: strcpy(szFile, "*.bmp\0");
767: ofn.lStructSize = sizeof(OPENFILENAME);
768: ofn.hwndOwner = hwnd;
769: ofn.lpstrFilter = szFilter;
770: ofn.lpstrCustomFilter = (LPSTR) NULL;
771: ofn.nMaxCustFilter = 0L;
772: ofn.nFilterIndex = 1;
773: ofn.lpstrFile = szFile;
774: ofn.nMaxFile = sizeof(szFile);
775: ofn.lpstrFileTitle = szFileTitle;
776: ofn.nMaxFileTitle = sizeof(szFileTitle);
777: ofn.lpstrInitialDir = szDirName;
778: ofn.lpstrTitle = (LPSTR) NULL;
779: ofn.Flags = 0L;
780: ofn.nFileOffset = 0;
781: ofn.nFileExtension = 0;
782: ofn.lpstrDefExt = "BMP";
783:
784: if (!GetOpenFileName(&ofn))
785: return 0L;
786: if ((pInfo = pGetInfoData(hwnd)) == NULL){
787: return 0L;
788: }
789: GetClientRect(pInfo->hwnd, &rc);
790: hDC = GetDC(pInfo->hwnd);
791: if (LoadBitmapFile(hDC, pInfo, szFile))
792: DrawBitmap(hDC, pInfo, 0, 0, rc.right, rc.bottom);
793: ReleaseDC(hwnd, hDC);
794:
795: bReleaseInfoData(hwnd);
796:
797: return 0L;
798: }
799:
800: case MM_SAVE: {
801: HDC hDC;
802: OPENFILENAME ofn;
803: char szDirName[256];
804: char szFile[256], szFileTitle[256];
805: static char *szFilter;
806: szFilter = "DIB files (*.bmp)\0\0";
807:
808: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
809: return 0L;
810: }
811: hDC = GetDC(pInfo->hwnd);
812:
813: //
814: // saving special effects user might have created in window
815: //
816: if (pInfo->hBmpSaved)
817: DeleteObject(pInfo->hBmpSaved);
818: pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd);
819:
820: GetSystemDirectory((LPSTR) szDirName, 256);
821: strcpy(szFile, "*.bmp\0");
822: ofn.lStructSize = sizeof(OPENFILENAME);
823: ofn.hwndOwner = hwnd;
824: ofn.lpstrFilter = szFilter;
825: ofn.lpstrCustomFilter = (LPSTR) NULL;
826: ofn.nMaxCustFilter = 0L;
827: ofn.nFilterIndex = 0L;
828: ofn.lpstrFile = szFile;
829: ofn.nMaxFile = sizeof(szFile);
830: ofn.lpstrFileTitle = szFileTitle;
831: ofn.nMaxFileTitle = sizeof(szFileTitle);
832: ofn.lpstrInitialDir = szDirName;
833: ofn.lpstrTitle = (LPSTR) NULL;
834: ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
835: ofn.nFileOffset = 0;
836: ofn.nFileExtension = 0;
837: ofn.lpstrDefExt = (LPSTR)NULL;
838:
839: if (!GetSaveFileName(&ofn)) {
840: ReleaseDC(pInfo->hwnd, hDC);
841: bReleaseInfoData(hwnd);
842: return 0L;
843: }
844:
845: SaveBitmapFile(hDC, pInfo->hBmpSaved, szFile);
846: ReleaseDC(pInfo->hwnd, hDC);
847:
848: bReleaseInfoData(hwnd);
849: return 0L;
850: }
851: case MM_SAVE_MONO: {
852: HDC hDC;
853: OPENFILENAME ofn;
854: char szDirName[256];
855: char szFile[256], szFileTitle[256];
856: static char *szFilter;
857: szFilter = "DIB files (*.bmp)\0\0";
858:
859: GetSystemDirectory((LPSTR) szDirName, 256);
860: strcpy(szFile, "*.bmp\0");
861: ofn.lStructSize = sizeof(OPENFILENAME);
862: ofn.hwndOwner = hwnd;
863: ofn.lpstrFilter = szFilter;
864: ofn.lpstrCustomFilter = (LPSTR) NULL;
865: ofn.nMaxCustFilter = 0L;
866: ofn.nFilterIndex = 0L;
867: ofn.lpstrFile = szFile;
868: ofn.nMaxFile = sizeof(szFile);
869: ofn.lpstrFileTitle = szFileTitle;
870: ofn.nMaxFileTitle = sizeof(szFileTitle);
871: ofn.lpstrInitialDir = szDirName;
872: ofn.lpstrTitle = "Saving Monochrome Bitmap";
873: ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
874: ofn.nFileOffset = 0;
875: ofn.nFileExtension = 0;
876: ofn.lpstrDefExt = (LPSTR)NULL;
877:
878: if (!GetSaveFileName(&ofn))
879: return 0L;
880: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
881: return 0L;
882: }
883: hDC = GetDC(pInfo->hwnd);
884:
885: SaveBitmapFile(hDC, pInfo->hBmpMono, szFile);
886: ReleaseDC(pInfo->hwnd, hDC);
887:
888: bReleaseInfoData(hwnd);
889: return 0L;
890: }
891: case MM_STRETCHBLT: {
892: gbStretch = TRUE;
893: bCheckMutexMenuItem(hChildMenu, MM_STRETCHBLT);
894: DrawMenuBar(GetParent(GetParent(hwnd))) ;
895: if ((pInfo = pGetInfoData(hwnd)) == NULL){
896: return 0L;
897: }
898: pInfo->bStretch = gbStretch;
899: InvalidateRect(pInfo->hwnd, NULL, FALSE);
900:
901: bReleaseInfoData(hwnd);
902: return 0L;
903:
904: }
905: case MM_BITBLT: {
906: gbStretch = FALSE;
907: bCheckMutexMenuItem(hChildMenu, MM_BITBLT);
908: DrawMenuBar(GetParent(GetParent(hwnd))) ;
909: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
910: return 0L;
911: }
912: pInfo->bStretch = gbStretch;
913: InvalidateRect(pInfo->hwnd, NULL, FALSE);
914:
915: bReleaseInfoData(hwnd);
916: return 0L;
917:
918: }
919: case MM_BLACKONWHITE: {
920: giStretchMode = BLACKONWHITE;
921: bCheckMutexMenuItem(hChildMenu, MM_BLACKONWHITE);
922: DrawMenuBar(GetParent(GetParent(hwnd))) ;
923: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
924: return 0L;
925: }
926: pInfo->iStretchMode = giStretchMode;
927: InvalidateRect(pInfo->hwnd, NULL, FALSE);
928:
929: bReleaseInfoData(hwnd);
930: return 0L;
931:
932: }
933: case MM_COLORONCOLOR: {
934: giStretchMode = COLORONCOLOR;
935: bCheckMutexMenuItem(hChildMenu, MM_COLORONCOLOR);
936: DrawMenuBar(GetParent(GetParent(hwnd))) ;
937: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
938: return 0L;
939: }
940: pInfo->iStretchMode = giStretchMode;
941: InvalidateRect(pInfo->hwnd, NULL, FALSE);
942:
943: bReleaseInfoData(hwnd);
944: return 0L;
945:
946: }
947: case MM_WHITEONBLACK: {
948: giStretchMode = WHITEONBLACK;
949: bCheckMutexMenuItem(hChildMenu, MM_WHITEONBLACK);
950: DrawMenuBar(GetParent(GetParent(hwnd))) ;
951: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
952: return 0L;
953: }
954: pInfo->iStretchMode = giStretchMode;
955: InvalidateRect(pInfo->hwnd, NULL, FALSE);
956:
957: bReleaseInfoData(hwnd);
958: return 0L;
959:
960: }
961: case MM_HALFTONE: {
962: giStretchMode = HALFTONE;
963: bCheckMutexMenuItem(hChildMenu, MM_HALFTONE);
964: DrawMenuBar(GetParent(GetParent(hwnd))) ;
965: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
966: return 0L;
967: }
968: pInfo->iStretchMode = giStretchMode;
969: InvalidateRect(pInfo->hwnd, NULL, FALSE);
970:
971: bReleaseInfoData(hwnd);
972: return 0L;
973: }
974: case MM_SETDIB2DEVICE: {
975: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
976: return 0L;
977: }
978: bDIB2Device = (bDIB2Device ? FALSE : TRUE);
979: pInfo->bSetDIBsToDevice = bDIB2Device;
980: CheckMenuItem(hChildMenu, MM_SETDIB2DEVICE, (bDIB2Device ? MF_CHECKED : MF_UNCHECKED));
981: bReleaseInfoData(hwnd);
982: return 0L;
983: }
984: case MM_BW: {
985: HDC hDC;
986:
987: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
988: return 0L;
989: }
990: hDC = GetDC(pInfo->hwnd);
991: bChangeDIBColor(hDC, pInfo, MM_BW);
992: ReleaseDC(hwnd, hDC);
993: bReleaseInfoData(hwnd);
994: return 0L;
995: }
996: case MM_SHIFT: {
997: HDC hDC;
998:
999: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
1000: return 0L;
1001: }
1002: hDC = GetDC(pInfo->hwnd);
1003: bChangeDIBColor(hDC, pInfo, MM_SHIFT);
1004: ReleaseDC(hwnd, hDC);
1005: bReleaseInfoData(hwnd);
1006: return 0L;
1007: }
1008: case MM_CUSTOM: {
1009: static DWORD argbCust[16] = {
1010: RGB(255, 255, 255), RGB(255, 255, 255),
1011: RGB(255, 255, 255), RGB(255, 255, 255),
1012: RGB(255, 255, 255), RGB(255, 255, 255),
1013: RGB(255, 255, 255), RGB(255, 255, 255),
1014: RGB(255, 255, 255), RGB(255, 255, 255),
1015: RGB(255, 255, 255), RGB(255, 255, 255),
1016: RGB(255, 255, 255), RGB(255, 255, 255),
1017: RGB(255, 255, 255), RGB(255, 255, 255)
1018: };
1019: CHOOSECOLOR cc;
1020: BOOL bResult;
1021: DWORD rgbOld;
1022: HBRUSH hBrush;
1023: HDC hDC;
1024:
1025: rgbOld = RGB(255, 255, 255);
1026: cc.lStructSize = sizeof(CHOOSECOLOR);
1027: cc.hwndOwner = ghwndMain;
1028: cc.hInstance = ghModule;
1029: cc.rgbResult = rgbOld;
1030: cc.lpCustColors = argbCust;
1031: cc.Flags = CC_RGBINIT | CC_SHOWHELP;
1032: cc.lCustData = 0;
1033: cc.lpfnHook = NULL;
1034: cc.lpTemplateName = NULL;
1035:
1036: bResult = ChooseColor(&cc);
1037: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
1038: return 0L;
1039: }
1040: if (bResult) {
1041: hDC = GetDC(pInfo->hwnd);
1042: hBrush = hBrCreateBrush(hDC, cc.rgbResult);
1043: ReleaseDC(pInfo->hwnd, hDC);
1044: if (pInfo->hBrush)
1045: DeleteObject(pInfo->hBrush);
1046: pInfo->hBrush = hBrush;
1047: pInfo->bFill = TRUE;
1048: }
1049: bReleaseInfoData(hwnd);
1050: return 0L;
1051: }
1052:
1053: #ifndef CYCLETHRD
1054: case MM_CYCLE: {
1055: HDC hDC;
1056:
1057: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
1058: return 0L;
1059: }
1060: hDC = GetDC(pInfo->hwnd);
1061:
1062: if (pInfo->bClrCycle) {
1063: CheckMenuItem(hChildMenu, MM_CYCLE, MF_UNCHECKED);
1064: pInfo->bClrCycle = FALSE;
1065: } else {
1066: CheckMenuItem(hChildMenu, MM_CYCLE, MF_CHECKED);
1067: pInfo->bClrCycle = TRUE;
1068: bChangeDIBColor(hDC, pInfo, MM_CYCLE);
1069: }
1070:
1071: ReleaseDC(hwnd, hDC);
1072: bReleaseInfoData(hwnd);
1073: return 0L;
1074: }
1075: #else
1076:
1077: case MM_CYCLE: {
1078: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
1079: return 0L;
1080: }
1081:
1082: if (pInfo->bFirstTime) {
1083: if (!SetEvent(pInfo->hQuitEvent)) {
1084: MessageBox(ghwndMain, "Can't set Quit Event!",
1085: "Error", MB_OK);
1086: return 0L;
1087: }
1088:
1089: pInfo->hCycleThrd = CreateThread(NULL, 0,
1090: (LPTHREAD_START_ROUTINE)bCycle,
1091: hwnd,
1092: STANDARD_RIGHTS_REQUIRED,
1093: &pInfo->dwCycleThrdID );
1094: pInfo->bClrCycle = TRUE;
1095: pInfo->bFirstTime = FALSE;
1096: CheckMenuItem(hChildMenu, MM_CYCLE, MF_CHECKED);
1097: } else {
1098: if (pInfo->bClrCycle) {
1099: CheckMenuItem(hChildMenu, MM_CYCLE, MF_UNCHECKED);
1100: pInfo->bClrCycle = FALSE;
1101: pInfo->dwSuspend = SuspendThread(pInfo->hCycleThrd);
1102: } else {
1103: CheckMenuItem(hChildMenu, MM_CYCLE, MF_CHECKED);
1104: pInfo->bClrCycle = TRUE;
1105: pInfo->dwSuspend = ResumeThread(pInfo->hCycleThrd);
1106: }
1107: if (pInfo->dwSuspend == -1) {
1108: (pInfo->bClrCycle ?
1109: sprintf( gtext,"Error in resuming thread\n") :
1110: sprintf( gtext,"Error in suspending thread\n") );
1111: OutputDebugString( gtext );
1112: }
1113: }
1114:
1115: bReleaseInfoData(hwnd);
1116: return 0L;
1117: }
1118: #endif
1119: case MM_CLIP: {
1120: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
1121: return 0L;
1122: }
1123:
1124: hTextWnd = pInfo->hTextWnd;
1125: sprintf( gtext,"(%g, %g) <-> (%g, %g)", pInfo->xFrom, pInfo->yFrom, pInfo->xTo, pInfo->yTo);
1126: SetWindowText(hTextWnd, gtext);
1127: sprintf( gtext,"(c1 = %g, c2 = %g)\n\n", pInfo->c1, pInfo->c2);
1128: OutputDebugString( gtext );
1129: if (!pInfo->bMandel) {
1130: MessageBox(ghwndMain, "Boundary Tracing and Setting clip region to the boundary points only works for Mandelbrot Set.", "Error", MB_OK);
1131: return 0L;
1132: }
1133: pInfo->hThrd = CreateThread(NULL, 0,
1134: (gFloat ? (LPTHREAD_START_ROUTINE)bBoundaryScanFix : (LPTHREAD_START_ROUTINE)bBoundaryScanFix),
1135: pInfo,
1136: STANDARD_RIGHTS_REQUIRED,
1137: &pInfo->dwThreadId );
1138:
1139: bReleaseInfoData(hwnd);
1140: return 0L;
1141: }
1142: case MM_RM_CLIP: {
1143: HDC hDC;
1144:
1145: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
1146: return 0L;
1147: }
1148:
1149: hDC = GetDC(pInfo->hwnd);
1150: SelectClipRgn(hDC, (HRGN) NULL);
1151: ReleaseDC(pInfo->hwnd, hDC);
1152: bReleaseInfoData(hwnd);
1153: InvalidateRect(pInfo->hwnd, NULL, FALSE);
1154: return 0L;
1155:
1156: }
1157: case MM_ERASE: {
1158: HDC hDC;
1159: RECT rc;
1160:
1161: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
1162: return 0L;
1163: }
1164: hDC = GetDC(pInfo->hwnd);
1165: if (pInfo->hRgnPath != (HRGN) NULL) {
1166: SelectClipRgn(hDC, pInfo->hRgnPath);
1167: }
1168: SelectObject(hDC, GetStockObject(WHITE_BRUSH));
1169: GetClientRect(pInfo->hwnd, &rc);
1170: PatBlt(hDC, 0, 0, rc.right, rc.bottom, PATCOPY);
1171: ReleaseDC(pInfo->hwnd, hDC);
1172: bReleaseInfoData(hwnd);
1173: return 0L;
1174: }
1175: case MM_PORTRAIT: {
1176: giDmOrient = DMORIENT_PORTRAIT;
1177: bCheckMutexMenuItem(hChildMenu, MM_PORTRAIT);
1178: DrawMenuBar(GetParent(GetParent(hwnd))) ;
1179: return 0L;
1180: }
1181: case MM_LANDSCAPE: {
1182: giDmOrient = DMORIENT_LANDSCAPE;
1183: bCheckMutexMenuItem(hChildMenu, MM_LANDSCAPE);
1184: DrawMenuBar(GetParent(GetParent(hwnd))) ;
1185: return 0L;
1186: }
1187: case MM_PRINTER:
1188: case MM_PRINTER + 1:
1189: case MM_PRINTER + 2:
1190: case MM_PRINTER + 3:
1191: case MM_PRINTER + 4:
1192: case MM_PRINTER + 5:
1193: case MM_PRINTER + 6:
1194: case MM_PRINTER + 7:
1195: case MM_PRINTER + 8:
1196:
1197: #ifdef PRTTHRD
1198: case MM_PRINTER + 9: {
1199: PINFO pInfo;
1200: PRTDATA PrtData, *pPrtData;
1201: ULONG sizINFO;
1202: PBYTE pjTmpInfo, pjTmp;
1203:
1204: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
1205: return 0L;
1206: }
1207:
1208: if (pInfo->hBmpSaved == NULL) {
1209: MessageBox(ghwndMain, "No Saved bitmap to print", "Error", MB_OK);
1210: return 0L;
1211: }
1212:
1213: //
1214: // Copy the info structure to PrtData
1215: //
1216: pPrtData = &PrtData;
1217: pjTmp = (PBYTE)&(pPrtData->info);
1218: pjTmpInfo = (PBYTE)pInfo;
1219: sizINFO = sizeof(INFO);
1220:
1221: while(sizINFO--)
1222: {
1223: *(((PBYTE)pjTmp)++) = *((pjTmpInfo)++);
1224: }
1225:
1226: PrtData.index = LOWORD(wParam) - MM_PRINTER;
1227:
1228: if (giDmOrient == DMORIENT_PORTRAIT) {
1229: PrtData.bUseDefault = TRUE;
1230: } else {
1231: PrtData.bUseDefault = FALSE;
1232: PrtData.DevMode.dmSize = sizeof(DEVMODE);
1233: PrtData.DevMode.dmDriverExtra = 0;
1234: PrtData.DevMode.dmOrientation = DMORIENT_LANDSCAPE;
1235: PrtData.DevMode.dmFields = DM_ORIENTATION;
1236: }
1237:
1238: pInfo->hPrtThrd = CreateThread(NULL, 0,
1239: (LPTHREAD_START_ROUTINE)bPrintBmp,
1240: &PrtData,
1241: STANDARD_RIGHTS_REQUIRED,
1242: &pInfo->dwPrtThrdID );
1243:
1244: bReleaseInfoData(hwnd);
1245: return 0L;
1246: }
1247:
1248: #else
1249: case MM_PRINTER + 9: {
1250: HDC hdcPrinter, hDC;
1251: int index;
1252: DEVMODE devmode;
1253: DEVMODE *pdevmode;
1254: PINFO pInfo;
1255: int iWidth, iHeight;
1256:
1257:
1258: index = LOWORD(wParam) - MM_PRINTER;
1259:
1260: if (giDmOrient == DMORIENT_PORTRAIT)
1261: pdevmode = NULL;
1262: else {
1263: pdevmode = &devmode;
1264: devmode.dmSize = sizeof(DEVMODE);
1265: devmode.dmDriverExtra = 0;
1266: devmode.dmOrientation = DMORIENT_LANDSCAPE;
1267: devmode.dmFields = DM_ORIENTATION;
1268: }
1269:
1270: if (!(hdcPrinter = CreateDC( "", gpszPrinterNames[index],
1271: "", pdevmode)))
1272: {
1273: return(0L);
1274: }
1275:
1276: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
1277: return 0L;
1278: }
1279:
1280: iWidth = GetDeviceCaps(hdcPrinter, HORZRES);
1281: iHeight = GetDeviceCaps(hdcPrinter, VERTRES);
1282:
1283: if (pInfo->hBmpSaved)
1284: DeleteObject(pInfo->hBmpSaved);
1285:
1286: pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd);
1287:
1288: Escape(hdcPrinter, STARTDOC, 20, "Mandelbrot", NULL);
1289: DrawBitmap(hdcPrinter, pInfo, 0, 0, iWidth, iHeight);
1290: Escape(hdcPrinter, NEWFRAME, NULL, NULL, NULL);
1291: Escape(hdcPrinter, ENDDOC, NULL, NULL, NULL);
1292: ReleaseDC(pInfo->hwnd, hDC);
1293: bReleaseInfoData(hwnd);
1294: DeleteDC(hdcPrinter);
1295: return 0L;
1296: }
1297: #endif
1298: default:
1299: return 0L;
1300:
1301: }
1302:
1303: }
1304: case WM_SETFOCUS:
1305: break;
1306:
1307: case WM_MDIACTIVATE: {
1308: PINFO pInfo;
1309:
1310: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
1311: return 0L;
1312: }
1313:
1314: if ((HWND) lParam == hwnd) {
1315: SendMessage(GetParent(hwnd), WM_MDISETMENU,
1316: (DWORD) hChildMenu,
1317: (LONG) hSubMenuThree) ;
1318: DrawMenuBar(GetParent(GetParent(hwnd))) ;
1319:
1320: (pInfo->bClrCycle ?
1321: CheckMenuItem(hChildMenu, MM_CYCLE, MF_CHECKED) :
1322: CheckMenuItem(hChildMenu, MM_CYCLE, MF_UNCHECKED) );
1323: }
1324:
1325: bReleaseInfoData(hwnd);
1326: return 0L;
1327: }
1328: #if 0
1329: case WM_WINDOWPOSCHANGING: {
1330: PWINDOWPOS pWndPos;
1331: PINFO pInfo;
1332: HWND hTextWnd;
1333: int iCyText, iCxBorder, iCyBorder, iCyCaption;
1334: RECT rect, rcl;
1335: LONG lcx, lcy;
1336:
1337: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
1338: break;
1339: }
1340:
1341: hTextWnd = pInfo->hTextWnd;
1342:
1343: bReleaseInfoData(hwnd);
1344:
1345: iCyText = GetWindowLong(hTextWnd, GWL_USERDATA);
1346: iCxBorder = GetSystemMetrics(SM_CXBORDER);
1347: iCyBorder = GetSystemMetrics(SM_CYBORDER);
1348: iCyCaption = GetSystemMetrics(SM_CYCAPTION) - iCyBorder;
1349: GetClientRect(GetParent(hwnd), &rcl);
1350: GetWindowRect(hwnd, &rect);
1351: lcx = rect.right-rect.left;
1352: lcy = rect.bottom-rect.top;
1353: pWndPos = (PWINDOWPOS)lParam;
1354: if ((pWndPos->cy > lcy) || (pWndPos->cx > lcx)) {
1355: pWndPos->cx =
1356: ((pWndPos->cx > pWndPos->cy) ? pWndPos->cy-iCyText : pWndPos->cx);
1357: pWndPos->cy = pWndPos->cx + iCyText;
1358: } else { if ((pWndPos->cy < lcy) || (pWndPos->cx < lcx)) {
1359: pWndPos->cx =
1360: ((pWndPos->cx > pWndPos->cy) ? pWndPos->cy-iCyText : pWndPos->cx);
1361: pWndPos->cy = pWndPos->cx + iCyText;
1362: }
1363: }
1364: break;
1365: }
1366: #endif
1367: case WM_SIZE: {
1368: HANDLE hThrd;
1369: PINFO pInfo;
1370: HWND hTextWnd, hJulia;
1371: BOOL bMandel;
1372: WORD wCx;
1373: int iCyText;
1374:
1375: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
1376: break;
1377: }
1378:
1379: hTextWnd = pInfo->hTextWnd;
1380: hJulia = pInfo->hwnd;
1381: hThrd = pInfo->hThrd;
1382: bMandel = pInfo->bMandel;
1383: bReleaseInfoData(hwnd);
1384: iCyText = GetWindowLong(hTextWnd, GWL_USERDATA);
1385: wCx = (WORD) (HIWORD(lParam) - iCyText);
1386:
1387: MoveWindow(hJulia, 0, 0,
1388: LOWORD(lParam),
1389: wCx,
1390: TRUE);
1391:
1392: MoveWindow(hTextWnd,
1393: 0,
1394: wCx,
1395: LOWORD(lParam),
1396: iCyText,
1397: TRUE);
1398:
1399: if (hThrd) {
1400: TerminateThread(hThrd, (DWORD)0L);
1401: /*
1402: PostMessage(hwnd, WM_COMMAND,
1403: bMandel ? (DWORD)((WORD)MM_CREATE_MANDEL_THREAD) : (DWORD)((WORD)MM_CREATE_JULIA_THREAD),
1404: (LONG)0L);
1405: */
1406: }
1407:
1408: break;
1409: }
1410:
1411: //
1412: // display info in the status window
1413: //
1414: case WM_USER+0xa: {
1415: PINFO pInfo;
1416: static ULONG ulClick = 0;
1417: HWND hTextWnd;
1418:
1419: ulClick++;
1420: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
1421: return 0L;
1422: }
1423:
1424: hTextWnd = pInfo->hTextWnd;
1425: switch (ulClick % 6) {
1426: case 0: sprintf( gtext,"%g <= x <= %g, %g <= y <= %g", pInfo->xFrom, pInfo->xTo, pInfo->yTo, pInfo->yFrom);
1427: break;
1428: case 1: sprintf( gtext,"c1 = %g, c2 = %g", pInfo->c1, pInfo->c2);
1429: break;
1430: case 2: sprintf( gtext,"Elapsed Time = %ld", (ULONG) pInfo->dwElapsed);
1431: break;
1432: case 3: sprintf( gtext,"Iteration = %d", pInfo->iIteration);
1433: break;
1434: case 4: sprintf( gtext,"Step = %d", pInfo->iStep);
1435: break;
1436: case 5: (gFloat ? sprintf( gtext,"Floating point math")
1437: : sprintf( gtext,"Fix point math")) ;
1438: break;
1439:
1440: default: break;
1441: }
1442: SetWindowText(hTextWnd, gtext);
1443: bReleaseInfoData(hwnd);
1444: return 0L;
1445: }
1446:
1447: case WM_SYSCOMMAND: {
1448: LONG lResult;
1449:
1450: EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnSuspendThrd, lParam);
1451:
1452: lResult = DefMDIChildProc(hwnd, message, wParam, lParam);
1453:
1454: EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnResumeThrd, lParam);
1455:
1456: return lResult;
1457: break;
1458: }
1459:
1460: case WM_CREATE: {
1461: PINFO pInfo;
1462: HANDLE hInfo;
1463: HWND hTextWnd, hJulia;
1464: RECT rcl;
1465:
1466: //
1467: // CR! MakeProcInstance is noop!
1468: //
1469: lpfnSuspendThrd = (FARPROC)MakeProcInstance (SuspendDrawThrd, ghModule);
1470: lpfnResumeThrd = (FARPROC)MakeProcInstance (ResumeDrawThrd, ghModule);
1471:
1472: hTextWnd = CreateWindow("Text", NULL,
1473: WS_BORDER | SS_LEFT | WS_CHILD | WS_VISIBLE,
1474: 0, 0, 0, 0,
1475: hwnd,
1476: (HMENU) 2,
1477: ghModule,
1478: NULL);
1479:
1480: GetClientRect(hwnd, &rcl);
1481: hJulia = CreateWindow("Julia", (LPSTR) NULL,
1482: WS_CHILD | WS_VISIBLE |
1483: WS_BORDER,
1484: 0,0, rcl.right-rcl.left,
1485: rcl.bottom-rcl.top-GetWindowLong(hTextWnd, GWL_USERDATA),
1486: hwnd, (HMENU)1, ghModule, (LPVOID)NULL);
1487:
1488: SetWindowText(hTextWnd, "Select the 'Draw Set' menu item to start drawing.");
1489: hInfo = (HANDLE) ((LPMDICREATESTRUCT) ((LPCREATESTRUCT) lParam)->lpCreateParams)->lParam ;
1490: if (hInfo) {
1491: if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) {
1492: MessageBox(ghwndMain, "Failed in LocalLock, hNode", "Error", MB_OK);
1493: break;
1494: } else {
1495: if (!GetClientRect(hwnd, &pInfo->rcClient))
1496: MessageBox(ghwndMain, "Failed in GetClientRect!", "Error", MB_OK);
1497:
1498: pInfo->hTextWnd = hTextWnd;
1499: pInfo->hwnd = hJulia;
1500: #ifdef CYCLETHRD
1501: //
1502: // Creating a signal quit color cycling event
1503: //
1504: if ((pInfo->hQuitEvent = CreateEvent(NULL, TRUE, TRUE, NULL)) == NULL)
1505: MessageBox(ghwndMain, "Failed in creating Quit Event!", "Error", MB_OK);
1506: #endif
1507: SetWindowLong(hwnd, 0, (LONG) hInfo);
1508: LocalUnlock(hInfo);
1509: }
1510: } else {
1511: MessageBox(ghwndMain, "Can't allocate hInfo!", "Error", MB_OK);
1512: }
1513:
1514: #if 0
1515: //
1516: // Initialize printers here will detect printers availiability
1517: // more often, but kind of overkill.
1518: //
1519: bInitPrinter(hwnd);
1520: #endif
1521: break;
1522: }
1523:
1524: case WM_CLOSE: {
1525: SendMessage(GetParent(hwnd), WM_MDISETMENU,
1526: (DWORD) hMenu,
1527: (LONG) hSubMenuOne) ;
1528: DrawMenuBar(GetParent(GetParent(hwnd))) ;
1529: break;
1530: }
1531:
1532: case WM_DESTROY: {
1533: PINFO pInfo;
1534: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
1535: break;
1536: }
1537:
1538: TerminateThread(pInfo->hThrd, (DWORD)0L);
1539: TerminateThread(pInfo->hPrtThrd, (DWORD)0L);
1540:
1541: #ifdef CYCLETHRD
1542: //
1543: // Cleanup color cycling
1544: //
1545: if (!ResetEvent(pInfo->hQuitEvent))
1546: MessageBox(ghwndMain, "Failed in reseting quit event!", "Error", MB_OK);
1547: #endif
1548: if (pInfo->hBmpMono)
1549: DeleteObject(pInfo->hBmpMono);
1550:
1551: if (pInfo->hBmpSaved)
1552: DeleteObject(pInfo->hBmpSaved);
1553:
1554: if (pInfo->hBrush)
1555: DeleteObject(pInfo->hBrush);
1556:
1557: bReleaseInfoData(hwnd);
1558: LocalFree((HANDLE) GetWindowLong(hwnd, 0));
1559: break;
1560: }
1561:
1562: default:
1563: return DefMDIChildProc(hwnd, message, wParam, lParam);
1564:
1565: } //switch
1566: return DefMDIChildProc(hwnd, message, wParam, lParam);
1567: }
1568:
1569: /***************************************************************************\
1570: * About
1571: *
1572: * About dialog proc.
1573: *
1574: * History:
1575: * 04-13-91 ???? Created.
1576: * 09-09-91 Petrus Wong Rewrote.
1577: \***************************************************************************/
1578:
1579: long About(
1580: HWND hDlg,
1581: UINT message,
1582: DWORD wParam,
1583: LONG lParam)
1584: {
1585: switch (message) {
1586: case WM_INITDIALOG:
1587: return TRUE;
1588:
1589: case WM_COMMAND:
1590: if (wParam == IDOK)
1591: EndDialog(hDlg, wParam);
1592: break;
1593: }
1594:
1595: return FALSE;
1596:
1597: UNREFERENCED_PARAMETER(lParam);
1598: UNREFERENCED_PARAMETER(hDlg);
1599: }
1600:
1601: /*************************************************************************
1602: *
1603: * TextWndProc
1604: *
1605: * Text Window proc.
1606: *
1607: * History:
1608: * 10-07-91 Petrus Wong Created.
1609: *
1610: \***************************************************************************/
1611:
1612: LONG TextWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam)
1613: {
1614: static HFONT hFont = (HFONT) NULL;
1615:
1616: switch (message)
1617: {
1618: case WM_CREATE:
1619: {
1620: LOGFONT lf;
1621: HDC hDC;
1622: HFONT hOldFont;
1623: TEXTMETRIC tm;
1624: RECT rect;
1625: LONG lHeight;
1626:
1627: SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), (PVOID) &lf, FALSE);
1628:
1629: hDC = GetDC(hwnd);
1630: // this is the height for 8 point size font in pixels
1631: lf.lfHeight = 8 * GetDeviceCaps(hDC, LOGPIXELSY) / 72;
1632:
1633: hFont = CreateFontIndirect(&lf);
1634: hOldFont = SelectObject(hDC, hFont);
1635: GetTextMetrics(hDC, &tm);
1636: GetClientRect(GetParent(hwnd), &rect);
1637:
1638: // base the height of the window on size of text
1639: lHeight = tm.tmHeight+6*GetSystemMetrics(SM_CYBORDER)+2;
1640: // saved the height for later reference
1641: SetWindowLong(hwnd, GWL_USERDATA, lHeight);
1642: SetWindowPos(hwnd, NULL,
1643: 0,
1644: rect.bottom-lHeight,
1645: rect.right-rect.left,
1646: lHeight,
1647: SWP_NOZORDER | SWP_NOMOVE);
1648:
1649: ReleaseDC(hwnd, hDC);
1650: break;
1651: }
1652:
1653: case WM_LBUTTONDOWN: {
1654: PostMessage(GetParent(hwnd), WM_USER+0xa, (DWORD)0L, (LONG)0L);
1655: break;
1656: }
1657:
1658: case WM_DESTROY:
1659: if (hFont)
1660: DeleteObject(hFont);
1661: break;
1662:
1663: case WM_SETTEXT:
1664: DefWindowProc(hwnd, message, wParam, lParam);
1665: InvalidateRect(hwnd,NULL,TRUE);
1666: UpdateWindow(hwnd);
1667: return 0L;
1668:
1669: case WM_PAINT:
1670: {
1671: PAINTSTRUCT ps;
1672: RECT rc;
1673: char ach[128];
1674: int len, nxBorder, nyBorder;
1675: HFONT hOldFont = NULL;
1676:
1677: BeginPaint(hwnd, &ps);
1678:
1679: GetClientRect(hwnd,&rc);
1680:
1681: nxBorder = GetSystemMetrics(SM_CXBORDER);
1682: rc.left += 9*nxBorder;
1683: rc.right -= 9*nxBorder;
1684:
1685: nyBorder = GetSystemMetrics(SM_CYBORDER);
1686: rc.top += 3*nyBorder;
1687: rc.bottom -= 3*nyBorder;
1688:
1689: // 3D Text
1690: len = GetWindowText(hwnd, ach, sizeof(ach));
1691: SetBkColor(ps.hdc, GetSysColor(COLOR_BTNFACE));
1692:
1693: SetBkMode(ps.hdc, TRANSPARENT);
1694: SetTextColor(ps.hdc, RGB(64,96,96));
1695: if (hFont)
1696: hOldFont = SelectObject(ps.hdc, hFont);
1697: ExtTextOut(ps.hdc, rc.left+2*nxBorder+2, rc.top+2, ETO_OPAQUE | ETO_CLIPPED,
1698: &rc, ach, len, NULL);
1699:
1700: SetTextColor(ps.hdc, RGB(128,128,128));
1701: if (hFont)
1702: hOldFont = SelectObject(ps.hdc, hFont);
1703: ExtTextOut(ps.hdc, rc.left+2*nxBorder+1, rc.top+1, ETO_CLIPPED,
1704: &rc, ach, len, NULL);
1705:
1706: SetTextColor(ps.hdc, RGB(255,255,255));
1707: if (hFont)
1708: hOldFont = SelectObject(ps.hdc, hFont);
1709: ExtTextOut(ps.hdc, rc.left+2*nxBorder, rc.top, ETO_CLIPPED,
1710: &rc, ach, len, NULL);
1711:
1712: SetBkMode(ps.hdc, OPAQUE);
1713:
1714: if (hOldFont)
1715: SelectObject(ps.hdc, hOldFont);
1716:
1717: EndPaint(hwnd, &ps);
1718: return 0L;
1719: }
1720: }
1721: return DefWindowProc(hwnd, message, wParam, lParam);
1722: }
1723:
1724:
1725: /**************************************************************************\
1726: *
1727: * JuliaWndProc
1728: *
1729: * History:
1730: * 14-Jun-1992 -by- Petrus Wong removed pens except red & black
1731: * 22-Nov-1991 -by- Petrus Wong
1732: * Wrote it.
1733: \**************************************************************************/
1734:
1735: LONG JuliaWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam)
1736: {
1737: //
1738: // These statics are shared by all the Julia windows. But, this is
1739: // fine because only one Julia window is tracking at any one time.
1740: // Ideally, we should place this in the per-window INFO data structure.
1741: // But, this is not necessary.
1742: //
1743: static BOOL bTrack = FALSE;
1744: static int OrgX, OrgY;
1745: static int PrevX, PrevY;
1746: static HDC hDC;
1747: static HCURSOR hCurArrow, hCurPaintCan;
1748:
1749: switch (message)
1750: {
1751: case WM_CREATE: {
1752:
1753: hpnRed = CreatePen(PS_SOLID, 0, RGB(0xFF, 0, 0));
1754: hpnGreen = CreatePen(PS_SOLID, 0, RGB(0, 0xFF, 0));
1755: hpnBlack = CreatePen(PS_SOLID, 0, RGB(0, 0, 0));
1756:
1757: hCurPaintCan = LoadCursor(ghModule, MAKEINTRESOURCE(PAINTCURSOR));
1758: hCurArrow = LoadCursor(NULL, IDC_ARROW);
1759: break;
1760: }
1761:
1762: case WM_DESTROY: {
1763:
1764: DeleteObject(hpnRed);
1765: DeleteObject(hpnGreen);
1766: DeleteObject(hpnBlack);
1767: break;
1768: }
1769: case WM_PAINT:
1770: {
1771: PAINTSTRUCT ps;
1772: HWND hParent;
1773: PINFO pInfo;
1774: HDC hDC;
1775: RECT rc;
1776:
1777: GetClientRect(hwnd,&rc);
1778: hDC = BeginPaint(hwnd, &ps);
1779: EndPaint(hwnd, &ps);
1780: if ((hParent=GetParent(hwnd)) == NULL) {
1781: MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
1782: return 0L;
1783: }
1784: if ((pInfo = pGetInfoData(hParent)) == NULL) {
1785: return 0L;
1786: }
1787:
1788: if (pInfo->hBmpSaved) {
1789: hDC = GetDC(hwnd);
1790: DrawBitmap(hDC, pInfo, 0, 0, rc.right, rc.bottom);
1791: ReleaseDC(hwnd, hDC);
1792: }
1793: bReleaseInfoData(hParent);
1794:
1795: //EndPaint(hwnd, &ps);
1796: return 0L;
1797: }
1798:
1799: case WM_RBUTTONDOWN: {
1800: RECT rc;
1801: HANDLE hParent;
1802: PINFO pInfo;
1803: int x, y;
1804: HWND hJulia;
1805: HANDLE hTextWnd;
1806:
1807: x = (int) LOWORD(lParam);
1808: y = (int) HIWORD(lParam);
1809: if ((hParent=GetParent(hwnd)) == NULL) {
1810: MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
1811: break;
1812: }
1813:
1814: if ((pInfo = pGetInfoData(hParent)) == NULL) {
1815: break;
1816: }
1817:
1818: hTextWnd = pInfo->hTextWnd;
1819:
1820: if (GetWindowLong(GetParent(hwnd), GWL_STYLE) & WS_MAXIMIZE) {
1821: GetClientRect(ghwndMain, &rc);
1822: rc.bottom -= GetWindowLong(hTextWnd,GWL_USERDATA);
1823: } else {
1824: GetClientRect(hwnd, &rc);
1825: }
1826:
1827: if (pInfo->bMandel) {
1828:
1829: hJulia = (HWND) SendMessage(ghwndMain, WM_COMMAND,
1830: (DWORD)((WORD)MM_JULIA), 0L);
1831: if (hJulia) {
1832: //GetClientRect(hwnd, &rc);
1833: //
1834: // calculate the c value corresponding to the point
1835: //
1836: c1 = Xform((double) x, 0.0, (double) rc.right, pInfo->xFrom, pInfo->xTo);
1837: c2 = Xform((double) y, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo);
1838: lc1 = XformFix(x, 0, rc.right, pInfo->lxFrom, pInfo->lxTo);
1839: lc2 = XformFix(y, 0, rc.bottom, pInfo->lyFrom, pInfo->lyTo);
1840:
1841: sprintf( gtext,"(c1 = %g, c2 = %g)\n", c1, c2);
1842: OutputDebugString( gtext );
1843:
1844: //
1845: // Reset globals to default values for creating Julia set
1846: // (Entire set, not zoom in)
1847: //
1848: bResetGlobal();
1849: PostMessage(hJulia, WM_COMMAND, (DWORD)((WORD) MM_SET_XFORM_ATTR), 0L);
1850: } else {
1851: MessageBox(ghwndMain, "Can't create hJulia!", "Error", MB_OK);
1852: }
1853: }
1854: bReleaseInfoData(hParent);
1855: break;
1856: }
1857: case WM_LBUTTONDOWN: {
1858: HANDLE hParent;
1859: PINFO pInfo;
1860: int x, y;
1861: DWORD dwRGB;
1862: HBRUSH hBrOld;
1863:
1864: x = (int) LOWORD(lParam);
1865: y = (int) HIWORD(lParam);
1866: if ((hParent=GetParent(hwnd)) == NULL) {
1867: MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
1868: break;
1869: }
1870:
1871: if ((pInfo = pGetInfoData(hParent)) == NULL) {
1872: break;
1873: }
1874:
1875: if (pInfo->bFill) {
1876: hDC = GetDC(hwnd);
1877: hBrOld = SelectObject(hDC, pInfo->hBrush);
1878: dwRGB = GetPixel(hDC, x, y);
1879: ExtFloodFill(hDC, x, y, (COLORREF)dwRGB, FLOODFILLSURFACE);
1880: SelectObject(hDC, hBrOld);
1881: ReleaseDC(hwnd, hDC);
1882: pInfo->bFill = FALSE;
1883:
1884: if (pInfo->hBmpSaved)
1885: DeleteObject(pInfo->hBmpSaved);
1886:
1887: pInfo->hBmpSaved = SaveBitmap(hwnd);
1888: SetCursor(hCurArrow);
1889: } else {
1890: bTrack = TRUE;
1891: OrgX = PrevX = x = LOWORD(lParam);
1892: OrgY = PrevY = y = HIWORD(lParam);
1893:
1894: hDC = GetDC(hwnd);
1895: SetCapture(hwnd);
1896: }
1897: bReleaseInfoData(hParent);
1898: break;
1899: }
1900: case WM_MOUSEMOVE: {
1901: RECT rectClient;
1902: int NextX;
1903: int NextY;
1904: HANDLE hParent;
1905: PINFO pInfo;
1906:
1907: if ((hParent=GetParent(hwnd)) == NULL) {
1908: MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
1909: break;
1910: }
1911:
1912: if ((pInfo = pGetInfoData(hParent)) == NULL) {
1913: break;
1914: }
1915:
1916: if (pInfo->bFill) {
1917: SetCursor(hCurPaintCan);
1918: } else {
1919: SetCursor(hCurArrow);
1920: }
1921:
1922: bReleaseInfoData(hParent);
1923:
1924: // Update the selection region
1925: if (bTrack) {
1926: NextX = (SHORT) LOWORD(lParam);
1927: NextY = (SHORT) HIWORD(lParam);
1928:
1929: // Do not draw outside the window's client area
1930:
1931: GetClientRect (hwnd, &rectClient);
1932: if (NextX < rectClient.left) {
1933: NextX = rectClient.left;
1934: } else if (NextX >= rectClient.right) {
1935: NextX = rectClient.right - 1;
1936: }
1937: if (NextY < rectClient.top) {
1938: NextY = rectClient.top;
1939: } else if (NextY >= rectClient.bottom) {
1940: NextY = rectClient.bottom - 1;
1941: }
1942: if ((NextX != PrevX) || (NextY != PrevY)) {
1943: SetROP2(hDC, R2_NOT); // Erases the previous box
1944:
1945: MoveToEx(hDC, OrgX, OrgY, NULL);
1946: LineTo(hDC, OrgX, PrevY);
1947: LineTo(hDC, PrevX, PrevY);
1948: LineTo(hDC, PrevX, OrgY);
1949: LineTo(hDC, OrgX, OrgY);
1950: // Get the current mouse position
1951:
1952: PrevX = NextX;
1953: PrevY = NextY;
1954: MoveToEx(hDC, OrgX, OrgY, NULL); // Draws the new box
1955: LineTo(hDC, OrgX, PrevY);
1956: LineTo(hDC, PrevX, PrevY);
1957: LineTo(hDC, PrevX, OrgY);
1958: LineTo(hDC, OrgX, OrgY);
1959: }
1960: }
1961: break;
1962:
1963: }
1964:
1965: case WM_LBUTTONUP: {
1966: RECT rc;
1967: HANDLE hParent;
1968: PINFO pInfo;
1969: int NextX;
1970: int NextY;
1971: int iDistX, iDistY, iAbsDstX, iAbsDstY;
1972: HWND hZoom;
1973: HANDLE hTextWnd;
1974:
1975: if (!bTrack)
1976: break;
1977:
1978: // End the selection
1979: ReleaseCapture();
1980: bTrack = FALSE;
1981:
1982: MoveToEx(hDC, OrgX, OrgY, NULL); // Erases the box
1983: LineTo(hDC, OrgX, PrevY);
1984: LineTo(hDC, PrevX, PrevY);
1985: LineTo(hDC, PrevX, OrgY);
1986: LineTo(hDC, OrgX, OrgY);
1987:
1988: NextX = LOWORD(lParam);
1989: NextY = HIWORD(lParam);
1990:
1991: iDistX = NextX - OrgX;
1992: iDistY = NextY - OrgY;
1993: iAbsDstX = (iDistX > 0 ? iDistX : -iDistX);
1994: iAbsDstY = (iDistY > 0 ? iDistY : -iDistY);
1995: if (iAbsDstX > iAbsDstY) {
1996: NextY = OrgY + (iDistY > 0 ? iAbsDstX : -iAbsDstX);
1997: } else if (iAbsDstX < iAbsDstY) {
1998: NextX = OrgX + (iDistX > 0 ? iAbsDstY : -iAbsDstY);
1999: }
2000:
2001: MoveToEx(hDC, OrgX, OrgY, NULL); // Draws the new box
2002: LineTo(hDC, OrgX, NextY);
2003: LineTo(hDC, NextX, NextY);
2004: LineTo(hDC, NextX, OrgY);
2005: LineTo(hDC, OrgX, OrgY);
2006:
2007: SetROP2(hDC, R2_COPYPEN);
2008:
2009: ReleaseDC(hwnd, hDC);
2010: if ((hParent=GetParent(hwnd)) == NULL) {
2011: MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
2012: break;
2013: }
2014:
2015: if ((pInfo = pGetInfoData(hParent)) == NULL) {
2016: break;
2017: }
2018:
2019: hTextWnd = pInfo->hTextWnd;
2020: sprintf(gtext, "Mouse (%d, %d), (%d, %d)\n", OrgX, OrgY, NextX, NextY);
2021: //SetWindowText(hTextWnd, gtext);
2022: OutputDebugString(gtext);
2023:
2024:
2025: if (GetWindowLong(GetParent(hwnd), GWL_STYLE) & WS_MAXIMIZE) {
2026:
2027: GetClientRect(ghwndMain, &rc);
2028: rc.bottom -= GetWindowLong(hTextWnd,GWL_USERDATA);
2029: sprintf(gtext, "(%d, %d), (%d, %d)\n", rc.left, rc.top, rc.right, rc.bottom);
2030: //SetWindowText(hTextWnd, gtext);
2031: OutputDebugString(gtext);
2032:
2033: } else {
2034: GetClientRect(hwnd, &rc);
2035: }
2036:
2037: if ((OrgX == NextX) && (OrgY == NextY)) {
2038: bReleaseInfoData(hParent);
2039: break;
2040: }
2041:
2042: hZoom = (HWND) SendMessage(ghwndMain, WM_COMMAND,
2043: pInfo->bMandel ? (DWORD)((WORD)MM_MANDEL) : (DWORD)((WORD)MM_JULIA),
2044: 0L);
2045: if (hZoom) {
2046: //GetClientRect(hwnd, &rc);
2047: xFrom = Xform((double) OrgX, 0.0, (double) rc.right, pInfo->xFrom, pInfo->xTo);
2048: xTo = Xform((double) NextX, 0.0, (double) rc.right, pInfo->xFrom, pInfo->xTo);
2049: yFrom = Xform((double) OrgY, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo);
2050: yTo = Xform((double) NextY, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo);
2051: lxFrom = XformFix(OrgX, 0, rc.right, pInfo->lxFrom, pInfo->lxTo);
2052: lxTo = XformFix(NextX, 0, rc.right, pInfo->lxFrom, pInfo->lxTo);
2053: lyFrom = XformFix(OrgY, 0, rc.bottom, pInfo->lyFrom, pInfo->lyTo);
2054: lyTo = XformFix(NextY, 0, rc.bottom, pInfo->lyFrom, pInfo->lyTo);
2055: if (!pInfo->bMandel) {
2056: c1 = pInfo->c1;
2057: c2 = pInfo->c2;
2058: lc1 = pInfo->lc1;
2059: lc2 = pInfo->lc2;
2060: }
2061: PostMessage(hZoom, WM_COMMAND, (DWORD)((WORD) MM_SET_XFORM_ATTR), 0L);
2062: } else {
2063: MessageBox(ghwndMain, "Can't create hZoom!", "Error", MB_OK);
2064: }
2065: bReleaseInfoData(hParent);
2066: break;
2067: } // case WM_LBUTTONUP
2068: } // switch
2069: return DefWindowProc(hwnd, message, wParam, lParam);
2070: }
2071:
2072:
2073: /******************************Public*Routine******************************\
2074: *
2075: * SuspendDrawThrd
2076: *
2077: * Effects: Enumerates all the MDI children. Suspending the drawing thread
2078: * in those windows, if any.
2079: *
2080: * Warnings: assumes the MDI children has class name "ChildClass."
2081: *
2082: * History:
2083: * 09-Dec-1991 -by- Petrus Wong
2084: * Wrote it.
2085: \**************************************************************************/
2086:
2087:
2088: BOOL APIENTRY SuspendDrawThrd (HWND hwnd, LONG lParam) {
2089: HANDLE hThrd;
2090: PINFO pInfo;
2091: DWORD dwSuspend;
2092: BOOL bDrawing;
2093: char sz[30];
2094:
2095: GetClassName(hwnd, sz, 15);
2096: if (strcmp(sz, "ChildClass") != 0)
2097: return 1L;
2098: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
2099: return 1L;
2100: }
2101:
2102: bDrawing = pInfo->bDrawing;
2103: hThrd = pInfo->hThrd;
2104: bReleaseInfoData(hwnd);
2105:
2106: if (hThrd && bDrawing) {
2107: dwSuspend = SuspendThread(hThrd);
2108: sprintf( gtext,"\nSuspend: dwSuspend = %d, dwSuspend = %g\n", dwSuspend, dwSuspend);
2109: OutputDebugString( gtext );
2110:
2111: if (dwSuspend == -1) {
2112: sprintf( gtext,"Error in suspending thread\n");
2113: OutputDebugString( gtext );
2114: }
2115: }
2116: return 1L;
2117: UNREFERENCED_PARAMETER(lParam);
2118: }
2119:
2120:
2121: /******************************Public*Routine******************************\
2122: *
2123: * ResumeDrawThrd
2124: *
2125: * Effects: Enumerates all the MDI children. Resuming the drawing thread
2126: * in those windows, if any.
2127: *
2128: * Warnings: Assumes the MDI children has class name "ChildClass." Also,
2129: * assumes the drawing has been suspended by SuspendDrawThrd.
2130: *
2131: * History:
2132: * 09-Dec-1991 -by- Petrus Wong
2133: * Wrote it.
2134: \**************************************************************************/
2135:
2136:
2137: BOOL APIENTRY ResumeDrawThrd (HWND hwnd, LONG lParam) {
2138: HANDLE hThrd;
2139: PINFO pInfo;
2140: DWORD dwSuspend;
2141: BOOL bDrawing;
2142: char sz[30];
2143:
2144: GetClassName(hwnd, sz, 15);
2145: if (strcmp(sz, "ChildClass") != 0)
2146: return 1L;
2147: if ((pInfo = pGetInfoData(hwnd)) == NULL) {
2148: return 1L;
2149: }
2150:
2151: bDrawing = pInfo->bDrawing;
2152: hThrd = pInfo->hThrd;
2153: bReleaseInfoData(hwnd);
2154:
2155: if (hThrd && bDrawing) {
2156: dwSuspend = ResumeThread(hThrd);
2157: sprintf( gtext,"Resume: dwSuspend = %d, dwSuspend = %g\n", dwSuspend, dwSuspend);
2158: OutputDebugString( gtext );
2159:
2160: if (dwSuspend == -1) {
2161: sprintf( gtext,"Error in resuming thread\n");
2162: OutputDebugString( gtext );
2163: }
2164: }
2165: return 1L;
2166: UNREFERENCED_PARAMETER(lParam);
2167: }
2168:
2169:
2170: /******************************Public*Routine******************************\
2171: *
2172: * lMul
2173: *
2174: * Effects: Fix point multiplication
2175: *
2176: * Warnings: 20.11 fix point representation used. This is only good for
2177: * multiplication in a limited range. Will overflow.
2178: * CR! Will be implemented as macros in the future
2179: *
2180: * History:
2181: * 20-Nov-1991 -by- Petrus Wong
2182: * Wrote it.
2183: \**************************************************************************/
2184:
2185: LONG lMul(LONG l1, LONG l2)
2186: {
2187: return( (l1 * l2) >> 11);
2188: }
2189:
2190: /******************************Public*Routine******************************\
2191: *
2192: * lDiv
2193: *
2194: * Effects: fix point division
2195: *
2196: * Warnings: 20.11 fix point representation used. This is only good for
2197: * division in a limited range. Will overflow.
2198: * CR! Will be implemented as macros in the future
2199: *
2200: * History:
2201: * 20-Nov-1991 -by- Petrus Wong
2202: * Wrote it.
2203: \**************************************************************************/
2204:
2205: LONG lDiv(long l1, long l2)
2206: {
2207: return( (l1 << 11) / l2);
2208: }
2209:
2210:
2211: /**************************************************************************\
2212: *
2213: * StartDrawFix
2214: * 2
2215: * Effects: Draw'g the Julia Set for Q (z) = z + c, where z, c are complex
2216: * c
2217: * Fact: |Q (0)| = |c| > 2, the orbit of 0 escapes immediately
2218: * c
2219: * claim: |z| >= |c| = 2 + l, l > 0 escapes under Q
2220: * c
2221: * The Julia Set: Basin Boundaries algorithm.
2222: *
2223: * Warnings:
2224: *
2225: * History:
2226: * 14-Jun-1992 -by- Petrus Wong Modified to use the pen array
2227: * 20-Nov-1991 -by- Petrus Wong
2228: * Wrote it.
2229: \**************************************************************************/
2230: BOOL StartDrawFix(PINFO pInfo)
2231: {
2232: DWORD dwTick1;
2233: HDC hDC;
2234: RECT rc;
2235:
2236: int m, n, i, iPrev;
2237: int xCurr, yCurr;
2238: int iPen;
2239:
2240: LONG c1, c2;
2241: LONG x0, y0, x1, y1, x, y, z;
2242:
2243: iPen = giPen + 1;
2244: iPrev = FIRST_PIXEL; // a big value to signal the first pixel
2245: //iPrev = pInfo->iIteration + FIRST_PIXEL;
2246: c1 = pInfo->lc1;
2247: c2 = pInfo->lc2;
2248:
2249: pInfo->bMandel = FALSE;
2250: pInfo->bDrawing = TRUE;
2251: hDC = GetDC(pInfo->hwnd);
2252:
2253: GetClientRect(pInfo->hwnd, &rc);
2254: yCurr = rc.top;
2255:
2256: dwTick1 = GetTickCount();
2257:
2258: for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) {
2259: xCurr = rc.left; // since LineTo excludes last point
2260: MoveToEx(hDC, 0, yCurr, NULL);
2261: y0 = XformFix(n, rc.top, rc.bottom, pInfo->lyFrom, pInfo->lyTo);
2262:
2263: for (m=rc.left; m<=rc.right; m++, xCurr++) {
2264: x0 = XformFix(m, rc.left, rc.right, pInfo->lxFrom, pInfo->lxTo);
2265: x = x0;
2266: y = y0;
2267:
2268: for (i=1; i<=pInfo->iIteration; i++) {
2269: x1 = lMul(x - y, x + y) + c1; // Z = x1 + i x2
2270:
2271: y1 = (lMul(x, y) * 2) + c2;
2272: x = x1;
2273: y = y1; // 2 2 2 1/2 2
2274: z = lMul(x, x) + lMul(y, y); // |Z| = ((x1 + x2 ) ) > 2
2275:
2276: if (z > 8192)
2277: break;
2278: }
2279:
2280: if (i != iPrev)
2281: {
2282: if (iPrev != FIRST_PIXEL)
2283: {
2284: switch(iPrev)
2285: {
2286: case 1: SelectObject(hDC, hpnRed); break;
2287: default:
2288:
2289: if (iPrev >= pInfo->iIteration) {
2290: SelectObject(hDC, hpnBlack);
2291: break;
2292: }
2293: SelectObject(hDC, (HPEN)gprghPen[iPrev % iPen]);
2294: break;
2295: }
2296: iPrev = i;
2297: LineTo(hDC,xCurr,yCurr);
2298: }
2299: else
2300: iPrev = i; // remember the color for the first pixel
2301: }
2302: }
2303: switch(i)
2304: {
2305: case 1: SelectObject(hDC, hpnRed); break;
2306: default:
2307: if (iPrev >= pInfo->iIteration) {
2308: SelectObject(hDC, hpnBlack);
2309: break;
2310: }
2311: SelectObject(hDC, (HPEN)gprghPen[i % iPen]);
2312: break;
2313: }
2314:
2315: LineTo(hDC,xCurr,yCurr);
2316: }
2317: ReleaseDC(pInfo->hwnd, hDC);
2318:
2319: pInfo->dwElapsed = GetTickCount() - dwTick1;
2320:
2321: if (pInfo->hBmpSaved)
2322: DeleteObject(pInfo->hBmpSaved);
2323:
2324: pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd);
2325: pInfo->bDrawing = FALSE;
2326:
2327: ExitThread(0);
2328: if (!CloseHandle(pInfo->hThrd))
2329: MessageBox(ghwndMain, "Failed in CloseHandle!", "Error", MB_OK);
2330:
2331: return TRUE;
2332: }
2333:
2334: /**************************************************************************\
2335: *
2336: * StartDraw
2337: * 2
2338: * Effects: Draw'g the Julia Set for Q (z) = z + c, where z, c are complex
2339: * c
2340: * Fact: |Q (0)| = |c| > 2, the orbit of 0 escapes immediately
2341: * c
2342: * claim: |z| >= |c| = 2 + l, l > 0 escapes under Q
2343: * c
2344: * The Julia Set: Basin Boundaries algorithm.
2345: *
2346: * Warnings:
2347: *
2348: * History:
2349: * 14-Jun-1992 -by- Petrus Wong Modified to use the pen array and LineTo
2350: * 20-Nov-1991 -by- Petrus Wong
2351: * Wrote it.
2352: \**************************************************************************/
2353: BOOL StartDraw(PINFO pInfo)
2354: {
2355: DWORD dwTick1;
2356: HDC hDC;
2357: RECT rc;
2358:
2359: int m, n, i, iPrev;
2360: int xCurr, yCurr;
2361: int iPen;
2362:
2363: double c1, c2;
2364: double x0, y0, x1, y1, x, y, z;
2365:
2366:
2367: iPen = giPen + 1;
2368: iPrev = FIRST_PIXEL; // a big value to signal the first pixel
2369: //iPrev = pInfo->iIteration + FIRST_PIXEL;
2370: c1 = pInfo->c1;
2371: c2 = pInfo->c2;
2372:
2373: pInfo->bMandel = FALSE;
2374: pInfo->bDrawing = TRUE;
2375: hDC = GetDC(pInfo->hwnd);
2376:
2377: GetClientRect(pInfo->hwnd, &rc);
2378: yCurr = rc.top;
2379:
2380: dwTick1 = GetTickCount();
2381:
2382: for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) {
2383: xCurr = rc.left; // since LineTo excludes last point
2384: MoveToEx(hDC, 0, yCurr, NULL);
2385: y0 = Xform((double) n, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo);
2386:
2387: for (m=rc.left; m<=rc.right; m++, xCurr++) {
2388: x0 = Xform((double) m, 0.0, (double) rc.right, pInfo->xFrom, pInfo->xTo);
2389: x = x0;
2390: y = y0;
2391:
2392: for (i=1; i<=pInfo->iIteration; i++) {
2393: x1 = (x - y) * (x + y) + c1; // Z = x1 + i x2
2394:
2395: y1 = 2 * x * y + c2;
2396: x = x1;
2397: y = y1; // 2 2 2 1/2 2
2398: z = x * x + y * y; // |Z| = ((x1 + x2 ) ) > 2
2399:
2400: if (z > 4.0)
2401: break;
2402: }
2403:
2404: if (i != iPrev)
2405: {
2406: if (iPrev != FIRST_PIXEL)
2407: {
2408: switch(iPrev)
2409: {
2410: case 1: SelectObject(hDC, hpnRed); break;
2411: default:
2412:
2413: if (iPrev >= pInfo->iIteration) {
2414: SelectObject(hDC, hpnBlack);
2415: break;
2416: }
2417: SelectObject(hDC, (HPEN)gprghPen[iPrev % iPen]);
2418: break;
2419: }
2420: iPrev = i;
2421: LineTo(hDC,xCurr,yCurr);
2422: }
2423: else
2424: iPrev = i; // remember the color for the first pixel
2425: }
2426: }
2427: switch(i)
2428: {
2429: case 1: SelectObject(hDC, hpnRed); break;
2430: default:
2431: if (iPrev >= pInfo->iIteration) {
2432: SelectObject(hDC, hpnBlack);
2433: break;
2434: }
2435: SelectObject(hDC, (HPEN)gprghPen[i % iPen]);
2436: break;
2437: }
2438:
2439: LineTo(hDC,xCurr,yCurr);
2440: }
2441: ReleaseDC(pInfo->hwnd, hDC);
2442:
2443: pInfo->dwElapsed = GetTickCount() - dwTick1;
2444:
2445: if (pInfo->hBmpSaved)
2446: DeleteObject(pInfo->hBmpSaved);
2447:
2448: pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd);
2449: pInfo->bDrawing = FALSE;
2450:
2451: ExitThread(0);
2452: if (!CloseHandle(pInfo->hThrd))
2453: MessageBox(ghwndMain, "Failed in CloseHandle!", "Error", MB_OK);
2454:
2455: return TRUE;
2456: }
2457:
2458: /**************************************************************************\
2459: *
2460: * StartDraw2
2461: * 2
2462: * Effects: Draw'g the Julia Set for Q (z) = z + c, where z, c are complex
2463: *
2464: * The Julia Set: Backward iteration algorithm.
2465: *
2466: * Warnings:
2467: *
2468: * History:
2469: * 20-Nov-1991 -by- Petrus Wong
2470: * Wrote it.
2471: \**************************************************************************/
2472:
2473: BOOL StartDraw2(PINFO pInfo)
2474: {
2475: HDC hDC;
2476: RECT rc;
2477: int m, n, i;
2478: double c1, c2;
2479: double x0, y0, w0, w1, pi, theta, r;
2480:
2481: pi = 22.0/7.0;
2482: c1 = 0.360284;
2483: c2 = 0.100376;
2484: x0 = 1.5;
2485: y0 = 1.5;
2486:
2487: hDC = GetDC(pInfo->hwnd);
2488:
2489: GetClientRect(pInfo->hwnd, &rc);
2490: for (i=0; i<=15000; i++) {
2491: w0 = x0 - c1;
2492: w1 = y0 - c2;
2493: sprintf( gtext,"w(%g, %g) xy(%g, %g)\n", w0, w1, x0, y0);
2494: OutputDebugString( gtext );
2495:
2496: if (w0 == 0.0) {
2497: theta = pi/2;
2498: sprintf( gtext,"(w0 == 0.0) theta = %g\n\n", theta);
2499: OutputDebugString( gtext );
2500:
2501: } else {
2502: if (w0 > 0.0) {
2503: theta = atan(w1/w0);
2504: sprintf( gtext,"(w0 > 0.0) theta = %g\n\n", theta);
2505: OutputDebugString( gtext );
2506:
2507: } else { // w0 < 0.0
2508: theta = pi + atan(w1/w0);
2509: sprintf( gtext,"(w0 < 0.0) theta = %g\n\n", theta);
2510: OutputDebugString( gtext );
2511: }
2512: }
2513: r = sqrt(w0 * w0 + w1 + w1);
2514: theta = theta/2.0 + ((int) ((2.0*rand()/(RAND_MAX+1.0)))*pi);
2515: r = sqrt(r);
2516: x0 = r*cos(theta);
2517: y0 = r*sin(theta);
2518: if (i > 50) {
2519: m = Xform2(x0, pInfo->xFrom, pInfo->xTo, 0.0, (double) rc.right);
2520: n = Xform2(y0, pInfo->yFrom, pInfo->yTo, 0.0, (double) rc.bottom);
2521: SetPixel(hDC, m, n, 0x000000ff);
2522: }
2523: }
2524:
2525: ReleaseDC(pInfo->hwnd, hDC);
2526:
2527: ExitThread(0);
2528: if (!CloseHandle(pInfo->hThrd))
2529: MessageBox(ghwndMain, "Failed in CloseHandle!", "Error", MB_OK);
2530:
2531: return TRUE;
2532: }
2533:
2534: /**************************************************************************\
2535: *
2536: * StartMandelbrotFix
2537: * 2
2538: * Effects: Draw'g the Mandelbrot Set for Q (z) = z + c, where z, c complex
2539: *
2540: * Warnings:
2541: *
2542: * History:
2543: * 14-Jun-1992 -by- Petrus Wong Modified to use the pen array
2544: * 20-Nov-1991 -by- Petrus Wong
2545: * Wrote it.
2546: \**************************************************************************/
2547: BOOL StartMandelbrotFix(PINFO pInfo)
2548: {
2549: DWORD dwTick1;
2550: HDC hDC;
2551: RECT rc;
2552: int m, n, i, iPrev;
2553: int xCurr, yCurr;
2554: int iPen;
2555:
2556: LONG c1, c2;
2557: LONG x1, y1, x, y, r;
2558:
2559: iPen = giPen + 1;
2560: pInfo->bMandel = TRUE;
2561: pInfo->bDrawing = TRUE;
2562: hDC = GetDC(pInfo->hwnd);
2563:
2564: GetClientRect(pInfo->hwnd, &rc);
2565:
2566: dwTick1 = GetTickCount();
2567: yCurr = rc.top;
2568: for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) {
2569: xCurr = rc.left; // since LineTo excludes last point
2570: MoveToEx(hDC, 0, yCurr, NULL);
2571: c2 = XformFix(n, rc.top, rc.bottom, pInfo->lyFrom, pInfo->lyTo);
2572:
2573: for (m=rc.left; m<=rc.right; m++, xCurr++) {
2574: c1 = XformFix(m, rc.left, rc.right, pInfo->lxFrom, pInfo->lxTo);
2575: x = c1;
2576: y = c2;
2577:
2578: for (i=1; i<=pInfo->iIteration; i++) {
2579: x1 = lMul(x - y, x + y) + c1;
2580: y1 = (lMul(x, y) * 2) + c2;
2581: r = lMul(x1, x1) + lMul(y1, y1);
2582: x = x1;
2583: y = y1;
2584: if (r > 8192) {
2585: break;
2586: }
2587: }
2588:
2589: if (i != iPrev) {
2590: if (iPrev != FIRST_PIXEL) {
2591: switch(iPrev) {
2592: case 1: SelectObject(hDC, hpnRed); break;
2593: default:
2594: if (iPrev >= pInfo->iIteration) {
2595: SelectObject(hDC, hpnBlack);
2596: break;
2597: }
2598: SelectObject(hDC, (HPEN)gprghPen[iPrev % iPen]);
2599: break;
2600: }
2601: iPrev = i;
2602: LineTo(hDC, xCurr, yCurr);
2603: }
2604: else
2605: iPrev = i; // remember the color for the first pixel
2606: }
2607: }
2608:
2609: switch(i)
2610: {
2611: case 1: SelectObject(hDC, hpnRed); break;
2612: default:
2613: if (i >= pInfo->iIteration) {
2614: SelectObject(hDC, hpnBlack);
2615: break;
2616: }
2617: SelectObject(hDC, (HPEN)gprghPen[i % iPen]);
2618: break;
2619: }
2620:
2621: LineTo(hDC,xCurr,yCurr);
2622:
2623: }
2624: ReleaseDC(pInfo->hwnd, hDC);
2625:
2626: pInfo->dwElapsed = GetTickCount() - dwTick1;
2627:
2628: if (pInfo->hBmpSaved)
2629: DeleteObject(pInfo->hBmpSaved);
2630:
2631: pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd);
2632: pInfo->bDrawing = FALSE;
2633:
2634: ExitThread(0);
2635: if (!CloseHandle(pInfo->hThrd))
2636: MessageBox(ghwndMain, "Failed in CloseHandle!", "Error", MB_OK);
2637:
2638: return TRUE;
2639: }
2640:
2641: /**************************************************************************\
2642: *
2643: * StartMandelbrot
2644: * 2
2645: * Effects: Draw'g the Mandelbrot Set for Q (z) = z + c, where z, c complex
2646: *
2647: * Warnings:
2648: *
2649: * History:
2650: * 14-Jun-1992 -by- Petrus Wong Modified to use the pen array and LineTo
2651: * 20-Nov-1991 -by- Petrus Wong
2652: * Wrote it.
2653: \**************************************************************************/
2654: BOOL StartMandelbrot(PINFO pInfo)
2655: {
2656: DWORD dwTick1;
2657: HDC hDC;
2658: RECT rc;
2659: int m, n, i, iPrev;
2660: int xCurr, yCurr;
2661: int iPen;
2662:
2663: double c1, c2;
2664: double x1, y1, x, y, r;
2665:
2666: iPen = giPen + 1;
2667: pInfo->bMandel = TRUE;
2668: pInfo->bDrawing = TRUE;
2669: hDC = GetDC(pInfo->hwnd);
2670:
2671: GetClientRect(pInfo->hwnd, &rc);
2672:
2673: dwTick1 = GetTickCount();
2674: yCurr = rc.top;
2675: for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) {
2676: xCurr = rc.left; // since LineTo excludes last point
2677: MoveToEx(hDC, 0, yCurr, NULL);
2678: c2 = Xform((double) n, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo);
2679:
2680: for (m=rc.left; m<=rc.right; m++, xCurr++) {
2681: c1 = Xform((double) m, 0.0, (double) rc.right, pInfo->xFrom, pInfo->xTo);
2682: x = c1;
2683: y = c2;
2684:
2685: for (i=1; i<=pInfo->iIteration; i++) {
2686: x1 = (x - y) * (x + y) + c1;
2687: y1 = 2 * x * y + c2;
2688: r = x1 * x1 + y1 * y1;
2689: x = x1;
2690: y = y1;
2691: if (r > 4.0) {
2692: break;
2693: }
2694: }
2695:
2696: if (i != iPrev) {
2697: if (iPrev != FIRST_PIXEL) {
2698: switch(iPrev) {
2699: case 1: SelectObject(hDC, hpnRed); break;
2700: default:
2701: if (iPrev >= pInfo->iIteration) {
2702: SelectObject(hDC, hpnBlack);
2703: break;
2704: }
2705: SelectObject(hDC, (HPEN)gprghPen[iPrev % iPen]);
2706: break;
2707: }
2708: iPrev = i;
2709: LineTo(hDC, xCurr, yCurr);
2710: }
2711: else
2712: iPrev = i; // remember the color for the first pixel
2713: }
2714: }
2715:
2716: switch(i)
2717: {
2718: case 1: SelectObject(hDC, hpnRed); break;
2719: default:
2720: if (i >= pInfo->iIteration) {
2721: SelectObject(hDC, hpnBlack);
2722: break;
2723: }
2724: SelectObject(hDC, (HPEN)gprghPen[i % iPen]);
2725: break;
2726: }
2727:
2728: LineTo(hDC,xCurr,yCurr);
2729:
2730: }
2731: ReleaseDC(pInfo->hwnd, hDC);
2732:
2733: pInfo->dwElapsed = GetTickCount() - dwTick1;
2734:
2735: if (pInfo->hBmpSaved)
2736: DeleteObject(pInfo->hBmpSaved);
2737:
2738: pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd);
2739: pInfo->bDrawing = FALSE;
2740:
2741: ExitThread(0);
2742: if (!CloseHandle(pInfo->hThrd))
2743: MessageBox(ghwndMain, "Failed in CloseHandle!", "Error", MB_OK);
2744:
2745: return TRUE;
2746: }
2747:
2748:
2749: /******************************Public*Routine******************************\
2750: *
2751: * Xform
2752: *
2753: * Effects: Given m, find x.
2754: *
2755: * Xform(Pt) : Src |--> Dest
2756: * eg.
2757: * Src |----|--------| |--> Dest |----|--------|
2758: * -2 x 2 0 m 320
2759: *
2760: * x = (m - 0)/(320 - 0) * (2 - -2) + -2
2761: *
2762: * Warnings: 1. This will become a macro in the future for speed. For now,
2763: * it is here for debugging purposes.
2764: *
2765: * History:
2766: * 25-Nov-1991 -by- Petrus Wong
2767: * Wrote it.
2768: \**************************************************************************/
2769: #if 0
2770: double Xform(
2771: double Pt,
2772: double SrcFrom,
2773: double SrcTo,
2774: double DestFrom,
2775: double DestTo)
2776: {
2777: //sprintf( gtext,"%g = Xform(%g, %g, %g, %g, %g)\n", ((Pt-SrcFrom)/(SrcTo-SrcFrom)*(DestTo-DestFrom))+DestFrom, Pt, SrcFrom, SrcTo, DestFrom, DestTo);
2778: //OutputDebugString( gtext );
2779: return(((Pt-SrcFrom)/(SrcTo-SrcFrom)*(DestTo-DestFrom))+DestFrom);
2780: }
2781: #endif
2782:
2783: /******************************Public*Routine******************************\
2784: *
2785: * Xform2
2786: *
2787: * Effects: Given x, find m.
2788: *
2789: * Xform(Pt) : Src |--> Dest
2790: * eg.
2791: * Src |----|--------| |--> Dest |----|--------|
2792: * -2 x 2 0 m 320
2793: *
2794: * m = (x - -2)/(2 - -2) * 320
2795: *
2796: * Warnings: 1. This will become a macro in the future for speed. For now,
2797: * it is here for debugging purposes.
2798: *
2799: * History:
2800: * 25-Nov-1991 -by- Petrus Wong
2801: * Wrote it.
2802: \**************************************************************************/
2803: #if 0
2804: int Xform2(
2805: double Pt,
2806: double SrcFrom,
2807: double SrcTo,
2808: double DestFrom,
2809: double DestTo)
2810: {
2811: //sprintf( gtext,"%g = Xform(%g, %g, %g, %g, %g)\n", ((Pt-SrcFrom)/(SrcTo-SrcFrom)*(DestTo-DestFrom))+DestFrom, Pt, SrcFrom, SrcTo, DestFrom, DestTo);
2812: //OutputDebugString( gtext );
2813: return((int) ((Pt-SrcFrom)/(SrcTo-SrcFrom)*(DestTo-DestFrom)+DestFrom));
2814: }
2815: #endif
2816:
2817: /******************************Public*Routine******************************\
2818: *
2819: * SaveBitmap
2820: *
2821: * Effects: Returns the handle of a bitmap corresponding to the window.
2822: * using utilizing BitBlt.
2823: *
2824: * Warnings:
2825: *
2826: * History:
2827: * 03-Dec-1991 -by- Petrus Wong
2828: * Wrote it.
2829: \**************************************************************************/
2830:
2831: HBITMAP SaveBitmap(HWND hWnd) {
2832: HDC hdcMem, hDC;
2833: HBITMAP hBitmap, hOldBitmap;
2834: RECT rc;
2835:
2836: hDC = GetDC(hWnd);
2837: GetClientRect(hWnd, &rc);
2838:
2839: hdcMem = CreateCompatibleDC(hDC);
2840:
2841: hBitmap = CreateCompatibleBitmap(hDC, (int)rc.right-rc.left, (int)rc.bottom-rc.top);
2842:
2843: hOldBitmap = SelectObject(hdcMem, hBitmap);
2844: BitBlt(hdcMem, 0, 0, (int)rc.right-rc.left, (int)rc.bottom-rc.top, hDC, 0, 0, SRCCOPY);
2845: hBitmap = SelectObject(hdcMem, hOldBitmap);
2846:
2847: DeleteDC(hdcMem);
2848: ReleaseDC(hWnd, hDC);
2849:
2850: return(hBitmap);
2851:
2852: }
2853:
2854: /******************************Public*Routine******************************\
2855: *
2856: * DrawBitmap
2857: *
2858: * Effects:
2859: *
2860: * Warnings:
2861: *
2862: * History:
2863: * 03-Dec-1991 -by- Petrus Wong
2864: * Wrote it.
2865: \**************************************************************************/
2866:
2867: void DrawBitmap(HDC hdc, PINFO pInfo, int xStart, int yStart, int cx, int cy) {
2868: BITMAP bm;
2869: HDC hdcMem;
2870: POINT ptSize, ptOrg;
2871:
2872: hdcMem = CreateCompatibleDC(hdc);
2873: SelectObject(hdcMem, (pInfo->bUseMono ? pInfo->hBmpMono : pInfo->hBmpSaved));
2874: SetMapMode(hdcMem, GetMapMode(hdc));
2875:
2876: GetObject((pInfo->bUseMono ? pInfo->hBmpMono : pInfo->hBmpSaved), sizeof(BITMAP), (LPSTR)&bm);
2877: ptSize.x = bm.bmWidth;
2878: ptSize.y = bm.bmHeight;
2879: DPtoLP(hdc, &ptSize, 1);
2880:
2881: ptOrg.x = 0;
2882: ptOrg.y = 0;
2883: DPtoLP(hdcMem, &ptOrg, 1);
2884:
2885: if (pInfo->bStretch) {
2886: SetStretchBltMode(hdc, pInfo->iStretchMode);
2887: // cx+1 and cy+1: temporary work around for a bug!
2888: StretchBlt(hdc, xStart, yStart, cx+1, cy+1,
2889: hdcMem, ptOrg.x, ptOrg.y, ptSize.x, ptSize.y,SRCCOPY);
2890: } else {
2891: BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y,
2892: hdcMem, xStart, yStart, SRCCOPY);
2893: }
2894:
2895: if (pInfo->bUseMono)
2896: pInfo->bUseMono = FALSE;
2897:
2898: DeleteDC(hdcMem);
2899: UNREFERENCED_PARAMETER(cx);
2900: UNREFERENCED_PARAMETER(cy);
2901: }
2902:
2903: /******************************Public*Routine******************************\
2904: *
2905: * pGetInfoData(HWND hwnd)
2906: *
2907: * Effects: calls LocalLock, returning pointer to Info structure.
2908: * assumes hwnd contains handle to Info structure at index 0.
2909: * should call bReleaseInfoData when done.
2910: * Global alert: ghwndMain used.
2911: *
2912: * Warnings:
2913: *
2914: * History:
2915: * 27-Jan-1992 -by- Petrus Wong
2916: * Wrote it.
2917: \**************************************************************************/
2918:
2919: PINFO pGetInfoData(HWND hwnd)
2920: {
2921: HANDLE hInfo;
2922: PINFO pInfo;
2923:
2924: hInfo = (HANDLE) GetWindowLong(hwnd, 0);
2925: if (hInfo == NULL) {
2926: MessageBox(ghwndMain, "Null Info handle retrieved - GetInfo", "Error", MB_OK);
2927: return NULL;
2928: }
2929:
2930: if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) {
2931: return NULL;
2932: }
2933:
2934: return pInfo;
2935: }
2936:
2937: /******************************Public*Routine******************************\
2938: *
2939: * bReleaseInfoData(HWND hwnd)
2940: *
2941: * Effects: calls LocalUnlock. Returns whatever LocalUnlock returns.
2942: *
2943: * Warnings: assumes LocalLock was called previously.
2944: * assumes hwnd contains handle to Info structure at index 0.
2945: * Global alert: ghwndMain used.
2946: *
2947: * History:
2948: * 27-Jan-1992 -by- Petrus Wong
2949: * Wrote it.
2950: \**************************************************************************/
2951:
2952: BOOL bReleaseInfoData(HWND hwnd)
2953: {
2954: HANDLE hInfo;
2955:
2956: hInfo = (HANDLE) GetWindowLong(hwnd, 0);
2957: if (hInfo == NULL) {
2958: MessageBox(ghwndMain, "Null Info handle retrieved - ReleaseInfo", "Error", MB_OK);
2959: return FALSE;
2960: }
2961:
2962: return (LocalUnlock(hInfo));
2963: }
2964:
2965:
2966: /******************************Public*Routine******************************\
2967: *
2968: * bCheckMutexMenuItem
2969: *
2970: * Effects: Put a check mark on uiCheckItem in the hMenu. Remove previous
2971: * check mark, if any, on items in the same group. Returns TRUE
2972: * if successful, FALSE otherwise (item not exists).
2973: *
2974: * Warnings:
2975: *
2976: * History:
2977: * 28-Jan-1992 -by- Petrus Wong
2978: * Wrote it.
2979: \**************************************************************************/
2980:
2981: BOOL bCheckMutexMenuItem(HMENU hMenu, UINT uiCheckItem)
2982: {
2983: switch(uiCheckItem) {
2984: case MM_FLOAT:
2985: case MM_FIX:
2986: CheckMenuItem(hMenu, MM_FLOAT, MF_UNCHECKED);
2987: CheckMenuItem(hMenu, MM_FIX, MF_UNCHECKED);
2988: break;
2989: case MM_ITERATION_TEN:
2990: case MM_ITERATION_TWENTY:
2991: case MM_ITERATION_THIRTY:
2992: case MM_ITERATION_FIFTY:
2993: case MM_ITERATION_DOUBLE:
2994: CheckMenuItem(hMenu, MM_ITERATION_TEN, MF_UNCHECKED);
2995: CheckMenuItem(hMenu, MM_ITERATION_TWENTY, MF_UNCHECKED);
2996: CheckMenuItem(hMenu, MM_ITERATION_THIRTY, MF_UNCHECKED);
2997: CheckMenuItem(hMenu, MM_ITERATION_FIFTY, MF_UNCHECKED);
2998: CheckMenuItem(hMenu, MM_ITERATION_DOUBLE, MF_UNCHECKED);
2999: break;
3000: case MM_STEP_ONE:
3001: case MM_STEP_TWO:
3002: case MM_STEP_THREE:
3003: CheckMenuItem(hMenu, MM_STEP_ONE, MF_UNCHECKED);
3004: CheckMenuItem(hMenu, MM_STEP_TWO, MF_UNCHECKED);
3005: CheckMenuItem(hMenu, MM_STEP_THREE, MF_UNCHECKED);
3006: break;
3007: case MM_STRETCHBLT:
3008: case MM_BITBLT:
3009: CheckMenuItem(hMenu, MM_STRETCHBLT, MF_UNCHECKED);
3010: CheckMenuItem(hMenu, MM_BITBLT, MF_UNCHECKED);
3011: break;
3012: case MM_BLACKONWHITE:
3013: case MM_COLORONCOLOR:
3014: case MM_WHITEONBLACK:
3015: case MM_HALFTONE:
3016: CheckMenuItem(hMenu, MM_BLACKONWHITE, MF_UNCHECKED);
3017: CheckMenuItem(hMenu, MM_COLORONCOLOR, MF_UNCHECKED);
3018: CheckMenuItem(hMenu, MM_WHITEONBLACK, MF_UNCHECKED);
3019: CheckMenuItem(hMenu, MM_HALFTONE, MF_UNCHECKED);
3020: break;
3021: case MM_PORTRAIT:
3022: case MM_LANDSCAPE:
3023: CheckMenuItem(hMenu, MM_PORTRAIT, MF_UNCHECKED);
3024: CheckMenuItem(hMenu, MM_LANDSCAPE, MF_UNCHECKED);
3025: break;
3026: default:
3027: return FALSE;
3028: }
3029: CheckMenuItem(hMenu, uiCheckItem, MF_CHECKED);
3030: return TRUE;
3031: }
3032:
3033: /******************************Public*Routine******************************\
3034: *
3035: * bInitInfo
3036: *
3037: * Effects: Initialize the Info data structure
3038: *
3039: * Warnings:
3040: *
3041: * History:
3042: * 28-Jan-1992 -by- Petrus Wong
3043: * Wrote it.
3044: \**************************************************************************/
3045:
3046: BOOL bInitInfo(PINFO pInfo)
3047: {
3048: pInfo->hParent = ghwndClient;
3049: pInfo->xFrom = -2.0;
3050: pInfo->xTo = 2.0;
3051: pInfo->yFrom = 2.0;
3052: pInfo->yTo = -2.0;
3053: pInfo->lxFrom = -4096; // 20.11 fix point
3054: pInfo->lxTo = 4096; // representation of
3055: pInfo->lyFrom = 4096; // -2, 2, 2, and -2
3056: pInfo->lyTo = -4096; //
3057: pInfo->iIteration = gIteration;
3058: pInfo->iStep = gStep;
3059: pInfo->bStretch = gbStretch;
3060: pInfo->iStretchMode = giStretchMode;
3061: wsprintf((LPSTR) &(pInfo->CaptionBarText), "");
3062: pInfo->hwnd = NULL;
3063: pInfo->hTextWnd = NULL;
3064: pInfo->rcClient.top = 0;
3065: pInfo->rcClient.left = 0;
3066: pInfo->rcClient.bottom = 0;
3067: pInfo->rcClient.right = 0;
3068: pInfo->hdcClient = NULL;
3069: pInfo->hRgnPath = NULL;
3070: pInfo->hThrd = NULL;
3071: pInfo->bDrawing = FALSE;
3072: pInfo->dwThreadId = 0;
3073: pInfo->dwElapsed = 0L;
3074: pInfo->c1 = 0.0;
3075: pInfo->c2 = 0.0;
3076: pInfo->lc1 = 0L;
3077: pInfo->lc2 = 0L;
3078: pInfo->hBmpSaved = NULL;
3079: pInfo->bSizeChng = FALSE;
3080: pInfo->bMandel = TRUE;
3081: pInfo->bSetDIBsToDevice = FALSE;
3082: pInfo->bFill = FALSE;
3083: pInfo->hBrush = NULL;
3084: pInfo->hQuitEvent = NULL;
3085: pInfo->hCycleThrd = NULL;
3086: pInfo->dwCycleThrdID = 0;
3087: pInfo->bClrCycle = FALSE;
3088: pInfo->bFirstTime = TRUE;
3089: pInfo->dwSuspend = 0;
3090: pInfo->hBmpMono = NULL;
3091: pInfo->bUseMono = FALSE;
3092: pInfo->hPrtThrd = NULL;
3093: pInfo->dwPrtThrdID = 0;
3094: return TRUE;
3095: }
3096:
3097: /******************************Public*Routine******************************\
3098: *
3099: * bResetGlobal
3100: *
3101: * Effects: Set (l) x/y From/To to their default values
3102: *
3103: * Warnings:
3104: *
3105: * History:
3106: * 28-Jan-1992 -by- Petrus Wong
3107: * Wrote it.
3108: \**************************************************************************/
3109:
3110: BOOL bResetGlobal(VOID)
3111: {
3112: xFrom = -2.0;
3113: xTo = 2.0;
3114: yFrom = 2.0;
3115: yTo = -2.0;
3116: lxFrom = -4096;
3117: lxTo = 4096;
3118: lyFrom = 4096;
3119: lyTo = -4096;
3120: return TRUE;
3121: }
3122:
3123: /******************************Public*Routine******************************\
3124: *
3125: * hBrCreateBrush
3126: *
3127: * Effects: Creates a brush with the specified RGB
3128: *
3129: * Warnings:
3130: *
3131: * History:
3132: * 04-Mar-1992 -by- Petrus Wong
3133: * Wrote it.
3134: \**************************************************************************/
3135:
3136: HBRUSH hBrCreateBrush(HDC hDC, DWORD dwRGB)
3137: {
3138: HDC hdcMem;
3139: HBRUSH hbr;
3140: HBRUSH hbrOld;
3141: HBITMAP hbmPat;
3142: HBITMAP hbmOld;
3143:
3144: hbr = CreateSolidBrush(dwRGB);
3145: hdcMem = CreateCompatibleDC(hDC);
3146:
3147: //
3148: // Minimum size for a bitmap to be used in a fill pattern is 8x8
3149: //
3150: hbmPat = CreateCompatibleBitmap(hDC, 8, 8);
3151:
3152: hbmOld = SelectObject(hdcMem, hbmPat);
3153: hbrOld = SelectObject(hdcMem, hbr);
3154: PatBlt(hdcMem, 0, 0, 8, 8, PATCOPY);
3155:
3156: //
3157: // Deselect hbmPat and hbr
3158: //
3159: SelectObject(hdcMem, hbmOld);
3160: SelectObject(hdcMem, hbrOld);
3161:
3162: DeleteDC(hdcMem);
3163: DeleteObject(hbr);
3164:
3165: hbr = CreatePatternBrush(hbmPat);
3166:
3167: DeleteObject(hbmPat);
3168:
3169: return hbr;
3170: }
3171:
3172:
3173: /******************************Public*Routine******************************\
3174: *
3175: * bPrintBmp
3176: *
3177: * Effects: A Thread routine for printing bitmap
3178: *
3179: * Warnings:
3180: *
3181: * History:
3182: * 31-May-1992 -by- Petrus Wong
3183: * Wrote it.
3184: \**************************************************************************/
3185:
3186: BOOL bPrintBmp(PPRTDATA pPrtData) {
3187: HDC hdcPrinter;
3188: int iWidth, iHeight;
3189:
3190: #ifdef NEWPRTAPI
3191: DOCINFO DocInfo;
3192: #endif
3193:
3194: if (pPrtData->bUseDefault) {
3195: hdcPrinter = CreateDC( "", gpszPrinterNames[pPrtData->index],
3196: "", NULL);
3197: } else {
3198: hdcPrinter = CreateDC( "", gpszPrinterNames[pPrtData->index],
3199: "", &(pPrtData->DevMode));
3200: }
3201:
3202: if (!hdcPrinter)
3203: {
3204: ExitThread(0);
3205: return(FALSE);
3206: }
3207:
3208: iWidth = GetDeviceCaps(hdcPrinter, HORZRES);
3209: iHeight = GetDeviceCaps(hdcPrinter, VERTRES);
3210:
3211: #ifdef NEWPRTAPI
3212:
3213: DocInfo.cbSize = sizeof(DOCINFO);
3214: DocInfo.lpszDocName = pPrtData->info.CaptionBarText;
3215: DocInfo.lpszOutput = NULL;
3216: StartDoc(hdcPrinter, &DocInfo);
3217: StartPage(hdcPrinter);
3218: DrawBitmap(hdcPrinter, &(pPrtData->info), 0, 0, iWidth, iHeight);
3219: EndPage(hdcPrinter);
3220: EndDoc(hdcPrinter);
3221:
3222: #else
3223:
3224: Escape(hdcPrinter, STARTDOC, 20, "Mandelbrot", NULL);
3225: DrawBitmap(hdcPrinter, &(pPrtData->info), 0, 0, iWidth, iHeight);
3226: Escape(hdcPrinter, NEWFRAME, NULL, NULL, NULL);
3227: Escape(hdcPrinter, ENDDOC, NULL, NULL, NULL);
3228:
3229: #endif
3230:
3231: DeleteDC(hdcPrinter);
3232: ExitThread(0);
3233: return(TRUE);
3234:
3235: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.