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