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