JULIA.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:146k
源码类别:

Windows编程

开发平台:

Visual C++

  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. *
  9. * Copyright (C) 1993-1997 Microsoft Corporation
  10. *
  11. * The Mandelbrot Dream serves to demonstrate the GDI and USER
  12. * functionalities in the setting of fractals.
  13. *
  14. * The Mandelbrot Dream provides the following functions:
  15. *       1.  Drawing the Mandelbrot set and the corresponding julia set
  16. *       2.  Zooming into any of the set
  17. *       3.  MDI fractal drawing windows
  18. *       4.  Floating Point Math/Fix Point Math
  19. *       5.  Shifting color table entries
  20. *       6.  Changing palette entries and animating palatte aka color cycling
  21. *       7.  Loading/Saving bitmap created with special effect
  22. *       8.  Changing bitmap color with flood fill
  23. *       9.  Boundary tracing and creating a clip region out of it for
  24. *           creating special effect
  25. *      10.  Enumerate printers for printing
  26. *      11.  Load RLE (or convert .bmp files to RLE) for playing in viewer
  27. *      12.  Save the RLE in memory to disk.
  28. *
  29. * Note: Users can now draw and saves the julia sets on disk as bmps in
  30. *       the Julia windows.  These bitmaps can then be read into the memory
  31. *       (and converted to RLE format) one by one for displaying in sequence
  32. *       in the viewer window.  Eg Load the julia.rle in the viewer window
  33. *       and select the play or play continuously menu item.     02-Jan-1993
  34. *
  35. * Note2: The fix point math in this sample makes use of the LargeInteger
  36. *        64 bit math library.
  37. *
  38. * Dependencies:
  39. *
  40. *       none
  41. *
  42. **************************************************************************/
  43. #include <windows.h>
  44. #include <stdlib.h>
  45. #include <commdlg.h>
  46. #include <stdarg.h>
  47. #include <math.h>
  48. #include <stdio.h>
  49. #include <shellapi.h>
  50. #include "julia.h"
  51. //
  52. // For T1 to create all pens in advance.  This is not a good approach
  53. // because pens are per thread basis.  The drawing threads won't be able
  54. // to use them if they are not created in their threads.    18-Sep-1992
  55. //
  56. //#define THRDONE
  57. #define CYCLETHRD
  58. #define PRTTHRD
  59. #define NEWPRTAPI
  60. #ifndef DEBUG
  61.    #undef OutputDebugString
  62.    #define OutputDebugString(LPCSTR)
  63. #endif
  64. //
  65. // Forward declarations.
  66. //
  67. BOOL InitializeApp            (INT*);
  68. LONG APIENTRY MainWndProc     (HWND, UINT, DWORD, LONG);
  69. LONG APIENTRY ChildWndProc    (HWND, UINT, DWORD, LONG);
  70. BOOL CALLBACK About           (HWND, UINT, DWORD, LONG);
  71. LONG APIENTRY TextWndProc     (HWND, UINT, DWORD, LONG);
  72. LONG APIENTRY JuliaWndProc    (HWND, UINT, DWORD, LONG);
  73. LONG APIENTRY ViewerWndProc   (HWND, UINT, DWORD, LONG);
  74. LONG APIENTRY ViewSurfWndProc (HWND, UINT, DWORD, LONG);
  75. BOOL APIENTRY SuspendDrawThrd (HWND, LONG);
  76. BOOL APIENTRY ResumeDrawThrd  (HWND, LONG);
  77. BOOL StartDraw       (PINFO);
  78. BOOL StartDrawFix    (PINFO);
  79. BOOL StartDraw2      (PINFO);
  80. BOOL StartMandelbrot (PINFO);
  81. BOOL StartMandelbrotFix (PINFO);
  82. HBITMAP SaveBitmap   (HWND, HPALETTE);
  83. void DrawBitmap      (HDC, PINFO, int, int, int, int);
  84. BOOL bDrawDIB        (HDC, PINFO, int, int, int, int);
  85. LONG lMul(LONG, LONG);
  86. LONG lDiv(LONG, LONG);
  87. PINFO pGetInfoData(HWND);
  88. BOOL bReleaseInfoData(HWND);
  89. BOOL bCheckMutexMenuItem(PINFO, HMENU, UINT);
  90. VOID vChkMenuItem(PINFO, HMENU, UINT);
  91. BOOL bInitInfo(PINFO);
  92. BOOL bResetGlobal(VOID);
  93. HBRUSH hBrCreateBrush(HDC, DWORD);
  94. BOOL bPrintBmp(PPRTDATA);
  95. BOOL bStoreRleFile(HDC, PINFO, PSTR);
  96. BOOL bFreeRleFile(PINFO);
  97. BOOL bPlayRle(PINFO);
  98. BOOL bSaveRleFile(HDC, PINFO, PSTR);
  99. BOOL bPlayRleCont2(PINFO);
  100. BOOL bSelectDIBPal(HDC, PINFO, LPBITMAPINFO, BOOL);
  101. HBITMAP DIBfromDDB(HDC, HBITMAP, PINFO);
  102. //
  103. // Global variable declarations.
  104. //
  105. HPEN   hpnRed;
  106. HPEN   hpnBlack;
  107. HPEN   hpnGreen;
  108. INT    giPen = 0;
  109. HANDLE ghModule;
  110. HWND   ghwndMain = NULL;
  111. HWND   ghwndClient = NULL;
  112. HANDLE ghAccel;
  113. HMENU  hMenu, hChildMenu, hViewMenu;
  114. HMENU  hViewSubOne, hSubMenuOne, hSubMenuThree;
  115. HMENU  hPrinterMenu;
  116. CHAR   gszFile[20];
  117. CHAR   gszMapName[20];
  118. char   gtext[256];
  119. BOOL   gFloat = TRUE;
  120. LONG   gStep = 1;
  121. LONG   gIteration = 500;
  122. BOOL   gbStretch = TRUE;
  123. INT    giStretchMode = COLORONCOLOR;
  124. INT    giDmOrient = DMORIENT_PORTRAIT;
  125. INT    giNPrinters = 0;
  126. HPALETTE        ghPal, ghPalOld;
  127. double xFrom, xTo, yFrom, yTo, c1, c2;
  128. LONG   lxFrom, lxTo, lyFrom, lyTo, lc1, lc2;
  129. /******************************Public*Routine******************************
  130. *
  131. * WinMain
  132. *
  133. **************************************************************************/
  134. int WINAPI WinMain(
  135.     HINSTANCE hInstance,
  136.     HINSTANCE hPrevInstance,
  137.     LPSTR lpCmdLine,
  138.     int nShowCmd)
  139. {
  140.     MSG    msg;
  141.     ghModule = GetModuleHandle(NULL);
  142.     if (!InitializeApp(&giPen)) 
  143. {
  144. OutputDebugString("memory: InitializeApp failure!");
  145. return 0;
  146.     }
  147.     if (!(ghAccel = LoadAccelerators (ghModule, MAKEINTRESOURCE(ACCEL_ID))))
  148. OutputDebugString("memory: Load Accel failure!");
  149.     while (GetMessage(&msg, NULL, 0, 0)) 
  150. {
  151. if (!TranslateAccelerator( ghwndMain, ghAccel, &msg) &&
  152.     !TranslateMDISysAccel( ghwndClient, &msg)) 
  153. {
  154. TranslateMessage(&msg);
  155. DispatchMessage(&msg);
  156. }
  157.     }
  158.     DeleteObject(ghPal);
  159.     return 1;
  160.     UNREFERENCED_PARAMETER(lpCmdLine);
  161.     UNREFERENCED_PARAMETER(nShowCmd);
  162.     UNREFERENCED_PARAMETER(hInstance);
  163.     UNREFERENCED_PARAMETER(hPrevInstance);
  164. }
  165. /***************************************************************************
  166. * InitializeApp
  167. *
  168. ***************************************************************************/
  169. BOOL InitializeApp(INT *piPen)
  170. {
  171.     WNDCLASS wc;
  172.     HDC      hDC;
  173. #ifdef THRDONE
  174.     INT      iNumClr;
  175. #endif
  176.     wc.style            = CS_OWNDC;
  177.     wc.lpfnWndProc      = (WNDPROC)MainWndProc;
  178.     wc.cbClsExtra       = 0;
  179.     wc.cbWndExtra       = sizeof(LONG);
  180.     wc.hInstance        = ghModule;
  181.     wc.hIcon            = LoadIcon(ghModule, MAKEINTRESOURCE(APPICON));
  182.     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
  183.     wc.hbrBackground    = (HBRUSH)(COLOR_APPWORKSPACE);
  184.     wc.lpszMenuName     = "MainMenu";
  185.     wc.lpszClassName    = "MandelClass";
  186.     if (!RegisterClass(&wc))
  187. return FALSE;
  188.     wc.lpfnWndProc      = (WNDPROC)ChildWndProc;
  189.     wc.hIcon            = LoadIcon(ghModule, MAKEINTRESOURCE(APPICON));
  190.     wc.lpszMenuName     = NULL;
  191.     wc.lpszClassName    = "ChildClass";
  192.     if (!RegisterClass(&wc))
  193. return FALSE;
  194.     wc.lpfnWndProc      = (WNDPROC)ViewerWndProc;
  195.     wc.hIcon            = LoadIcon(ghModule, MAKEINTRESOURCE(VIEWICON));
  196.     wc.lpszMenuName     = NULL;
  197.     wc.lpszClassName    = "ViewerClass";
  198.     if (!RegisterClass(&wc))
  199. return FALSE;
  200.     wc.style            = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
  201.     wc.lpfnWndProc      = (WNDPROC)TextWndProc;
  202.     wc.hIcon            = NULL;
  203.     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
  204.     wc.hbrBackground    = (HBRUSH)(COLOR_BTNSHADOW);
  205.     wc.lpszMenuName     = NULL;
  206.     wc.lpszClassName    = "Text";
  207.     if (!RegisterClass(&wc))
  208.     return FALSE;
  209.     wc.style            = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
  210.     wc.lpfnWndProc      = (WNDPROC)JuliaWndProc;
  211.     wc.hIcon            = NULL;
  212.     //
  213.     // Nope.  Can't have this, screw up my Paint Can cursor
  214.     //
  215.     //wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
  216.     wc.hCursor          = NULL;
  217.     wc.hbrBackground    = (HBRUSH)(COLOR_BACKGROUND);
  218.     wc.lpszMenuName     = NULL;
  219.     wc.lpszClassName    = "Julia";
  220.     if (!RegisterClass(&wc))
  221.     return FALSE;
  222.     wc.style            = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
  223.     wc.lpfnWndProc      = (WNDPROC)ViewSurfWndProc;
  224.     wc.hIcon            = NULL;
  225.     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
  226.     wc.hbrBackground    = (HBRUSH)(COLOR_BACKGROUND);
  227.     wc.lpszMenuName     = NULL;
  228.     wc.lpszClassName    = "View";
  229.     if (!RegisterClass(&wc))
  230.     return FALSE;
  231.     //
  232.     // Notice, submenu is zero-based
  233.     //
  234.     hMenu       = LoadMenu(ghModule, "MainMenu");
  235.     hChildMenu  = LoadMenu(ghModule, "ChildMenu");
  236.     hViewMenu   = LoadMenu(ghModule, "ViewMenu");
  237.     hViewSubOne = GetSubMenu(hViewMenu, 1);
  238.     hSubMenuOne = GetSubMenu(hMenu, 1);
  239.     hSubMenuThree = GetSubMenu(hChildMenu, 8);
  240.     hPrinterMenu = GetSubMenu(hChildMenu, 7);
  241.     //
  242.     // Disable color-cycling for display devices that does not support
  243.     // palette like the VGA.  As as 29-May-1992, the MIPS display driver
  244.     // is the only one that supports palette
  245.     //
  246.     hDC = GetDC(NULL);
  247.     if (!((GetDeviceCaps(hDC, RASTERCAPS)) & RC_PALETTE)) {
  248. EnableMenuItem(hChildMenu, MM_CYCLE, MF_GRAYED);
  249.     }
  250. #ifdef THRDONE
  251.     if ((iNumClr = iCreatePenFrPal(hDC, NULL, 0, &ghPal)) != 0) 
  252. {
  253. sprintf( gtext,"iNumClr = %dn", iNumClr);
  254. OutputDebugString( gtext);
  255. if ((pInfo->prghPen = (PVOID*) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(HPEN)*iNumClr)) == NULL) 
  256.     OutputDebugString ("Failed in Memory Allocation for pInfo->prghPen!");
  257. else 
  258. if ((*piPen = iCreatePenFrPal(hDC, pInfo->prghPen, 0, &ghPal)) == 0)
  259. OutputDebugString("Failed in creating pen!");
  260.     }
  261. #endif
  262.     ReleaseDC(NULL, hDC);
  263.     ghwndMain = CreateWindowEx(0L, "MandelClass", 
  264.    GetStringRes (IDS_MANDEL_DREAM),
  265.     WS_OVERLAPPED   | WS_CAPTION     | WS_BORDER       |
  266.     WS_THICKFRAME   | WS_MAXIMIZEBOX | WS_MINIMIZEBOX  |
  267.     WS_CLIPCHILDREN | WS_VISIBLE     | WS_SYSMENU,
  268.     80, 70, 550, 400 /* 550 */,
  269.     NULL, hMenu, ghModule, NULL);
  270.     if (ghwndMain == NULL)
  271. return FALSE;
  272.     bInitPrinter(ghwndMain);
  273.     SetWindowLong(ghwndMain, GWL_USERDATA, 0L);
  274.     SetFocus(ghwndMain);    /* set initial focus */
  275.     PostMessage(ghwndMain, WM_COMMAND, MM_MANDEL, 0L);
  276.     PostMessage(ghwndMain, WM_COMMAND, MM_CREATE_MANDEL_THREAD, 0L);
  277.     return TRUE;
  278. }
  279. /******************************Public*Routine******************************
  280. *
  281. * MainWndProc
  282. *
  283. **************************************************************************/
  284. long APIENTRY MainWndProc(
  285.     HWND hwnd,
  286.     UINT message,
  287.     DWORD wParam,
  288.     LONG lParam)
  289. {
  290.     static int         iJuliaCount=1;
  291.     static int         iMandelCount=1;
  292.     static int         iViewerCount=1;
  293.     CLIENTCREATESTRUCT clientcreate;
  294.     HWND               hwndChildWindow;
  295.     static FARPROC     lpfnSuspendThrd, lpfnResumeThrd;
  296.     switch (message) {
  297.       case WM_CREATE:
  298. SetWindowLong(hwnd, 0, (LONG)NULL);
  299. clientcreate.hWindowMenu  = hSubMenuOne;
  300. clientcreate.idFirstChild = 1;
  301. ghwndClient = CreateWindow("MDICLIENT", NULL,
  302.     WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
  303.     0,0,0,0,
  304.     hwnd, NULL, ghModule, (LPVOID)&clientcreate);
  305. lpfnSuspendThrd = (FARPROC)MakeProcInstance (SuspendDrawThrd, ghModule);
  306. lpfnResumeThrd  = (FARPROC)MakeProcInstance (ResumeDrawThrd, ghModule);
  307. return 0L;
  308.       case WM_DESTROY: {
  309. bCleanupPrinter();
  310. PostQuitMessage(0);
  311. return 0L;
  312.       }
  313.       //
  314.       // Wait! User is going to zero out our app's visible region.  This
  315.       // is going to mess up our drawing (we are not keeping any shadow
  316.       // bitmap in this version yet.) So, let's suspend our drawing thread
  317.       // first before user does that.  We will resume after user is done.
  318.       //
  319.       case WM_SYSCOMMAND: {
  320. LONG        lResult;
  321. //
  322. // We'll enumerate our children and suspend their drawing thread.
  323. //
  324. EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnSuspendThrd, lParam);
  325. //
  326. // Now, let user does it supposed to do
  327. //
  328. lResult = DefFrameProc(hwnd,  ghwndClient, message, wParam, lParam);
  329. //
  330. // User's done, we'll resume the suspended threads in our children
  331. //
  332. EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnResumeThrd, lParam);
  333. return lResult;
  334. break;
  335.       }
  336. #if 0
  337.       //
  338.       // Our window's size is going to change, we'll make sure the new
  339.       // window is a square.
  340.       //
  341.       case WM_WINDOWPOSCHANGING: {
  342.     PWINDOWPOS pWndPos;
  343.     RECT       rect;
  344.     LONG       lcx, lcy;
  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. switch (LOWORD(wParam)) {
  360.     case IDM_TILE:
  361. SendMessage(ghwndClient, WM_MDITILE, 0L, 0L);
  362. return 0L;
  363.     case IDM_CASCADE:
  364. SendMessage(ghwndClient, WM_MDICASCADE, 0L, 0L);
  365. return 0L;
  366.     case IDM_ARRANGE:
  367. SendMessage(ghwndClient, WM_MDIICONARRANGE, 0L, 0L);
  368. return 0L;
  369.     //
  370.     // Create Julia or Mandelbrot set
  371.     //
  372.     case MM_JULIA:
  373.     case MM_MANDEL: {
  374. HANDLE hInfo;
  375. PINFO  pInfo;
  376. MDICREATESTRUCT mdicreate;
  377. hInfo = LocalAlloc(LHND, (WORD) sizeof(INFO));
  378. if (hInfo == NULL) 
  379. {
  380.     OutputDebugString("Failed to Allocate Info!");
  381.     return 0L;
  382. }
  383. if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) 
  384. {
  385.     OutputDebugString("Failed in LocalLock, hInfo");
  386.     return 0L;
  387. }
  388. bInitInfo(pInfo);
  389. wsprintf((LPSTR) &(pInfo->CaptionBarText),
  390.  (LOWORD(wParam) == MM_JULIA) ? 
  391.  GetStringRes (IDS_JULIA): 
  392.  GetStringRes (IDS_MANDELBROT),
  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. // Fill in the MDICREATE structure for MDI child creation
  405. //
  406. mdicreate.szClass = "ChildClass";
  407. mdicreate.szTitle = (LPTSTR)&(pInfo->CaptionBarText);
  408. mdicreate.hOwner  = ghModule;
  409. mdicreate.x       =
  410. mdicreate.y       = CW_USEDEFAULT;
  411. mdicreate.cx      = 300;
  412. mdicreate.cy      = 300;
  413. mdicreate.style   = 0L;
  414. mdicreate.lParam  = (LONG) hInfo;
  415. /*Create Child Window*/
  416. hwndChildWindow =
  417.     (HANDLE) SendMessage(ghwndClient, WM_MDICREATE,
  418. 0L,
  419. (LONG)(LPMDICREATESTRUCT)&mdicreate);
  420. if (hwndChildWindow == NULL) 
  421. {
  422.     OutputDebugString ("Failed in Creating Child Window");
  423.     return 0L;
  424. }
  425. (LOWORD(wParam) == MM_JULIA) ? iJuliaCount++ : iMandelCount++ ;
  426. LocalUnlock(hInfo);
  427. return ((LONG)hwndChildWindow);
  428.     }
  429.     case MM_RLEVIEWER: {
  430. HANDLE hInfo;
  431. PINFO  pInfo;
  432. MDICREATESTRUCT mdicreate;
  433. hInfo = LocalAlloc(LHND, (WORD) sizeof(INFO));
  434. if (hInfo == NULL) 
  435. {
  436.     OutputDebugString ("Failed to Allocate Info!");
  437.     return 0L;
  438. }
  439. if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) 
  440. {
  441.     OutputDebugString ("Failed in LocalLock, hInfo");
  442.     return 0L;
  443. }
  444. bInitInfo(pInfo);
  445. wsprintf((LPSTR) &(pInfo->CaptionBarText), GetStringRes (IDS_VIEWER), iViewerCount );
  446. //
  447. // Fill in the MDICREATE structure for MDI child creation
  448. //
  449. mdicreate.szClass = "ViewerClass";
  450. mdicreate.szTitle = (LPTSTR)&(pInfo->CaptionBarText);
  451. mdicreate.hOwner  = ghModule;
  452. mdicreate.x       =
  453. mdicreate.y       = CW_USEDEFAULT;
  454. mdicreate.cx      = 300;
  455. mdicreate.cy      = 300;
  456. mdicreate.style   = 0L;
  457. mdicreate.lParam  = (LONG) hInfo;
  458. /*Create Child Window*/
  459. hwndChildWindow =
  460.     (HANDLE) SendMessage(ghwndClient, WM_MDICREATE,
  461. 0L,
  462. (LONG)(LPMDICREATESTRUCT)&mdicreate);
  463. if (hwndChildWindow == NULL) 
  464. {
  465.     OutputDebugString ("Failed in Creating Child Window");
  466.     return 0L;
  467. }
  468. iViewerCount++ ;
  469. LocalUnlock(hInfo);
  470. return ((LONG)hwndChildWindow);
  471.     }
  472.     case MM_ABOUT:
  473. if (DialogBox(ghModule, "AboutBox", ghwndMain, (DLGPROC)About) == -1)
  474.    OutputDebugString ("DEMO: About Dialog Creation Error!");
  475. return 0L;
  476.     //
  477.     // Only my children know how to deal with these messages, so
  478.     // pass these to children for processing
  479.     //
  480.     case MM_CREATE_JULIA_THREAD:
  481.     case MM_SET_XFORM_ATTR:
  482.     case MM_CREATE_MANDEL_THREAD:
  483.     case MM_OPT_4:              // currently not used
  484.     case MM_DRAW_SET:
  485.     case MM_SETDIB2DEVICE:
  486.     case MM_BW:
  487.     case MM_SHIFT:
  488.     case MM_CUSTOM:
  489.     case MM_CYCLE:
  490.     case MM_TP_IDLE:
  491.     case MM_TP_LOW:
  492.     case MM_TP_BELOW_NORMAL:
  493.     case MM_TP_NORMAL:
  494.     case MM_TP_ABOVE_NORMAL:
  495.     case MM_TP_HIGH:
  496.     case MM_TP_TIME_CRITICAL:
  497.     case MM_FLOAT:
  498.     case MM_FIX:
  499.     case MM_ITERATION_100:
  500.     case MM_ITERATION_500:
  501.     case MM_ITERATION_1000:
  502.     case MM_ITERATION_5000:
  503.     case MM_ITERATION_DOUBLE:
  504.     case MM_STEP_ONE:
  505.     case MM_STEP_TWO:
  506.     case MM_STEP_THREE:
  507.     case MM_SAVE:
  508.     case MM_SAVE_MONO:
  509.     case MM_LOAD:
  510.     case MM_STRETCHBLT:
  511.     case MM_BITBLT:
  512.     case MM_BLACKONWHITE:
  513.     case MM_COLORONCOLOR:
  514.     case MM_WHITEONBLACK:
  515.     case MM_HALFTONE:
  516.     case MM_CLIP:
  517.     case MM_RM_CLIP:
  518.     case MM_SELCLIPRGN:
  519.     case MM_ERASE:
  520.     case MM_PORTRAIT:
  521.     case MM_LANDSCAPE:
  522.     case MM_PRINTER:
  523.     case MM_PRINTER + 1:
  524.     case MM_PRINTER + 2:
  525.     case MM_PRINTER + 3:
  526.     case MM_PRINTER + 4:
  527.     case MM_PRINTER + 5:
  528.     case MM_PRINTER + 6:
  529.     case MM_PRINTER + 7:
  530.     case MM_PRINTER + 8:
  531.     case MM_PRINTER + 9:
  532.     case MM_RLELOAD_DEMO:
  533.     case MM_RLEPLAYCONT:
  534.     case MM_RLELOAD:
  535.     case MM_RLESAVE:
  536.     case MM_CLEAR:
  537.     case MM_RLEPLAY:
  538.     {
  539. HWND hActiveChild;
  540. hActiveChild = (HANDLE) SendMessage(ghwndClient, WM_MDIGETACTIVE, 0L, 0L);
  541. if (hActiveChild)
  542.     SendMessage(hActiveChild, WM_COMMAND, wParam, lParam);
  543. return 0L;
  544.     }
  545.     default:
  546. return DefFrameProc(hwnd,  ghwndClient, message, wParam, lParam);
  547. }
  548.     default:
  549. return DefFrameProc(hwnd,  ghwndClient, message, wParam, lParam);
  550.     }
  551. }
  552. /***************************************************************************
  553. * ChildWndProc
  554. *
  555. ***************************************************************************/
  556. long APIENTRY ChildWndProc(
  557.     HWND hwnd,
  558.     UINT message,
  559.     DWORD wParam,
  560.     LONG lParam)
  561. {
  562.     static FARPROC     lpfnSuspendThrd, lpfnResumeThrd;
  563.     static BOOL        bDIB2Device = FALSE;
  564.     sprintf( gtext,"message = %lxn", message);
  565.     OutputDebugString( gtext);
  566.     switch (message) {
  567. case WM_COMMAND: {
  568.   PINFO       pInfo;
  569.   HWND        hTextWnd;
  570.   switch (LOWORD(wParam)) {
  571.     //
  572.     // Create a Julia drawing thread
  573.     //
  574.     case MM_CREATE_JULIA_THREAD: {
  575. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  576.     return 0L;
  577. }
  578. hTextWnd = pInfo->hTextWnd;
  579. sprintf( gtext,"(%g, %g) <-> (%g, %g)", pInfo->xFrom, pInfo->yFrom, pInfo->xTo, pInfo->yTo);
  580. SetWindowText(hTextWnd, gtext);
  581. sprintf( gtext,"(c1 = %g, c2 = %g)nn", pInfo->c1, pInfo->c2);
  582. OutputDebugString( gtext );
  583. if (pInfo->hThrd)
  584.     CloseHandle(pInfo->hThrd);
  585. pInfo->hThrd = CreateThread(NULL, 0,
  586.  (gFloat ? (LPTHREAD_START_ROUTINE)StartDraw : (LPTHREAD_START_ROUTINE)StartDrawFix),
  587.  pInfo,
  588.  STANDARD_RIGHTS_REQUIRED,
  589.  &pInfo->dwThreadId );
  590.        if (pInfo->hThrd && pInfo->bDrawing) 
  591.    {
  592.     if (!SetThreadPriority(pInfo->hThrd, pInfo->iPriority))
  593.      OutputDebugString ("Can't set Priority!");
  594.        }
  595.        bReleaseInfoData(hwnd);
  596.        return 0L;
  597.     }
  598.     //
  599.     // Reset pInfo reflecting new transformation
  600.     //
  601.     case MM_SET_XFORM_ATTR: {
  602. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  603.     return 0L;
  604. }
  605. hTextWnd = pInfo->hTextWnd;
  606. SetWindowText(hTextWnd, GetStringRes (IDS_CLICK_HERE_VIEW));
  607. pInfo->xFrom      = xFrom;
  608. pInfo->xTo        = xTo;
  609. pInfo->yFrom      = yFrom;
  610. pInfo->yTo        = yTo;
  611. pInfo->c1         = c1;
  612. pInfo->c2         = c2;
  613. pInfo->lxFrom      = lxFrom;
  614. pInfo->lxTo        = lxTo;
  615. pInfo->lyFrom      = lyFrom;
  616. pInfo->lyTo        = lyTo;
  617. pInfo->lc1         = lc1;
  618. pInfo->lc2         = lc2;
  619.        bReleaseInfoData(hwnd);
  620.        return 0L;
  621.     }
  622.     //
  623.     // Create a Mandelbrot drawing thread
  624.     //
  625.     case MM_CREATE_MANDEL_THREAD: {
  626. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  627.     return 0L;
  628. }
  629. hTextWnd = pInfo->hTextWnd;
  630. sprintf( gtext,"(%g, %g) <-> (%g, %g)", pInfo->xFrom, pInfo->yFrom, pInfo->xTo, pInfo->yTo);
  631. SetWindowText(hTextWnd, gtext);
  632. sprintf( gtext,"(c1 = %g, c2 = %g)nn", pInfo->c1, pInfo->c2);
  633. OutputDebugString( gtext );
  634. if (pInfo->hThrd)
  635.     CloseHandle(pInfo->hThrd);
  636. pInfo->hThrd = CreateThread(NULL, 0,
  637.  (gFloat ? (LPTHREAD_START_ROUTINE)StartMandelbrot : (LPTHREAD_START_ROUTINE)StartMandelbrotFix),
  638.  pInfo,
  639.  STANDARD_RIGHTS_REQUIRED,
  640.  &pInfo->dwThreadId );
  641.        if (pInfo->hThrd && pInfo->bDrawing) 
  642.    {
  643.   if (!SetThreadPriority(pInfo->hThrd, pInfo->iPriority))
  644.      OutputDebugString ("Can't set Priority!");
  645.        }
  646.        bReleaseInfoData(hwnd);
  647.        return 0L;
  648.     }
  649.     //
  650.     // Create a Julia drawing thread using algorithm StartDraw2
  651.     // Currently not used
  652.     //
  653.     case MM_OPT_4: {
  654. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  655.     return 0L;
  656. }
  657. hTextWnd = pInfo->hTextWnd;
  658. SetWindowText(hTextWnd, "MM_OPT_4");
  659. sprintf( gtext,"xFrom = %g, xTo = %g, yFrom = %g, yTo = %gn", pInfo->xFrom, pInfo->xTo, pInfo->yFrom, pInfo->yTo);
  660. OutputDebugString( gtext );
  661. if (pInfo->hThrd)
  662.     CloseHandle(pInfo->hThrd);
  663. pInfo->hThrd = CreateThread(NULL, 0,
  664.  (LPTHREAD_START_ROUTINE)StartDraw2,
  665.  pInfo,
  666.  STANDARD_RIGHTS_REQUIRED,
  667.  &pInfo->dwThreadId );
  668.        if (pInfo->hThrd && pInfo->bDrawing) 
  669.    {
  670.       if (!SetThreadPriority(pInfo->hThrd, pInfo->iPriority))
  671.      OutputDebugString ("Can't set Priority!");
  672.        }
  673.        bReleaseInfoData(hwnd);
  674.        return 0L;
  675.     }
  676.     case MM_DRAW_SET: {
  677. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  678.     return 0L;
  679. }
  680. PostMessage(hwnd, WM_COMMAND,
  681.     pInfo->bMandel ? (DWORD)((WORD)MM_CREATE_MANDEL_THREAD) : (DWORD)((WORD)MM_CREATE_JULIA_THREAD),
  682.     (LONG)0L);
  683.        bReleaseInfoData(hwnd);
  684.        return 0L;
  685.     }
  686.     {
  687.     int     iPriority;
  688. case MM_TP_IDLE:
  689.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  690. return 0L;
  691.     }
  692.     iPriority = THREAD_PRIORITY_IDLE;
  693.     bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_IDLE);
  694.     DrawMenuBar(GetParent(GetParent(hwnd))) ;
  695.     goto CWP_SET_PRIORITY;
  696. case MM_TP_LOW:
  697.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  698. return 0L;
  699.     }
  700.     iPriority = THREAD_PRIORITY_LOWEST;
  701.     bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_LOW);
  702.     DrawMenuBar(GetParent(GetParent(hwnd))) ;
  703.     goto CWP_SET_PRIORITY;
  704. case MM_TP_BELOW_NORMAL:
  705.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  706. return 0L;
  707.     }
  708.     iPriority = THREAD_PRIORITY_BELOW_NORMAL;
  709.     bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_BELOW_NORMAL);
  710.     DrawMenuBar(GetParent(GetParent(hwnd))) ;
  711.     goto CWP_SET_PRIORITY;
  712. case MM_TP_NORMAL:
  713.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  714. return 0L;
  715.     }
  716.     iPriority = THREAD_PRIORITY_NORMAL;
  717.     bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_NORMAL);
  718.     DrawMenuBar(GetParent(GetParent(hwnd))) ;
  719.     goto CWP_SET_PRIORITY;
  720. case MM_TP_ABOVE_NORMAL:
  721.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  722. return 0L;
  723.     }
  724.     iPriority = THREAD_PRIORITY_ABOVE_NORMAL;
  725.     bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_ABOVE_NORMAL);
  726.     DrawMenuBar(GetParent(GetParent(hwnd))) ;
  727.     goto CWP_SET_PRIORITY;
  728. case MM_TP_HIGH:
  729.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  730. return 0L;
  731.     }
  732.     iPriority = THREAD_PRIORITY_HIGHEST;
  733.     bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_HIGH);
  734.     DrawMenuBar(GetParent(GetParent(hwnd))) ;
  735.     goto CWP_SET_PRIORITY;
  736. case MM_TP_TIME_CRITICAL:
  737.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  738. return 0L;
  739.     }
  740.     iPriority = THREAD_PRIORITY_TIME_CRITICAL;
  741.     bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_TIME_CRITICAL);
  742.     DrawMenuBar(GetParent(GetParent(hwnd))) ;
  743. CWP_SET_PRIORITY:
  744.     {
  745.        HANDLE       hThrd;
  746.        hThrd = pInfo->hThrd;
  747.        pInfo->iPriority = iPriority;
  748.        if (hThrd && pInfo->bDrawing) 
  749.    {
  750.       if (!SetThreadPriority(hThrd, iPriority))
  751.      OutputDebugString ("Can't set Priority!");
  752.        }
  753.     }
  754.     bReleaseInfoData(hwnd);
  755.     return 0L;
  756.     }
  757.     case MM_FLOAT: {
  758. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  759.     return 0L;
  760. }
  761. bCheckMutexMenuItem(pInfo, hChildMenu, MM_FLOAT);
  762. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  763. gFloat = TRUE;
  764. bReleaseInfoData(hwnd);
  765. return 0L;
  766.     }
  767.     case MM_FIX: {
  768. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  769.     return 0L;
  770. }
  771. bCheckMutexMenuItem(pInfo, hChildMenu, MM_FIX);
  772. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  773. gFloat = FALSE;
  774. bReleaseInfoData(hwnd);
  775. return 0L;
  776.     }
  777.     case MM_ITERATION_100: {
  778. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  779.     return 0L;
  780. }
  781. bCheckMutexMenuItem(pInfo, hChildMenu, MM_ITERATION_100);
  782. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  783. gIteration = 100;
  784. pInfo->iIteration = 100;
  785. SetWindowText(pInfo->hTextWnd, GetStringRes (IDS_ITER_100));
  786. bReleaseInfoData(hwnd);
  787. return 0L;
  788.     }
  789.     case MM_ITERATION_500: {
  790. if ((pInfo = pGetInfoData(hwnd)) == NULL){
  791.     return 0L;
  792. }
  793. bCheckMutexMenuItem(pInfo, hChildMenu, MM_ITERATION_500);
  794. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  795. gIteration = 500;
  796. pInfo->iIteration = 500;
  797. SetWindowText(pInfo->hTextWnd, GetStringRes (IDS_ITER_500));
  798. bReleaseInfoData(hwnd);
  799. return 0L;
  800.     }
  801.     case MM_ITERATION_1000: {
  802. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  803.     return 0L;
  804. }
  805. bCheckMutexMenuItem(pInfo, hChildMenu, MM_ITERATION_1000);
  806. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  807. gIteration = 1000;
  808. pInfo->iIteration = 1000;
  809. SetWindowText(pInfo->hTextWnd, GetStringRes (IDS_ITER_1000));
  810. bReleaseInfoData(hwnd);
  811. return 0L;
  812.     }
  813.     case MM_ITERATION_5000: {
  814. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  815.     return 0L;
  816. }
  817. bCheckMutexMenuItem(pInfo, hChildMenu, MM_ITERATION_5000);
  818. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  819. gIteration = 5000;
  820. pInfo->iIteration = 5000;
  821. SetWindowText(pInfo->hTextWnd, GetStringRes (IDS_ITER_5000));
  822. bReleaseInfoData(hwnd);
  823. return 0L;
  824.     }
  825.     case MM_ITERATION_DOUBLE: {
  826. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  827.     return 0L;
  828. }
  829. bCheckMutexMenuItem(pInfo, hChildMenu, MM_ITERATION_DOUBLE);
  830. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  831. gIteration *= 2;
  832. pInfo->iIteration = gIteration;
  833. sprintf( gtext, GetStringRes (IDS_ITERATION), pInfo->iIteration);
  834. SetWindowText(pInfo->hTextWnd, gtext);
  835. bReleaseInfoData(hwnd);
  836. return 0L;
  837.     }
  838.     case MM_STEP_ONE: {
  839. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  840.     return 0L;
  841. }
  842. bCheckMutexMenuItem(pInfo, hChildMenu, MM_STEP_ONE);
  843. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  844. gStep = 1;
  845. pInfo->iStep = 1;
  846. bReleaseInfoData(hwnd);
  847. return 0L;
  848.     }
  849.     case MM_STEP_TWO:  {
  850. if ((pInfo = pGetInfoData(hwnd)) == NULL){
  851.     return 0L;
  852. }
  853. bCheckMutexMenuItem(pInfo, hChildMenu, MM_STEP_TWO);
  854. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  855. gStep = 2;
  856. pInfo->iStep = 2;
  857. bReleaseInfoData(hwnd);
  858. return 0L;
  859.     }
  860.     case MM_STEP_THREE: {
  861. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  862.     return 0L;
  863. }
  864. bCheckMutexMenuItem(pInfo, hChildMenu, MM_STEP_THREE);
  865. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  866. gStep = 3;
  867. pInfo->iStep = 3;
  868. bReleaseInfoData(hwnd);
  869. return 0L;
  870.     }
  871.     case MM_LOAD: {
  872. HDC hDC;
  873. OPENFILENAME ofn;
  874. char szDirName[256];
  875. char szFile[256], szFileTitle[256];
  876. static char *szFilter;
  877. RECT    rc;
  878. if ((pInfo = pGetInfoData(hwnd)) == NULL){
  879.     return 0L;
  880. }
  881. szFilter = GetStringRes (IDS_FILE_LIST1);
  882. GetSystemDirectory((LPSTR) szDirName, 256);
  883. strcpy(szFile, "*.bmp");
  884. ofn.lStructSize = sizeof(OPENFILENAME);
  885. ofn.hwndOwner = pInfo->hwnd;
  886. ofn.lpstrFilter = szFilter;
  887. ofn.lpstrCustomFilter = (LPSTR) NULL;
  888. ofn.nMaxCustFilter = 0L;
  889. ofn.nFilterIndex = 1;
  890. ofn.lpstrFile = szFile;
  891. ofn.nMaxFile = sizeof(szFile);
  892. ofn.lpstrFileTitle = szFileTitle;
  893. ofn.nMaxFileTitle = sizeof(szFileTitle);
  894. ofn.lpstrInitialDir = szDirName;
  895. ofn.lpstrTitle = (LPSTR) NULL;
  896. ofn.Flags = 0L;
  897. ofn.nFileOffset = 0;
  898. ofn.nFileExtension = 0;
  899. ofn.lpstrDefExt = "BMP";
  900. if (!GetOpenFileName(&ofn))
  901.     return 0L;
  902. GetClientRect(pInfo->hwnd, &rc);
  903. hDC = GetDC(pInfo->hwnd);
  904. if (LoadBitmapFile(hDC, pInfo, szFile))
  905.   bDrawDIB(hDC, pInfo, 0, 0, rc.right, rc.bottom);
  906. ReleaseDC(hwnd, hDC);
  907. bReleaseInfoData(hwnd);
  908. return 0L;
  909.     }
  910.     case MM_SAVE: {
  911. HDC hDC;
  912. OPENFILENAME ofn;
  913. char szDirName[256];
  914. char szFile[256], szFileTitle[256];
  915. static char *szFilter;
  916. szFilter = GetStringRes (IDS_FILE_LIST2);
  917. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  918.     return 0L;
  919. }
  920. hDC = GetDC(pInfo->hwnd);
  921. #if 0
  922. {
  923. HPALETTE hPalTmp;
  924. hPalTmp = CopyPalette(pInfo->hPal);
  925. DeleteObject(pInfo->hPal);
  926. pInfo->hPal = hPalTmp;
  927. }
  928. #endif
  929. //
  930. // saving special effects user might have created in window
  931. //
  932. if (pInfo->hBmpSaved)
  933.     DeleteObject(pInfo->hBmpSaved);
  934. pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd, pInfo->hPal);
  935. pInfo->bUseDIB = FALSE;
  936. GetSystemDirectory((LPSTR) szDirName, 256);
  937. strcpy(szFile, "*.bmp");
  938. ofn.lStructSize = sizeof(OPENFILENAME);
  939. ofn.hwndOwner = pInfo->hwnd;
  940. ofn.lpstrFilter = szFilter;
  941. ofn.lpstrCustomFilter = (LPSTR) NULL;
  942. ofn.nMaxCustFilter = 0L;
  943. ofn.nFilterIndex = 0L;
  944. ofn.lpstrFile = szFile;
  945. ofn.nMaxFile = sizeof(szFile);
  946. ofn.lpstrFileTitle = szFileTitle;
  947. ofn.nMaxFileTitle = sizeof(szFileTitle);
  948. ofn.lpstrInitialDir = szDirName;
  949. ofn.lpstrTitle = (LPSTR) NULL;
  950. ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
  951. ofn.nFileOffset = 0;
  952. ofn.nFileExtension = 0;
  953. ofn.lpstrDefExt = (LPSTR)NULL;
  954. if (!GetSaveFileName(&ofn)) {
  955.     ReleaseDC(pInfo->hwnd, hDC);
  956.     bReleaseInfoData(hwnd);
  957.     return 0L;
  958. }
  959. SelectPalette(hDC,
  960.    ((pInfo->iStretchMode == HALFTONE) ? pInfo->hHTPal : pInfo->hPal),
  961.    FALSE);
  962. RealizePalette(hDC);
  963. UpdateColors(hDC);
  964. //
  965. // test
  966. //
  967. ghPal = pInfo->hPal;
  968. SaveBitmapFile(hDC, pInfo->hBmpSaved, szFile);
  969. ReleaseDC(pInfo->hwnd, hDC);
  970. bReleaseInfoData(hwnd);
  971. return 0L;
  972.     }
  973.     case MM_SAVE_MONO: {
  974. HDC hDC;
  975. OPENFILENAME ofn;
  976. char szDirName[256];
  977. char szFile[256], szFileTitle[256];
  978. static char *szFilter;
  979. if ((pInfo = pGetInfoData(hwnd)) == NULL){
  980.     return 0L;
  981. }
  982. szFilter = GetStringRes (IDS_FILE_LIST2);
  983. GetSystemDirectory((LPSTR) szDirName, 256);
  984. strcpy(szFile, "*.bmp");
  985. ofn.lStructSize = sizeof(OPENFILENAME);
  986. ofn.hwndOwner = pInfo->hwnd;
  987. ofn.lpstrFilter = szFilter;
  988. ofn.lpstrCustomFilter = (LPSTR) NULL;
  989. ofn.nMaxCustFilter = 0L;
  990. ofn.nFilterIndex = 0L;
  991. ofn.lpstrFile = szFile;
  992. ofn.nMaxFile = sizeof(szFile);
  993. ofn.lpstrFileTitle = szFileTitle;
  994. ofn.nMaxFileTitle = sizeof(szFileTitle);
  995. ofn.lpstrInitialDir = szDirName;
  996. ofn.lpstrTitle = GetStringRes (IDS_SAVING_MONO_BITMAP);
  997. ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
  998. ofn.nFileOffset = 0;
  999. ofn.nFileExtension = 0;
  1000. ofn.lpstrDefExt = (LPSTR)NULL;
  1001. if (!GetSaveFileName(&ofn))
  1002.     return 0L;
  1003. hDC = GetDC(pInfo->hwnd);
  1004. SaveBitmapFile(hDC, pInfo->hBmpMono, szFile);
  1005. ReleaseDC(pInfo->hwnd, hDC);
  1006. bReleaseInfoData(hwnd);
  1007. return 0L;
  1008.     }
  1009.     case MM_STRETCHBLT: {
  1010. if ((pInfo = pGetInfoData(hwnd)) == NULL){
  1011.     return 0L;
  1012. }
  1013. gbStretch = TRUE;
  1014. bCheckMutexMenuItem(pInfo, hChildMenu, MM_STRETCHBLT);
  1015. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  1016. pInfo->bStretch = gbStretch;
  1017. InvalidateRect(pInfo->hwnd, NULL, FALSE);
  1018. bReleaseInfoData(hwnd);
  1019. return 0L;
  1020.     }
  1021.     case MM_BITBLT: {
  1022. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1023.     return 0L;
  1024. }
  1025. gbStretch = FALSE;
  1026. bCheckMutexMenuItem(pInfo, hChildMenu, MM_BITBLT);
  1027. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  1028. pInfo->bStretch = gbStretch;
  1029. InvalidateRect(pInfo->hwnd, NULL, FALSE);
  1030. bReleaseInfoData(hwnd);
  1031. return 0L;
  1032.     }
  1033.     case MM_BLACKONWHITE: {
  1034. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1035.     return 0L;
  1036. }
  1037. giStretchMode = BLACKONWHITE;
  1038. bCheckMutexMenuItem(pInfo, hChildMenu, MM_BLACKONWHITE);
  1039. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  1040. pInfo->iStretchMode = giStretchMode;
  1041. InvalidateRect(pInfo->hwnd, NULL, FALSE);
  1042. bReleaseInfoData(hwnd);
  1043. return 0L;
  1044.     }
  1045.     case MM_COLORONCOLOR: {
  1046. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1047.     return 0L;
  1048. }
  1049. giStretchMode = COLORONCOLOR;
  1050. bCheckMutexMenuItem(pInfo, hChildMenu, MM_COLORONCOLOR);
  1051. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  1052. pInfo->iStretchMode = giStretchMode;
  1053. InvalidateRect(pInfo->hwnd, NULL, FALSE);
  1054. bReleaseInfoData(hwnd);
  1055. return 0L;
  1056.     }
  1057.     case MM_WHITEONBLACK: {
  1058. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1059.     return 0L;
  1060. }
  1061. giStretchMode = WHITEONBLACK;
  1062. bCheckMutexMenuItem(pInfo, hChildMenu, MM_WHITEONBLACK);
  1063. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  1064. pInfo->iStretchMode = giStretchMode;
  1065. InvalidateRect(pInfo->hwnd, NULL, FALSE);
  1066. bReleaseInfoData(hwnd);
  1067. return 0L;
  1068.     }
  1069.     case MM_HALFTONE: {
  1070. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1071.     return 0L;
  1072. }
  1073. giStretchMode = HALFTONE;
  1074. bCheckMutexMenuItem(pInfo, hChildMenu, MM_HALFTONE);
  1075. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  1076. pInfo->iStretchMode = giStretchMode;
  1077. InvalidateRect(pInfo->hwnd, NULL, FALSE);
  1078. bReleaseInfoData(hwnd);
  1079. return 0L;
  1080.     }
  1081.     case MM_SETDIB2DEVICE: {
  1082. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1083.     return 0L;
  1084. }
  1085. bDIB2Device = (bDIB2Device ? FALSE : TRUE);
  1086. pInfo->bSetDIBsToDevice = bDIB2Device;
  1087. CheckMenuItem(hChildMenu, MM_SETDIB2DEVICE, (bDIB2Device ? MF_CHECKED : MF_UNCHECKED));
  1088. bReleaseInfoData(hwnd);
  1089. return 0L;
  1090.     }
  1091.     case MM_BW: {
  1092. HDC hDC;
  1093. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1094.     return 0L;
  1095. }
  1096. hDC = GetDC(pInfo->hwnd);
  1097. bChangeDIBColor(hDC, pInfo, MM_BW);
  1098. ReleaseDC(hwnd, hDC);
  1099. bReleaseInfoData(hwnd);
  1100. return 0L;
  1101.     }
  1102.     case MM_SHIFT: {
  1103. HDC hDC;
  1104. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1105.     return 0L;
  1106. }
  1107. hDC = GetDC(pInfo->hwnd);
  1108. bChangeDIBColor(hDC, pInfo, MM_SHIFT);
  1109. ReleaseDC(hwnd, hDC);
  1110. bReleaseInfoData(hwnd);
  1111. return 0L;
  1112.     }
  1113.     case MM_CUSTOM: {
  1114. static DWORD argbCust[16] = {
  1115.     RGB(255, 255, 255), RGB(255, 255, 255),
  1116.     RGB(255, 255, 255), RGB(255, 255, 255),
  1117.     RGB(255, 255, 255), RGB(255, 255, 255),
  1118.     RGB(255, 255, 255), RGB(255, 255, 255),
  1119.     RGB(255, 255, 255), RGB(255, 255, 255),
  1120.     RGB(255, 255, 255), RGB(255, 255, 255),
  1121.     RGB(255, 255, 255), RGB(255, 255, 255),
  1122.     RGB(255, 255, 255), RGB(255, 255, 255)
  1123. };
  1124. CHOOSECOLOR cc;
  1125. BOOL bResult;
  1126. DWORD rgbOld;
  1127. HBRUSH hBrush;
  1128. HDC hDC;
  1129. rgbOld = RGB(255, 255, 255);
  1130. cc.lStructSize = sizeof(CHOOSECOLOR);
  1131. cc.hwndOwner = ghwndMain;
  1132. cc.hInstance = ghModule;
  1133. cc.rgbResult = rgbOld;
  1134. cc.lpCustColors = argbCust;
  1135. cc.Flags = CC_RGBINIT | CC_SHOWHELP;
  1136. cc.lCustData = 0;
  1137. cc.lpfnHook = NULL;
  1138. cc.lpTemplateName = NULL;
  1139. bResult = ChooseColor(&cc);
  1140. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1141.     return 0L;
  1142. }
  1143. if (bResult) {
  1144.     hDC = GetDC(pInfo->hwnd);
  1145.     hBrush = hBrCreateBrush(hDC, cc.rgbResult);
  1146.     ReleaseDC(pInfo->hwnd, hDC);
  1147.     if (pInfo->hBrush)
  1148. DeleteObject(pInfo->hBrush);
  1149.     pInfo->hBrush = hBrush;
  1150.     pInfo->bFill = TRUE;
  1151. }
  1152. bReleaseInfoData(hwnd);
  1153. return 0L;
  1154. }
  1155. #ifndef CYCLETHRD
  1156.     case MM_CYCLE: {
  1157. HDC hDC;
  1158. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1159.     return 0L;
  1160. }
  1161. hDC = GetDC(pInfo->hwnd);
  1162. if (pInfo->bClrCycle) {
  1163.     CheckMenuItem(hChildMenu, MM_CYCLE, MF_UNCHECKED);
  1164.     pInfo->bClrCycle = FALSE;
  1165. } else {
  1166.     CheckMenuItem(hChildMenu, MM_CYCLE, MF_CHECKED);
  1167.     pInfo->bClrCycle = TRUE;
  1168.     bChangeDIBColor(hDC, pInfo, MM_CYCLE);
  1169. }
  1170. ReleaseDC(hwnd, hDC);
  1171. bReleaseInfoData(hwnd);
  1172. return 0L;
  1173.     }
  1174. #else
  1175.     case MM_CYCLE: {
  1176. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1177.     return 0L;
  1178. }
  1179. if (pInfo->bFirstTime) 
  1180. {
  1181.     if (!SetEvent(pInfo->hQuitEvent)) 
  1182. {
  1183. OutputDebugString ("Can't set Quit Event!");
  1184. return 0L;
  1185.     }
  1186.     if (pInfo->hCycleThrd)
  1187. CloseHandle(pInfo->hCycleThrd);
  1188.     pInfo->hCycleThrd = CreateThread(NULL, 0,
  1189.      (LPTHREAD_START_ROUTINE)bCycle,
  1190.      (LPVOID)hwnd,
  1191.      STANDARD_RIGHTS_REQUIRED,
  1192.      &pInfo->dwCycleThrdID );
  1193.     pInfo->bClrCycle = TRUE;
  1194.     pInfo->bFirstTime = FALSE;
  1195.     CheckMenuItem(hChildMenu, MM_CYCLE, MF_CHECKED);
  1196. } else {
  1197.     if (pInfo->bClrCycle) {
  1198. CheckMenuItem(hChildMenu, MM_CYCLE, MF_UNCHECKED);
  1199. pInfo->bClrCycle = FALSE;
  1200. pInfo->dwSuspend = SuspendThread(pInfo->hCycleThrd);
  1201.     } else {
  1202. CheckMenuItem(hChildMenu, MM_CYCLE, MF_CHECKED);
  1203. pInfo->bClrCycle = TRUE;
  1204. pInfo->dwSuspend = ResumeThread(pInfo->hCycleThrd);
  1205.     }
  1206.     if (pInfo->dwSuspend == -1) {
  1207. (pInfo->bClrCycle ?
  1208.  sprintf( gtext,"Error in resuming threadn") :
  1209.  sprintf( gtext,"Error in suspending threadn")  );
  1210. OutputDebugString( gtext );
  1211.     }
  1212. }
  1213. bReleaseInfoData(hwnd);
  1214. return 0L;
  1215.     }
  1216. #endif
  1217.     case MM_CLIP: {
  1218. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1219.     return 0L;
  1220. }
  1221. hTextWnd = pInfo->hTextWnd;
  1222. sprintf( gtext,"(%g, %g) <-> (%g, %g)", pInfo->xFrom, pInfo->yFrom, pInfo->xTo, pInfo->yTo);
  1223. SetWindowText(hTextWnd, gtext);
  1224. sprintf( gtext,"(c1 = %g, c2 = %g)nn", pInfo->c1, pInfo->c2);
  1225. OutputDebugString( gtext );
  1226. if (!pInfo->bMandel) 
  1227. {
  1228.     MessageBox(ghwndMain, 
  1229.    GetStringRes (IDS_BOUNDARY),
  1230.    NULL, MB_OK);
  1231.     return 0L;
  1232. }
  1233. if (pInfo->hThrd)
  1234.     CloseHandle(pInfo->hThrd);
  1235. pInfo->hThrd = CreateThread(NULL, 0,
  1236.  (gFloat ? (LPTHREAD_START_ROUTINE)bBoundaryScanFix : (LPTHREAD_START_ROUTINE)bBoundaryScanFix),
  1237.  pInfo,
  1238.  STANDARD_RIGHTS_REQUIRED,
  1239.  &pInfo->dwThreadId );
  1240.        bReleaseInfoData(hwnd);
  1241.        return 0L;
  1242.     }
  1243.     case MM_RM_CLIP: {
  1244. HDC     hDC;
  1245. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1246.     return 0L;
  1247. }
  1248. hDC = GetDC(pInfo->hwnd);
  1249. SelectClipRgn(hDC, (HRGN) NULL);
  1250. ReleaseDC(pInfo->hwnd, hDC);
  1251. bReleaseInfoData(hwnd);
  1252. InvalidateRect(pInfo->hwnd, NULL, FALSE);
  1253. return 0L;
  1254.     }
  1255.     case MM_SELCLIPRGN: {
  1256. HDC     hDC;
  1257. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1258.     return 0L;
  1259. }
  1260. hDC = GetDC(pInfo->hwnd);
  1261. if (pInfo->hRgnPath != (HRGN) NULL) {
  1262.     SelectClipRgn(hDC, pInfo->hRgnPath);
  1263. }
  1264. ReleaseDC(pInfo->hwnd, hDC);
  1265. bReleaseInfoData(hwnd);
  1266. return 0L;
  1267.     }
  1268.     case MM_ERASE: {
  1269. HDC     hDC;
  1270. RECT    rc;
  1271. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1272.     return 0L;
  1273. }
  1274. hDC = GetDC(pInfo->hwnd);
  1275. if (pInfo->hRgnPath != (HRGN) NULL) {
  1276.     SelectClipRgn(hDC, pInfo->hRgnPath);
  1277. }
  1278. SelectObject(hDC, GetStockObject(WHITE_BRUSH));
  1279. GetClientRect(pInfo->hwnd, &rc);
  1280. PatBlt(hDC, 0, 0, rc.right, rc.bottom, PATCOPY);
  1281. ReleaseDC(pInfo->hwnd, hDC);
  1282. bReleaseInfoData(hwnd);
  1283. return 0L;
  1284.     }
  1285.     case MM_PORTRAIT: {
  1286. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1287.     return 0L;
  1288. }
  1289. giDmOrient = DMORIENT_PORTRAIT;
  1290. bCheckMutexMenuItem(pInfo, hChildMenu, MM_PORTRAIT);
  1291. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  1292. bReleaseInfoData(hwnd);
  1293. return 0L;
  1294.     }
  1295.     case MM_LANDSCAPE: {
  1296. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1297.     return 0L;
  1298. }
  1299. giDmOrient = DMORIENT_LANDSCAPE;
  1300. bCheckMutexMenuItem(pInfo, hChildMenu, MM_LANDSCAPE);
  1301. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  1302. bReleaseInfoData(hwnd);
  1303. return 0L;
  1304.     }
  1305.     case MM_PRINTER:
  1306.     case MM_PRINTER + 1:
  1307.     case MM_PRINTER + 2:
  1308.     case MM_PRINTER + 3:
  1309.     case MM_PRINTER + 4:
  1310.     case MM_PRINTER + 5:
  1311.     case MM_PRINTER + 6:
  1312.     case MM_PRINTER + 7:
  1313.     case MM_PRINTER + 8:
  1314. #ifdef PRTTHRD
  1315.     case MM_PRINTER + 9: {
  1316. PINFO       pInfo;
  1317. PRTDATA     PrtData, *pPrtData;
  1318. ULONG       sizINFO;
  1319. PBYTE       pjTmpInfo, pjTmp;
  1320. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1321.     return 0L;
  1322. }
  1323. if (pInfo->hBmpSaved == NULL) 
  1324. {
  1325.     MessageBox(ghwndMain, 
  1326.        GetStringRes (IDS_NO_SAVED_BITMAP),
  1327.    NULL, MB_OK);
  1328.     return 0L;
  1329. }
  1330. //
  1331. // Copy the info structure to PrtData
  1332. //
  1333. pPrtData = &PrtData;
  1334. pjTmp    = (PBYTE)&(pPrtData->info);
  1335. pjTmpInfo = (PBYTE)pInfo;
  1336. sizINFO = sizeof(INFO);
  1337. while(sizINFO--)
  1338. {
  1339.     *(((PBYTE)pjTmp)++) = *((pjTmpInfo)++);
  1340. }
  1341. PrtData.index = LOWORD(wParam) - MM_PRINTER;
  1342. if (giDmOrient == DMORIENT_PORTRAIT) {
  1343.     PrtData.bUseDefault = TRUE;
  1344. } else {
  1345.     PrtData.bUseDefault = FALSE;
  1346.     PrtData.DevMode.dmSize = sizeof(DEVMODE);
  1347.     PrtData.DevMode.dmDriverExtra = 0;
  1348.     PrtData.DevMode.dmOrientation = DMORIENT_LANDSCAPE;
  1349.     PrtData.DevMode.dmFields = DM_ORIENTATION;
  1350. }
  1351. if (pInfo->hPrtThrd)
  1352.     CloseHandle(pInfo->hPrtThrd);
  1353. pInfo->hPrtThrd = CreateThread(NULL, 0,
  1354.  (LPTHREAD_START_ROUTINE)bPrintBmp,
  1355.  &PrtData,
  1356.  STANDARD_RIGHTS_REQUIRED,
  1357.  &pInfo->dwPrtThrdID );
  1358. bReleaseInfoData(hwnd);
  1359. return 0L;
  1360.     }
  1361. #else
  1362.     case MM_PRINTER + 9: {
  1363. HDC         hdcPrinter, hDC;
  1364. int         index;
  1365. DEVMODE     devmode;
  1366. DEVMODE     *pdevmode;
  1367. PINFO       pInfo;
  1368. int         iWidth, iHeight;
  1369. index = LOWORD(wParam) - MM_PRINTER;
  1370. if (giDmOrient == DMORIENT_PORTRAIT)
  1371.     pdevmode = NULL;
  1372. else {
  1373.     pdevmode = &devmode;
  1374.     devmode.dmSize = sizeof(DEVMODE);
  1375.     devmode.dmDriverExtra = 0;
  1376.     devmode.dmOrientation = DMORIENT_LANDSCAPE;
  1377.     devmode.dmFields = DM_ORIENTATION;
  1378. }
  1379. if (!(hdcPrinter = CreateDC( "", gpszPrinterNames[index],
  1380.      "", pdevmode)))
  1381. {
  1382.     return(0L);
  1383. }
  1384. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1385.     return 0L;
  1386. }
  1387. iWidth = GetDeviceCaps(hdcPrinter, HORZRES);
  1388. iHeight = GetDeviceCaps(hdcPrinter, VERTRES);
  1389. // !!! Why is it necessary to save the image over again?  May not want to
  1390. //     do this because user may want to print the nice HT bitmap. So,
  1391. //     use the DIB src.
  1392. #if 0
  1393. if (pInfo->hBmpSaved)
  1394.     DeleteObject(pInfo->hBmpSaved);
  1395. pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd, pInfo->hPal);
  1396. #endif
  1397. Escape(hdcPrinter, STARTDOC, 20, "Mandelbrot", NULL);
  1398. bDrawDIB(hdcPrinter, pInfo, 0, 0, iWidth, iHeight);
  1399. Escape(hdcPrinter, NEWFRAME, 0, NULL, NULL);
  1400. Escape(hdcPrinter, ENDDOC, 0, NULL, NULL);
  1401. ReleaseDC(pInfo->hwnd, hDC);
  1402. bReleaseInfoData(hwnd);
  1403. DeleteDC(hdcPrinter);
  1404. return 0L;
  1405.     }
  1406. #endif
  1407.     default:
  1408.        return 0L;
  1409.   }
  1410. }
  1411. case WM_SETFOCUS:
  1412.     break;
  1413. case WM_MDIACTIVATE: {
  1414.     PINFO       pInfo;
  1415.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1416. return 0L;
  1417.     }
  1418.     if ((HWND) lParam == hwnd) {                // being activated
  1419. SendMessage(GetParent(hwnd), WM_MDISETMENU,
  1420.     (DWORD)  hChildMenu,
  1421.     (LONG)   hSubMenuThree) ;
  1422. (pInfo->bClrCycle ?
  1423.     CheckMenuItem(hChildMenu, MM_CYCLE, MF_CHECKED) :
  1424.     CheckMenuItem(hChildMenu, MM_CYCLE, MF_UNCHECKED) );
  1425. vChkMenuItem(pInfo, hChildMenu, MF_CHECKED);
  1426. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  1427. goto MDI_ACT_EXIT;
  1428.     }
  1429.     if ((HWND) wParam == hwnd) {                // being deactivated
  1430. vChkMenuItem(pInfo, hChildMenu, MF_UNCHECKED);
  1431. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  1432.     }
  1433. MDI_ACT_EXIT:
  1434.     bReleaseInfoData(hwnd);
  1435.     return 0L;
  1436. }
  1437. case WM_QUERYNEWPALETTE:
  1438. case WM_PALETTECHANGED: {
  1439.     PINFO       pInfo;
  1440.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1441. return 0L;
  1442.     }
  1443.     SendMessage(pInfo->hwnd, message, wParam, lParam);
  1444.     bReleaseInfoData(hwnd);
  1445.     return 0L;
  1446. }
  1447. #if 0
  1448. case WM_WINDOWPOSCHANGING: {
  1449.     PWINDOWPOS  pWndPos;
  1450.     PINFO       pInfo;
  1451.     HWND        hTextWnd;
  1452.     int         iCyText, iCxBorder, iCyBorder, iCyCaption;
  1453.     RECT        rect, rcl;
  1454.     LONG        lcx, lcy;
  1455.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1456. break;
  1457.     }
  1458.     hTextWnd = pInfo->hTextWnd;
  1459.     bReleaseInfoData(hwnd);
  1460.     iCyText = GetWindowLong(hTextWnd, GWL_USERDATA);
  1461.     iCxBorder = GetSystemMetrics(SM_CXBORDER);
  1462.     iCyBorder = GetSystemMetrics(SM_CYBORDER);
  1463.     iCyCaption = GetSystemMetrics(SM_CYCAPTION) - iCyBorder;
  1464.     GetClientRect(GetParent(hwnd), &rcl);
  1465.     GetWindowRect(hwnd, &rect);
  1466.     lcx = rect.right-rect.left;
  1467.     lcy = rect.bottom-rect.top;
  1468.     pWndPos = (PWINDOWPOS)lParam;
  1469.     if ((pWndPos->cy > lcy) || (pWndPos->cx > lcx)) {
  1470. pWndPos->cx =
  1471.    ((pWndPos->cx > pWndPos->cy) ? pWndPos->cy-iCyText : pWndPos->cx);
  1472. pWndPos->cy = pWndPos->cx + iCyText;
  1473.     } else { if ((pWndPos->cy < lcy) || (pWndPos->cx < lcx)) {
  1474.      pWndPos->cx =
  1475. ((pWndPos->cx > pWndPos->cy) ? pWndPos->cy-iCyText : pWndPos->cx);
  1476.      pWndPos->cy = pWndPos->cx + iCyText;
  1477.    }
  1478.     }
  1479.     break;
  1480. }
  1481. #endif
  1482. case WM_SIZE: {
  1483.     HANDLE      hThrd;
  1484.     PINFO       pInfo;
  1485.     HWND        hTextWnd, hJulia;
  1486.     BOOL        bMandel;
  1487.     WORD        wCx;
  1488.     int         iCyText;
  1489.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1490. break;
  1491.     }
  1492.     hTextWnd = pInfo->hTextWnd;
  1493.     hJulia   = pInfo->hwnd;
  1494.     hThrd    = pInfo->hThrd;
  1495.     bMandel  = pInfo->bMandel;
  1496.     bReleaseInfoData(hwnd);
  1497.     iCyText = GetWindowLong(hTextWnd, GWL_USERDATA);
  1498.     wCx = (WORD) (HIWORD(lParam) - iCyText);
  1499.     MoveWindow(hJulia, 0, 0,
  1500.    LOWORD(lParam),
  1501.    wCx,
  1502.    TRUE);
  1503.     MoveWindow(hTextWnd,
  1504.        0,
  1505.        wCx,
  1506.        LOWORD(lParam),
  1507.        iCyText,
  1508.        TRUE);
  1509.     if (hThrd) {
  1510. TerminateThread(hThrd, (DWORD)0L);
  1511. /*
  1512. PostMessage(hwnd, WM_COMMAND,
  1513.     bMandel ? (DWORD)((WORD)MM_CREATE_MANDEL_THREAD) : (DWORD)((WORD)MM_CREATE_JULIA_THREAD),
  1514.     (LONG)0L);
  1515.   */
  1516.     }
  1517.     break;
  1518. }
  1519. //
  1520. // display info in the status window
  1521. //
  1522. case WM_USER+0xa: {
  1523.     PINFO       pInfo;
  1524.     static ULONG ulClick = 0;
  1525.     HWND        hTextWnd;
  1526.     ulClick++;
  1527.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1528. return 0L;
  1529.     }
  1530.     hTextWnd = pInfo->hTextWnd;
  1531.     switch (ulClick % 6) {
  1532. case 0: sprintf( gtext,"%g <= x <= %g, %g <= y <= %g", pInfo->xFrom, pInfo->xTo, pInfo->yTo, pInfo->yFrom);
  1533. break;
  1534. case 1: sprintf( gtext,"c1 = %g, c2 = %g", pInfo->c1, pInfo->c2);
  1535. break;
  1536. case 2: sprintf( gtext,
  1537.      GetStringRes (IDS_ELAPSED_TIME),
  1538.  (ULONG) pInfo->dwElapsed);
  1539. break;
  1540. case 3: sprintf( gtext,
  1541.      GetStringRes (IDS_ITERATION),
  1542.  pInfo->iIteration);
  1543. break;
  1544. case 4: sprintf( gtext,
  1545.  GetStringRes (IDS_STEP),
  1546.  pInfo->iStep);
  1547. break;
  1548. case 5: 
  1549. (gFloat ? sprintf( gtext, GetStringRes (IDS_FLOATING_PT))
  1550.         : sprintf( gtext, GetStringRes (IDS_FIXED_PT))) ;
  1551. break;
  1552. default: break;
  1553.     }
  1554.     SetWindowText(hTextWnd, gtext);
  1555.     bReleaseInfoData(hwnd);
  1556.     return 0L;
  1557. }
  1558. case WM_SYSCOMMAND: {
  1559.     LONG        lResult;
  1560.     EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnSuspendThrd, lParam);
  1561.     lResult = DefMDIChildProc(hwnd, message, wParam, lParam);
  1562.     EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnResumeThrd, lParam);
  1563.     return lResult;
  1564.     break;
  1565. }
  1566. case WM_CREATE: {
  1567.     PINFO           pInfo;
  1568.     HANDLE          hInfo;
  1569.     HWND            hTextWnd, hJulia;
  1570.     RECT            rcl;
  1571.     //
  1572.     // CR! MakeProcInstance is noop!
  1573.     //
  1574.     lpfnSuspendThrd = (FARPROC)MakeProcInstance (SuspendDrawThrd, ghModule);
  1575.     lpfnResumeThrd  = (FARPROC)MakeProcInstance (ResumeDrawThrd, ghModule);
  1576.     hTextWnd = CreateWindow("Text", NULL,
  1577.     WS_BORDER | SS_LEFT | WS_CHILD | WS_VISIBLE,
  1578.     0, 0, 0, 0,
  1579.     hwnd,
  1580.     (HMENU) 2,
  1581.     ghModule,
  1582.     NULL);
  1583.     GetClientRect(hwnd, &rcl);
  1584.     hJulia = CreateWindow("Julia", (LPSTR) NULL,
  1585.   WS_CHILD      | WS_VISIBLE     |
  1586.   WS_BORDER,
  1587.   0,0, rcl.right-rcl.left,
  1588.   rcl.bottom-rcl.top-GetWindowLong(hTextWnd, GWL_USERDATA),
  1589.   hwnd, (HMENU)1, ghModule, (LPVOID)NULL);
  1590.     SetWindowText(hTextWnd, GetStringRes (IDS_SELECT_DRAW_SET));
  1591.     hInfo = (HANDLE) ((LPMDICREATESTRUCT) ((LPCREATESTRUCT) lParam)->lpCreateParams)->lParam ;
  1592.     if (hInfo) {
  1593. if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) 
  1594. {
  1595.     OutputDebugString ("Failed in LocalLock, hNode");
  1596.     break;
  1597. else 
  1598. {
  1599.     HDC hDC;
  1600.     if (!GetClientRect(hwnd, &pInfo->rcClient))
  1601. OutputDebugString ("Failed in GetClientRect!");
  1602.     pInfo->hTextWnd = hTextWnd;
  1603.     pInfo->hwnd = hJulia;
  1604.     hDC = GetDC(hJulia);
  1605.     pInfo->hHTPal = CreateHalftonePalette(hDC);
  1606.     ReleaseDC(hJulia, hDC);
  1607. #ifdef CYCLETHRD
  1608.     //
  1609.     // Creating a signal quit color cycling event
  1610.     //
  1611.     if ((pInfo->hQuitEvent = CreateEvent(NULL, TRUE, TRUE, NULL)) == NULL)
  1612. OutputDebugString ("Failed in creating Quit Event!");
  1613. #endif
  1614.     SetWindowLong(hwnd, 0, (LONG) hInfo);
  1615.     LocalUnlock(hInfo);
  1616. }
  1617.     } 
  1618. else 
  1619. {
  1620. OutputDebugString ("Can't allocate hInfo!");
  1621.     }
  1622. #if 0
  1623.     //
  1624.     // Initialize printers here will detect printers availiability
  1625.     // more often, but kind of overkill.
  1626.     //
  1627.     bInitPrinter(hwnd);
  1628. #endif
  1629.     break;
  1630. }
  1631. case WM_CLOSE: {
  1632.     SendMessage(GetParent(hwnd), WM_MDISETMENU,
  1633.     (DWORD) hMenu,
  1634.     (LONG)  hSubMenuOne) ;
  1635.     DrawMenuBar(GetParent(GetParent(hwnd))) ;
  1636.     break;
  1637. }
  1638. case WM_DESTROY: {
  1639.     PINFO            pInfo;
  1640.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1641. break;
  1642.     }
  1643.     if (pInfo->hThrd) {
  1644. TerminateThread(pInfo->hThrd, (DWORD)0L);
  1645. CloseHandle(pInfo->hThrd);
  1646.     }
  1647.     if (pInfo->hPrtThrd) {
  1648. TerminateThread(pInfo->hPrtThrd, (DWORD)0L);
  1649. CloseHandle(pInfo->hPrtThrd);
  1650.     }
  1651.     if (pInfo->hCycleThrd) {
  1652. TerminateThread(pInfo->hCycleThrd, (DWORD)0L);
  1653. CloseHandle(pInfo->hCycleThrd);
  1654.     }
  1655. #ifdef CYCLETHRD
  1656.     //
  1657.     // Cleanup color cycling
  1658.     //
  1659.     if (!ResetEvent(pInfo->hQuitEvent))
  1660. OutputDebugString ("Failed in reseting quit event!");
  1661. #endif
  1662.     if (pInfo->hBmpMono)
  1663. DeleteObject(pInfo->hBmpMono);
  1664.     if (pInfo->hBmpSaved)
  1665. DeleteObject(pInfo->hBmpSaved);
  1666.     if (pInfo->hBrush)
  1667. DeleteObject(pInfo->hBrush);
  1668.     bReleaseInfoData(hwnd);
  1669.     LocalFree((HANDLE) GetWindowLong(hwnd, 0));
  1670.     break;
  1671. }
  1672. default:
  1673.     return DefMDIChildProc(hwnd, message, wParam, lParam);
  1674.     } //switch
  1675.     return DefMDIChildProc(hwnd, message, wParam, lParam);
  1676. }
  1677. /******************************Public*Routine******************************
  1678. *
  1679. * ViewerWndProc
  1680. *
  1681. * Effects:
  1682. *
  1683. * Warnings:
  1684. *
  1685. **************************************************************************/
  1686. LONG APIENTRY ViewerWndProc(
  1687.     HWND hwnd,
  1688.     UINT message,
  1689.     DWORD wParam,
  1690.     LONG lParam)
  1691. {
  1692.     static FARPROC     lpfnSuspendThrd, lpfnResumeThrd;
  1693.     switch (message) {
  1694. case WM_COMMAND: {
  1695.   PINFO       pInfo;
  1696.   HWND        hTextWnd;
  1697.   switch (LOWORD(wParam)) {
  1698.     case MM_RLELOAD_DEMO: {
  1699. HDC             hDC;
  1700. char            szDirName[256];
  1701. char            szFile[400];
  1702. HWND            hViewSurf;
  1703. GetCurrentDirectory(256, (LPTSTR) szDirName);
  1704. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1705.     return 0L;
  1706. }
  1707. if ((hViewSurf = pInfo->hwnd) == NULL)
  1708.     return 0L;
  1709. hTextWnd = pInfo->hTextWnd;
  1710. sprintf( gtext,"Loading bitmap(s) into memory");
  1711. SetWindowText(hTextWnd, gtext);
  1712. hDC = GetDC(hViewSurf);
  1713. strcpy(szFile, szDirName);
  1714. strcat(szFile, "\rsc\julia.rle");
  1715. if (bStoreRleFile(hDC, pInfo, szFile)) {
  1716.     pInfo->RleData.ulFiles++;
  1717.     PostMessage(ghwndMain, WM_COMMAND, MM_RLEPLAYCONT, 0L);
  1718. }
  1719. ReleaseDC(hViewSurf, hDC);
  1720. bReleaseInfoData(hwnd);
  1721. return 0L;
  1722.     }
  1723.     case MM_RLELOAD: {
  1724. HDC             hDC;
  1725. OPENFILENAME    ofn;
  1726. char            szDirName[256];
  1727. char            szFile[256], szFileTitle[256];
  1728. static char     *szFilter;
  1729. RECT            rc;
  1730. HWND            hViewSurf;
  1731. szFilter = GetStringRes (IDS_FILE_LIST1);
  1732. GetSystemDirectory((LPSTR) szDirName, 256);
  1733. strcpy(szFile, "*.bmp");
  1734. ofn.lStructSize = sizeof(OPENFILENAME);
  1735. ofn.hwndOwner = hwnd;
  1736. ofn.lpstrFilter = szFilter;
  1737. ofn.lpstrCustomFilter = (LPSTR) NULL;
  1738. ofn.nMaxCustFilter = 0L;
  1739. ofn.nFilterIndex = 1;
  1740. ofn.lpstrFile = szFile;
  1741. ofn.nMaxFile = sizeof(szFile);
  1742. ofn.lpstrFileTitle = szFileTitle;
  1743. ofn.nMaxFileTitle = sizeof(szFileTitle);
  1744. ofn.lpstrInitialDir = szDirName;
  1745. ofn.lpstrTitle = (LPSTR) NULL;
  1746. ofn.Flags = 0L;
  1747. ofn.nFileOffset = 0;
  1748. ofn.nFileExtension = 0;
  1749. ofn.lpstrDefExt = "BMP";
  1750. if (!GetOpenFileName(&ofn))
  1751.     return 0L;
  1752. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1753.     return 0L;
  1754. }
  1755. if ((hViewSurf = pInfo->hwnd) == NULL)
  1756.     return 0L;
  1757. hTextWnd = pInfo->hTextWnd;
  1758. sprintf( gtext, GetStringRes (IDS_LOADING_BITMAPS));
  1759. SetWindowText(hTextWnd, gtext);
  1760. GetClientRect(hwnd, &rc);
  1761. hDC = GetDC(hViewSurf);
  1762. if (bStoreRleFile(hDC, pInfo, szFile))
  1763.     pInfo->RleData.ulFiles++;
  1764. ReleaseDC(hViewSurf, hDC);
  1765. bReleaseInfoData(hwnd);
  1766. return 0L;
  1767.     }
  1768.     case MM_RLESAVE: {
  1769. HDC             hDC;
  1770. OPENFILENAME    ofn;
  1771. char            szDirName[256];
  1772. char            szFile[256], szFileTitle[256];
  1773. static char     *szFilter;
  1774. HWND            hViewSurf;
  1775. szFilter = GetStringRes (IDS_FILE_LIST3);
  1776. GetSystemDirectory((LPSTR) szDirName, 256);
  1777. strcpy(szFile, "*.rle");
  1778. ofn.lStructSize = sizeof(OPENFILENAME);
  1779. ofn.hwndOwner = hwnd;
  1780. ofn.lpstrFilter = szFilter;
  1781. ofn.lpstrCustomFilter = (LPSTR) NULL;
  1782. ofn.nMaxCustFilter = 0L;
  1783. ofn.nFilterIndex = 0L;
  1784. ofn.lpstrFile = szFile;
  1785. ofn.nMaxFile = sizeof(szFile);
  1786. ofn.lpstrFileTitle = szFileTitle;
  1787. ofn.nMaxFileTitle = sizeof(szFileTitle);
  1788. ofn.lpstrInitialDir = szDirName;
  1789. ofn.lpstrTitle = GetStringRes(IDS_SAVING_MEMORY_RLE); 
  1790. ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
  1791. ofn.nFileOffset = 0;
  1792. ofn.nFileExtension = 0;
  1793. ofn.lpstrDefExt = (LPSTR)NULL;
  1794. if (!GetSaveFileName(&ofn))
  1795.     return 0L;
  1796. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1797.     return 0L;
  1798. }
  1799. if ((hViewSurf = pInfo->hwnd) == NULL)
  1800.     return 0L;
  1801. hTextWnd = pInfo->hTextWnd;
  1802. sprintf( gtext, GetStringRes (IDS_SAVING_LOADED_BMP)); 
  1803. SetWindowText(hTextWnd, gtext);
  1804. hDC = GetDC(hViewSurf);
  1805. bSaveRleFile(hDC, pInfo, szFile);
  1806. ReleaseDC(hViewSurf, hDC);
  1807. bReleaseInfoData(hwnd);
  1808. return 0L;
  1809.     }
  1810.     case MM_CLEAR: {
  1811. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1812.     return 0L;
  1813. }
  1814. hTextWnd = pInfo->hTextWnd;
  1815. sprintf( gtext,GetStringRes (IDS_DISCARD_LOADED_BMP));
  1816. SetWindowText(hTextWnd, gtext);
  1817. bFreeRleFile(pInfo);
  1818. bReleaseInfoData(hwnd);
  1819. return 0L;
  1820.     }
  1821.     case MM_RLEPLAY: {
  1822. HDC     hDC;
  1823. HWND    hViewSurf;
  1824. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1825.     return 0L;
  1826. }
  1827. if ((hViewSurf = pInfo->hwnd) == NULL)
  1828.     return 0L;
  1829. hTextWnd = pInfo->hTextWnd;
  1830. sprintf( gtext, GetStringRes (IDS_PLAY_LOADED_BMP)); 
  1831. SetWindowText(hTextWnd, gtext);
  1832. hDC = GetDC(hViewSurf);
  1833. EnableMenuItem(hViewSubOne, MM_CLEAR, MF_GRAYED);
  1834. if (pInfo->hThrd0)
  1835.     CloseHandle(pInfo->hThrd0);
  1836. pInfo->hThrd0 = CreateThread(NULL, 0,
  1837.      (LPTHREAD_START_ROUTINE)bPlayRle,
  1838.      pInfo,
  1839.      STANDARD_RIGHTS_REQUIRED,
  1840.      &pInfo->dwThreadId );
  1841. if (pInfo->hThrd0) 
  1842. {
  1843.     if (!SetThreadPriority(pInfo->hThrd0, THREAD_PRIORITY_BELOW_NORMAL))
  1844.    OutputDebugString ("Can't set Priority!");
  1845. }
  1846. //bPlayRle(hDC, pInfo);
  1847. EnableMenuItem(hViewSubOne, MM_CLEAR, MF_ENABLED);
  1848. ReleaseDC(hViewSurf, hDC);
  1849. bReleaseInfoData(hwnd);
  1850. return 0L;
  1851.     }
  1852.     case MM_RLEPLAYCONT: {
  1853. HWND    hViewSurf;
  1854. if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1855.     return 0L;
  1856. }
  1857. if ((hViewSurf = pInfo->hwnd) == NULL)
  1858.     return 0L;
  1859. hTextWnd = pInfo->hTextWnd;
  1860. sprintf( gtext, GetStringRes (IDS_PLAY_BMP_CONT));
  1861. SetWindowText(hTextWnd, gtext);
  1862. if (pInfo->bFirstTime) 
  1863. {
  1864.     if (!SetEvent(pInfo->hQuitEvent)) 
  1865. {
  1866. OutputDebugString ("Can't set Quit Event!");
  1867.     return 0L;
  1868.     }
  1869.     EnableMenuItem(hViewSubOne, MM_CLEAR, MF_GRAYED);
  1870.     if (pInfo->hThrd)
  1871. CloseHandle(pInfo->hThrd);
  1872.     pInfo->hThrd = CreateThread(NULL, 0,
  1873.  (LPTHREAD_START_ROUTINE)bPlayRleCont2,
  1874.  pInfo,
  1875.  STANDARD_RIGHTS_REQUIRED,
  1876.  &pInfo->dwThreadId );
  1877.     if (pInfo->hThrd) {
  1878. if (!SetThreadPriority(pInfo->hThrd, THREAD_PRIORITY_BELOW_NORMAL))
  1879.      OutputDebugString ("Can't set Priority!");
  1880.     }
  1881.     pInfo->bPlayRleCont = TRUE;
  1882.     pInfo->bFirstTime = FALSE;
  1883.     CheckMenuItem(hViewMenu, MM_RLEPLAYCONT, MF_CHECKED);
  1884. else 
  1885. {
  1886.     if (pInfo->bPlayRleCont) {
  1887. EnableMenuItem(hViewSubOne, MM_CLEAR, MF_ENABLED);
  1888. CheckMenuItem(hViewMenu, MM_RLEPLAYCONT, MF_UNCHECKED);
  1889. pInfo->bPlayRleCont = FALSE;
  1890. pInfo->dwSuspend = SuspendThread(pInfo->hThrd);
  1891.     } else {
  1892. EnableMenuItem(hViewSubOne, MM_CLEAR, MF_GRAYED);
  1893. CheckMenuItem(hViewMenu, MM_RLEPLAYCONT, MF_CHECKED);
  1894. pInfo->bPlayRleCont = TRUE;
  1895. pInfo->dwSuspend = ResumeThread(pInfo->hThrd);
  1896.     }
  1897.     if (pInfo->dwSuspend == -1) {
  1898. (pInfo->bPlayRleCont ?
  1899.  sprintf( gtext,"Error in resuming threadn") :
  1900.  sprintf( gtext,"Error in suspending threadn")  );
  1901. OutputDebugString( gtext );
  1902.     }
  1903. }
  1904. bReleaseInfoData(hwnd);
  1905. return 0L;
  1906.     }
  1907.     default:
  1908.        return 0L;
  1909.   } //switch
  1910. } // WM_COMMAND
  1911. case WM_SETFOCUS:
  1912.     break;
  1913. case WM_MDIACTIVATE: {
  1914.     PINFO       pInfo;
  1915.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1916. return 0L;
  1917.     }
  1918.     if ((HWND) lParam == hwnd) {
  1919. SendMessage(GetParent(hwnd), WM_MDISETMENU,
  1920.     (WPARAM)  hViewMenu,
  1921.     (LPARAM)  NULL) ;
  1922. DrawMenuBar(GetParent(GetParent(hwnd))) ;
  1923.     }
  1924.     bReleaseInfoData(hwnd);
  1925.     return 0L;
  1926. }
  1927. case WM_QUERYNEWPALETTE:
  1928. case WM_PALETTECHANGED: {
  1929.     PINFO       pInfo;
  1930.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1931. return 0L;
  1932.     }
  1933.     SendMessage(pInfo->hwnd, message, wParam, lParam);
  1934.     bReleaseInfoData(hwnd);
  1935.     return 0L;
  1936. }
  1937. case WM_SIZE: {
  1938.     PINFO       pInfo;
  1939.     HWND        hTextWnd, hView;
  1940.     WORD        wCx;
  1941.     int         iCyText;
  1942.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1943. break;
  1944.     }
  1945.     hTextWnd = pInfo->hTextWnd;
  1946.     hView    = pInfo->hwnd;
  1947.     bReleaseInfoData(hwnd);
  1948.     iCyText = GetWindowLong(hTextWnd, GWL_USERDATA);
  1949.     wCx = (WORD) (HIWORD(lParam) - iCyText);
  1950.     MoveWindow(hView, 0, 0,
  1951.    LOWORD(lParam),
  1952.    wCx,
  1953.    TRUE);
  1954.     MoveWindow(hTextWnd,
  1955.        0,
  1956.        wCx,
  1957.        LOWORD(lParam),
  1958.        iCyText,
  1959.        TRUE);
  1960.     break;
  1961. }
  1962. //
  1963. // display info in the status window
  1964. //
  1965. case WM_USER+0xa: {
  1966.     PINFO       pInfo;
  1967.     static ULONG ulClick = 0;
  1968.     HWND        hTextWnd;
  1969.     ulClick++;
  1970.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  1971. return 0L;
  1972.     }
  1973.     hTextWnd = pInfo->hTextWnd;
  1974.     switch (ulClick % 4) {
  1975. case 0: 
  1976. sprintf( gtext, GetStringRes (IDS_FRAMES)); 
  1977. break;
  1978. case 1: 
  1979. sprintf( gtext, GetStringRes (IDS_FRAMES));
  1980. break;
  1981. case 2: sprintf( gtext, (pInfo->bPlayRleCont ? 
  1982.                GetStringRes (IDS_CONT_PLAY) :
  1983.                        GetStringRes (IDS_SINGLE_PLAY)));
  1984. break;
  1985. case 3: sprintf( gtext,"");
  1986. break;
  1987. default: break;
  1988.     }
  1989.     SetWindowText(hTextWnd, gtext);
  1990.     bReleaseInfoData(hwnd);
  1991.     return 0L;
  1992. }
  1993. case WM_SYSCOMMAND: {
  1994.     LONG        lResult;
  1995.     EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnSuspendThrd, lParam);
  1996.     lResult = DefMDIChildProc(hwnd, message, wParam, lParam);
  1997.     EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnResumeThrd, lParam);
  1998.     return lResult;
  1999.     break;
  2000. }
  2001. case WM_CREATE: {
  2002.     PINFO           pInfo;
  2003.     HANDLE          hInfo;
  2004.     HWND            hTextWnd, hView;
  2005.     RECT            rcl;
  2006.     //
  2007.     // CR! MakeProcInstance is noop!
  2008.     //
  2009.     lpfnSuspendThrd = (FARPROC)MakeProcInstance (SuspendDrawThrd, ghModule);
  2010.     lpfnResumeThrd  = (FARPROC)MakeProcInstance (ResumeDrawThrd, ghModule);
  2011.     hTextWnd = CreateWindow("Text", NULL,
  2012.     WS_BORDER | SS_LEFT | WS_CHILD | WS_VISIBLE,
  2013.     0, 0, 0, 0,
  2014.     hwnd,
  2015.     (HMENU) 2,
  2016.     ghModule,
  2017.     NULL);
  2018.     GetClientRect(hwnd, &rcl);
  2019.     hView = CreateWindow("View", (LPSTR) NULL,
  2020.   WS_CHILD      | WS_VISIBLE     |
  2021.   WS_BORDER,
  2022.   0,0, rcl.right-rcl.left,
  2023.   rcl.bottom-rcl.top-GetWindowLong(hTextWnd, GWL_USERDATA),
  2024.   hwnd, (HMENU)1, ghModule, (LPVOID)NULL);
  2025.     SetWindowText(hTextWnd, GetStringRes (IDS_SELECT_DRAW_SET));
  2026.     hInfo = (HANDLE) ((LPMDICREATESTRUCT) ((LPCREATESTRUCT) lParam)->lpCreateParams)->lParam ;
  2027.     if (hInfo) {
  2028. if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) 
  2029. {
  2030.     OutputDebugString ("Failed in LocalLock, hNode");
  2031.     break;
  2032. else 
  2033. {
  2034.     HDC hDC;
  2035.     if (!GetClientRect(hwnd, &pInfo->rcClient))
  2036. OutputDebugString ("Failed in GetClientRect!");
  2037.     pInfo->hTextWnd = hTextWnd;
  2038.     pInfo->hwnd = hView;
  2039.     hDC = GetDC(hView);
  2040.     pInfo->hHTPal = CreateHalftonePalette(hDC);
  2041.     ReleaseDC(hView, hDC);
  2042.     //
  2043.     // Creating a signal quit play continuous event
  2044.     //
  2045.     if ((pInfo->hQuitEvent = CreateEvent(NULL, TRUE, TRUE, NULL)) == NULL)
  2046. OutputDebugString ("Failed in creating Quit Event!");
  2047.     SetWindowLong(hwnd, 0, (LONG) hInfo);
  2048.     LocalUnlock(hInfo);
  2049. }
  2050.     } 
  2051. else 
  2052. {
  2053. OutputDebugString ("Can't allocate hInfo!");
  2054.     }
  2055.     break;
  2056. }
  2057. case WM_CLOSE: {
  2058.     SendMessage(GetParent(hwnd), WM_MDISETMENU,
  2059.     (DWORD) hMenu,
  2060.     (LONG)  hSubMenuOne) ;
  2061.     DrawMenuBar(GetParent(GetParent(hwnd))) ;
  2062.     break;
  2063. }
  2064. case WM_DESTROY: {
  2065.     PINFO            pInfo;
  2066.     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
  2067. break;
  2068.     }
  2069.     TerminateThread(pInfo->hThrd, (DWORD)0L);
  2070.     CloseHandle(pInfo->hThrd);
  2071.     //
  2072.     // Cleanup continuous play
  2073.     //
  2074.     if (!ResetEvent(pInfo->hQuitEvent))
  2075. OutputDebugString ("Failed in reseting quit event!");
  2076.     bFreeRleFile(pInfo);
  2077.     bReleaseInfoData(hwnd);
  2078.     LocalFree((HANDLE) GetWindowLong(hwnd, 0));
  2079.     break;
  2080. }
  2081. default:
  2082.     return DefMDIChildProc(hwnd, message, wParam, lParam);
  2083.     } //switch
  2084.     return DefMDIChildProc(hwnd, message, wParam, lParam);
  2085. }
  2086. /******************************Public*Routine******************************
  2087. *
  2088. * ViewSurfWndProc
  2089. *
  2090. * Effects:
  2091. *
  2092. * Warnings:
  2093. *
  2094. **************************************************************************/
  2095. LONG APIENTRY ViewSurfWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam)
  2096. {
  2097.     switch (message)
  2098.     {
  2099.        case WM_CREATE: {
  2100.     break;
  2101.        }
  2102.        case WM_DESTROY: {
  2103.     break;
  2104.        }
  2105.        case WM_QUERYNEWPALETTE: {
  2106.      HWND        hParent;
  2107.      PINFO       pInfo;
  2108.      HDC         hDC;
  2109.      UINT        i;
  2110.      HPALETTE    hOldPal;
  2111.      if ((hParent=GetParent(hwnd)) == NULL) 
  2112.  {
  2113. OutputDebugString ("Can't get hParent!");
  2114. return 0L;
  2115.      }
  2116.      if ((pInfo = pGetInfoData(hParent)) == NULL) {
  2117.   return 0L;
  2118.      }
  2119.      // If palette realization causes a palette change,
  2120.      // we need to do a full redraw.
  2121.      hDC = GetDC (hwnd);
  2122.      hOldPal = SelectPalette (hDC,
  2123.        pInfo->RleData.hPal,
  2124.        0);
  2125.      i = RealizePalette(hDC);
  2126.      SelectPalette (hDC, hOldPal, 0);
  2127.      ReleaseDC (hwnd, hDC);
  2128.      bReleaseInfoData(hParent);
  2129.      if (i) {
  2130.  InvalidateRect (hwnd, (LPRECT) (NULL), TRUE);
  2131.  return TRUE;
  2132.      } else
  2133.  return FALSE;
  2134.        }
  2135.        case WM_PALETTECHANGED: {
  2136.      HWND        hParent;
  2137.      PINFO       pInfo;
  2138.      HDC         hDC;
  2139.      UINT        i;
  2140.      HPALETTE    hOldPal;
  2141.      if ((hParent=GetParent(hwnd)) == NULL) {
  2142.  MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
  2143.  return 0L;
  2144.      }
  2145.      if ((pInfo = pGetInfoData(hParent)) == NULL) {
  2146.   return 0L;
  2147.      }
  2148.      // if we were not responsible for palette change and if
  2149.      // palette realization causes a palette change, do a redraw.
  2150.      if ((HWND)wParam != hwnd){
  2151. hDC = GetDC (hwnd);
  2152. hOldPal = SelectPalette (hDC,
  2153. pInfo->RleData.hPal,
  2154. 0);
  2155. i = RealizePalette (hDC);
  2156. if (i){
  2157.     UpdateColors (hDC);
  2158. }
  2159. SelectPalette (hDC, hOldPal, 0);
  2160. ReleaseDC (hwnd, hDC);
  2161.     }
  2162.     bReleaseInfoData(hParent);
  2163.     break;
  2164.        }
  2165.        case WM_PAINT:
  2166.  {
  2167.      PAINTSTRUCT ps;
  2168.      HDC         hDC;
  2169.      RECT        rc;
  2170.      GetClientRect(hwnd,&rc);
  2171.      hDC = BeginPaint(hwnd, &ps);
  2172.      EndPaint(hwnd, &ps);
  2173.      return 0L;
  2174.  }
  2175.     } // switch
  2176.     return DefWindowProc(hwnd, message, wParam, lParam);
  2177. }
  2178. /***************************************************************************
  2179. * About
  2180. *
  2181. * About dialog proc.
  2182. *
  2183. ***************************************************************************/
  2184. BOOL CALLBACK About(
  2185.     HWND hDlg,
  2186.     UINT message,
  2187.     DWORD wParam,
  2188.     LONG lParam)
  2189. {
  2190.     switch (message) {
  2191.     case WM_INITDIALOG:
  2192. return TRUE;
  2193.     case WM_COMMAND:
  2194. if (wParam == IDOK)
  2195.     EndDialog(hDlg, wParam);
  2196. break;
  2197.     }
  2198.     return FALSE;
  2199.     UNREFERENCED_PARAMETER(lParam);
  2200.     UNREFERENCED_PARAMETER(hDlg);
  2201. }
  2202. /*************************************************************************
  2203. *
  2204. * TextWndProc
  2205. *
  2206. * Text Window proc.
  2207. *
  2208. ***************************************************************************/
  2209. LONG APIENTRY TextWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam)
  2210. {
  2211.     static HFONT hFont = (HFONT) NULL;
  2212.     switch (message)
  2213.     {
  2214.     case WM_CREATE:
  2215. {
  2216.     LOGFONT    lf;
  2217.     HDC        hDC;
  2218.     HFONT      hOldFont;
  2219.     TEXTMETRIC tm;
  2220.     RECT       rect;
  2221.     LONG       lHeight;
  2222.     SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), (PVOID) &lf, FALSE);
  2223.     hDC = GetDC(hwnd);
  2224.     // this is the height for 8 point size font in pixels
  2225.     lf.lfHeight = 8 * GetDeviceCaps(hDC, LOGPIXELSY) / 72;
  2226.     hFont = CreateFontIndirect(&lf);
  2227.     hOldFont = SelectObject(hDC, hFont);
  2228.     GetTextMetrics(hDC, &tm);
  2229.     GetClientRect(GetParent(hwnd), &rect);
  2230.     // base the height of the window on size of text
  2231.     lHeight = tm.tmHeight+6*GetSystemMetrics(SM_CYBORDER)+2;
  2232.     // saved the height for later reference
  2233.     SetWindowLong(hwnd, GWL_USERDATA, lHeight);
  2234.     SetWindowPos(hwnd, NULL,
  2235.     0,
  2236.     rect.bottom-lHeight,
  2237.     rect.right-rect.left,
  2238.     lHeight,
  2239.     SWP_NOZORDER | SWP_NOMOVE);
  2240.     ReleaseDC(hwnd, hDC);
  2241.     break;
  2242. }
  2243.     case WM_LBUTTONDOWN: {
  2244. PostMessage(GetParent(hwnd), WM_USER+0xa, (DWORD)0L, (LONG)0L);
  2245. break;
  2246.     }
  2247.     case WM_DESTROY:
  2248.     if (hFont)
  2249. DeleteObject(hFont);
  2250.     break;
  2251.     case WM_SETTEXT:
  2252.     DefWindowProc(hwnd, message, wParam, lParam);
  2253.     InvalidateRect(hwnd,NULL,TRUE);
  2254.     UpdateWindow(hwnd);
  2255.     return 0L;
  2256.     case WM_PAINT:
  2257. {
  2258.     PAINTSTRUCT ps;
  2259.     RECT   rc;
  2260.     char   ach[128];
  2261.     int    len, nxBorder, nyBorder;
  2262.     HFONT  hOldFont = NULL;
  2263.     BeginPaint(hwnd, &ps);
  2264.     GetClientRect(hwnd,&rc);
  2265.     nxBorder = GetSystemMetrics(SM_CXBORDER);
  2266.     rc.left  += 9*nxBorder;
  2267.     rc.right -= 9*nxBorder;
  2268.     nyBorder = GetSystemMetrics(SM_CYBORDER);
  2269.     rc.top    += 3*nyBorder;
  2270.     rc.bottom -= 3*nyBorder;
  2271.     // 3D Text
  2272.     len = GetWindowText(hwnd, ach, sizeof(ach));
  2273.     SetBkColor(ps.hdc, GetSysColor(COLOR_BTNFACE));
  2274.     SetBkMode(ps.hdc, TRANSPARENT);
  2275.     SetTextColor(ps.hdc, RGB(64,96,96));
  2276.     if (hFont)
  2277. hOldFont = SelectObject(ps.hdc, hFont);
  2278.     ExtTextOut(ps.hdc, rc.left+2*nxBorder+2, rc.top+2, ETO_OPAQUE | ETO_CLIPPED,
  2279. &rc, ach, len, NULL);
  2280.     SetTextColor(ps.hdc, RGB(128,128,128));
  2281.     if (hFont)
  2282. hOldFont = SelectObject(ps.hdc, hFont);
  2283.     ExtTextOut(ps.hdc, rc.left+2*nxBorder+1, rc.top+1, ETO_CLIPPED,
  2284. &rc, ach, len, NULL);
  2285.     SetTextColor(ps.hdc, RGB(255,255,255));
  2286.     if (hFont)
  2287. hOldFont = SelectObject(ps.hdc, hFont);
  2288.     ExtTextOut(ps.hdc, rc.left+2*nxBorder, rc.top, ETO_CLIPPED,
  2289. &rc, ach, len, NULL);
  2290.     SetBkMode(ps.hdc, OPAQUE);
  2291.     if (hOldFont)
  2292. SelectObject(ps.hdc, hOldFont);
  2293.     EndPaint(hwnd, &ps);
  2294.     return 0L;
  2295. }
  2296.     }
  2297.     return DefWindowProc(hwnd, message, wParam, lParam);
  2298. }
  2299. /**************************************************************************
  2300. *
  2301. * JuliaWndProc
  2302. *
  2303. **************************************************************************/
  2304. LONG APIENTRY JuliaWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam)
  2305. {
  2306.     //
  2307.     // These statics are shared by all the Julia windows.  But, this is
  2308.     // fine because only one Julia window is tracking at any one time.
  2309.     // Ideally, we should place this in the per-window INFO data structure.
  2310.     // But, this is not necessary.
  2311.     //
  2312.     static BOOL    bTrack = FALSE;
  2313.     static int     OrgX, OrgY;
  2314.     static int     PrevX, PrevY;
  2315.     static HDC     hDC;
  2316.     static HCURSOR hCurArrow, hCurPaintCan;
  2317.     switch (message)
  2318.     {
  2319.        case WM_CREATE: {
  2320.     hpnRed     = CreatePen(PS_SOLID, 0, RGB(0xFF, 0,    0));
  2321.     hpnGreen   = CreatePen(PS_SOLID, 0, RGB(0,    0xFF, 0));
  2322.     hpnBlack   = CreatePen(PS_SOLID, 0, RGB(0,    0,    0));
  2323.     hCurPaintCan = LoadCursor(ghModule, MAKEINTRESOURCE(PAINTCURSOR));
  2324.     hCurArrow = LoadCursor(NULL, IDC_ARROW);
  2325.     break;
  2326.        }
  2327.        case WM_DESTROY: {
  2328.     HWND        hParent;
  2329.     PINFO       pInfo;
  2330.     DeleteObject(hpnRed);
  2331.     DeleteObject(hpnGreen);
  2332.     DeleteObject(hpnBlack);
  2333.     if ((hParent=GetParent(hwnd)) == NULL) 
  2334. {
  2335. OutputDebugString ("Can't get hParent!");
  2336. break;
  2337.     }
  2338.     if ((pInfo = pGetInfoData(hParent)) == NULL) {
  2339. break;
  2340.     }
  2341.     // we might have open resource if we ever load bitmap in this wnd.
  2342.     bFreeRleFile(pInfo);
  2343.     bReleaseInfoData(hParent);
  2344.     break;
  2345.        }
  2346.        case WM_QUERYNEWPALETTE: {
  2347.      HWND        hParent;
  2348.      PINFO       pInfo;
  2349.      HDC         hDC;
  2350.      UINT        i;
  2351.      HPALETTE    hOldPal;
  2352.      if ((hParent=GetParent(hwnd)) == NULL) 
  2353.  {
  2354. OutputDebugString ("Can't get hParent!");
  2355. return 0L;
  2356.      }
  2357.      if ((pInfo = pGetInfoData(hParent)) == NULL) {
  2358.   return 0L;
  2359.      }
  2360.      // If palette realization causes a palette change,
  2361.      // we need to do a full redraw.
  2362.      hDC = GetDC (hwnd);
  2363.      hOldPal = SelectPalette (hDC,
  2364.        ((pInfo->iStretchMode == HALFTONE) ? pInfo->hHTPal : pInfo->hPal),
  2365.        0);
  2366.      i = RealizePalette(hDC);
  2367.      SelectPalette (hDC, hOldPal, 0);
  2368.      ReleaseDC (hwnd, hDC);
  2369.      bReleaseInfoData(hParent);
  2370.      if (i) {
  2371.  InvalidateRect (hwnd, (LPRECT) (NULL), TRUE);
  2372.  return TRUE;
  2373.      } else
  2374.  return FALSE;
  2375.        }
  2376.        case WM_PALETTECHANGED: {
  2377.      HWND        hParent;
  2378.      PINFO       pInfo;
  2379.      HDC         hDC;
  2380.      UINT        i;
  2381.      HPALETTE    hOldPal;
  2382.      if ((hParent=GetParent(hwnd)) == NULL) {
  2383. OutputDebugString ("Can't get hParent!");
  2384. return 0L;
  2385.      }
  2386.      if ((pInfo = pGetInfoData(hParent)) == NULL) {
  2387.   return 0L;
  2388.      }
  2389.      // if we were not responsible for palette change and if
  2390.      // palette realization causes a palette change, do a redraw.
  2391.      if ((HWND)wParam != hwnd){
  2392. hDC = GetDC (hwnd);
  2393. hOldPal = SelectPalette (hDC,
  2394.        ((pInfo->iStretchMode == HALFTONE) ? pInfo->hHTPal : pInfo->hPal),
  2395. 0);
  2396. i = RealizePalette (hDC);
  2397. if (i){
  2398.     UpdateColors (hDC);
  2399. }
  2400. SelectPalette (hDC, hOldPal, 0);
  2401. ReleaseDC (hwnd, hDC);
  2402.     }
  2403.     bReleaseInfoData(hParent);
  2404.     break;
  2405.        }
  2406.        case WM_PAINT: