--- mstools/samples/mandel/julia.c 2018/08/09 18:20:41 1.1 +++ mstools/samples/mandel/julia.c 2018/08/09 18:23:43 1.1.1.3 @@ -7,7 +7,7 @@ * Created: 24-Oct-1991 18:34:08 * Author: Petrus Wong * -* Copyright (c) 1990 Microsoft Corporation +* Copyright (c) 1993 Microsoft Corporation * * The Mandelbrot Dream serves to demonstrate the GDI and USER * functionalities in the setting of fractals. @@ -24,6 +24,17 @@ * 9. Boundary tracing and creating a clip region out of it for * creating special effect * 10. Enumerate printers for printing +* 11. Load RLE (or convert .bmp files to RLE) for playing in viewer +* 12. Save the RLE in memory to disk. +* +* Note: Users can now draw and saves the julia sets on disk as bmps in +* the Julia windows. These bitmaps can then be read into the memory +* (and converted to RLE format) one by one for displaying in sequence +* in the viewer window. Eg Load the julia.rle in the viewer window +* and select the play or play continuously menu item. 02-Jan-1993 +* +* Note2: The fix point math in this sample makes use of the LargeInteger +* 64 bit math library. * * Dependencies: * @@ -36,31 +47,38 @@ #include #include #include +#include #include "julia.h" +#include + +// +// For T1 to create all pens in advance. This is not a good approach +// because pens are per thread basis. The drawing threads won't be able +// to use them if they are not created in their threads. 18-Sep-1992 +// +//#define THRDONE + +#define CYCLETHRD -//#define CYCLETHRD #define PRTTHRD #define NEWPRTAPI -//#define DEBUG - #ifndef DEBUG #undef OutputDebugString #define OutputDebugString(LPCSTR) #endif - - // // Forward declarations. // -BOOL InitializeApp (INT*); -LONG MainWndProc (HWND, UINT, DWORD, LONG); -LONG ChildWndProc (HWND, UINT, DWORD, LONG); -LONG About (HWND, UINT, DWORD, LONG); -LONG TextWndProc (HWND, UINT, DWORD, LONG); -LONG JuliaWndProc (HWND, UINT, DWORD, LONG); -LONG DrawWndProc (HWND, UINT, DWORD, LONG); +BOOL InitializeApp (INT*); +LONG APIENTRY MainWndProc (HWND, UINT, DWORD, LONG); +LONG APIENTRY ChildWndProc (HWND, UINT, DWORD, LONG); +BOOL CALLBACK About (HWND, UINT, DWORD, LONG); +LONG APIENTRY TextWndProc (HWND, UINT, DWORD, LONG); +LONG APIENTRY JuliaWndProc (HWND, UINT, DWORD, LONG); +LONG APIENTRY ViewerWndProc (HWND, UINT, DWORD, LONG); +LONG APIENTRY ViewSurfWndProc (HWND, UINT, DWORD, LONG); BOOL APIENTRY SuspendDrawThrd (HWND, LONG); BOOL APIENTRY ResumeDrawThrd (HWND, LONG); BOOL StartDraw (PINFO); @@ -68,20 +86,26 @@ BOOL StartDrawFix (PINFO); BOOL StartDraw2 (PINFO); BOOL StartMandelbrot (PINFO); BOOL StartMandelbrotFix (PINFO); -HBITMAP SaveBitmap (HWND); +HBITMAP SaveBitmap (HWND, HPALETTE); void DrawBitmap (HDC, PINFO, int, int, int, int); +BOOL bDrawDIB (HDC, PINFO, int, int, int, int); LONG lMul(LONG, LONG); LONG lDiv(LONG, LONG); PINFO pGetInfoData(HWND); BOOL bReleaseInfoData(HWND); -BOOL bCheckMutexMenuItem(HMENU, UINT); +BOOL bCheckMutexMenuItem(PINFO, HMENU, UINT); +VOID vChkMenuItem(PINFO, HMENU, UINT); BOOL bInitInfo(PINFO); BOOL bResetGlobal(VOID); HBRUSH hBrCreateBrush(HDC, DWORD); BOOL bPrintBmp(PPRTDATA); -extern BOOL bCycle(HWND); -extern BOOL bCleanupPrinter(VOID); -extern INT iCreatePenFrPal(HDC, PVOID *); +BOOL bStoreRleFile(HDC, PINFO, PSTR); +BOOL bFreeRleFile(PINFO); +BOOL bPlayRle(PINFO); +BOOL bSaveRleFile(HDC, PINFO, PSTR); +BOOL bPlayRleCont2(PINFO); +BOOL bSelectDIBPal(HDC, PINFO, LPBITMAPINFO, BOOL); +HBITMAP DIBfromDDB(HDC, HBITMAP, PINFO); /******************************Public*Routine******************************\ * @@ -93,14 +117,13 @@ extern INT iCreatePenFrPal(HDC, PVOID * * Wrote it. \**************************************************************************/ -int APIENTRY WinMain( +int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { MSG msg; - INT i; ghModule = GetModuleHandle(NULL); if (!InitializeApp(&giPen)) { @@ -120,18 +143,8 @@ int APIENTRY WinMain( } } - // - // Delete all the pens created and free the array of hPens; - // The pens and the array of hPens was created and allocated respectively - // in InitializeApp - // - if (gprghPen != NULL) { - for (i = 0; i <= giPen; i++) { - DeleteObject((HPEN) gprghPen[i]); - } - GlobalFree(gprghPen); - } + DeleteObject(ghPal); return 1; @@ -155,7 +168,10 @@ BOOL InitializeApp(INT *piPen) { WNDCLASS wc; HDC hDC; + +#ifdef THRDONE INT iNumClr; +#endif wc.style = CS_OWNDC; wc.lpfnWndProc = (WNDPROC)MainWndProc; @@ -179,6 +195,14 @@ BOOL InitializeApp(INT *piPen) if (!RegisterClass(&wc)) return FALSE; + wc.lpfnWndProc = (WNDPROC)ViewerWndProc; + wc.hIcon = LoadIcon(ghModule, MAKEINTRESOURCE(VIEWICON)); + wc.lpszMenuName = NULL; + wc.lpszClassName = "ViewerClass"; + + if (!RegisterClass(&wc)) + return FALSE; + wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC)TextWndProc; wc.hIcon = NULL; @@ -207,12 +231,25 @@ BOOL InitializeApp(INT *piPen) if (!RegisterClass(&wc)) return FALSE; + wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = (WNDPROC)ViewSurfWndProc; + wc.hIcon = NULL; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND); + wc.lpszMenuName = NULL; + wc.lpszClassName = "View"; + + if (!RegisterClass(&wc)) + return FALSE; + // // Notice, submenu is zero-based // hMenu = LoadMenu(ghModule, "MainMenu"); hChildMenu = LoadMenu(ghModule, "ChildMenu"); + hViewMenu = LoadMenu(ghModule, "ViewMenu"); + hViewSubOne = GetSubMenu(hViewMenu, 1); hSubMenuOne = GetSubMenu(hMenu, 1); hSubMenuThree = GetSubMenu(hChildMenu, 8); hPrinterMenu = GetSubMenu(hChildMenu, 7); @@ -227,18 +264,21 @@ BOOL InitializeApp(INT *piPen) EnableMenuItem(hChildMenu, MM_CYCLE, MF_GRAYED); } - if ((iNumClr = iCreatePenFrPal(hDC, NULL)) != 0) { +#ifdef THRDONE + + if ((iNumClr = iCreatePenFrPal(hDC, NULL, 0, &ghPal)) != 0) { sprintf( gtext,"iNumClr = %d\n", iNumClr); OutputDebugString( gtext); - if ((gprghPen = (PVOID*) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(HPEN)*iNumClr)) == NULL) { - MessageBox(ghwndMain, "Failed in Memory Allocation for gprghPen!", "Error", MB_OK); + if ((pInfo->prghPen = (PVOID*) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(HPEN)*iNumClr)) == NULL) { + MessageBox(ghwndMain, "Failed in Memory Allocation for pInfo->prghPen!", "Error", MB_OK); } else { - if ((*piPen = iCreatePenFrPal(hDC, gprghPen)) == 0) + if ((*piPen = iCreatePenFrPal(hDC, pInfo->prghPen, 0, &ghPal)) == 0) MessageBox(ghwndMain, "Failed in creating pen!", "Error", MB_OK); } } +#endif ReleaseDC(NULL, hDC); ghwndMain = CreateWindowEx(0L, "MandelClass", "Mandelbrot Dream", @@ -257,6 +297,9 @@ BOOL InitializeApp(INT *piPen) SetFocus(ghwndMain); /* set initial focus */ + PostMessage(ghwndMain, WM_COMMAND, MM_MANDEL, 0L); + PostMessage(ghwndMain, WM_COMMAND, MM_CREATE_MANDEL_THREAD, 0L); + return TRUE; } @@ -270,7 +313,7 @@ BOOL InitializeApp(INT *piPen) * Wrote it. \**************************************************************************/ -long MainWndProc( +long APIENTRY MainWndProc( HWND hwnd, UINT message, DWORD wParam, @@ -278,6 +321,7 @@ long MainWndProc( { static int iJuliaCount=1; static int iMandelCount=1; + static int iViewerCount=1; CLIENTCREATESTRUCT clientcreate; HWND hwndChildWindow; static FARPROC lpfnSuspendThrd, lpfnResumeThrd; @@ -297,6 +341,7 @@ long MainWndProc( hwnd, NULL, ghModule, (LPVOID)&clientcreate); lpfnSuspendThrd = (FARPROC)MakeProcInstance (SuspendDrawThrd, ghModule); lpfnResumeThrd = (FARPROC)MakeProcInstance (ResumeDrawThrd, ghModule); + return 0L; case WM_DESTROY: { @@ -355,6 +400,7 @@ long MainWndProc( break; } #endif + case WM_COMMAND: switch (LOWORD(wParam)) { @@ -430,9 +476,57 @@ long MainWndProc( return ((LONG)hwndChildWindow); } + case MM_RLEVIEWER: { + HANDLE hInfo; + PINFO pInfo; + MDICREATESTRUCT mdicreate; + + hInfo = LocalAlloc(LHND, (WORD) sizeof(INFO)); + if (hInfo == NULL) { + MessageBox(ghwndMain, "Failed to Allocate Info!", "Error", MB_OK); + return 0L; + } + if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) { + MessageBox(ghwndMain, "Failed in LocalLock, hInfo", "Error", MB_OK); + return 0L; + } + + bInitInfo(pInfo); + wsprintf((LPSTR) &(pInfo->CaptionBarText), "Viewer %d", iViewerCount ); + + // + // Fill in the MDICREATE structure for MDI child creation + // + mdicreate.szClass = "ViewerClass"; + mdicreate.szTitle = (LPTSTR)&(pInfo->CaptionBarText); + mdicreate.hOwner = ghModule; + mdicreate.x = + mdicreate.y = CW_USEDEFAULT; + mdicreate.cx = 300; + mdicreate.cy = 300; + mdicreate.style = 0L; + mdicreate.lParam = (LONG) hInfo; + + /*Create Child Window*/ + hwndChildWindow = + (HANDLE) SendMessage(ghwndClient, WM_MDICREATE, + 0L, + (LONG)(LPMDICREATESTRUCT)&mdicreate); + + if (hwndChildWindow == NULL) { + MessageBox(ghwndMain, "Failed in Creating Child Window", "Error", MB_OK); + return 0L; + } + + iViewerCount++ ; + LocalUnlock(hInfo); + return ((LONG)hwndChildWindow); + + } + case MM_ABOUT: if (DialogBox(ghModule, "AboutBox", ghwndMain, (DLGPROC)About) == -1) - MessageBox(ghwndMain, "DEMO: About Dialog Creation Error!", "Error", MB_OK); + MessageBox(ghwndMain, "DEMO: About Dialog Creation Error!", "Error", MB_OK); return 0L; // @@ -449,12 +543,19 @@ long MainWndProc( case MM_SHIFT: case MM_CUSTOM: case MM_CYCLE: + case MM_TP_IDLE: + case MM_TP_LOW: + case MM_TP_BELOW_NORMAL: + case MM_TP_NORMAL: + case MM_TP_ABOVE_NORMAL: + case MM_TP_HIGH: + case MM_TP_TIME_CRITICAL: case MM_FLOAT: case MM_FIX: - case MM_ITERATION_TEN: - case MM_ITERATION_TWENTY: - case MM_ITERATION_THIRTY: - case MM_ITERATION_FIFTY: + case MM_ITERATION_100: + case MM_ITERATION_500: + case MM_ITERATION_1000: + case MM_ITERATION_5000: case MM_ITERATION_DOUBLE: case MM_STEP_ONE: case MM_STEP_TWO: @@ -470,6 +571,7 @@ long MainWndProc( case MM_HALFTONE: case MM_CLIP: case MM_RM_CLIP: + case MM_SELCLIPRGN: case MM_ERASE: case MM_PORTRAIT: case MM_LANDSCAPE: @@ -483,6 +585,12 @@ long MainWndProc( case MM_PRINTER + 7: case MM_PRINTER + 8: case MM_PRINTER + 9: + case MM_RLELOAD_DEMO: + case MM_RLEPLAYCONT: + case MM_RLELOAD: + case MM_RLESAVE: + case MM_CLEAR: + case MM_RLEPLAY: { HWND hActiveChild; @@ -509,7 +617,7 @@ long MainWndProc( * 09-09-91 Petrus Wong Rewrote. \***************************************************************************/ -long ChildWndProc( +long APIENTRY ChildWndProc( HWND hwnd, UINT message, DWORD wParam, @@ -522,7 +630,6 @@ long ChildWndProc( OutputDebugString( gtext); switch (message) { - case WM_COMMAND: { PINFO pInfo; HWND hTextWnd; @@ -542,12 +649,21 @@ long ChildWndProc( sprintf( gtext,"(c1 = %g, c2 = %g)\n\n", pInfo->c1, pInfo->c2); OutputDebugString( gtext ); + if (pInfo->hThrd) + CloseHandle(pInfo->hThrd); + pInfo->hThrd = CreateThread(NULL, 0, (gFloat ? (LPTHREAD_START_ROUTINE)StartDraw : (LPTHREAD_START_ROUTINE)StartDrawFix), pInfo, STANDARD_RIGHTS_REQUIRED, &pInfo->dwThreadId ); + if (pInfo->hThrd && pInfo->bDrawing) { + if (!SetThreadPriority(pInfo->hThrd, pInfo->iPriority)) + MessageBox(ghwndMain, "Can't set Priority!", + "Error", MB_OK); + } + bReleaseInfoData(hwnd); return 0L; } @@ -594,11 +710,22 @@ long ChildWndProc( sprintf( gtext,"(c1 = %g, c2 = %g)\n\n", pInfo->c1, pInfo->c2); OutputDebugString( gtext ); + if (pInfo->hThrd) + CloseHandle(pInfo->hThrd); + pInfo->hThrd = CreateThread(NULL, 0, (gFloat ? (LPTHREAD_START_ROUTINE)StartMandelbrot : (LPTHREAD_START_ROUTINE)StartMandelbrotFix), pInfo, STANDARD_RIGHTS_REQUIRED, &pInfo->dwThreadId ); + + if (pInfo->hThrd && pInfo->bDrawing) { + if (!SetThreadPriority(pInfo->hThrd, pInfo->iPriority)) + MessageBox(ghwndMain, "Can't set Priority!", + "Error", MB_OK); + } + + bReleaseInfoData(hwnd); return 0L; } @@ -618,12 +745,21 @@ long ChildWndProc( sprintf( gtext,"xFrom = %g, xTo = %g, yFrom = %g, yTo = %g\n", pInfo->xFrom, pInfo->xTo, pInfo->yFrom, pInfo->yTo); OutputDebugString( gtext ); + if (pInfo->hThrd) + CloseHandle(pInfo->hThrd); + pInfo->hThrd = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)StartDraw2, pInfo, STANDARD_RIGHTS_REQUIRED, &pInfo->dwThreadId ); + if (pInfo->hThrd && pInfo->bDrawing) { + if (!SetThreadPriority(pInfo->hThrd, pInfo->iPriority)) + MessageBox(ghwndMain, "Can't set Priority!", + "Error", MB_OK); + } + bReleaseInfoData(hwnd); return 0L; } @@ -641,110 +777,210 @@ long ChildWndProc( return 0L; } + { + int iPriority; + + case MM_TP_IDLE: + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + + iPriority = THREAD_PRIORITY_IDLE; + bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_IDLE); + DrawMenuBar(GetParent(GetParent(hwnd))) ; + goto CWP_SET_PRIORITY; + + case MM_TP_LOW: + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + + iPriority = THREAD_PRIORITY_LOWEST; + bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_LOW); + DrawMenuBar(GetParent(GetParent(hwnd))) ; + goto CWP_SET_PRIORITY; + + case MM_TP_BELOW_NORMAL: + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + + iPriority = THREAD_PRIORITY_BELOW_NORMAL; + bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_BELOW_NORMAL); + DrawMenuBar(GetParent(GetParent(hwnd))) ; + goto CWP_SET_PRIORITY; + + case MM_TP_NORMAL: + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + + iPriority = THREAD_PRIORITY_NORMAL; + bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_NORMAL); + DrawMenuBar(GetParent(GetParent(hwnd))) ; + goto CWP_SET_PRIORITY; + + case MM_TP_ABOVE_NORMAL: + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + + iPriority = THREAD_PRIORITY_ABOVE_NORMAL; + bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_ABOVE_NORMAL); + DrawMenuBar(GetParent(GetParent(hwnd))) ; + goto CWP_SET_PRIORITY; + + case MM_TP_HIGH: + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + + iPriority = THREAD_PRIORITY_HIGHEST; + bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_HIGH); + DrawMenuBar(GetParent(GetParent(hwnd))) ; + goto CWP_SET_PRIORITY; + + case MM_TP_TIME_CRITICAL: + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + + iPriority = THREAD_PRIORITY_TIME_CRITICAL; + bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_TIME_CRITICAL); + DrawMenuBar(GetParent(GetParent(hwnd))) ; + +CWP_SET_PRIORITY: + { + HANDLE hThrd; + + hThrd = pInfo->hThrd; + pInfo->iPriority = iPriority; + + if (hThrd && pInfo->bDrawing) { + if (!SetThreadPriority(hThrd, iPriority)) + MessageBox(ghwndMain, "Can't set Priority!", + "Error", MB_OK); + } + + } + bReleaseInfoData(hwnd); + return 0L; + + } + case MM_FLOAT: { - bCheckMutexMenuItem(hChildMenu, MM_FLOAT); + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + bCheckMutexMenuItem(pInfo, hChildMenu, MM_FLOAT); DrawMenuBar(GetParent(GetParent(hwnd))) ; gFloat = TRUE; + bReleaseInfoData(hwnd); return 0L; } case MM_FIX: { - bCheckMutexMenuItem(hChildMenu, MM_FIX); + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + bCheckMutexMenuItem(pInfo, hChildMenu, MM_FIX); DrawMenuBar(GetParent(GetParent(hwnd))) ; gFloat = FALSE; + bReleaseInfoData(hwnd); return 0L; } - case MM_ITERATION_TEN: { - bCheckMutexMenuItem(hChildMenu, MM_ITERATION_TEN); - DrawMenuBar(GetParent(GetParent(hwnd))) ; - gIteration = 10; + case MM_ITERATION_100: { if ((pInfo = pGetInfoData(hwnd)) == NULL) { return 0L; } - pInfo->iIteration = 10; - + bCheckMutexMenuItem(pInfo, hChildMenu, MM_ITERATION_100); + DrawMenuBar(GetParent(GetParent(hwnd))) ; + gIteration = 100; + pInfo->iIteration = 100; + SetWindowText(pInfo->hTextWnd, "Iteration = 100"); bReleaseInfoData(hwnd); return 0L; } - case MM_ITERATION_TWENTY: { - bCheckMutexMenuItem(hChildMenu, MM_ITERATION_TWENTY); - DrawMenuBar(GetParent(GetParent(hwnd))) ; - gIteration = 20; + case MM_ITERATION_500: { if ((pInfo = pGetInfoData(hwnd)) == NULL){ return 0L; } + bCheckMutexMenuItem(pInfo, hChildMenu, MM_ITERATION_500); + DrawMenuBar(GetParent(GetParent(hwnd))) ; + gIteration = 500; - pInfo->iIteration = 20; - + pInfo->iIteration = 500; + SetWindowText(pInfo->hTextWnd, "Iteration = 500"); bReleaseInfoData(hwnd); return 0L; } - case MM_ITERATION_THIRTY: { - bCheckMutexMenuItem(hChildMenu, MM_ITERATION_THIRTY); - DrawMenuBar(GetParent(GetParent(hwnd))) ; - gIteration = 30; + case MM_ITERATION_1000: { if ((pInfo = pGetInfoData(hwnd)) == NULL) { return 0L; } - pInfo->iIteration = 30; - + bCheckMutexMenuItem(pInfo, hChildMenu, MM_ITERATION_1000); + DrawMenuBar(GetParent(GetParent(hwnd))) ; + gIteration = 1000; + pInfo->iIteration = 1000; + SetWindowText(pInfo->hTextWnd, "Iteration = 1000"); bReleaseInfoData(hwnd); return 0L; } - case MM_ITERATION_FIFTY: { - bCheckMutexMenuItem(hChildMenu, MM_ITERATION_FIFTY); - DrawMenuBar(GetParent(GetParent(hwnd))) ; - gIteration = 50; + case MM_ITERATION_5000: { if ((pInfo = pGetInfoData(hwnd)) == NULL) { return 0L; } - pInfo->iIteration = 50; - + bCheckMutexMenuItem(pInfo, hChildMenu, MM_ITERATION_5000); + DrawMenuBar(GetParent(GetParent(hwnd))) ; + gIteration = 5000; + pInfo->iIteration = 5000; + SetWindowText(pInfo->hTextWnd, "Iteration = 5000"); bReleaseInfoData(hwnd); return 0L; } case MM_ITERATION_DOUBLE: { - bCheckMutexMenuItem(hChildMenu, MM_ITERATION_DOUBLE); - DrawMenuBar(GetParent(GetParent(hwnd))) ; - gIteration *= 2; if ((pInfo = pGetInfoData(hwnd)) == NULL) { return 0L; } + bCheckMutexMenuItem(pInfo, hChildMenu, MM_ITERATION_DOUBLE); + DrawMenuBar(GetParent(GetParent(hwnd))) ; + gIteration *= 2; pInfo->iIteration = gIteration; - + sprintf( gtext,"Iteration = %d", pInfo->iIteration); + SetWindowText(pInfo->hTextWnd, gtext); bReleaseInfoData(hwnd); return 0L; } case MM_STEP_ONE: { - bCheckMutexMenuItem(hChildMenu, MM_STEP_ONE); - DrawMenuBar(GetParent(GetParent(hwnd))) ; - gStep = 1; if ((pInfo = pGetInfoData(hwnd)) == NULL) { return 0L; } + bCheckMutexMenuItem(pInfo, hChildMenu, MM_STEP_ONE); + DrawMenuBar(GetParent(GetParent(hwnd))) ; + gStep = 1; pInfo->iStep = 1; bReleaseInfoData(hwnd); return 0L; } case MM_STEP_TWO: { - bCheckMutexMenuItem(hChildMenu, MM_STEP_TWO); - DrawMenuBar(GetParent(GetParent(hwnd))) ; - gStep = 2; if ((pInfo = pGetInfoData(hwnd)) == NULL){ return 0L; } + bCheckMutexMenuItem(pInfo, hChildMenu, MM_STEP_TWO); + DrawMenuBar(GetParent(GetParent(hwnd))) ; + gStep = 2; pInfo->iStep = 2; bReleaseInfoData(hwnd); return 0L; } case MM_STEP_THREE: { - bCheckMutexMenuItem(hChildMenu, MM_STEP_THREE); - DrawMenuBar(GetParent(GetParent(hwnd))) ; - gStep = 3; if ((pInfo = pGetInfoData(hwnd)) == NULL) { return 0L; } + bCheckMutexMenuItem(pInfo, hChildMenu, MM_STEP_THREE); + DrawMenuBar(GetParent(GetParent(hwnd))) ; + gStep = 3; pInfo->iStep = 3; bReleaseInfoData(hwnd); @@ -759,13 +995,17 @@ long ChildWndProc( static char *szFilter; RECT rc; + if ((pInfo = pGetInfoData(hwnd)) == NULL){ + return 0L; + } + szFilter = "DIB files (*.bmp)\0*.bmp\0RLE files (*.rle)\0*.rle\0\0"; GetSystemDirectory((LPSTR) szDirName, 256); strcpy(szFile, "*.bmp\0"); ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = hwnd; + ofn.hwndOwner = pInfo->hwnd; ofn.lpstrFilter = szFilter; ofn.lpstrCustomFilter = (LPSTR) NULL; ofn.nMaxCustFilter = 0L; @@ -783,13 +1023,11 @@ long ChildWndProc( if (!GetOpenFileName(&ofn)) return 0L; - if ((pInfo = pGetInfoData(hwnd)) == NULL){ - return 0L; - } + GetClientRect(pInfo->hwnd, &rc); hDC = GetDC(pInfo->hwnd); if (LoadBitmapFile(hDC, pInfo, szFile)) - DrawBitmap(hDC, pInfo, 0, 0, rc.right, rc.bottom); + bDrawDIB(hDC, pInfo, 0, 0, rc.right, rc.bottom); ReleaseDC(hwnd, hDC); bReleaseInfoData(hwnd); @@ -809,18 +1047,27 @@ long ChildWndProc( return 0L; } hDC = GetDC(pInfo->hwnd); +#if 0 + { + HPALETTE hPalTmp; + hPalTmp = CopyPalette(pInfo->hPal); + DeleteObject(pInfo->hPal); + pInfo->hPal = hPalTmp; + } +#endif // // saving special effects user might have created in window // if (pInfo->hBmpSaved) DeleteObject(pInfo->hBmpSaved); - pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd); + pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd, pInfo->hPal); + pInfo->bUseDIB = FALSE; GetSystemDirectory((LPSTR) szDirName, 256); strcpy(szFile, "*.bmp\0"); ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = hwnd; + ofn.hwndOwner = pInfo->hwnd; ofn.lpstrFilter = szFilter; ofn.lpstrCustomFilter = (LPSTR) NULL; ofn.nMaxCustFilter = 0L; @@ -842,7 +1089,19 @@ long ChildWndProc( return 0L; } + SelectPalette(hDC, + ((pInfo->iStretchMode == HALFTONE) ? pInfo->hHTPal : pInfo->hPal), + FALSE); + RealizePalette(hDC); + UpdateColors(hDC); + + // + // test + // + ghPal = pInfo->hPal; + SaveBitmapFile(hDC, pInfo->hBmpSaved, szFile); + ReleaseDC(pInfo->hwnd, hDC); bReleaseInfoData(hwnd); @@ -854,12 +1113,17 @@ long ChildWndProc( char szDirName[256]; char szFile[256], szFileTitle[256]; static char *szFilter; + + if ((pInfo = pGetInfoData(hwnd)) == NULL){ + return 0L; + } + szFilter = "DIB files (*.bmp)\0\0"; GetSystemDirectory((LPSTR) szDirName, 256); strcpy(szFile, "*.bmp\0"); ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = hwnd; + ofn.hwndOwner = pInfo->hwnd; ofn.lpstrFilter = szFilter; ofn.lpstrCustomFilter = (LPSTR) NULL; ofn.nMaxCustFilter = 0L; @@ -877,9 +1141,7 @@ long ChildWndProc( if (!GetSaveFileName(&ofn)) return 0L; - if ((pInfo = pGetInfoData(hwnd)) == NULL) { - return 0L; - } + hDC = GetDC(pInfo->hwnd); SaveBitmapFile(hDC, pInfo->hBmpMono, szFile); @@ -889,12 +1151,12 @@ long ChildWndProc( return 0L; } case MM_STRETCHBLT: { - gbStretch = TRUE; - bCheckMutexMenuItem(hChildMenu, MM_STRETCHBLT); - DrawMenuBar(GetParent(GetParent(hwnd))) ; if ((pInfo = pGetInfoData(hwnd)) == NULL){ return 0L; } + gbStretch = TRUE; + bCheckMutexMenuItem(pInfo, hChildMenu, MM_STRETCHBLT); + DrawMenuBar(GetParent(GetParent(hwnd))) ; pInfo->bStretch = gbStretch; InvalidateRect(pInfo->hwnd, NULL, FALSE); @@ -903,12 +1165,12 @@ long ChildWndProc( } case MM_BITBLT: { - gbStretch = FALSE; - bCheckMutexMenuItem(hChildMenu, MM_BITBLT); - DrawMenuBar(GetParent(GetParent(hwnd))) ; if ((pInfo = pGetInfoData(hwnd)) == NULL) { return 0L; } + gbStretch = FALSE; + bCheckMutexMenuItem(pInfo, hChildMenu, MM_BITBLT); + DrawMenuBar(GetParent(GetParent(hwnd))) ; pInfo->bStretch = gbStretch; InvalidateRect(pInfo->hwnd, NULL, FALSE); @@ -917,12 +1179,12 @@ long ChildWndProc( } case MM_BLACKONWHITE: { - giStretchMode = BLACKONWHITE; - bCheckMutexMenuItem(hChildMenu, MM_BLACKONWHITE); - DrawMenuBar(GetParent(GetParent(hwnd))) ; if ((pInfo = pGetInfoData(hwnd)) == NULL) { return 0L; } + giStretchMode = BLACKONWHITE; + bCheckMutexMenuItem(pInfo, hChildMenu, MM_BLACKONWHITE); + DrawMenuBar(GetParent(GetParent(hwnd))) ; pInfo->iStretchMode = giStretchMode; InvalidateRect(pInfo->hwnd, NULL, FALSE); @@ -931,12 +1193,12 @@ long ChildWndProc( } case MM_COLORONCOLOR: { - giStretchMode = COLORONCOLOR; - bCheckMutexMenuItem(hChildMenu, MM_COLORONCOLOR); - DrawMenuBar(GetParent(GetParent(hwnd))) ; if ((pInfo = pGetInfoData(hwnd)) == NULL) { return 0L; } + giStretchMode = COLORONCOLOR; + bCheckMutexMenuItem(pInfo, hChildMenu, MM_COLORONCOLOR); + DrawMenuBar(GetParent(GetParent(hwnd))) ; pInfo->iStretchMode = giStretchMode; InvalidateRect(pInfo->hwnd, NULL, FALSE); @@ -945,12 +1207,12 @@ long ChildWndProc( } case MM_WHITEONBLACK: { - giStretchMode = WHITEONBLACK; - bCheckMutexMenuItem(hChildMenu, MM_WHITEONBLACK); - DrawMenuBar(GetParent(GetParent(hwnd))) ; if ((pInfo = pGetInfoData(hwnd)) == NULL) { return 0L; } + giStretchMode = WHITEONBLACK; + bCheckMutexMenuItem(pInfo, hChildMenu, MM_WHITEONBLACK); + DrawMenuBar(GetParent(GetParent(hwnd))) ; pInfo->iStretchMode = giStretchMode; InvalidateRect(pInfo->hwnd, NULL, FALSE); @@ -959,12 +1221,12 @@ long ChildWndProc( } case MM_HALFTONE: { - giStretchMode = HALFTONE; - bCheckMutexMenuItem(hChildMenu, MM_HALFTONE); - DrawMenuBar(GetParent(GetParent(hwnd))) ; if ((pInfo = pGetInfoData(hwnd)) == NULL) { return 0L; } + giStretchMode = HALFTONE; + bCheckMutexMenuItem(pInfo, hChildMenu, MM_HALFTONE); + DrawMenuBar(GetParent(GetParent(hwnd))) ; pInfo->iStretchMode = giStretchMode; InvalidateRect(pInfo->hwnd, NULL, FALSE); @@ -1086,9 +1348,12 @@ long ChildWndProc( return 0L; } + if (pInfo->hCycleThrd) + CloseHandle(pInfo->hCycleThrd); + pInfo->hCycleThrd = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)bCycle, - hwnd, + (LPVOID)hwnd, STANDARD_RIGHTS_REQUIRED, &pInfo->dwCycleThrdID ); pInfo->bClrCycle = TRUE; @@ -1130,6 +1395,10 @@ long ChildWndProc( MessageBox(ghwndMain, "Boundary Tracing and Setting clip region to the boundary points only works for Mandelbrot Set.", "Error", MB_OK); return 0L; } + + if (pInfo->hThrd) + CloseHandle(pInfo->hThrd); + pInfo->hThrd = CreateThread(NULL, 0, (gFloat ? (LPTHREAD_START_ROUTINE)bBoundaryScanFix : (LPTHREAD_START_ROUTINE)bBoundaryScanFix), pInfo, @@ -1154,6 +1423,22 @@ long ChildWndProc( return 0L; } + case MM_SELCLIPRGN: { + HDC hDC; + + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + hDC = GetDC(pInfo->hwnd); + + if (pInfo->hRgnPath != (HRGN) NULL) { + SelectClipRgn(hDC, pInfo->hRgnPath); + } + + ReleaseDC(pInfo->hwnd, hDC); + bReleaseInfoData(hwnd); + return 0L; + } case MM_ERASE: { HDC hDC; RECT rc; @@ -1173,15 +1458,25 @@ long ChildWndProc( return 0L; } case MM_PORTRAIT: { + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + giDmOrient = DMORIENT_PORTRAIT; - bCheckMutexMenuItem(hChildMenu, MM_PORTRAIT); + bCheckMutexMenuItem(pInfo, hChildMenu, MM_PORTRAIT); DrawMenuBar(GetParent(GetParent(hwnd))) ; + bReleaseInfoData(hwnd); return 0L; } case MM_LANDSCAPE: { + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + giDmOrient = DMORIENT_LANDSCAPE; - bCheckMutexMenuItem(hChildMenu, MM_LANDSCAPE); + bCheckMutexMenuItem(pInfo, hChildMenu, MM_LANDSCAPE); DrawMenuBar(GetParent(GetParent(hwnd))) ; + bReleaseInfoData(hwnd); return 0L; } case MM_PRINTER: @@ -1235,6 +1530,9 @@ long ChildWndProc( PrtData.DevMode.dmFields = DM_ORIENTATION; } + if (pInfo->hPrtThrd) + CloseHandle(pInfo->hPrtThrd); + pInfo->hPrtThrd = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)bPrintBmp, &PrtData, @@ -1280,15 +1578,19 @@ long ChildWndProc( iWidth = GetDeviceCaps(hdcPrinter, HORZRES); iHeight = GetDeviceCaps(hdcPrinter, VERTRES); +// !!! Why is it necessary to save the image over again? May not want to +// do this because user may want to print the nice HT bitmap. So, +// use the DIB src. +#if 0 if (pInfo->hBmpSaved) DeleteObject(pInfo->hBmpSaved); - pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd); - + pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd, pInfo->hPal); +#endif Escape(hdcPrinter, STARTDOC, 20, "Mandelbrot", NULL); - DrawBitmap(hdcPrinter, pInfo, 0, 0, iWidth, iHeight); - Escape(hdcPrinter, NEWFRAME, NULL, NULL, NULL); - Escape(hdcPrinter, ENDDOC, NULL, NULL, NULL); + bDrawDIB(hdcPrinter, pInfo, 0, 0, iWidth, iHeight); + Escape(hdcPrinter, NEWFRAME, 0, NULL, NULL); + Escape(hdcPrinter, ENDDOC, 0, NULL, NULL); ReleaseDC(pInfo->hwnd, hDC); bReleaseInfoData(hwnd); DeleteDC(hdcPrinter); @@ -1311,20 +1613,43 @@ long ChildWndProc( return 0L; } - if ((HWND) lParam == hwnd) { + if ((HWND) lParam == hwnd) { // being activated SendMessage(GetParent(hwnd), WM_MDISETMENU, (DWORD) hChildMenu, (LONG) hSubMenuThree) ; - DrawMenuBar(GetParent(GetParent(hwnd))) ; (pInfo->bClrCycle ? CheckMenuItem(hChildMenu, MM_CYCLE, MF_CHECKED) : CheckMenuItem(hChildMenu, MM_CYCLE, MF_UNCHECKED) ); - } + vChkMenuItem(pInfo, hChildMenu, MF_CHECKED); + DrawMenuBar(GetParent(GetParent(hwnd))) ; + goto MDI_ACT_EXIT; + } + + if ((HWND) wParam == hwnd) { // being deactivated + + vChkMenuItem(pInfo, hChildMenu, MF_UNCHECKED); + DrawMenuBar(GetParent(GetParent(hwnd))) ; + } +MDI_ACT_EXIT: bReleaseInfoData(hwnd); return 0L; } + + case WM_QUERYNEWPALETTE: + case WM_PALETTECHANGED: { + PINFO pInfo; + + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + + SendMessage(pInfo->hwnd, message, wParam, lParam); + bReleaseInfoData(hwnd); + return 0L; + } + #if 0 case WM_WINDOWPOSCHANGING: { PWINDOWPOS pWndPos; @@ -1492,11 +1817,16 @@ long ChildWndProc( MessageBox(ghwndMain, "Failed in LocalLock, hNode", "Error", MB_OK); break; } else { + HDC hDC; + if (!GetClientRect(hwnd, &pInfo->rcClient)) MessageBox(ghwndMain, "Failed in GetClientRect!", "Error", MB_OK); pInfo->hTextWnd = hTextWnd; pInfo->hwnd = hJulia; + hDC = GetDC(hJulia); + pInfo->hHTPal = CreateHalftonePalette(hDC); + ReleaseDC(hJulia, hDC); #ifdef CYCLETHRD // // Creating a signal quit color cycling event @@ -1535,8 +1865,19 @@ long ChildWndProc( break; } - TerminateThread(pInfo->hThrd, (DWORD)0L); - TerminateThread(pInfo->hPrtThrd, (DWORD)0L); + if (pInfo->hThrd) { + TerminateThread(pInfo->hThrd, (DWORD)0L); + CloseHandle(pInfo->hThrd); + } + if (pInfo->hPrtThrd) { + TerminateThread(pInfo->hPrtThrd, (DWORD)0L); + CloseHandle(pInfo->hPrtThrd); + } + if (pInfo->hCycleThrd) { + TerminateThread(pInfo->hCycleThrd, (DWORD)0L); + CloseHandle(pInfo->hCycleThrd); + } + #ifdef CYCLETHRD // @@ -1566,6 +1907,626 @@ long ChildWndProc( return DefMDIChildProc(hwnd, message, wParam, lParam); } +/******************************Public*Routine******************************\ +* +* ViewerWndProc +* +* Effects: +* +* Warnings: +* +* History: +* 11-Dec-1992 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +LONG APIENTRY ViewerWndProc( + HWND hwnd, + UINT message, + DWORD wParam, + LONG lParam) +{ + static FARPROC lpfnSuspendThrd, lpfnResumeThrd; + + switch (message) { + case WM_COMMAND: { + PINFO pInfo; + HWND hTextWnd; + + switch (LOWORD(wParam)) { + case MM_RLELOAD_DEMO: { + HDC hDC; + char szDirName[256]; + char szFile[400]; + HWND hViewSurf; + + GetCurrentDirectory(256, (LPTSTR) szDirName); + + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + + if ((hViewSurf = pInfo->hwnd) == NULL) + return 0L; + + hTextWnd = pInfo->hTextWnd; + sprintf( gtext,"Loading bitmap(s) into memory"); + SetWindowText(hTextWnd, gtext); + + hDC = GetDC(hViewSurf); + strcpy(szFile, szDirName); + strcat(szFile, "\\rsc\\julia.rle"); + + if (bStoreRleFile(hDC, pInfo, szFile)) { + pInfo->RleData.ulFiles++; + PostMessage(ghwndMain, WM_COMMAND, MM_RLEPLAYCONT, 0L); + } + + ReleaseDC(hViewSurf, hDC); + + bReleaseInfoData(hwnd); + return 0L; + + } + + + case MM_RLELOAD: { + HDC hDC; + OPENFILENAME ofn; + char szDirName[256]; + char szFile[256], szFileTitle[256]; + static char *szFilter; + RECT rc; + HWND hViewSurf; + + szFilter = + "DIB files (*.bmp)\0*.bmp\0RLE files (*.rle)\0*.rle\0\0"; + + GetSystemDirectory((LPSTR) szDirName, 256); + strcpy(szFile, "*.bmp\0"); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = szFilter; + ofn.lpstrCustomFilter = (LPSTR) NULL; + ofn.nMaxCustFilter = 0L; + ofn.nFilterIndex = 1; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = sizeof(szFileTitle); + ofn.lpstrInitialDir = szDirName; + ofn.lpstrTitle = (LPSTR) NULL; + ofn.Flags = 0L; + ofn.nFileOffset = 0; + ofn.nFileExtension = 0; + ofn.lpstrDefExt = "BMP"; + + if (!GetOpenFileName(&ofn)) + return 0L; + + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + + if ((hViewSurf = pInfo->hwnd) == NULL) + return 0L; + + hTextWnd = pInfo->hTextWnd; + sprintf( gtext,"Loading bitmap(s) into memory"); + SetWindowText(hTextWnd, gtext); + + GetClientRect(hwnd, &rc); + hDC = GetDC(hViewSurf); + if (bStoreRleFile(hDC, pInfo, szFile)) + pInfo->RleData.ulFiles++; + ReleaseDC(hViewSurf, hDC); + + bReleaseInfoData(hwnd); + return 0L; + + } + + case MM_RLESAVE: { + HDC hDC; + OPENFILENAME ofn; + char szDirName[256]; + char szFile[256], szFileTitle[256]; + static char *szFilter; + HWND hViewSurf; + + szFilter = "DIB files (*.rle)\0\0"; + + GetSystemDirectory((LPSTR) szDirName, 256); + strcpy(szFile, "*.rle\0"); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = szFilter; + ofn.lpstrCustomFilter = (LPSTR) NULL; + ofn.nMaxCustFilter = 0L; + ofn.nFilterIndex = 0L; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = sizeof(szFileTitle); + ofn.lpstrInitialDir = szDirName; + ofn.lpstrTitle = "Saving Memory RLE Bitmap in File"; + ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT; + ofn.nFileOffset = 0; + ofn.nFileExtension = 0; + ofn.lpstrDefExt = (LPSTR)NULL; + + if (!GetSaveFileName(&ofn)) + return 0L; + + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + + if ((hViewSurf = pInfo->hwnd) == NULL) + return 0L; + + hTextWnd = pInfo->hTextWnd; + sprintf( gtext,"Saving loaded bitmap(s) into one RLE file"); + SetWindowText(hTextWnd, gtext); + + hDC = GetDC(hViewSurf); + bSaveRleFile(hDC, pInfo, szFile); + ReleaseDC(hViewSurf, hDC); + + bReleaseInfoData(hwnd); + return 0L; + } + + case MM_CLEAR: { + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + + hTextWnd = pInfo->hTextWnd; + sprintf( gtext,"Discard loaded bitmap(s) from memory"); + SetWindowText(hTextWnd, gtext); + + bFreeRleFile(pInfo); + + bReleaseInfoData(hwnd); + return 0L; + } + + case MM_RLEPLAY: { + HDC hDC; + HWND hViewSurf; + + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + + if ((hViewSurf = pInfo->hwnd) == NULL) + return 0L; + + hTextWnd = pInfo->hTextWnd; + sprintf( gtext,"Play loaded bitmap(s)"); + SetWindowText(hTextWnd, gtext); + + hDC = GetDC(hViewSurf); + EnableMenuItem(hViewSubOne, MM_CLEAR, MF_GRAYED); + + if (pInfo->hThrd0) + CloseHandle(pInfo->hThrd0); + + pInfo->hThrd0 = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE)bPlayRle, + pInfo, + STANDARD_RIGHTS_REQUIRED, + &pInfo->dwThreadId ); + + if (pInfo->hThrd0) { + if (!SetThreadPriority(pInfo->hThrd0, THREAD_PRIORITY_BELOW_NORMAL)) + MessageBox(ghwndMain, "Can't set Priority!", + "Error", MB_OK); + } + + //bPlayRle(hDC, pInfo); + EnableMenuItem(hViewSubOne, MM_CLEAR, MF_ENABLED); + ReleaseDC(hViewSurf, hDC); + + bReleaseInfoData(hwnd); + return 0L; + } + + case MM_RLEPLAYCONT: { + HWND hViewSurf; + + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + + if ((hViewSurf = pInfo->hwnd) == NULL) + return 0L; + + hTextWnd = pInfo->hTextWnd; + sprintf( gtext,"Play loaded bitmap(s) continuously"); + SetWindowText(hTextWnd, gtext); + + if (pInfo->bFirstTime) { + if (!SetEvent(pInfo->hQuitEvent)) { + MessageBox(ghwndMain, "Can't set Quit Event!", + "Error", MB_OK); + return 0L; + } + + EnableMenuItem(hViewSubOne, MM_CLEAR, MF_GRAYED); + + if (pInfo->hThrd) + CloseHandle(pInfo->hThrd); + + pInfo->hThrd = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE)bPlayRleCont2, + pInfo, + STANDARD_RIGHTS_REQUIRED, + &pInfo->dwThreadId ); + + if (pInfo->hThrd) { + if (!SetThreadPriority(pInfo->hThrd, THREAD_PRIORITY_BELOW_NORMAL)) + MessageBox(ghwndMain, "Can't set Priority!", + "Error", MB_OK); + } + + pInfo->bPlayRleCont = TRUE; + pInfo->bFirstTime = FALSE; + CheckMenuItem(hViewMenu, MM_RLEPLAYCONT, MF_CHECKED); + } else { + if (pInfo->bPlayRleCont) { + EnableMenuItem(hViewSubOne, MM_CLEAR, MF_ENABLED); + CheckMenuItem(hViewMenu, MM_RLEPLAYCONT, MF_UNCHECKED); + pInfo->bPlayRleCont = FALSE; + pInfo->dwSuspend = SuspendThread(pInfo->hThrd); + } else { + EnableMenuItem(hViewSubOne, MM_CLEAR, MF_GRAYED); + CheckMenuItem(hViewMenu, MM_RLEPLAYCONT, MF_CHECKED); + pInfo->bPlayRleCont = TRUE; + pInfo->dwSuspend = ResumeThread(pInfo->hThrd); + } + if (pInfo->dwSuspend == -1) { + (pInfo->bPlayRleCont ? + sprintf( gtext,"Error in resuming thread\n") : + sprintf( gtext,"Error in suspending thread\n") ); + OutputDebugString( gtext ); + } + } + + bReleaseInfoData(hwnd); + return 0L; + } + + default: + return 0L; + + } //switch + + } // WM_COMMAND + case WM_SETFOCUS: + break; + + case WM_MDIACTIVATE: { + PINFO pInfo; + + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + + if ((HWND) lParam == hwnd) { + SendMessage(GetParent(hwnd), WM_MDISETMENU, + (WPARAM) hViewMenu, + (LPARAM) NULL) ; + DrawMenuBar(GetParent(GetParent(hwnd))) ; + } + + bReleaseInfoData(hwnd); + return 0L; + } + case WM_QUERYNEWPALETTE: + case WM_PALETTECHANGED: { + PINFO pInfo; + + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + + SendMessage(pInfo->hwnd, message, wParam, lParam); + bReleaseInfoData(hwnd); + return 0L; + } + + case WM_SIZE: { + PINFO pInfo; + HWND hTextWnd, hView; + WORD wCx; + int iCyText; + + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + break; + } + + hTextWnd = pInfo->hTextWnd; + hView = pInfo->hwnd; + bReleaseInfoData(hwnd); + iCyText = GetWindowLong(hTextWnd, GWL_USERDATA); + wCx = (WORD) (HIWORD(lParam) - iCyText); + + MoveWindow(hView, 0, 0, + LOWORD(lParam), + wCx, + TRUE); + + MoveWindow(hTextWnd, + 0, + wCx, + LOWORD(lParam), + iCyText, + TRUE); + + break; + } + + // + // display info in the status window + // + case WM_USER+0xa: { + PINFO pInfo; + static ULONG ulClick = 0; + HWND hTextWnd; + + ulClick++; + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + return 0L; + } + + hTextWnd = pInfo->hTextWnd; + switch (ulClick % 4) { + case 0: sprintf( gtext,"%d Frames", pInfo->RleData.ulFrames); + break; + case 1: sprintf( gtext,"%d Files", pInfo->RleData.ulFiles); + break; + case 2: sprintf( gtext, + (pInfo->bPlayRleCont ? "Continuous Play" + : "Single Play")); + break; + case 3: sprintf( gtext,""); + break; + default: break; + } + SetWindowText(hTextWnd, gtext); + bReleaseInfoData(hwnd); + return 0L; + } + + case WM_SYSCOMMAND: { + LONG lResult; + + EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnSuspendThrd, lParam); + + lResult = DefMDIChildProc(hwnd, message, wParam, lParam); + + EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnResumeThrd, lParam); + + return lResult; + break; + } + + case WM_CREATE: { + PINFO pInfo; + HANDLE hInfo; + HWND hTextWnd, hView; + RECT rcl; + + // + // CR! MakeProcInstance is noop! + // + lpfnSuspendThrd = (FARPROC)MakeProcInstance (SuspendDrawThrd, ghModule); + lpfnResumeThrd = (FARPROC)MakeProcInstance (ResumeDrawThrd, ghModule); + + hTextWnd = CreateWindow("Text", NULL, + WS_BORDER | SS_LEFT | WS_CHILD | WS_VISIBLE, + 0, 0, 0, 0, + hwnd, + (HMENU) 2, + ghModule, + NULL); + + GetClientRect(hwnd, &rcl); + hView = CreateWindow("View", (LPSTR) NULL, + WS_CHILD | WS_VISIBLE | + WS_BORDER, + 0,0, rcl.right-rcl.left, + rcl.bottom-rcl.top-GetWindowLong(hTextWnd, GWL_USERDATA), + hwnd, (HMENU)1, ghModule, (LPVOID)NULL); + + SetWindowText(hTextWnd, "Select the 'Draw Set' menu item to start drawing."); + hInfo = (HANDLE) ((LPMDICREATESTRUCT) ((LPCREATESTRUCT) lParam)->lpCreateParams)->lParam ; + if (hInfo) { + if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) { + MessageBox(ghwndMain, "Failed in LocalLock, hNode", "Error", MB_OK); + break; + } else { + HDC hDC; + + if (!GetClientRect(hwnd, &pInfo->rcClient)) + MessageBox(ghwndMain, "Failed in GetClientRect!", "Error", MB_OK); + + pInfo->hTextWnd = hTextWnd; + pInfo->hwnd = hView; + + hDC = GetDC(hView); + pInfo->hHTPal = CreateHalftonePalette(hDC); + ReleaseDC(hView, hDC); + + // + // Creating a signal quit play continuous event + // + if ((pInfo->hQuitEvent = CreateEvent(NULL, TRUE, TRUE, NULL)) == NULL) + MessageBox(ghwndMain, "Failed in creating Quit Event!", "Error", MB_OK); + + SetWindowLong(hwnd, 0, (LONG) hInfo); + LocalUnlock(hInfo); + } + } else { + MessageBox(ghwndMain, "Can't allocate hInfo!", "Error", MB_OK); + } + + break; + } + + case WM_CLOSE: { + SendMessage(GetParent(hwnd), WM_MDISETMENU, + (DWORD) hMenu, + (LONG) hSubMenuOne) ; + DrawMenuBar(GetParent(GetParent(hwnd))) ; + break; + } + + case WM_DESTROY: { + PINFO pInfo; + if ((pInfo = pGetInfoData(hwnd)) == NULL) { + break; + } + + TerminateThread(pInfo->hThrd, (DWORD)0L); + CloseHandle(pInfo->hThrd); + + // + // Cleanup continuous play + // + if (!ResetEvent(pInfo->hQuitEvent)) + MessageBox(ghwndMain, "Failed in reseting quit event!", "Error", MB_OK); + + bFreeRleFile(pInfo); + bReleaseInfoData(hwnd); + LocalFree((HANDLE) GetWindowLong(hwnd, 0)); + break; + } + + default: + return DefMDIChildProc(hwnd, message, wParam, lParam); + + } //switch + return DefMDIChildProc(hwnd, message, wParam, lParam); +} + +/******************************Public*Routine******************************\ +* +* ViewSurfWndProc +* +* Effects: +* +* Warnings: +* +* History: +* 13-Dec-1992 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +LONG APIENTRY ViewSurfWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam) +{ + switch (message) + { + case WM_CREATE: { + break; + } + + case WM_DESTROY: { + break; + } + + case WM_QUERYNEWPALETTE: { + HWND hParent; + PINFO pInfo; + HDC hDC; + UINT i; + HPALETTE hOldPal; + + if ((hParent=GetParent(hwnd)) == NULL) { + MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK); + return 0L; + } + if ((pInfo = pGetInfoData(hParent)) == NULL) { + return 0L; + } + + // If palette realization causes a palette change, + // we need to do a full redraw. + + hDC = GetDC (hwnd); + + hOldPal = SelectPalette (hDC, + pInfo->RleData.hPal, + 0); + + i = RealizePalette(hDC); + + SelectPalette (hDC, hOldPal, 0); + ReleaseDC (hwnd, hDC); + bReleaseInfoData(hParent); + + if (i) { + InvalidateRect (hwnd, (LPRECT) (NULL), TRUE); + return TRUE; + } else + return FALSE; + + } + case WM_PALETTECHANGED: { + HWND hParent; + PINFO pInfo; + HDC hDC; + UINT i; + HPALETTE hOldPal; + + if ((hParent=GetParent(hwnd)) == NULL) { + MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK); + return 0L; + } + if ((pInfo = pGetInfoData(hParent)) == NULL) { + return 0L; + } + + // if we were not responsible for palette change and if + // palette realization causes a palette change, do a redraw. + + if ((HWND)wParam != hwnd){ + hDC = GetDC (hwnd); + + hOldPal = SelectPalette (hDC, + pInfo->RleData.hPal, + 0); + + i = RealizePalette (hDC); + + if (i){ + UpdateColors (hDC); + } + SelectPalette (hDC, hOldPal, 0); + ReleaseDC (hwnd, hDC); + } + bReleaseInfoData(hParent); + break; + } + + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hDC; + RECT rc; + + GetClientRect(hwnd,&rc); + hDC = BeginPaint(hwnd, &ps); + EndPaint(hwnd, &ps); + return 0L; + } + + } // switch + return DefWindowProc(hwnd, message, wParam, lParam); +} + /***************************************************************************\ * About * @@ -1576,7 +2537,7 @@ long ChildWndProc( * 09-09-91 Petrus Wong Rewrote. \***************************************************************************/ -long About( +BOOL CALLBACK About( HWND hDlg, UINT message, DWORD wParam, @@ -1609,7 +2570,7 @@ long About( * \***************************************************************************/ -LONG TextWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam) +LONG APIENTRY TextWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam) { static HFONT hFont = (HFONT) NULL; @@ -1732,7 +2693,7 @@ LONG TextWndProc (HWND hwnd, UINT messag * Wrote it. \**************************************************************************/ -LONG JuliaWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam) +LONG APIENTRY JuliaWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam) { // // These statics are shared by all the Julia windows. But, this is @@ -1760,12 +2721,100 @@ LONG JuliaWndProc (HWND hwnd, UINT messa } case WM_DESTROY: { + HWND hParent; + PINFO pInfo; DeleteObject(hpnRed); DeleteObject(hpnGreen); DeleteObject(hpnBlack); + + if ((hParent=GetParent(hwnd)) == NULL) { + MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK); + break; + } + if ((pInfo = pGetInfoData(hParent)) == NULL) { + break; + } + + // we might have open resource if we ever load bitmap in this wnd. + bFreeRleFile(pInfo); + bReleaseInfoData(hParent); + break; + } + + case WM_QUERYNEWPALETTE: { + HWND hParent; + PINFO pInfo; + HDC hDC; + UINT i; + HPALETTE hOldPal; + + if ((hParent=GetParent(hwnd)) == NULL) { + MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK); + return 0L; + } + if ((pInfo = pGetInfoData(hParent)) == NULL) { + return 0L; + } + + // If palette realization causes a palette change, + // we need to do a full redraw. + + hDC = GetDC (hwnd); + + hOldPal = SelectPalette (hDC, + ((pInfo->iStretchMode == HALFTONE) ? pInfo->hHTPal : pInfo->hPal), + 0); + + i = RealizePalette(hDC); + SelectPalette (hDC, hOldPal, 0); + ReleaseDC (hwnd, hDC); + bReleaseInfoData(hParent); + + if (i) { + InvalidateRect (hwnd, (LPRECT) (NULL), TRUE); + return TRUE; + } else + return FALSE; + + } + case WM_PALETTECHANGED: { + HWND hParent; + PINFO pInfo; + HDC hDC; + UINT i; + HPALETTE hOldPal; + + if ((hParent=GetParent(hwnd)) == NULL) { + MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK); + return 0L; + } + if ((pInfo = pGetInfoData(hParent)) == NULL) { + return 0L; + } + + // if we were not responsible for palette change and if + // palette realization causes a palette change, do a redraw. + + if ((HWND)wParam != hwnd){ + hDC = GetDC (hwnd); + + hOldPal = SelectPalette (hDC, + ((pInfo->iStretchMode == HALFTONE) ? pInfo->hHTPal : pInfo->hPal), + 0); + + i = RealizePalette (hDC); + + if (i){ + UpdateColors (hDC); + } + SelectPalette (hDC, hOldPal, 0); + ReleaseDC (hwnd, hDC); + } + bReleaseInfoData(hParent); break; } + case WM_PAINT: { PAINTSTRUCT ps; @@ -1787,7 +2836,7 @@ LONG JuliaWndProc (HWND hwnd, UINT messa if (pInfo->hBmpSaved) { hDC = GetDC(hwnd); - DrawBitmap(hDC, pInfo, 0, 0, rc.right, rc.bottom); + bDrawDIB(hDC, pInfo, 0, 0, rc.right, rc.bottom); ReleaseDC(hwnd, hDC); } bReleaseInfoData(hParent); @@ -1875,7 +2924,9 @@ LONG JuliaWndProc (HWND hwnd, UINT messa if (pInfo->bFill) { hDC = GetDC(hwnd); hBrOld = SelectObject(hDC, pInfo->hBrush); + dwRGB = GetPixel(hDC, x, y); + ExtFloodFill(hDC, x, y, (COLORREF)dwRGB, FLOODFILLSURFACE); SelectObject(hDC, hBrOld); ReleaseDC(hwnd, hDC); @@ -1884,7 +2935,10 @@ LONG JuliaWndProc (HWND hwnd, UINT messa if (pInfo->hBmpSaved) DeleteObject(pInfo->hBmpSaved); - pInfo->hBmpSaved = SaveBitmap(hwnd); + pInfo->hBmpSaved = SaveBitmap(hwnd, pInfo->hPal); + pInfo->bUseDIB = FALSE; + + SetCursor(hCurArrow); } else { bTrack = TRUE; @@ -2173,18 +3227,23 @@ BOOL APIENTRY ResumeDrawThrd (HWND hwnd * * Effects: Fix point multiplication * -* Warnings: 20.11 fix point representation used. This is only good for +* Warnings: 9.23 fix point representation used. This is only good for * multiplication in a limited range. Will overflow. * CR! Will be implemented as macros in the future * * History: +* 16-Feb-1993 Petrus Wong 9.23 fix i LARGE_INTEGER support * 20-Nov-1991 -by- Petrus Wong * Wrote it. \**************************************************************************/ LONG lMul(LONG l1, LONG l2) { - return( (l1 * l2) >> 11); + LARGE_INTEGER liTmp; + + liTmp = EnlargedIntegerMultiply(l1, l2); + liTmp = LargeIntegerShiftRight(liTmp, 23); + return(liTmp.LowPart); } /******************************Public*Routine******************************\ @@ -2193,18 +3252,26 @@ LONG lMul(LONG l1, LONG l2) * * Effects: fix point division * -* Warnings: 20.11 fix point representation used. This is only good for +* Warnings: 9.23 fix point representation used. This is only good for * division in a limited range. Will overflow. * CR! Will be implemented as macros in the future * * History: +* 16-Feb-1993 Petrus Wong 9.23 fix i LARGE_INTEGER support * 20-Nov-1991 -by- Petrus Wong * Wrote it. \**************************************************************************/ LONG lDiv(long l1, long l2) { - return( (l1 << 11) / l2); + LARGE_INTEGER liTmp, liTmp2; + + + liTmp = ConvertLongToLargeInteger(l1); + liTmp2 = ConvertLongToLargeInteger(l2); + liTmp = LargeIntegerShiftLeft(liTmp, 23); + liTmp = LargeIntegerDivide(liTmp, liTmp2, NULL); + return (liTmp.LowPart); } @@ -2223,6 +3290,9 @@ LONG lDiv(long l1, long l2) * Warnings: * * History: +* 16-Feb-1993 Petrus Wong 9.23 fix +* 11-Feb-1993 Petrus Wong Minimize device access +* 14-Dec-1992 -by- Petrus Wong Enable shadow bitmap * 14-Jun-1992 -by- Petrus Wong Modified to use the pen array * 20-Nov-1991 -by- Petrus Wong * Wrote it. @@ -2240,7 +3310,18 @@ BOOL StartDrawFix(PINFO pInfo) LONG c1, c2; LONG x0, y0, x1, y1, x, y, z; - iPen = giPen + 1; + int iBand=1; + int iScan=0; + int iDiff=0; + +#ifndef THRDONE + INT iNumClr; +#endif + + HDC hDCMem; + HBITMAP hBitmap, hOldBitmap; + + iPen = pInfo->iPen + 1; iPrev = FIRST_PIXEL; // a big value to signal the first pixel //iPrev = pInfo->iIteration + FIRST_PIXEL; c1 = pInfo->lc1; @@ -2250,14 +3331,38 @@ BOOL StartDrawFix(PINFO pInfo) pInfo->bDrawing = TRUE; hDC = GetDC(pInfo->hwnd); +#ifndef THRDONE + if ((iNumClr = iCreatePenFrPal(hDC, NULL, 0, &(pInfo->hPal))) != 0) { + sprintf( gtext,"iNumClr = %d\n", iNumClr); + OutputDebugString( gtext); + + if ((pInfo->prghPen = (PVOID*) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(HPEN)*iNumClr)) == NULL) { + MessageBox(ghwndMain, "Failed in Memory Allocation for pInfo->prghPen!", "Error", MB_OK); + } else { + if ((pInfo->iPen = iCreatePenFrPal(hDC, pInfo->prghPen, 0, &(pInfo->hPal))) == 0) + MessageBox(ghwndMain, "Failed in creating pen!", "Error", MB_OK); + } + } + + hDCMem = CreateCompatibleDC(hDC); + + SelectPalette(hDCMem, pInfo->hPal, FALSE); + SelectPalette(hDC, pInfo->hPal, FALSE); + RealizePalette(hDC); + iPen = pInfo->iPen + 1; +#endif + GetClientRect(pInfo->hwnd, &rc); + hBitmap = CreateCompatibleBitmap(hDC, (int)rc.right, (int)rc.bottom); + hOldBitmap = SelectObject(hDCMem, hBitmap); yCurr = rc.top; dwTick1 = GetTickCount(); + iScan = (((iScan = BATCH / rc.right) == 0) ? 1 : iScan); for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) { xCurr = rc.left; // since LineTo excludes last point - MoveToEx(hDC, 0, yCurr, NULL); + MoveToEx(hDCMem, 0, yCurr, NULL); y0 = XformFix(n, rc.top, rc.bottom, pInfo->lyFrom, pInfo->lyTo); for (m=rc.left; m<=rc.right; m++, xCurr++) { @@ -2273,7 +3378,7 @@ BOOL StartDrawFix(PINFO pInfo) y = y1; // 2 2 2 1/2 2 z = lMul(x, x) + lMul(y, y); // |Z| = ((x1 + x2 ) ) > 2 - if (z > 8192) + if (z > 33554432) break; } @@ -2283,37 +3388,56 @@ BOOL StartDrawFix(PINFO pInfo) { switch(iPrev) { - case 1: SelectObject(hDC, hpnRed); break; + case 1: + SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]); + break; default: if (iPrev >= pInfo->iIteration) { - SelectObject(hDC, hpnBlack); + SelectObject(hDCMem, hpnBlack); break; } - SelectObject(hDC, (HPEN)gprghPen[iPrev % iPen]); + SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[iPrev % iPen]); break; } iPrev = i; - LineTo(hDC,xCurr,yCurr); + LineTo(hDCMem,xCurr,yCurr); } else iPrev = i; // remember the color for the first pixel } } - switch(i) - { - case 1: SelectObject(hDC, hpnRed); break; - default: - if (iPrev >= pInfo->iIteration) { - SelectObject(hDC, hpnBlack); - break; - } - SelectObject(hDC, (HPEN)gprghPen[i % iPen]); - break; - } + switch(i) { + case 1: + SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]); + break; + default: + if (iPrev >= pInfo->iIteration) { + SelectObject(hDCMem, hpnBlack); + break; + } + SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[i % iPen]); + break; + } + + LineTo(hDCMem,xCurr,yCurr); - LineTo(hDC,xCurr,yCurr); + sprintf(gtext, "Drawing: %3.2f %%", ((FLOAT)n/(FLOAT)rc.bottom)*100); + SetWindowText(pInfo->hTextWnd, gtext); + + if (n >= iScan * iBand) { + BitBlt(hDC, 0, iScan * (iBand-1), rc.right, iScan, hDCMem, 0, iScan * (iBand-1), SRCCOPY); + iBand++; + } } + + if ((iDiff = iScan * iBand - rc.bottom) != 0) { + BitBlt(hDC, 0, iScan * (iBand-1), rc.right, iScan-iDiff, hDCMem, 0, iScan * (iBand-1), SRCCOPY); + } + + sprintf(gtext, "Drawing: DONE"); + SetWindowText(pInfo->hTextWnd, gtext); + ReleaseDC(pInfo->hwnd, hDC); pInfo->dwElapsed = GetTickCount() - dwTick1; @@ -2321,13 +3445,18 @@ BOOL StartDrawFix(PINFO pInfo) if (pInfo->hBmpSaved) DeleteObject(pInfo->hBmpSaved); - pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd); + pInfo->hBmpSaved = SelectObject(hDCMem, hOldBitmap); pInfo->bDrawing = FALSE; - +#ifndef THRDONE + if (pInfo->prghPen != NULL) { + for (i = 0; i <= pInfo->iPen; i++) { + DeleteObject((HPEN) (pInfo->prghPen)[i]); + } + GlobalFree(pInfo->prghPen); + } +#endif + DeleteDC(hDCMem); ExitThread(0); - if (!CloseHandle(pInfo->hThrd)) - MessageBox(ghwndMain, "Failed in CloseHandle!", "Error", MB_OK); - return TRUE; } @@ -2346,6 +3475,8 @@ BOOL StartDrawFix(PINFO pInfo) * Warnings: * * History: +* 11-Feb-1993 Petrus Wong Minimize device access +* 14-Dec-1992 -by- Petrus Wong Enable shadow bitmap * 14-Jun-1992 -by- Petrus Wong Modified to use the pen array and LineTo * 20-Nov-1991 -by- Petrus Wong * Wrote it. @@ -2363,8 +3494,19 @@ BOOL StartDraw(PINFO pInfo) double c1, c2; double x0, y0, x1, y1, x, y, z; + int iBand=1; + int iScan=0; + int iDiff=0; - iPen = giPen + 1; + + HDC hDCMem; + HBITMAP hBitmap, hOldBitmap; + +#ifndef THRDONE + INT iNumClr; +#endif + + iPen = pInfo->iPen + 1; iPrev = FIRST_PIXEL; // a big value to signal the first pixel //iPrev = pInfo->iIteration + FIRST_PIXEL; c1 = pInfo->c1; @@ -2374,14 +3516,39 @@ BOOL StartDraw(PINFO pInfo) pInfo->bDrawing = TRUE; hDC = GetDC(pInfo->hwnd); +#ifndef THRDONE + if ((iNumClr = iCreatePenFrPal(hDC, NULL, 0, &(pInfo->hPal))) != 0) { + sprintf( gtext,"iNumClr = %d\n", iNumClr); + OutputDebugString( gtext); + + if ((pInfo->prghPen = (PVOID*) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(HPEN)*iNumClr)) == NULL) { + MessageBox(ghwndMain, "Failed in Memory Allocation for pInfo->prghPen!", "Error", MB_OK); + } else { + if ((pInfo->iPen = iCreatePenFrPal(hDC, pInfo->prghPen, 0, &(pInfo->hPal))) == 0) + MessageBox(ghwndMain, "Failed in creating pen!", "Error", MB_OK); + } + } + + hDCMem = CreateCompatibleDC(hDC); + + SelectPalette(hDCMem, pInfo->hPal, FALSE); + SelectPalette(hDC, pInfo->hPal, FALSE); + RealizePalette(hDC); + iPen = pInfo->iPen + 1; +#endif + GetClientRect(pInfo->hwnd, &rc); + hBitmap = CreateCompatibleBitmap(hDC, (int)rc.right, (int)rc.bottom); + hOldBitmap = SelectObject(hDCMem, hBitmap); yCurr = rc.top; dwTick1 = GetTickCount(); + iScan = (((iScan = BATCH / rc.right) == 0) ? 1 : iScan); + for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) { xCurr = rc.left; // since LineTo excludes last point - MoveToEx(hDC, 0, yCurr, NULL); + MoveToEx(hDCMem, 0, yCurr, NULL); y0 = Xform((double) n, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo); for (m=rc.left; m<=rc.right; m++, xCurr++) { @@ -2407,37 +3574,56 @@ BOOL StartDraw(PINFO pInfo) { switch(iPrev) { - case 1: SelectObject(hDC, hpnRed); break; + case 1: + SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]); + break; default: if (iPrev >= pInfo->iIteration) { - SelectObject(hDC, hpnBlack); + SelectObject(hDCMem, hpnBlack); break; } - SelectObject(hDC, (HPEN)gprghPen[iPrev % iPen]); + SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[iPrev % iPen]); break; } iPrev = i; - LineTo(hDC,xCurr,yCurr); + LineTo(hDCMem,xCurr,yCurr); } else iPrev = i; // remember the color for the first pixel } } - switch(i) - { - case 1: SelectObject(hDC, hpnRed); break; - default: - if (iPrev >= pInfo->iIteration) { - SelectObject(hDC, hpnBlack); - break; - } - SelectObject(hDC, (HPEN)gprghPen[i % iPen]); - break; - } + switch(i) { + case 1: + SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]); + break; + default: + if (iPrev >= pInfo->iIteration) { + SelectObject(hDCMem, hpnBlack); + break; + } + SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[i % iPen]); + break; + } + + LineTo(hDCMem,xCurr,yCurr); - LineTo(hDC,xCurr,yCurr); + sprintf(gtext, "Drawing: %3.2f %%", ((FLOAT)n/(FLOAT)rc.bottom)*100); + SetWindowText(pInfo->hTextWnd, gtext); + + if (n >= iScan * iBand) { + BitBlt(hDC, 0, iScan * (iBand-1), rc.right, iScan, hDCMem, 0, iScan * (iBand-1), SRCCOPY); + iBand++; + } } + + if ((iDiff = iScan * iBand - rc.bottom) != 0) { + BitBlt(hDC, 0, iScan * (iBand-1), rc.right, iScan-iDiff, hDCMem, 0, iScan * (iBand-1), SRCCOPY); + } + + sprintf(gtext, "Drawing: DONE"); + SetWindowText(pInfo->hTextWnd, gtext); + ReleaseDC(pInfo->hwnd, hDC); pInfo->dwElapsed = GetTickCount() - dwTick1; @@ -2445,13 +3631,19 @@ BOOL StartDraw(PINFO pInfo) if (pInfo->hBmpSaved) DeleteObject(pInfo->hBmpSaved); - pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd); + pInfo->hBmpSaved = SelectObject(hDCMem, hOldBitmap); pInfo->bDrawing = FALSE; +#ifndef THRDONE + if (pInfo->prghPen != NULL) { + for (i = 0; i <= pInfo->iPen; i++) { + DeleteObject((HPEN) (pInfo->prghPen)[i]); + } + GlobalFree(pInfo->prghPen); + } +#endif + DeleteDC(hDCMem); ExitThread(0); - if (!CloseHandle(pInfo->hThrd)) - MessageBox(ghwndMain, "Failed in CloseHandle!", "Error", MB_OK); - return TRUE; } @@ -2511,7 +3703,8 @@ BOOL StartDraw2(PINFO pInfo) } } r = sqrt(w0 * w0 + w1 + w1); - theta = theta/2.0 + ((int) ((2.0*rand()/(RAND_MAX+1.0)))*pi); + //theta = theta/2.0 + ((int) ((2.0*rand()/(RAND_MAX+1.0)))*pi); + //theta = theta/2.0 + ((2.0*rand()/((double)RAND_MAX+1.0))*pi); r = sqrt(r); x0 = r*cos(theta); y0 = r*sin(theta); @@ -2525,9 +3718,6 @@ BOOL StartDraw2(PINFO pInfo) ReleaseDC(pInfo->hwnd, hDC); ExitThread(0); - if (!CloseHandle(pInfo->hThrd)) - MessageBox(ghwndMain, "Failed in CloseHandle!", "Error", MB_OK); - return TRUE; } @@ -2540,6 +3730,9 @@ BOOL StartDraw2(PINFO pInfo) * Warnings: * * History: +* 16-Feb-1993 Petrus Wong 9.23 fix +* 11-Feb-1993 Petrus Wong Minimize device access +* 14-Dec-1992 -by- Petrus Wong Enable shadow bitmap * 14-Jun-1992 -by- Petrus Wong Modified to use the pen array * 20-Nov-1991 -by- Petrus Wong * Wrote it. @@ -2555,19 +3748,56 @@ BOOL StartMandelbrotFix(PINFO pInfo) LONG c1, c2; LONG x1, y1, x, y, r; +#ifndef THRDONE + INT iNumClr; +#endif + + HDC hDCMem; + HBITMAP hBitmap, hOldBitmap; + + int iBand=1; + int iScan=0; + int iDiff=0; - iPen = giPen + 1; + iPen = pInfo->iPen + 1; pInfo->bMandel = TRUE; pInfo->bDrawing = TRUE; hDC = GetDC(pInfo->hwnd); +#ifndef THRDONE + if ((iNumClr = iCreatePenFrPal(hDC, NULL, 0, &(pInfo->hPal))) != 0) { + sprintf( gtext,"iNumClr = %d\n", iNumClr); + OutputDebugString( gtext); + + if ((pInfo->prghPen = (PVOID*) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(HPEN)*iNumClr)) == NULL) { + MessageBox(ghwndMain, "Failed in Memory Allocation for pInfo->prghPen!", "Error", MB_OK); + } else { + if ((pInfo->iPen = iCreatePenFrPal(hDC, pInfo->prghPen, 0, &(pInfo->hPal))) == 0) + MessageBox(ghwndMain, "Failed in creating pen!", "Error", MB_OK); + } + } + + hDCMem = CreateCompatibleDC(hDC); + + SelectPalette(hDCMem, pInfo->hPal, FALSE); + SelectPalette(hDC, pInfo->hPal, FALSE); + RealizePalette(hDC); + iPen = pInfo->iPen + 1; +#endif + GetClientRect(pInfo->hwnd, &rc); + hBitmap = CreateCompatibleBitmap(hDC, (int)rc.right, (int)rc.bottom); + hOldBitmap = SelectObject(hDCMem, hBitmap); + dwTick1 = GetTickCount(); yCurr = rc.top; + + iScan = (((iScan = BATCH / rc.right) == 0) ? 1 : iScan); + for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) { xCurr = rc.left; // since LineTo excludes last point - MoveToEx(hDC, 0, yCurr, NULL); + MoveToEx(hDCMem, 0, yCurr, NULL); c2 = XformFix(n, rc.top, rc.bottom, pInfo->lyFrom, pInfo->lyTo); for (m=rc.left; m<=rc.right; m++, xCurr++) { @@ -2581,7 +3811,7 @@ BOOL StartMandelbrotFix(PINFO pInfo) r = lMul(x1, x1) + lMul(y1, y1); x = x1; y = y1; - if (r > 8192) { + if (r > 33554432) { break; } } @@ -2589,38 +3819,55 @@ BOOL StartMandelbrotFix(PINFO pInfo) if (i != iPrev) { if (iPrev != FIRST_PIXEL) { switch(iPrev) { - case 1: SelectObject(hDC, hpnRed); break; + case 1: + SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]); break; default: if (iPrev >= pInfo->iIteration) { - SelectObject(hDC, hpnBlack); + SelectObject(hDCMem, hpnBlack); break; } - SelectObject(hDC, (HPEN)gprghPen[iPrev % iPen]); + SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[iPrev % iPen]); break; } iPrev = i; - LineTo(hDC, xCurr, yCurr); + LineTo(hDCMem, xCurr, yCurr); } else iPrev = i; // remember the color for the first pixel } } - switch(i) - { - case 1: SelectObject(hDC, hpnRed); break; - default: - if (i >= pInfo->iIteration) { - SelectObject(hDC, hpnBlack); - break; - } - SelectObject(hDC, (HPEN)gprghPen[i % iPen]); - break; - } + switch(i) { + case 1: + SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]); + break; + default: + if (i >= pInfo->iIteration) { + SelectObject(hDCMem, hpnBlack); + break; + } + SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[i % iPen]); + break; + } + LineTo(hDCMem,xCurr,yCurr); + + sprintf(gtext, "Drawing: %3.2f %%", ((FLOAT)n/(FLOAT)rc.bottom)*100); + SetWindowText(pInfo->hTextWnd, gtext); - LineTo(hDC,xCurr,yCurr); + if (n >= iScan * iBand) { + BitBlt(hDC, 0, iScan * (iBand-1), rc.right, iScan, hDCMem, 0, iScan * (iBand-1), SRCCOPY); + iBand++; + } + + } + if ((iDiff = iScan * iBand - rc.bottom) != 0) { + BitBlt(hDC, 0, iScan * (iBand-1), rc.right, iScan-iDiff, hDCMem, 0, iScan * (iBand-1), SRCCOPY); } + + sprintf(gtext, "Drawing: DONE"); + SetWindowText(pInfo->hTextWnd, gtext); + ReleaseDC(pInfo->hwnd, hDC); pInfo->dwElapsed = GetTickCount() - dwTick1; @@ -2628,13 +3875,21 @@ BOOL StartMandelbrotFix(PINFO pInfo) if (pInfo->hBmpSaved) DeleteObject(pInfo->hBmpSaved); - pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd); + pInfo->hBmpSaved = SelectObject(hDCMem, hOldBitmap); pInfo->bDrawing = FALSE; - ExitThread(0); - if (!CloseHandle(pInfo->hThrd)) - MessageBox(ghwndMain, "Failed in CloseHandle!", "Error", MB_OK); +#ifndef THRDONE + if (pInfo->prghPen != NULL) { + for (i = 0; i <= pInfo->iPen; i++) { + DeleteObject((HPEN) (pInfo->prghPen)[i]); + } + GlobalFree(pInfo->prghPen); + } +#endif + DeleteDC(hDCMem); + + ExitThread(0); return TRUE; } @@ -2647,6 +3902,8 @@ BOOL StartMandelbrotFix(PINFO pInfo) * Warnings: * * History: +* 11-Feb-1993 Petrus Wong Minimize device access +* 14-Dec-1992 -by- Petrus Wong Enable shadow bitmap * 14-Jun-1992 -by- Petrus Wong Modified to use the pen array and LineTo * 20-Nov-1991 -by- Petrus Wong * Wrote it. @@ -2660,21 +3917,79 @@ BOOL StartMandelbrot(PINFO pInfo) int xCurr, yCurr; int iPen; +#ifndef THRDONE + INT iNumClr; + char text[256]; +#endif + double c1, c2; double x1, y1, x, y, r; - iPen = giPen + 1; + HDC hDCMem; + HBITMAP hBitmap, hOldBitmap; + + int iBand=1; + int iScan=0; + int iDiff=0; + + iPen = pInfo->iPen + 1; pInfo->bMandel = TRUE; pInfo->bDrawing = TRUE; hDC = GetDC(pInfo->hwnd); +#ifndef THRDONE + if ((iNumClr = iCreatePenFrPal(hDC, NULL, 0, &(pInfo->hPal))) != 0) { + sprintf( gtext,"iNumClr = %d\n", iNumClr); + OutputDebugString( gtext); + + if ((pInfo->prghPen = (PVOID*) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(HPEN)*iNumClr)) == NULL) { + MessageBox(ghwndMain, "Failed in Memory Allocation for pInfo->prghPen!", "Error", MB_OK); + } else { + if ((pInfo->iPen = iCreatePenFrPal(hDC, pInfo->prghPen, 1, &(pInfo->hPal))) == 0) + MessageBox(ghwndMain, "Failed in creating pen!", "Error", MB_OK); + } + } + + hDCMem = CreateCompatibleDC(hDC); + + SelectPalette(hDCMem, pInfo->hPal, FALSE); + SelectPalette(hDC, pInfo->hPal, FALSE); + RealizePalette(hDC); + iPen = pInfo->iPen + 1; + wsprintf(text, "iPen = %d\n", iPen); + //MessageBox(ghwndMain, text, "Error", MB_OK); +#endif + GetClientRect(pInfo->hwnd, &rc); + hBitmap = CreateCompatibleBitmap(hDC, (int)rc.right, (int)rc.bottom); + hOldBitmap = SelectObject(hDCMem, hBitmap); + +#if 0 + { + int iWidth, i, j; + + iWidth = rc.right/iNumClr; + + for (i = 0; i < iNumClr; i++) { + SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[i % iNumClr]); + for (j = 0; j < iWidth; j++) { + MoveToEx(hDCMem, i*iWidth+j, 0, NULL); + LineTo(hDCMem, i*iWidth+j, rc.bottom); + } + + } + } +#endif + dwTick1 = GetTickCount(); + + iScan = (((iScan = BATCH / rc.right) == 0) ? 1 : iScan); + yCurr = rc.top; for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) { xCurr = rc.left; // since LineTo excludes last point - MoveToEx(hDC, 0, yCurr, NULL); + MoveToEx(hDCMem, 0, yCurr, NULL); c2 = Xform((double) n, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo); for (m=rc.left; m<=rc.right; m++, xCurr++) { @@ -2696,38 +4011,56 @@ BOOL StartMandelbrot(PINFO pInfo) if (i != iPrev) { if (iPrev != FIRST_PIXEL) { switch(iPrev) { - case 1: SelectObject(hDC, hpnRed); break; + case 1: + SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]); + break; default: if (iPrev >= pInfo->iIteration) { - SelectObject(hDC, hpnBlack); + SelectObject(hDCMem, hpnBlack); break; } - SelectObject(hDC, (HPEN)gprghPen[iPrev % iPen]); + SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[iPrev % iPen]); break; } iPrev = i; - LineTo(hDC, xCurr, yCurr); + LineTo(hDCMem, xCurr, yCurr); } else iPrev = i; // remember the color for the first pixel } } - switch(i) - { - case 1: SelectObject(hDC, hpnRed); break; - default: - if (i >= pInfo->iIteration) { - SelectObject(hDC, hpnBlack); - break; - } - SelectObject(hDC, (HPEN)gprghPen[i % iPen]); + switch(i) { + case 1: + SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]); + break; + default: + if (i >= pInfo->iIteration) { + SelectObject(hDCMem, hpnBlack); break; - } + } + SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[i % iPen]); + break; + } - LineTo(hDC,xCurr,yCurr); + LineTo(hDCMem,xCurr,yCurr); + sprintf(gtext, "Drawing: %3.2f %%", ((FLOAT)n/(FLOAT)rc.bottom)*100); + SetWindowText(pInfo->hTextWnd, gtext); + + if (n >= iScan * iBand) { + BitBlt(hDC, 0, iScan * (iBand-1), rc.right, iScan, hDCMem, 0, iScan * (iBand-1), SRCCOPY); + iBand++; + } + } + + if ((iDiff = iScan * iBand - rc.bottom) != 0) { + BitBlt(hDC, 0, iScan * (iBand-1), rc.right, iScan-iDiff, hDCMem, 0, iScan * (iBand-1), SRCCOPY); } + + sprintf(gtext, "Drawing: DONE"); + SetWindowText(pInfo->hTextWnd, gtext); + ReleaseDC(pInfo->hwnd, hDC); pInfo->dwElapsed = GetTickCount() - dwTick1; @@ -2735,13 +4068,20 @@ BOOL StartMandelbrot(PINFO pInfo) if (pInfo->hBmpSaved) DeleteObject(pInfo->hBmpSaved); - pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd); + pInfo->hBmpSaved = SelectObject(hDCMem, hOldBitmap); pInfo->bDrawing = FALSE; +#ifndef THRDONE + if (pInfo->prghPen != NULL) { + for (i = 0; i <= pInfo->iPen; i++) { + DeleteObject((HPEN) (pInfo->prghPen)[i]); + } + GlobalFree(pInfo->prghPen); + } +#endif - ExitThread(0); - if (!CloseHandle(pInfo->hThrd)) - MessageBox(ghwndMain, "Failed in CloseHandle!", "Error", MB_OK); + DeleteDC(hDCMem); + ExitThread(0); return TRUE; } @@ -2822,25 +4162,47 @@ int Xform2( * using utilizing BitBlt. * * Warnings: +* // should we set the dirty flag here? +* * * History: * 03-Dec-1991 -by- Petrus Wong * Wrote it. \**************************************************************************/ -HBITMAP SaveBitmap(HWND hWnd) { +HBITMAP SaveBitmap(HWND hWnd, HPALETTE hPal) { HDC hdcMem, hDC; HBITMAP hBitmap, hOldBitmap; RECT rc; + HPALETTE hPalOld, hPalMemOld; + int ii; hDC = GetDC(hWnd); GetClientRect(hWnd, &rc); + if (hPal) { + + hPalOld = SelectPalette(hDC, hPal, FALSE); + ii=RealizePalette(hDC); + if (ii){ + UpdateColors (hDC); + } + + } + hdcMem = CreateCompatibleDC(hDC); + if (hPal) { + + hPalMemOld = SelectPalette(hdcMem, hPal, FALSE); + RealizePalette(hdcMem); + } + hBitmap = CreateCompatibleBitmap(hDC, (int)rc.right-rc.left, (int)rc.bottom-rc.top); hOldBitmap = SelectObject(hdcMem, hBitmap); + + BitBlt(hdcMem, 0, 0, (int)rc.right-rc.left, (int)rc.bottom-rc.top, hDC, 0, 0, SRCCOPY); hBitmap = SelectObject(hdcMem, hOldBitmap); @@ -2868,8 +4230,39 @@ void DrawBitmap(HDC hdc, PINFO pInfo, in BITMAP bm; HDC hdcMem; POINT ptSize, ptOrg; + HPALETTE hPalOld, hPalMemOld; + char text[128]; + + if ((pInfo->hPal) && !(pInfo->bUseMono)) { + + hPalOld = SelectPalette(hdc, + ((pInfo->iStretchMode == HALFTONE) ? pInfo->hHTPal : pInfo->hPal), + FALSE); + //RealizePalette(hdc); + wsprintf(text, "Realized Palette = %d", RealizePalette(hdc)); + MessageBox(ghwndMain, text, "", MB_OK); + + UpdateColors (hdc); + } hdcMem = CreateCompatibleDC(hdc); + + if ((pInfo->hPal) && !(pInfo->bUseMono)) { + + hPalMemOld = SelectPalette(hdcMem, + ((pInfo->iStretchMode == HALFTONE) ? pInfo->hHTPal : pInfo->hPal), + FALSE); + //RealizePalette(hdcMem); + wsprintf(text, "Realized Palette = %d", RealizePalette(hdcMem)); + MessageBox(ghwndMain, text, "", MB_OK); + + + UpdateColors (hdcMem); + + + + } + SelectObject(hdcMem, (pInfo->bUseMono ? pInfo->hBmpMono : pInfo->hBmpSaved)); SetMapMode(hdcMem, GetMapMode(hdc)); @@ -2902,6 +4295,135 @@ void DrawBitmap(HDC hdc, PINFO pInfo, in /******************************Public*Routine******************************\ * +* bDrawDIB +* +* Effects: +* +* Warnings: +* +* History: +* 17-Jun-1993 Petrus Wong updated for latest HT changes +* 06-Feb-1993 Petrus Wong rewritten for HT support +* 14-Dec-1992 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +BOOL bDrawDIB(HDC hDC, PINFO pInfo, int xStart, int yStart, int cx, int cy) +{ + HBITMAP hBmpOld, hBmp; + BOOL bSuccess; + PBITMAPINFO pbmi; + HDC hdcMem; + BITMAP bm; + + bSuccess = TRUE; + if (pInfo->bUseMono) { + DrawBitmap(hDC, pInfo, xStart, yStart, cx, cy); + return bSuccess; + } + + if ((hBmp = pInfo->hBmpSaved) == NULL) { + MessageBox(ghwndMain, "There's no Bitmap to draw!", "Error", MB_OK); + return FALSE; + } + + if (pInfo->bStretch) { + SetStretchBltMode(hDC, pInfo->iStretchMode); + + if (pInfo->bUseDIB) { // this'll give a src for halftone... + pbmi = (PBITMAPINFO) (pInfo->RleData.rgpbmi[0]); + + // Select and realize the appropriate palette to destination DC + if ((pInfo->iStretchMode == HALFTONE) && (pInfo->hHTPal)) { + SelectPalette(hDC, pInfo->hHTPal, FALSE); + RealizePalette(hDC); + } else { + if ((pInfo->iStretchMode != HALFTONE) && (pInfo->hPal)) { + SelectPalette(hDC, pInfo->hPal, FALSE); + RealizePalette(hDC); + } + } + if (pInfo->bCoreHdr) { + StretchDIBits(hDC, xStart, yStart, cx, cy, + 0, 0, ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcWidth, + ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcHeight, + (LPSTR)pInfo->RleData.rgpjFrame[0], pbmi, DIB_RGB_COLORS, SRCCOPY); + } else { + StretchDIBits(hDC, xStart, yStart, cx, cy, + 0, 0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight, + (LPSTR)pInfo->RleData.rgpjFrame[0], pbmi, DIB_RGB_COLORS, SRCCOPY); + } + } else { // image is dirty or created on this device + + HBITMAP hDIB; + + // + // Get the source DIB info from the DDB for halftoning + // + hDIB = DIBfromDDB(hDC, hBmp, pInfo); + + hdcMem = CreateCompatibleDC(hDC); + hBmpOld = SelectObject(hdcMem, hDIB); + + if ((pInfo->iStretchMode == HALFTONE) && (pInfo->hHTPal)) { + SelectPalette(hDC, pInfo->hHTPal, FALSE); + RealizePalette(hDC); + } else { + if ((pInfo->iStretchMode != HALFTONE) && (pInfo->hPal)) { + SelectPalette(hDC, pInfo->hPal, FALSE); + RealizePalette(hDC); + } + } + + // + // Use StretchBlt here instead of StretchDIBits just for + // demonstrating using the API with halftone + // + GetObject(hDIB, sizeof(BITMAP), (LPSTR)&bm); + StretchBlt(hDC, xStart, yStart, cx, cy, hdcMem, + 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); + + DeleteDC(hdcMem); + + } + return bSuccess; + } + + // + // Not stretching...No halftone + // + + GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bm); + + // Select and realize the appropriate palette to destination DC + if (pInfo->hPal) { + SelectPalette(hDC, pInfo->hPal, FALSE); + RealizePalette(hDC); + } + + if (pInfo->bUseDIB) { // this'll give a src + pbmi = (PBITMAPINFO) (pInfo->RleData.rgpbmi[0]); + + // default to use SetDIBitsToDevice + SetDIBitsToDevice(hDC, xStart, yStart, bm.bmWidth, bm.bmHeight, + 0, 0, 0, bm.bmHeight, pInfo->RleData.rgpjFrame[0], + pbmi, DIB_RGB_COLORS); + } else { // image is dirty or created on this device + + hdcMem = CreateCompatibleDC(hDC); + hBmpOld = SelectObject(hdcMem, hBmp); + + BitBlt(hDC, xStart, yStart, bm.bmWidth, bm.bmHeight, + hdcMem, 0, 0, SRCCOPY); + + DeleteDC(hdcMem); + } + + return bSuccess; +} + +/******************************Public*Routine******************************\ +* * pGetInfoData(HWND hwnd) * * Effects: calls LocalLock, returning pointer to Info structure. @@ -2974,35 +4496,90 @@ BOOL bReleaseInfoData(HWND hwnd) * Warnings: * * History: +* 12-Jan-1993 Petrus Wong rewritten * 28-Jan-1992 -by- Petrus Wong * Wrote it. \**************************************************************************/ -BOOL bCheckMutexMenuItem(HMENU hMenu, UINT uiCheckItem) +BOOL bCheckMutexMenuItem(PINFO pInfo, HMENU hMenu, UINT uiCheckItem) { + switch(uiCheckItem) { + case MM_TP_IDLE: + case MM_TP_LOW: + case MM_TP_BELOW_NORMAL: + case MM_TP_NORMAL: + case MM_TP_ABOVE_NORMAL: + case MM_TP_HIGH: + case MM_TP_TIME_CRITICAL: + switch (pInfo->iPriority) { + case THREAD_PRIORITY_IDLE: + CheckMenuItem(hMenu, MM_TP_IDLE, MF_UNCHECKED); + break; + case THREAD_PRIORITY_LOWEST: + CheckMenuItem(hMenu, MM_TP_LOW, MF_UNCHECKED); + break; + case THREAD_PRIORITY_BELOW_NORMAL: + CheckMenuItem(hMenu, MM_TP_BELOW_NORMAL, MF_UNCHECKED); + break; + case THREAD_PRIORITY_NORMAL: + CheckMenuItem(hMenu, MM_TP_NORMAL, MF_UNCHECKED); + break; + case THREAD_PRIORITY_ABOVE_NORMAL: + CheckMenuItem(hMenu, MM_TP_ABOVE_NORMAL, MF_UNCHECKED); + break; + case THREAD_PRIORITY_HIGHEST: + CheckMenuItem(hMenu, MM_TP_HIGH, MF_UNCHECKED); + break; + case THREAD_PRIORITY_TIME_CRITICAL: + CheckMenuItem(hMenu, MM_TP_TIME_CRITICAL, MF_UNCHECKED); + break; + default: + break; + } + break; case MM_FLOAT: case MM_FIX: CheckMenuItem(hMenu, MM_FLOAT, MF_UNCHECKED); CheckMenuItem(hMenu, MM_FIX, MF_UNCHECKED); break; - case MM_ITERATION_TEN: - case MM_ITERATION_TWENTY: - case MM_ITERATION_THIRTY: - case MM_ITERATION_FIFTY: + case MM_ITERATION_100: + case MM_ITERATION_500: + case MM_ITERATION_1000: + case MM_ITERATION_5000: case MM_ITERATION_DOUBLE: - CheckMenuItem(hMenu, MM_ITERATION_TEN, MF_UNCHECKED); - CheckMenuItem(hMenu, MM_ITERATION_TWENTY, MF_UNCHECKED); - CheckMenuItem(hMenu, MM_ITERATION_THIRTY, MF_UNCHECKED); - CheckMenuItem(hMenu, MM_ITERATION_FIFTY, MF_UNCHECKED); - CheckMenuItem(hMenu, MM_ITERATION_DOUBLE, MF_UNCHECKED); + switch (pInfo->iIteration) { + case 100: + CheckMenuItem(hMenu, MM_ITERATION_100, MF_UNCHECKED); + break; + case 500: + CheckMenuItem(hMenu, MM_ITERATION_500, MF_UNCHECKED); + break; + case 1000: + CheckMenuItem(hMenu, MM_ITERATION_1000, MF_UNCHECKED); + break; + case 5000: + CheckMenuItem(hMenu, MM_ITERATION_5000, MF_UNCHECKED); + break; + default: + CheckMenuItem(hMenu, MM_ITERATION_DOUBLE, MF_UNCHECKED); + break; + } break; case MM_STEP_ONE: case MM_STEP_TWO: case MM_STEP_THREE: - CheckMenuItem(hMenu, MM_STEP_ONE, MF_UNCHECKED); - CheckMenuItem(hMenu, MM_STEP_TWO, MF_UNCHECKED); - CheckMenuItem(hMenu, MM_STEP_THREE, MF_UNCHECKED); + switch (pInfo->iStep) { + case 1: + CheckMenuItem(hMenu, MM_STEP_ONE, MF_UNCHECKED); + break; + case 2: + CheckMenuItem(hMenu, MM_STEP_TWO, MF_UNCHECKED); + break; + default: + CheckMenuItem(hMenu, MM_STEP_THREE, MF_UNCHECKED); + break; + } break; case MM_STRETCHBLT: case MM_BITBLT: @@ -3013,10 +4590,22 @@ BOOL bCheckMutexMenuItem(HMENU hMenu, UI case MM_COLORONCOLOR: case MM_WHITEONBLACK: case MM_HALFTONE: - CheckMenuItem(hMenu, MM_BLACKONWHITE, MF_UNCHECKED); - CheckMenuItem(hMenu, MM_COLORONCOLOR, MF_UNCHECKED); - CheckMenuItem(hMenu, MM_WHITEONBLACK, MF_UNCHECKED); - CheckMenuItem(hMenu, MM_HALFTONE, MF_UNCHECKED); + switch (pInfo->iStretchMode) { + case BLACKONWHITE: + CheckMenuItem(hMenu, MM_BLACKONWHITE, MF_UNCHECKED); + break; + case COLORONCOLOR: + CheckMenuItem(hMenu, MM_COLORONCOLOR, MF_UNCHECKED); + break; + case WHITEONBLACK: + CheckMenuItem(hMenu, MM_WHITEONBLACK, MF_UNCHECKED); + break; + case HALFTONE: + CheckMenuItem(hMenu, MM_HALFTONE, MF_UNCHECKED); + break; + default: + break; + } break; case MM_PORTRAIT: case MM_LANDSCAPE: @@ -3030,6 +4619,103 @@ BOOL bCheckMutexMenuItem(HMENU hMenu, UI return TRUE; } + +/******************************Public*Routine******************************\ +* +* vChkMenuItem +* +* Effects: Helper function for checking or unchecking menu items based on +* values set in the pInfo. Gets called when processing +* WM_MDIACTIVATE +* +* Warnings: +* +* History: +* 12-Jan-1993 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +VOID vChkMenuItem(PINFO pInfo, HMENU hMenu, UINT uiFlag) +{ + (pInfo->bStretch ? + CheckMenuItem(hMenu, MM_STRETCHBLT, uiFlag) : + CheckMenuItem(hMenu, MM_BITBLT, uiFlag) ); + + switch (pInfo->iPriority) { + case THREAD_PRIORITY_IDLE: + CheckMenuItem(hMenu, MM_TP_IDLE, uiFlag); + break; + case THREAD_PRIORITY_LOWEST: + CheckMenuItem(hMenu, MM_TP_LOW, uiFlag); + break; + case THREAD_PRIORITY_BELOW_NORMAL: + CheckMenuItem(hMenu, MM_TP_BELOW_NORMAL, uiFlag); + break; + case THREAD_PRIORITY_NORMAL: + CheckMenuItem(hMenu, MM_TP_NORMAL, uiFlag); + break; + case THREAD_PRIORITY_ABOVE_NORMAL: + CheckMenuItem(hMenu, MM_TP_ABOVE_NORMAL, uiFlag); + break; + case THREAD_PRIORITY_HIGHEST: + CheckMenuItem(hMenu, MM_TP_HIGH, uiFlag); + break; + case THREAD_PRIORITY_TIME_CRITICAL: + CheckMenuItem(hMenu, MM_TP_TIME_CRITICAL, uiFlag); + break; + default: + break; + } + + switch (pInfo->iStretchMode) { + case BLACKONWHITE: + CheckMenuItem(hMenu, MM_BLACKONWHITE, uiFlag); + break; + case COLORONCOLOR: + CheckMenuItem(hMenu, MM_COLORONCOLOR, uiFlag); + break; + case WHITEONBLACK: + CheckMenuItem(hMenu, MM_WHITEONBLACK, uiFlag); + break; + case HALFTONE: + CheckMenuItem(hMenu, MM_HALFTONE, uiFlag); + break; + default: + break; + } + + switch (pInfo->iStep) { + case 1: + CheckMenuItem(hMenu, MM_STEP_ONE, uiFlag); + break; + case 2: + CheckMenuItem(hMenu, MM_STEP_TWO, uiFlag); + break; + default: + CheckMenuItem(hMenu, MM_STEP_THREE, uiFlag); + break; + } + + switch (pInfo->iIteration) { + case 100: + CheckMenuItem(hMenu, MM_ITERATION_100, uiFlag); + break; + case 500: + CheckMenuItem(hMenu, MM_ITERATION_500, uiFlag); + break; + case 1000: + CheckMenuItem(hMenu, MM_ITERATION_1000, uiFlag); + break; + case 5000: + CheckMenuItem(hMenu, MM_ITERATION_5000, uiFlag); + break; + default: + CheckMenuItem(hMenu, MM_ITERATION_DOUBLE, uiFlag); + break; + } + return; +} + /******************************Public*Routine******************************\ * * bInitInfo @@ -3039,6 +4725,9 @@ BOOL bCheckMutexMenuItem(HMENU hMenu, UI * Warnings: * * History: +* 16-Feb-1993 Petrus Wong changed to 9.23 fix value +* 08-Feb-1993 Petrus Wong Added bUseDIB flag +* 14-Dec-1992 -by- Petrus Wong Added Rle and pens stuff * 28-Jan-1992 -by- Petrus Wong * Wrote it. \**************************************************************************/ @@ -3047,13 +4736,13 @@ BOOL bInitInfo(PINFO pInfo) { pInfo->hParent = ghwndClient; pInfo->xFrom = -2.0; - pInfo->xTo = 2.0; - pInfo->yFrom = 2.0; - pInfo->yTo = -2.0; - pInfo->lxFrom = -4096; // 20.11 fix point - pInfo->lxTo = 4096; // representation of - pInfo->lyFrom = 4096; // -2, 2, 2, and -2 - pInfo->lyTo = -4096; // + pInfo->xTo = 1.0; + pInfo->yFrom = 1.5; + pInfo->yTo = -1.5; + pInfo->lxFrom = -16777216; // 9.23 fix point + pInfo->lxTo = 8388608; // representation of + pInfo->lyFrom = 12582912; // -2, 1.0, 1.5, and -1.5 + pInfo->lyTo = -12582912; // pInfo->iIteration = gIteration; pInfo->iStep = gStep; pInfo->bStretch = gbStretch; @@ -3067,6 +4756,7 @@ BOOL bInitInfo(PINFO pInfo) pInfo->rcClient.right = 0; pInfo->hdcClient = NULL; pInfo->hRgnPath = NULL; + pInfo->hThrd0 = NULL; pInfo->hThrd = NULL; pInfo->bDrawing = FALSE; pInfo->dwThreadId = 0; @@ -3091,6 +4781,17 @@ BOOL bInitInfo(PINFO pInfo) pInfo->bUseMono = FALSE; pInfo->hPrtThrd = NULL; pInfo->dwPrtThrdID = 0; + pInfo->hPal = NULL; + pInfo->hCyclePal = NULL; + pInfo->RleData.ulFiles = 0; + pInfo->RleData.ulFrames = 0; + pInfo->bPlayRleCont = FALSE; + pInfo->prghPen = NULL; + pInfo->iPen = 0; + pInfo->iPriority = THREAD_PRIORITY_NORMAL; + pInfo->bUseDIB = FALSE; + pInfo->bCoreHdr = FALSE; + return TRUE; } @@ -3099,24 +4800,26 @@ BOOL bInitInfo(PINFO pInfo) * bResetGlobal * * Effects: Set (l) x/y From/To to their default values +* Used for Julia set * * Warnings: * * History: +* 16-Feb-1993 Petrus Wong changed to 9.23 fix value * 28-Jan-1992 -by- Petrus Wong * Wrote it. \**************************************************************************/ BOOL bResetGlobal(VOID) { - xFrom = -2.0; - xTo = 2.0; - yFrom = 2.0; - yTo = -2.0; - lxFrom = -4096; - lxTo = 4096; - lyFrom = 4096; - lyTo = -4096; + xFrom = -2.0; + xTo = 2.0; + yFrom = 2.0; + yTo = -2.0; + lxFrom = -16777216; + lxTo = 16777216; + lyFrom = 16777216; + lyTo = -16777216; return TRUE; } @@ -3215,16 +4918,16 @@ BOOL bPrintBmp(PPRTDATA pPrtData) { DocInfo.lpszOutput = NULL; StartDoc(hdcPrinter, &DocInfo); StartPage(hdcPrinter); - DrawBitmap(hdcPrinter, &(pPrtData->info), 0, 0, iWidth, iHeight); + bDrawDIB(hdcPrinter, &(pPrtData->info), 0, 0, iWidth, iHeight); EndPage(hdcPrinter); EndDoc(hdcPrinter); #else Escape(hdcPrinter, STARTDOC, 20, "Mandelbrot", NULL); - DrawBitmap(hdcPrinter, &(pPrtData->info), 0, 0, iWidth, iHeight); - Escape(hdcPrinter, NEWFRAME, NULL, NULL, NULL); - Escape(hdcPrinter, ENDDOC, NULL, NULL, NULL); + bDrawDIB(hdcPrinter, &(pPrtData->info), 0, 0, iWidth, iHeight); + Escape(hdcPrinter, NEWFRAME, 0, NULL, NULL); + Escape(hdcPrinter, ENDDOC, 0, NULL, NULL); #endif @@ -3233,3 +4936,840 @@ BOOL bPrintBmp(PPRTDATA pPrtData) { return(TRUE); } + + + +/******************************Public*Routine******************************\ +* +* StoreRleFile +* +* Effects: +* +* Warnings: +* +* History: +* 05-Dec-1992 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +BOOL bStoreRleFile(HDC hDC, PINFO pInfo, PSTR pszFileName) +{ + BOOL bSuccess; + HANDLE hFile, hMapFile; + LPVOID pMapFile; + LPBITMAPINFOHEADER pbmh; + LPBITMAPINFO pbmi; + PBYTE pjTmp, pjDIBits, pjRleBits; + ULONG sizBMI, sizImage, ulfSize; + DWORD dwOffBits; + LONG lScan; + INT iNumClr; + ULONG ulFrames, ulFiles, ulOffset; + PFILEINFO pFileInfo; + DWORD dwFileSizeLow, dwFileSizeHigh; + WORD wBitCount; + BOOL bCoreHdr; + + bSuccess = TRUE; + + if ((hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL)) == (HANDLE)-1) { + ErrorOut("Fail in file open"); + bSuccess = FALSE; + goto ErrExit1; + } + + dwFileSizeLow = GetFileSize(hFile, &dwFileSizeHigh); + if ((dwFileSizeLow == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) { + ErrorOut("GetFileSize failed"); + bSuccess = FALSE; + goto ErrExit2; + } + + // + // Create a map file of the opened file + // + if ((hMapFile = CreateFileMapping(hFile, NULL, + PAGE_READONLY, 0, 0, NULL)) == (HANDLE)-1) { + ErrorOut("Fail in creating map file"); + bSuccess = FALSE; + goto ErrExit2; + } + + // + // Map a view of the whole file + // + if ((pMapFile = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0)) == NULL) { + ErrorOut("Fail in mapping view of the Map File object"); + bSuccess = FALSE; + goto ErrExit3; + } + + ulFiles = pInfo->RleData.ulFiles; + pFileInfo = &(pInfo->RleData.rgFileInfo[ulFiles]); + pFileInfo->hFile = hFile; + pFileInfo->hMapFile = hMapFile; + pFileInfo->lpvMapView = pMapFile; + + ulFrames = pInfo->RleData.ulFrames; + ulOffset = 0; + + while (TRUE) { + // + // First check that it is a bitmap file + // + if (*((PWORD)pMapFile) != 0x4d42) { // 'BM' + MessageBox(ghwndMain, "This is not a DIB bitmap file!", "Error", MB_OK); + bSuccess = FALSE; + goto ErrExit3; + } +#ifdef DEBUG + { + static ULONG ulCnt=0; + char buf[128]; + + ulCnt++; + wsprintf(buf, "ulCnt = %ld", ulCnt); + MessageBox(ghwndMain, buf, "debug", MB_OK); + } +#endif + // + // Saving the bfSize field in the BITMAPFILEHEADER for incrementing to the + // next frame. bfSize does not start at DWORD boundary... + // + { + PBYTE pjTmp; + FILEHDR fHdr, *pfHdr; + ULONG ulSiz; + + pjTmp = (PBYTE)pMapFile+2; + pfHdr = &fHdr; + + ulSiz = sizeof(FILEHDR); + while (ulSiz--) { + *(((PBYTE)pfHdr)++) = *(((PBYTE)pjTmp)++); + } + ulfSize = fHdr.bfSize; + dwOffBits = fHdr.bfOffbits; + } + + // + // advance pMapFile to point pass BITMAPFILEHEADER + // + //pMapFile = (PBYTE)pMapFile + sizeof(BITMAPFILEHEADER); + + // + // Since the file header doesn't end on DWORD boundary... + // + pbmh = (LPBITMAPINFOHEADER)((PBYTE)pMapFile + sizeof(BITMAPFILEHEADER)); + + { + BITMAPCOREHEADER bmch, *pbmch; + BITMAPINFOHEADER bmih, *pbmih; + PBYTE pjTmp; + ULONG ulSiz; + + pbmch = &bmch; + pbmih = &bmih; + + pjTmp = (PBYTE)pbmh; + ulSiz = sizeof(BITMAPCOREHEADER); + while (ulSiz--) { + *(((PBYTE)pbmch)++) = *(((PBYTE)pjTmp)++); + } + + pjTmp = (PBYTE)pbmh; + ulSiz = sizeof(BITMAPINFOHEADER); + while (ulSiz--) { + *(((PBYTE)pbmih)++) = *(((PBYTE)pjTmp)++); + } + + // + // Use the size to determine if it is a BitmapCoreHeader or + // BitmapInfoHeader + // + if (bmch.bcSize == sizeof(BITMAPCOREHEADER)) + { + wBitCount = bmch.bcBitCount; + iNumClr = ((wBitCount == 24) ? 0 : (1 << wBitCount)); + sizBMI = sizeof(BITMAPCOREHEADER)+sizeof(RGBTRIPLE)*iNumClr; + bCoreHdr = TRUE; + } + else // BITMAPINFOHEADER + { + wBitCount = bmih.biBitCount; + switch (wBitCount) { + case 16: + case 32: + sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3; + break; + case 24: + sizBMI = sizeof(BITMAPINFOHEADER); + break; + default: + iNumClr = (1 << wBitCount); + sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*iNumClr; + break; + } + bCoreHdr = FALSE; + } + } + + if ((pbmi = (LPBITMAPINFO) LocalAlloc(LMEM_FIXED,sizBMI)) == NULL) { + MessageBox(ghwndMain, "Fail in Memory Allocation!", "Error", MB_OK); + bSuccess = FALSE; + goto ErrExit3; + } + + // + // Make sure we pass in a DWORD aligned BitmapInfo to CreateDIBitmap + // Otherwise, exception on the MIPS platform + // CR!!! Equivalent to memcpy + // + pjTmp = (PBYTE)pbmi; + + while(sizBMI--) + { + *(((PBYTE)pjTmp)++) = *(((PBYTE)pbmh)++); + } + + // + // assuming CreateDIBitmap() is doing a byte fetch... + // + pjDIBits = (PBYTE)pMapFile + dwOffBits; + + if (pbmi->bmiHeader.biCompression == BI_RGB) + { + // + // Converting to RLE bits... + // + + MessageBox(ghwndMain, "Converting to RLE format!", "Store", MB_OK); + lScan = pbmi->bmiHeader.biHeight; + sizImage = pbmi->bmiHeader.biSizeImage; + + // + // select the palette into the DC first... + // + bSelectDIBPal(hDC, pInfo, pbmi, bCoreHdr); + if ((pInfo->hBmpSaved = CreateDIBitmap(hDC, (LPBITMAPINFOHEADER)pbmi, + CBM_INIT, pjDIBits, pbmi, DIB_RGB_COLORS)) == NULL) { + ErrorOut("Fail in creating DIB bitmap from file!"); + bSuccess = FALSE; + goto ErrExit4; + } + + // We want to retrieve the RLE format... + pbmi->bmiHeader.biCompression = ((wBitCount==4) ? BI_RLE4 : BI_RLE8); + + pbmi->bmiHeader.biSizeImage = 0; + pbmi->bmiHeader.biXPelsPerMeter = 0; + pbmi->bmiHeader.biYPelsPerMeter = 0; + pbmi->bmiHeader.biClrUsed = 0; + pbmi->bmiHeader.biClrImportant = 0; + + if (GetDIBits(hDC, pInfo->hBmpSaved, 0, lScan, NULL, pbmi, + DIB_RGB_COLORS) == 0) { + MessageBox(ghwndMain, "Not all scans are converted!", "Error", MB_OK); + bSuccess = FALSE; + goto ErrExit4; + } + + if (pbmi->bmiHeader.biSizeImage == 0) { + if (sizImage == 0) { + MessageBox(ghwndMain, "biSizeImage == 0!", "Error", MB_OK); + bSuccess = FALSE; + goto ErrExit4; + } + MessageBox(ghwndMain, + "Engine returns zero image size, making one up!", + "Error", MB_OK); + sizImage = (sizImage *3)/2; + } else { + sizImage = pbmi->bmiHeader.biSizeImage; + } + + if ((pjRleBits = (PBYTE) LocalAlloc(LMEM_FIXED, sizImage)) == NULL) { + MessageBox(ghwndMain, "Fail in Memory Allocation!", "Error", MB_OK); + bSuccess = FALSE; + goto ErrExit4; + } + + pbmi->bmiHeader.biSizeImage = sizImage; + if (GetDIBits(hDC, pInfo->hBmpSaved, 0, lScan, pjRleBits, pbmi, + DIB_RGB_COLORS) < lScan) { + MessageBox(ghwndMain, "Not all scans are converted!", "Error", MB_OK); + bSuccess = FALSE; + goto ErrExit5; + } + + SetDIBitsToDevice(hDC, 0, 0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight, + 0, 0, 0, lScan, pjRleBits, pbmi, DIB_RGB_COLORS); + + pInfo->RleData.rgpjFrame[ulFrames] = pjRleBits; + } else { + bSelectDIBPal(hDC, pInfo, pbmi, bCoreHdr); + lScan = pbmi->bmiHeader.biHeight; + if (bCoreHdr) { + lScan = ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcHeight; + SetDIBitsToDevice(hDC, 0, 0, ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcWidth, ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcHeight, + 0, 0, 0, lScan, pjDIBits, pbmi, DIB_RGB_COLORS); + } else { + lScan = pbmi->bmiHeader.biHeight; + SetDIBitsToDevice(hDC, 0, 0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight, + 0, 0, 0, lScan, pjDIBits, pbmi, DIB_RGB_COLORS); + } + pInfo->RleData.rgpjFrame[ulFrames] = pjDIBits; + } + + pInfo->RleData.ulSize[ulFrames] = sizImage; + pInfo->RleData.rgpbmi[ulFrames] = pbmi; + + // + // Go to next frame + // + pMapFile = (PBYTE)pMapFile + ulfSize; + ulOffset += ulfSize; + ulFrames++; + + // + // end condition + // + if (ulOffset >= dwFileSizeLow) { + break; + } + + } + + // + // set pbmi to the very first bmi + // + pInfo->RleData.pbmi = pInfo->RleData.rgpbmi[0]; + + pInfo->RleData.hPal = pInfo->hPal; + pInfo->RleData.ulFrames = ulFrames; + return (bSuccess); + +ErrExit5: + LocalFree(pjRleBits); +ErrExit4: + LocalFree(pbmi); +ErrExit3: + CloseHandle(pFileInfo->hMapFile); +ErrExit2: + CloseHandle(pFileInfo->hFile); +ErrExit1: + return (bSuccess); + +} + +/******************************Public*Routine******************************\ +* +* bSelectDIBPal +* +* Effects: Creates a logical palette from the DIB and select it into the DC +* and realize the palette. Saving the hPal in the pInfo->hPal +* +* Warnings: Based on Windows NT DIB support. If PM support 16,24,32 bpp +* we need to modify this routine. +* +* History: +* 22-Jan-1993 Petrus Wong PM support +* 31-Dec-1992 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +BOOL bSelectDIBPal(HDC hDC, PINFO pInfo, LPBITMAPINFO pbmi, BOOL bCoreHdr) +{ + LOGPALETTE *plogPal; + UINT uiSizPal; + INT i, iNumClr; + WORD wBitCount; + + if (bCoreHdr) { + wBitCount = ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcBitCount; + } else { + wBitCount = pbmi->bmiHeader.biBitCount; + } + + switch (wBitCount) { + case 16: + case 24: + case 32: // Does PM supports these? + return FALSE; + default: + iNumClr = (1 << wBitCount); + break; + } + + uiSizPal = sizeof(WORD)*2 + sizeof(PALETTEENTRY)*iNumClr; + if ((plogPal = (LOGPALETTE *) LocalAlloc(LMEM_FIXED,uiSizPal)) == NULL) { + ErrorOut("Fail in Allocating palette!"); + pInfo->hPal = NULL; + return FALSE; + } + + plogPal->palVersion = 0x300; + plogPal->palNumEntries = (WORD) iNumClr; + + if (bCoreHdr) { + for (i=0; ipalPalEntry[i].peRed = ((LPBITMAPCOREINFO)pbmi)->bmciColors[i].rgbtRed; + plogPal->palPalEntry[i].peGreen = ((LPBITMAPCOREINFO)pbmi)->bmciColors[i].rgbtGreen; + plogPal->palPalEntry[i].peBlue = ((LPBITMAPCOREINFO)pbmi)->bmciColors[i].rgbtBlue; + plogPal->palPalEntry[i].peFlags = PC_RESERVED; + } + } else { + for (i=0; ipalPalEntry[i].peRed = pbmi->bmiColors[i].rgbRed; + plogPal->palPalEntry[i].peGreen = pbmi->bmiColors[i].rgbGreen; + plogPal->palPalEntry[i].peBlue = pbmi->bmiColors[i].rgbBlue; + plogPal->palPalEntry[i].peFlags = PC_RESERVED; + } + } + + DeleteObject(pInfo->hPal); + pInfo->hPal = CreatePalette((LPLOGPALETTE)plogPal); + if ((pInfo->hPal) == NULL) { + ErrorOut("Fail in creating palette!"); + return FALSE; + } + + if ((GetDeviceCaps(hDC, RASTERCAPS)) & RC_PALETTE) { + SelectPalette(hDC, pInfo->hPal, FALSE); + RealizePalette(hDC); + } + + GlobalFree(plogPal); + + return TRUE; +} + +/******************************Public*Routine******************************\ +* +* bFreeRleFile +* +* Effects: +* +* Warnings: +* +* History: +* 05-Dec-1992 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +BOOL bFreeRleFile(PINFO pInfo) +{ + ULONG ulFiles; + ULONG ulFrames; + ULONG i; + PFILEINFO pFileInfo; + + ulFiles = pInfo->RleData.ulFiles; + ulFrames = pInfo->RleData.ulFrames; + + for (i = 0; i < ulFrames; i++) { + LocalFree(pInfo->RleData.rgpjFrame[i]); + LocalFree(pInfo->RleData.rgpbmi[i]); + } + + for (i = 0; i < ulFiles; i++) { + pFileInfo = &(pInfo->RleData.rgFileInfo[i]); + CloseHandle(pFileInfo->hFile); + CloseHandle(pFileInfo->hMapFile); + UnmapViewOfFile(pFileInfo->lpvMapView); + } + + pInfo->RleData.ulFiles = 0; + pInfo->RleData.ulFrames = 0; + return TRUE; +} + +/******************************Public*Routine******************************\ +* +* bPlayRle +* +* Effects: +* +* Warnings: +* +* History: +* 05-Dec-1992 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +BOOL bPlayRle(PINFO pInfo) +{ + ULONG ulFrames; + ULONG i; + LPBITMAPINFO pbmi; + HDC hDC; + HWND hViewSurf; + int ii; + +// RECT rc; + + hDC = GetDC(hViewSurf=pInfo->hwnd); + + SelectPalette(hDC, pInfo->RleData.hPal, FALSE); + ii=RealizePalette(hDC); + if (ii){ + UpdateColors (hDC); + } + + ulFrames = pInfo->RleData.ulFrames; + + for (i = 0; i < ulFrames; i++) { + pbmi = pInfo->RleData.rgpbmi[i]; + SetDIBitsToDevice(hDC, + 0, 0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight, + 0, 0, 0, pbmi->bmiHeader.biHeight, + pInfo->RleData.rgpjFrame[i], pbmi, DIB_RGB_COLORS); + +#if 0 + GetClientRect(pInfo->hwnd, &rc); + StretchDIBits(hDC, + 0, 0, rc.right, rc.bottom, + 0, 0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight, + (LPSTR)pInfo->RleData.rgpjFrame[i], pbmi, DIB_RGB_COLORS, + SRCCOPY); +#endif + } + + ReleaseDC(hViewSurf, hDC); + + return TRUE; +} + + +/******************************Public*Routine******************************\ +* +* bSaveRleFile +* +* Effects: +* +* Warnings: +* +* History: +* 14-Dec-1992 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +BOOL bSaveRleFile(HDC hDC, PINFO pInfo, PSTR pszFileName) +{ + int hFile; + OFSTRUCT ofReOpenBuff; + BOOL bSuccess; + BITMAPFILEHEADER bfh; + ULONG ulFrames; + ULONG i; + LPBITMAPINFO pbmi; + ULONG ulNumClr; + ULONG ulSize; + + bSuccess = TRUE; + ulFrames = pInfo->RleData.ulFrames; + + if (ulFrames == 0) { + MessageBox(GetFocus(), "There's no RLE to save!", "Error", MB_OK); + return FALSE; + } + + // Let's open the file and get ready for writing + if ((hFile = OpenFile(pszFileName, (LPOFSTRUCT)&ofReOpenBuff, + OF_CREATE | OF_WRITE)) == -1) { + MessageBox(GetFocus(), "Failed in OpenFile!", "Error", MB_OK); + ErrorOut("OpenFile"); + return FALSE; + } + + for (i = 0; i < ulFrames; i++) { + + pbmi = pInfo->RleData.rgpbmi[i]; + + switch(pbmi->bmiHeader.biBitCount) { + case 24: + ulSize = 0; + break; + case 16: + case 32: + ulSize = sizeof(DWORD)*3; + break; + default: + ulNumClr = 1<bmiHeader.biBitCount; + ulSize = sizeof(RGBQUAD)*ulNumClr; + break; + } +#if 0 + ulNumClr = ((pbmi->bmiHeader.biBitCount == 24) + ? 0 + : (1<bmiHeader.biBitCount)); +#endif + // fill in the info for the BitmapFileHeader + bfh.bfType = 0x4D42; // 'BM' + bfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+ + ulSize; + //sizeof(RGBQUAD)*ulNumClr; + bfh.bfSize = bfh.bfOffBits + pbmi->bmiHeader.biSizeImage; + bfh.bfReserved1 = + bfh.bfReserved2 = 0; + + // Write out the file header now + if (_lwrite(hFile, (LPSTR)&bfh, sizeof(BITMAPFILEHEADER)) == -1) { + MessageBox(GetFocus(), "Failed in Writing File Header!", + "Error", MB_OK); + bSuccess = FALSE; + goto ErrExit1; + } + + // Now write out the BitmapInfoHeader and color table, if any + if (_lwrite(hFile, (LPSTR)pbmi, sizeof(BITMAPINFOHEADER) + + ulSize) == -1) { + //sizeof(RGBQUAD)*ulNumClr) == -1) { + MessageBox(GetFocus(), "Failed in Writing Bitmap Info!", + "Error", MB_OK); + bSuccess = FALSE; + goto ErrExit1; + } + + // write the bits also + if (_lwrite(hFile, (LPSTR)pInfo->RleData.rgpjFrame[i], + pbmi->bmiHeader.biSizeImage) == -1) { + MessageBox(GetFocus(), "Failed in Writing RLE bits!", + "Error", MB_OK); + bSuccess = FALSE; + goto ErrExit1; + } + + } + +ErrExit1: + _lclose(hFile); + return bSuccess; +} + + +/******************************Public*Routine******************************\ +* +* bPlayRleCont +* +* Effects: +* +* Warnings: +* +* History: +* 14-Dec-1992 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +BOOL bPlayRleCont(HDC hDC, PINFO pInfo) +{ + BOOL bQuit; + MSG msg; + int ii; + + bQuit = FALSE; + + SelectPalette(hDC, pInfo->RleData.hPal, FALSE); + ii=RealizePalette(hDC); + if (ii){ + UpdateColors (hDC); + } + + while (TRUE && !bQuit) { + + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + + if ((msg.message == WM_QUIT) || (msg.message == WM_CLOSE) || + ((msg.message == WM_SYSCOMMAND) && (msg.wParam == SC_CLOSE))) { + bQuit = TRUE; + PostMessage(msg.hwnd, msg.message, msg.wParam, msg.lParam); + } else { + if (!TranslateAccelerator(msg.hwnd, ghAccel, &msg)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } + + if (!pInfo->bPlayRleCont) { + bQuit = TRUE; + } + + if (!bQuit) { + bPlayRle(pInfo); + } + + } + return TRUE; +} + + +/******************************Public*Routine******************************\ +* +* bPlayRleCont2 +* +* Effects: +* +* Warnings: +* +* History: +* 14-Dec-1992 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +BOOL bPlayRleCont2(PINFO pInfo) +{ + HDC hDC; + HWND hViewSurf; + DWORD dwWait; + BOOL bQuit; + int ii; + + hDC = GetDC(hViewSurf=pInfo->hwnd); + + SelectPalette(hDC, pInfo->RleData.hPal, FALSE); + ii=RealizePalette(hDC); + if (ii){ + UpdateColors (hDC); + } + + bQuit = FALSE; + while (TRUE) { + // + // If parent gets a WM_CLOSE, we will return + // + dwWait = WaitForSingleObject(pInfo->hQuitEvent, 0); + if (dwWait == WAIT_TIMEOUT) { + MessageBox(ghwndMain, + "Continuous Play Thread Quitting!", + "Continuous Play Thread", MB_OK); + break; + } + + if (!pInfo->bPlayRleCont) { + bQuit = TRUE; + } + + if (!bQuit) + bPlayRle(pInfo); + } + + ReleaseDC(hViewSurf, hDC); + + ExitThread(0); + return TRUE; + +} + + +/******************************Public*Routine******************************\ +* +* DIBfromDDB +* +* Effects: Call GetDIBits to retrieve the DIB info from DDB +* +* Warnings: +* +* History: +* 17-Jun-1993 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +HBITMAP DIBfromDDB(HDC hDC, HBITMAP hBmp, PINFO pInfo) +{ + LPBITMAPINFO pbmi; + HBITMAP hDIB; + INT iBitCount, iNumClr; + BITMAP bm; + DWORD sizImage; + PBYTE pjBits; + ULONG sizBMI; + LONG lScan; + + iBitCount = GetDeviceCaps(hDC, BITSPIXEL); + switch (iBitCount) { + case 16: + case 32: + sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3; + break; + case 24: + sizBMI = sizeof(BITMAPINFOHEADER); + break; + default: + iNumClr = (1 << iBitCount); + sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*iNumClr; + break; + } + + if ((pbmi = (LPBITMAPINFO) LocalAlloc(LMEM_FIXED,sizBMI)) == NULL) { + MessageBox(ghwndMain, "Fail in Memory Allocation!", "Error", MB_OK); + goto ErrExit1; + } + + pbmi->bmiHeader.biSize = 0x28; // GDI need this to work + pbmi->bmiHeader.biBitCount = 0; // don't get the color table + pbmi->bmiHeader.biCompression = BI_RGB; + pbmi->bmiHeader.biSizeImage = 0; + pbmi->bmiHeader.biXPelsPerMeter = 0; + pbmi->bmiHeader.biYPelsPerMeter = 0; + pbmi->bmiHeader.biClrUsed = 0; + pbmi->bmiHeader.biClrImportant = 0; + + GetObject(hBmp, sizeof(BITMAP), &bm); + + // + // Important! Select the correct palette corresponding to the DDB + // + SelectPalette(hDC, pInfo->hPal, FALSE); + if (GetDIBits(hDC, hBmp, 0, bm.bmHeight, NULL, pbmi, + DIB_RGB_COLORS) == 0) { + MessageBox(ghwndMain, "Not all scans are returned!", "Error", MB_OK); + goto ErrExit2; + } + + sizImage = pbmi->bmiHeader.biSizeImage; + if (sizImage == 0) { + MessageBox(ghwndMain, "biSizeImage == 0!", "Error", MB_OK); + goto ErrExit2; + } + + if ((pjBits = (PBYTE) LocalAlloc(LMEM_FIXED, sizImage)) == NULL) { + MessageBox(ghwndMain, "Fail in Memory Allocation!", "Error", MB_OK); + goto ErrExit2; + } + + lScan = pbmi->bmiHeader.biHeight; + + if (GetDIBits(hDC, pInfo->hBmpSaved, 0, lScan, pjBits, pbmi, + DIB_RGB_COLORS) < lScan) { + MessageBox(ghwndMain, "Not all scans are returned!", "Error", MB_OK); + goto ErrExit3; + } + + // + // Saving the DIB...free memory when the windows is closed. + // + pInfo->RleData.rgpjFrame[0] = pjBits; + pInfo->RleData.rgpbmi[0] = pbmi; + pInfo->RleData.pbmi = (PBITMAPINFO) &(pInfo->RleData.rgpbmi[0]); + pInfo->RleData.ulFrames = 1; + pInfo->RleData.ulFiles = 1; + + // set flag to use original DIB as source for blting so HT can be done + pInfo->bUseDIB = TRUE; + + pInfo->bCoreHdr = FALSE; + + hDIB = CreateDIBitmap(hDC, NULL, CBM_CREATEDIB | CBM_INIT, pjBits, pbmi, + DIB_RGB_COLORS); + + return hDIB; + +ErrExit3: + LocalFree(pjBits); +ErrExit2: + LocalFree(pbmi); +ErrExit1: + return ((HBITMAP)NULL); +}