/**************************************************************************** Copyright (c) 1994, 1995 by SimSoft PROGRAM: testapp.c PURPOSE: Test program to exercise the functionality of ImgLib Revision History: Nov 6, 94 Beta release Dec 18, 94 Release 1.0 Feb 19, 95 Release 1.1: Added support for file saving, scrolling, sizing printing Mar 25, 95 Release 1.2: Removed references to unsupported image types. Added clipdoard operations by utilizing ClipDIB Added the "Zoom x5" feature. Simplified palette handling. ****************************************************************************/ #include #include #ifndef WIN32 #include #endif #include #include #include #include "tstapp.h" #include "imglib.h" #ifdef USE_WING #include typedef HDC (WINGAPI *WINGCREATEDC) (void); typedef HBITMAP (WINGAPI *WINGCREATEBITMAP) (HDC, BITMAPINFO const FAR *, void FAR *FAR *); typedef BOOL (WINGAPI *WINGSTRETCHBLT) (HDC, int, int, int, int, HDC, int, int, int, int); WINGSTRETCHBLT fpWinGStretchBlt; WINGCREATEBITMAP fpWinGCreateBitmap; WINGCREATEDC fpWinGCreateDC; #endif #ifdef WIN32 #define huge #define CONTROL_ID(w) (LOWORD (w)) #define allocmem(s) (malloc (s)) #define freemem(p) (free (p)) #define copymem(d, s, c) (memcpy (d, s, c)) #else #define CONTROL_ID(w) (w) #define allocmem(s) (GlobalLock (GlobalAlloc (GHND, (DWORD)s))) #define freemem(p) (GlobalFree (LOWORD (GlobalHandle (HIWORD (p))))) #define copymem(d, s, c) (hmemcpy (d, s, c)) #endif typedef char huge * HPSTR; #define WINDOW_NAME "ImgLib Test App" #define MENU_POSITION_ROTATE 5 #define MENU_POSITION_MIRROR 6 #define MENU_POSITION_TC_OPT 0 static HWND hwndMain; static HINSTANCE hInst; static char szBuffer[256]; static HINSTANCE hWinGInst; static HACCEL hAccel; static LPVOID lpDIB1, lpDIB2, lpDIBDisplay; static HPALETTE hPalette; static LPPRINTDLG pPrintDlgStruct; static BOOL bHalftoneImgLib, bFillPage; static unsigned int uPrintCopies = 1; static RECT rcSelection; static POINT ptAnchor; static BOOL bDrawSelection, bPasting; static HDC hdcWinG; static HBITMAP hbmpWinG, hbmpWinGOld; static BOOL InitApplication (HANDLE); static BOOL InitInstance (HANDLE, int); LRESULT CALLBACK MainWndProc (HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK AboutProc (HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK FileTypeProc (HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK BrightnessProc (HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK PrintProc (HWND, UINT, WPARAM, LPARAM); static BOOL GetOpenFile (LPSTR); static BOOL GetSaveFile (LPSTR); LPVOID CreateDisplayDIB (HWND, LPVOID*, HPALETTE *); static void UpdateWindowTitle (LPSTR, BOOL); static void ResizeWindowToDIB (HWND, LPVOID); static void HandleVerticalScroll (WPARAM, LPARAM); static void HandleHorizontalScroll (WPARAM, LPARAM); static void HandleWindowSizing (LPVOID, WPARAM, LPARAM); static void HandlePrinting (LPVOID); static void HandleMenuPopup (WPARAM, LPARAM); static void InitializePrintStruct (void); static void HandleLButtonDown (WPARAM, LPARAM); static void HandleLButtonUp (WPARAM, LPARAM); static void HandleMouseMove (WPARAM, LPARAM); static void HandleRButtonDown (WPARAM, LPARAM); static void HandleCharacter (WPARAM, LPARAM); static void HandlePasting (WPARAM, LPARAM); static void HandleCopying (WPARAM, LPARAM); static void HandleZoomin (WPARAM, LPARAM); static void DrawSelectionBox (void); static void EraseSelectionBox (void); static void ProcessNewDIB (LPVOID); static LRESULT HandlePaintingAndUpdates (UINT, WPARAM, LPARAM); #ifdef USE_WING static void InitializeWinG (void); static void UpdateWinGBitmap (LPVOID); #endif /**************************************************************************** FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int) PURPOSE: calls initialization function, processes message loop ****************************************************************************/ int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; hInst = hInstance; if (!hPrevInstance) { if (!InitApplication (hInstance)) return (FALSE); } if (!InitInstance (hInstance, nCmdShow)) return (FALSE); while (GetMessage (&msg, NULL, 0, 0xffff)) { if (!TranslateAccelerator (hwndMain, hAccel, &msg)) { TranslateMessage (&msg); DispatchMessage (&msg); } } return (0); } /**************************************************************************** FUNCTION: InitApplication(HANDLE) PURPOSE: Initializes window data and registers window class ****************************************************************************/ BOOL InitApplication (HANDLE hInstance) { WNDCLASS wc; wc.style = 0; wc.lpfnWndProc = MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon (NULL, IDI_APPLICATION); wc.hCursor = LoadCursor (NULL, IDC_ARROW); wc.hbrBackground = GetStockObject (WHITE_BRUSH); wc.lpszMenuName = "tstappmenu"; wc.lpszClassName = "Test App"; return (RegisterClass (&wc)); } /**************************************************************************** FUNCTION: InitInstance(HANDLE, int) PURPOSE: Saves instance handle and creates main window ****************************************************************************/ BOOL InitInstance (HANDLE hInstance, int nCmdShow) { UINT uErrMode; HMENU hMenu; HDC hDC; hAccel = LoadAccelerators (hInstance, "tstappaccel"); if (!hAccel) return (FALSE); /* * Just use default size and location. It's easier to size an already * created window for the specific client area size. */ hwndMain = CreateWindow ("Test App", WINDOW_NAME, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); if (!hwndMain) return (FALSE); ShowWindow (hwndMain, nCmdShow); UpdateWindow (hwndMain); hDC = GetDC (hwndMain); if (GetDeviceCaps (hDC, RASTERCAPS) & RC_PALETTE) { uErrMode = SetErrorMode (SEM_NOOPENFILEERRORBOX); #ifdef WIN32 hWinGInst = LoadLibrary ("wing32.dll"); #else hWinGInst = LoadLibrary ("wing.dll"); if (hWinGInst < HINSTANCE_ERROR) hWinGInst = 0; #endif SetErrorMode (uErrMode); } else hWinGInst = NULL; ReleaseDC (hwndMain, hDC); hMenu = GetMenu (hwndMain); #ifdef USE_WING if (hWinGInst) { InitializeWinG (); CheckMenuItem (hMenu, ID_OPTIONS_TC_DISPLAY_WING, MF_BYCOMMAND | MF_CHECKED); CheckMenuItem (hMenu, ID_OPTIONS_TC_DISPLAY_IMGLIB, MF_BYCOMMAND | MF_UNCHECKED); } else #endif EnableMenuItem (hMenu, ID_OPTIONS_TC_DISPLAY_WING, MF_BYCOMMAND | MF_GRAYED); return (TRUE); } /**************************************************************************** FUNCTION: MainWndProc(HWND, UINT, WPARAM, LPARAM) PURPOSE: Processes messages ****************************************************************************/ LRESULT CALLBACK MainWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int iCount, iBrightness; static char szFileName[260], szOldTitle[256]; LPVOID lpDIBNew; HMENU hMenu; DWORD dwStartTime; static short nFileType; PRINTDLG PrintDlgStruct; switch (message) { case WM_QUERYNEWPALETTE: case WM_PALETTECHANGED: case WM_PAINT: return (HandlePaintingAndUpdates (message, wParam, lParam)); break; case WM_CHAR: HandleCharacter (wParam, lParam); break; case WM_LBUTTONDOWN: HandleLButtonDown (wParam, lParam); break; case WM_RBUTTONDOWN: HandleRButtonDown (wParam, lParam); break; case WM_LBUTTONUP: HandleLButtonUp (wParam, lParam); break; case WM_MOUSEMOVE: HandleMouseMove (wParam, lParam); break; case WM_INITMENUPOPUP: HandleMenuPopup (wParam, lParam); break; case WM_VSCROLL: HandleVerticalScroll (wParam, lParam); break; case WM_HSCROLL: HandleHorizontalScroll (wParam, lParam); break; case WM_SIZE: HandleWindowSizing (lpDIBDisplay, wParam, lParam); break; case WM_COMMAND: switch (CONTROL_ID (wParam)) { case ID_FILE_PRINT: if (lpDIB1) HandlePrinting (lpDIB1); break; case ID_FILE_PRINT_SETUP: if (!pPrintDlgStruct) InitializePrintStruct (); if (!pPrintDlgStruct) break; PrintDlgStruct = *pPrintDlgStruct; PrintDlgStruct.hwndOwner = hWnd; PrintDlgStruct.Flags = PD_PRINTSETUP; if (PrintDlg (&PrintDlgStruct) == TRUE) *pPrintDlgStruct = PrintDlgStruct; break; case ID_FILE_SAVE: if (lpDIB1) { if (GetSaveFile (szFileName) == FALSE) break; if (DialogBoxParam (hInst, "IDD_FILETYPE", hWnd, FileTypeProc, (LPARAM)(LPINT)&nFileType) != TRUE) break; UpdateWindowTitle (szFileName, TRUE); if (WriteDIBToFile (lpDIB1, szFileName, nFileType) == FALSE) { switch (GetLastImgLibError ()) { case ERROR_WRITE_ACCESS_DENIED: wsprintf ((LPSTR)szBuffer, (LPSTR)"Error writing to file \"%s\"", (LPSTR)szFileName); break; case ERROR_INVALID_POINTER: wsprintf ((LPSTR)szBuffer, (LPSTR)"Error accessing one of the pointer parameters", (LPSTR)szFileName); break; case ERROR_INCOMPATIBLE_IMAGE: wsprintf ((LPSTR)szBuffer, (LPSTR)"Image format incompatible with the selected file type", (LPSTR)szFileName); break; } MessageBox (NULL, szBuffer, "Save Error", MB_TASKMODAL | MB_ICONSTOP | MB_OK); } } break; case ID_FILE_OPEN: if (GetOpenFile (szFileName) == FALSE) break; SetCursor (LoadCursor (NULL, IDC_WAIT)); lpDIBNew = ReadFileIntoDIB (szFileName); if (lpDIBNew) { bDrawSelection = FALSE; UpdateWindowTitle (szFileName, TRUE); ProcessNewDIB (lpDIBNew);; } SetCursor (LoadCursor (NULL, IDC_ARROW)); if (!lpDIBNew) { switch (GetLastImgLibError ()) { case ERROR_UNSUPPORTED_IMAGE: MessageBox (hWnd, "Unsupported image type", WINDOW_NAME, MB_OK | MB_ICONSTOP); break; case ERROR_NO_MEMORY: MessageBox (hWnd, "Out of memory reading image", WINDOW_NAME, MB_OK | MB_ICONSTOP); break; case ERROR_INVALID_POINTER: MessageBox (hWnd, "Access violation", WINDOW_NAME, MB_OK | MB_ICONSTOP); break; } } break; case ID_OPTIONS_TIME: if (GetOpenFile (szFileName) == FALSE) break; SetCursor (LoadCursor (NULL, IDC_WAIT)); GetWindowText (hWnd, szOldTitle, sizeof (szOldTitle)); dwStartTime = GetTickCount (); for (iCount = 0;iCount < 10;iCount++) { wsprintf ((LPSTR)szBuffer, (LPSTR)"Testing image loading speed \"%s\" -- %d", (LPSTR)szFileName, iCount); UpdateWindowTitle (szBuffer, FALSE); lpDIBNew = ReadFileIntoDIB (szFileName); if (lpDIBNew) { DIBFree (lpDIBNew); } else { break; } } SetWindowText (hWnd, szOldTitle); SetCursor (LoadCursor (NULL, IDC_ARROW)); if (iCount == 10) wsprintf ((LPSTR)szBuffer, (LPSTR)"File \"%s\" loaded 10 times in %ld milliseconds", (LPSTR)szFileName, GetTickCount () - dwStartTime); else wsprintf ((LPSTR)szBuffer, (LPSTR)"File \"%s\" failed to load 10 times", (LPSTR)szFileName); MessageBox (hWnd, szBuffer, "ImgLib Timing Results", MB_OK); break; case ID_FILE_EXIT: DestroyWindow (hWnd); break; case ID_EDIT_UNDO: if (lpDIB1 && lpDIB2) { SetCursor (LoadCursor (NULL, IDC_WAIT)); if (lpDIBDisplay && lpDIBDisplay != lpDIB1) DIBFree (lpDIBDisplay); lpDIBNew = lpDIB2; lpDIB2 = lpDIB1; lpDIB1 = lpDIBNew; if (hPalette) { DeleteObject (hPalette); hPalette = NULL; } lpDIBDisplay = CreateDisplayDIB (hWnd, &lpDIB1, &hPalette); bDrawSelection = FALSE; ResizeWindowToDIB (hWnd, lpDIBDisplay); SetCursor (LoadCursor (NULL, IDC_ARROW)); } break; case ID_EDIT_PASTE: HandlePasting (wParam, lParam); break; case ID_EDIT_COPY: HandleCopying (wParam, lParam); break; case ID_EDIT_ZOOM: HandleZoomin (wParam, lParam); break; case ID_EDIT_EMPTY: if (OpenClipboard (hWnd)) { EmptyClipboard (); CloseClipboard (); } break; case ID_PROCESS_BRIGHTNESS: if (lpDIB1) { iBrightness = DialogBox (hInst, "IDD_BRIGHTNESS", hWnd, BrightnessProc); if (iBrightness) { SetCursor (LoadCursor (NULL, IDC_WAIT)); lpDIBNew = BrightenDIB (lpDIB1, (short)iBrightness); ProcessNewDIB (lpDIBNew); SetCursor (LoadCursor (NULL, IDC_ARROW)); } } break; case ID_PROCESS_SMOOTH: if (lpDIB1) { SetCursor (LoadCursor (NULL, IDC_WAIT)); lpDIBNew = SmoothDIB (lpDIB1, 1); ProcessNewDIB (lpDIBNew); SetCursor (LoadCursor (NULL, IDC_ARROW)); } break; case ID_PROCESS_HALFTONE: if (lpDIB1) { SetCursor (LoadCursor (NULL, IDC_WAIT)); lpDIBNew = HalftoneDIB (lpDIB1); ProcessNewDIB (lpDIBNew); SetCursor (LoadCursor (NULL, IDC_ARROW)); } break; case ID_PROCESS_GRAY: if (lpDIB1) { SetCursor (LoadCursor (NULL, IDC_WAIT)); lpDIBNew = GrayDIB (lpDIB1); ProcessNewDIB (lpDIBNew); SetCursor (LoadCursor (NULL, IDC_ARROW)); } break; case ID_PROCESS_EXPAND: if (lpDIB1) { SetCursor (LoadCursor (NULL, IDC_WAIT)); lpDIBNew = ExpandToTrueDIB (lpDIB1); ProcessNewDIB (lpDIBNew); SetCursor (LoadCursor (NULL, IDC_ARROW)); } break; case ID_PROCESS_ROT90: case ID_PROCESS_ROT180: case ID_PROCESS_ROT270: if (lpDIB1) { SetCursor (LoadCursor (NULL, IDC_WAIT)); switch (CONTROL_ID (wParam)) { case ID_PROCESS_ROT90: lpDIBNew = RotateDIB (lpDIB1, 90); break; case ID_PROCESS_ROT180: lpDIBNew = RotateDIB (lpDIB1, 180); break; case ID_PROCESS_ROT270: lpDIBNew = RotateDIB (lpDIB1, 270); break; } ProcessNewDIB (lpDIBNew); SetCursor (LoadCursor (NULL, IDC_ARROW)); } break; case ID_PROCESS_MIRRORH: case ID_PROCESS_MIRRORV: if (lpDIB1) { SetCursor (LoadCursor (NULL, IDC_WAIT)); switch (CONTROL_ID (wParam)) { case ID_PROCESS_MIRRORH: lpDIBNew = MirrorDIB (lpDIB1, FALSE); break; case ID_PROCESS_MIRRORV: lpDIBNew = MirrorDIB (lpDIB1, TRUE); break; } ProcessNewDIB (lpDIBNew); SetCursor (LoadCursor (NULL, IDC_ARROW)); } break; case ID_OPTIONS_TC_DISPLAY_GDI: hMenu = GetMenu (hWnd); CheckMenuItem (hMenu, ID_OPTIONS_TC_DISPLAY_GDI, MF_BYCOMMAND | MF_CHECKED); CheckMenuItem (hMenu, ID_OPTIONS_TC_DISPLAY_WING, MF_BYCOMMAND | MF_UNCHECKED); CheckMenuItem (hMenu, ID_OPTIONS_TC_DISPLAY_IMGLIB, MF_BYCOMMAND | MF_UNCHECKED); if (lpDIB1) { if (lpDIBDisplay && lpDIBDisplay != lpDIB1) DIBFree (lpDIBDisplay); lpDIBDisplay = CreateDisplayDIB (hWnd, &lpDIB1, &hPalette); InvalidateRect (hWnd, (LPRECT) (NULL), FALSE); } break; case ID_OPTIONS_TC_DISPLAY_WING: hMenu = GetMenu (hWnd); CheckMenuItem (hMenu, ID_OPTIONS_TC_DISPLAY_GDI, MF_BYCOMMAND | MF_UNCHECKED); CheckMenuItem (hMenu, ID_OPTIONS_TC_DISPLAY_WING, MF_BYCOMMAND | MF_CHECKED); CheckMenuItem (hMenu, ID_OPTIONS_TC_DISPLAY_IMGLIB, MF_BYCOMMAND | MF_UNCHECKED); if (lpDIB1) { SetCursor (LoadCursor (NULL, IDC_WAIT)); if (lpDIBDisplay && lpDIBDisplay != lpDIB1) DIBFree (lpDIBDisplay); lpDIBDisplay = CreateDisplayDIB (hWnd, &lpDIB1, &hPalette); InvalidateRect (hWnd, (LPRECT) (NULL), FALSE); SetCursor (LoadCursor (NULL, IDC_ARROW)); } break; case ID_OPTIONS_TC_DISPLAY_IMGLIB: hMenu = GetMenu (hWnd); CheckMenuItem (hMenu, ID_OPTIONS_TC_DISPLAY_GDI, MF_BYCOMMAND | MF_UNCHECKED); CheckMenuItem (hMenu, ID_OPTIONS_TC_DISPLAY_WING, MF_BYCOMMAND | MF_UNCHECKED); CheckMenuItem (hMenu, ID_OPTIONS_TC_DISPLAY_IMGLIB, MF_BYCOMMAND | MF_CHECKED); if (lpDIB1) { SetCursor (LoadCursor (NULL, IDC_WAIT)); if (lpDIBDisplay && lpDIBDisplay != lpDIB1) DIBFree (lpDIBDisplay); lpDIBDisplay = CreateDisplayDIB (hWnd, &lpDIB1, &hPalette); InvalidateRect (hWnd, (LPRECT) (NULL), FALSE); SetCursor (LoadCursor (NULL, IDC_ARROW)); } break; case ID_OPTIONS_RETAIN_TC: hMenu = GetMenu (hWnd); if (GetMenuState (hMenu, ID_OPTIONS_RETAIN_TC, MF_BYCOMMAND) & MF_CHECKED) { CheckMenuItem (hMenu, ID_OPTIONS_RETAIN_TC, MF_BYCOMMAND | MF_UNCHECKED); if (lpDIBDisplay && lpDIB1 != lpDIBDisplay) { DIBFree (lpDIB1); lpDIB1 = lpDIBDisplay; } } else { CheckMenuItem (hMenu, ID_OPTIONS_RETAIN_TC, MF_BYCOMMAND | MF_CHECKED); } break; case ID_HELP_ABOUT: DialogBox (hInst, "IDD_ABOUT_DIALOG", hWnd, AboutProc); break; default: return (DefWindowProc (hWnd, message, wParam, lParam)); } break; case WM_DESTROY: if (lpDIB1) DIBFree (lpDIB1); if (lpDIB2) DIBFree (lpDIB2); if (lpDIBDisplay && lpDIBDisplay != lpDIB1) DIBFree (lpDIBDisplay); if (hPalette) { DeleteObject (hPalette); hPalette = NULL; } if (hWinGInst) { if (hbmpWinG) { SelectObject (hdcWinG, hbmpWinGOld); DeleteObject (hbmpWinG); } DeleteDC (hdcWinG); FreeLibrary (hWinGInst); } PostQuitMessage(0); break; default: return (DefWindowProc (hWnd, message, wParam, lParam)); } return (0); } /**************************************************************************** FUNCTION: AboutProc(HWND, UINT, WPARAM, LPARAM) PURPOSE: Processes messages for the About dialog ****************************************************************************/ BOOL CALLBACK AboutProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND hwndStatic; char szImgLibVer[512]; switch (message) { case WM_INITDIALOG: hwndStatic = GetDlgItem (hDlg, IDC_ABOUT_STRING); GetImgLibVersion (szImgLibVer, sizeof (szImgLibVer)); SetWindowText (hwndStatic, szImgLibVer); return (TRUE); case WM_COMMAND: if (CONTROL_ID (wParam) == IDOK) { EndDialog(hDlg, TRUE); return (TRUE); } break; } return (FALSE); } /**************************************************************************** FUNCTION: BrightnessProc(HWND, UINT, WPARAM, LPARAM) PURPOSE: Processes messages for the Brightness Control dialog ****************************************************************************/ BOOL CALLBACK BrightnessProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND hwndStatic, hwndScroll; char szMessage[32]; int iScrollCode, iNewPos; static LPVOID lpDIBSave; LPVOID lpDIBNew; switch (message) { case WM_INITDIALOG: lpDIBSave = lpDIBDisplay; hwndScroll = GetDlgItem (hDlg, IDC_BRIGHTNESS_SCROLLBAR); SetScrollRange (hwndScroll, SB_CTL, 50, 150, TRUE); SetScrollPos (hwndScroll, SB_CTL, 100, TRUE); return (TRUE); case WM_HSCROLL: #ifdef WIN32 iScrollCode = (int) LOWORD (wParam); iNewPos = (int) HIWORD (wParam); #else iScrollCode = (int) wParam; iNewPos = (int) LOWORD (lParam); #endif hwndScroll = GetDlgItem (hDlg, IDC_BRIGHTNESS_SCROLLBAR); switch (iScrollCode) { case SB_ENDSCROLL: iNewPos = GetScrollPos (hwndScroll, SB_CTL); lpDIBNew = BrightenDIB (lpDIBSave, (short) iNewPos); if (lpDIBNew) { if (lpDIBDisplay != lpDIBSave) DIBFree (lpDIBDisplay); lpDIBDisplay = lpDIBNew; InvalidateRect (hwndMain, NULL, FALSE); } break; case SB_LINEDOWN: iNewPos = GetScrollPos (hwndScroll, SB_CTL) + 1; break; case SB_LINEUP: iNewPos = GetScrollPos (hwndScroll, SB_CTL) - 1; break; case SB_PAGEDOWN: iNewPos = GetScrollPos (hwndScroll, SB_CTL) + 10; break; case SB_PAGEUP: iNewPos = GetScrollPos (hwndScroll, SB_CTL) - 10; break; } if (iNewPos < 50) iNewPos = 50; if (iNewPos > 150) iNewPos = 150; wsprintf ((LPSTR)szMessage, (LPSTR)"%d %%", iNewPos); hwndStatic = GetDlgItem (hDlg, IDC_BRIGHTNESS_PERCENTAGE); SetWindowText (hwndStatic, szMessage); SetScrollPos (hwndScroll, SB_CTL, iNewPos, TRUE); return (TRUE); case WM_COMMAND: switch (CONTROL_ID (wParam)) { case IDOK: hwndScroll = GetDlgItem (hDlg, IDC_BRIGHTNESS_SCROLLBAR); iNewPos = GetScrollPos (hwndScroll, SB_CTL); if (lpDIBDisplay != lpDIBSave) { DIBFree (lpDIBDisplay); lpDIBDisplay = lpDIBSave; } EndDialog(hDlg, iNewPos); return (TRUE); case IDCANCEL: if (lpDIBDisplay != lpDIBSave) { DIBFree (lpDIBDisplay); lpDIBDisplay = lpDIBSave; InvalidateRect (hwndMain, NULL, FALSE); } EndDialog(hDlg, FALSE); return (TRUE); } break; } return (FALSE); } /**************************************************************************** FUNCTION: FileTypeProc(HWND, UINT, WPARAM, LPARAM) PURPOSE: Processes messages for the FileType dialog ****************************************************************************/ BOOL CALLBACK FileTypeProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static short *pnFileType; int iCtrl; switch (message) { case WM_INITDIALOG: pnFileType = (short *)lParam; switch (*pnFileType) { case FILETYPE_BMP: iCtrl = IDC_IT_BMP; break; case FILETYPE_TIFF_DEFAULT: iCtrl = IDC_IT_TIFF; break; case FILETYPE_TIFF_NO_COMPRESSION: iCtrl = IDC_IT_TIFF_NOCOMP; break; case FILETYPE_TIFF_HUFFMAN: iCtrl = IDC_IT_TIFF_HUFFMAN; break; case FILETYPE_TIFF_PACKBITS: iCtrl = IDC_IT_TIFF_PACKBITS; break; case FILETYPE_TIFF_G3: iCtrl = IDC_IT_TIFF_G3; break; case FILETYPE_TIFF_G4: iCtrl = IDC_IT_TIFF_G4; break; default: iCtrl = IDC_IT_BMP; break; } CheckRadioButton (hDlg, IDC_IT_BMP, IDC_IT_TIFF_G4, iCtrl); return (TRUE); case WM_COMMAND: if (CONTROL_ID (wParam) == IDOK) { if (IsDlgButtonChecked (hDlg, IDC_IT_BMP)) *pnFileType = FILETYPE_BMP; else if (IsDlgButtonChecked (hDlg, IDC_IT_TIFF)) *pnFileType = FILETYPE_TIFF_DEFAULT; else if (IsDlgButtonChecked (hDlg, IDC_IT_TIFF_NOCOMP)) *pnFileType = FILETYPE_TIFF_NO_COMPRESSION; else if (IsDlgButtonChecked (hDlg, IDC_IT_TIFF_HUFFMAN)) *pnFileType = FILETYPE_TIFF_HUFFMAN; else if (IsDlgButtonChecked (hDlg, IDC_IT_TIFF_PACKBITS)) *pnFileType = FILETYPE_TIFF_PACKBITS; else if (IsDlgButtonChecked (hDlg, IDC_IT_TIFF_G3)) *pnFileType = FILETYPE_TIFF_G3; else if (IsDlgButtonChecked (hDlg, IDC_IT_TIFF_G4)) *pnFileType = FILETYPE_TIFF_G4; EndDialog(hDlg, TRUE); return (TRUE); } else if (CONTROL_ID (wParam) == IDCANCEL) { EndDialog(hDlg, FALSE); return (TRUE); } break; } return (FALSE); } /**************************************************************************** FUNCTION: PrintProc(HWND, UINT, WPARAM, LPARAM) PURPOSE: Processes messages for the Print dialog ****************************************************************************/ BOOL CALLBACK PrintProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static LPBITMAPINFOHEADER pBmi; HWND hwndCtl; LPDEVNAMES pDevNames, pDevNamesNew; LPDEVMODE pDevMode, pDevModeNew; char szBuffer[256]; static PRINTDLG PrintDlgStruct; unsigned int uCopyCount; BOOL bConvertOK; HANDLE hDevModeNew, hDevNamesNew; switch (message) { case WM_INITDIALOG: PrintDlgStruct = *pPrintDlgStruct; SetDlgItemInt (hDlg, IDC_COPY_COUNT, uPrintCopies, FALSE); pBmi = (LPBITMAPINFOHEADER) lParam; pDevNames = (LPDEVNAMES)GlobalLock (pPrintDlgStruct->hDevNames); pDevMode = (LPDEVMODE)GlobalLock (pPrintDlgStruct->hDevMode); /* * Make copies of the DEVNAMES and DEVMODE structures */ hDevNamesNew = GlobalAlloc (GMEM_MOVEABLE, GlobalSize (pPrintDlgStruct->hDevNames)); pDevNamesNew = (LPDEVNAMES) GlobalLock (hDevNamesNew); hDevModeNew = GlobalAlloc (GMEM_MOVEABLE, GlobalSize (pPrintDlgStruct->hDevMode)); pDevModeNew = (LPDEVMODE) GlobalLock (hDevModeNew); copymem (pDevModeNew, pDevMode, GlobalSize (hDevModeNew)); copymem (pDevNamesNew, pDevNames, GlobalSize (hDevNamesNew)); GlobalUnlock (pPrintDlgStruct->hDevNames); GlobalUnlock (pPrintDlgStruct->hDevMode); PrintDlgStruct.hDevMode = hDevModeNew; PrintDlgStruct.hDevNames = hDevNamesNew; if (pBmi->biPlanes * pBmi->biBitCount == 1 || pDevModeNew->dmColor == DMCOLOR_COLOR) // monochrome bitmap or color printer { hwndCtl = GetDlgItem (hDlg, IDC_HALFTONE_GROUP); EnableWindow (hwndCtl, FALSE); hwndCtl = GetDlgItem (hDlg, IDC_METHOD_GDI); EnableWindow (hwndCtl, FALSE); hwndCtl = GetDlgItem (hDlg, IDC_METHOD_IMGLIB); EnableWindow (hwndCtl, FALSE); } else { if (bHalftoneImgLib) CheckRadioButton (hDlg, IDC_METHOD_GDI, IDC_METHOD_IMGLIB, IDC_METHOD_IMGLIB); else CheckRadioButton (hDlg, IDC_METHOD_GDI, IDC_METHOD_IMGLIB, IDC_METHOD_GDI); } if (bFillPage) CheckDlgButton (hDlg, IDC_FILL_PAGE, TRUE); wsprintf ((LPSTR)szBuffer, (LPSTR)"%s on %s", (LPSTR)pDevNamesNew + pDevNamesNew->wDeviceOffset, (LPSTR)pDevNamesNew + pDevNamesNew->wOutputOffset); SetDlgItemText (hDlg, IDC_PRINTERNAME, szBuffer); GlobalUnlock (hDevNamesNew); GlobalUnlock (hDevModeNew); return (TRUE); case WM_COMMAND: switch (CONTROL_ID (wParam)) { case IDC_SETUP_PRINTER: PrintDlgStruct.hwndOwner = hDlg; PrintDlgStruct.Flags = PD_PRINTSETUP; if (PrintDlg (&PrintDlgStruct)) { pDevModeNew = (LPDEVMODE) GlobalLock (PrintDlgStruct.hDevMode); if (pBmi->biPlanes * pBmi->biBitCount == 1 || pDevModeNew->dmColor == DMCOLOR_COLOR) // monochrome bitmap or color printer { hwndCtl = GetDlgItem (hDlg, IDC_HALFTONE_GROUP); EnableWindow (hwndCtl, FALSE); hwndCtl = GetDlgItem (hDlg, IDC_METHOD_GDI); EnableWindow (hwndCtl, FALSE); hwndCtl = GetDlgItem (hDlg, IDC_METHOD_IMGLIB); EnableWindow (hwndCtl, FALSE); } else { hwndCtl = GetDlgItem (hDlg, IDC_HALFTONE_GROUP); EnableWindow (hwndCtl, TRUE); hwndCtl = GetDlgItem (hDlg, IDC_METHOD_GDI); EnableWindow (hwndCtl, TRUE); hwndCtl = GetDlgItem (hDlg, IDC_METHOD_IMGLIB); EnableWindow (hwndCtl, TRUE); } GlobalUnlock (PrintDlgStruct.hDevMode); } return (TRUE); case IDOK: uCopyCount = GetDlgItemInt (hDlg, IDC_COPY_COUNT, &bConvertOK, FALSE); if (!bConvertOK || uCopyCount < 1 || uCopyCount > 100) { MessageBox (hDlg, "Invalid value. Please enter a number between 1 and 100", "Print", MB_ICONSTOP | MB_OK); SetFocus (GetDlgItem (hDlg, IDC_COPY_COUNT)); return (TRUE); } uPrintCopies = uCopyCount; bFillPage = IsDlgButtonChecked (hDlg, IDC_FILL_PAGE); bHalftoneImgLib = IsDlgButtonChecked (hDlg, IDC_METHOD_IMGLIB); GlobalFree (pPrintDlgStruct->hDevNames); GlobalFree (pPrintDlgStruct->hDevMode); *pPrintDlgStruct = PrintDlgStruct; EndDialog (hDlg, TRUE); return (TRUE); case IDCANCEL: GlobalFree (PrintDlgStruct.hDevNames); GlobalFree (PrintDlgStruct.hDevMode); EndDialog (hDlg, FALSE); return (TRUE); } break; } return (FALSE); } /************************************************************************* Function: GetOpenFile (LPSTR. WORD) Purpose: Prompts user for a filename through the use of a Windows FileOpen common dialog box. Returns: TRUE if a filename is selected. FALSE if no filename is selected. Comments: Filename is put into the string passed to the routine. If a filename is not selected, NULL is returned. *************************************************************************/ BOOL GetOpenFile (LPSTR szFileName) { OPENFILENAME of; DWORD flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST; static char szTitle[30]; // Dialog Box title static char szTemplate[20]; // Dialog Box template static char szFile[256]; // File name static char szFileTitle[256]; // Title static char szDrive[5]; // Drive static char szDir[256]; // Directory char szFilter[] = // Filter "Pictures\0*.bmp;*.jpg;*.tga;*.pcd;*.pcx;*.tif\0All Files\0*.*\0"; LPSTR pFile; szFile[0] = '\0'; of.lStructSize = sizeof (OPENFILENAME); of.hwndOwner = hwndMain; of.hInstance = hInst; of.lpstrFilter = szFilter; of.lpstrCustomFilter = NULL; of.nMaxCustFilter = 0L; of.nFilterIndex = 1L; of.lpstrFile = szFile; of.nMaxFile = sizeof (szFile); of.lpstrFileTitle = szFileTitle; of.nMaxFileTitle = sizeof (szFileTitle); of.lpstrInitialDir = szDir; of.lpstrTitle = "Open a new test bitmap file"; of.Flags = flags; of.nFileOffset = 0; of.nFileExtension = 0; of.lpstrDefExt = NULL; of.lCustData = 0; of.lpfnHook = NULL; of.lpTemplateName = NULL; if (GetOpenFileName (&of)) { lstrcpy (szFileName, of.lpstrFile); lstrcpy (szDir, of.lpstrFile); pFile = strrchr (szDir, '\\'); if (pFile) *pFile = 0; return TRUE; } else return FALSE; } /************************************************************************* Function: GetSaveFile (LPSTR. WORD) Purpose: Prompts user for a filename through the use of a Windows FileOpen common dialog box. Returns: TRUE if a filename is selected. FALSE if no filename is selected. Comments: Filename is put into the string passed to the routine. If a filename is not selected, NULL is returned. *************************************************************************/ BOOL GetSaveFile (LPSTR szFileName) { OPENFILENAME of; DWORD flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT; static char szTitle[30]; // Dialog Box title static char szTemplate[20]; // Dialog Box template static char szFile[256]; // File name static char szFileTitle[256]; // Title static char szDrive[5]; // Drive static char szDir[256]; // Directory char szFilter[] = // Filter "Windows Pictures\0*.bmp;*.tif\0All Files\0*.*\0"; LPSTR pFile; szFile[0] = '\0'; of.lStructSize = sizeof (OPENFILENAME); of.hwndOwner = GetFocus (); of.hInstance = hInst; of.lpstrFilter = szFilter; of.lpstrCustomFilter = NULL; of.nMaxCustFilter = 0L; of.nFilterIndex = 1L; of.lpstrFile = szFile; of.nMaxFile = sizeof (szFile); of.lpstrFileTitle = szFileTitle; of.nMaxFileTitle = sizeof (szFileTitle); of.lpstrInitialDir = szDir; of.lpstrTitle = "Save the image in a bitmap file"; of.Flags = flags; of.nFileOffset = 0; of.nFileExtension = 0; of.lpstrDefExt = "*.bmp"; of.lCustData = 0; of.lpfnHook = NULL; of.lpTemplateName = NULL; if (GetSaveFileName (&of)) { lstrcpy (szFileName, of.lpstrFile); lstrcpy (szDir, of.lpstrFile); pFile = strrchr (szDir, '\\'); if (pFile) *pFile = 0; return TRUE; } else return FALSE; } /************************************************************************* Function: CreateDisplayDIB() Purpose: Creates a DIB suitable for the display based on user-selected options. Returns: a new DIB pointer *************************************************************************/ LPVOID CreateDisplayDIB (HWND hwnd, LPVOID *lpDIB, HPALETTE *phPal) { HMENU hMenu; LPBITMAPINFO pBitmapInfo; UINT uState; LPVOID lpDIBDisplay; long lColors; int iPixelBits, iPlanes; HDC hDC; hDC = GetDC (hwnd); iPixelBits = GetDeviceCaps (hDC, BITSPIXEL); iPlanes = GetDeviceCaps (hDC, PLANES); ReleaseDC (hwnd, hDC); if (iPixelBits * iPlanes > 8) { /* * No color reduction on true color (or high color) displays */ *phPal = NULL; return (*lpDIB); } pBitmapInfo = (LPBITMAPINFO) *lpDIB; hMenu = GetMenu (hwnd); uState = GetMenuState (hMenu, ID_OPTIONS_TC_DISPLAY_GDI, MF_BYCOMMAND); if (uState & MF_CHECKED || pBitmapInfo->bmiHeader.biClrUsed) { lpDIBDisplay = *lpDIB; if (pBitmapInfo->bmiHeader.biClrUsed > 2) *phPal = CreateDIBPalette (lpDIBDisplay); else *phPal = NULL; } else { uState = GetMenuState (hMenu, ID_OPTIONS_TC_DISPLAY_WING, MF_BYCOMMAND); if (uState & MF_CHECKED && hWinGInst) { lpDIBDisplay = WinGHalftoneDIB (*lpDIB, phPal); } else { lColors = 1 << iPixelBits * iPlanes; lpDIBDisplay = ReduceDIB (*lpDIB, lColors, TRUE); *phPal = CreateDIBPalette (lpDIBDisplay); } if (lpDIBDisplay && lpDIBDisplay != *lpDIB) { if (!(GetMenuState (hMenu, ID_OPTIONS_RETAIN_TC, MF_BYCOMMAND) & MF_CHECKED)) { DIBFree (*lpDIB); *lpDIB = lpDIBDisplay; } } } #ifdef USE_WING /* * Use WinG for displaying if available */ if (hWinGInst) UpdateWinGBitmap (lpDIBDisplay); #endif return (lpDIBDisplay); } /************************************************************************* Function: UpdateWindowTitle () Purpose: Updates the window title with the name of the file displayed. Returns: none *************************************************************************/ static void UpdateWindowTitle (LPSTR pszFilePath, BOOL bStripPath) { static char szWindowName[260]; char szFileName[260]; char *pszFileName = NULL; if (pszFilePath && *pszFilePath) { /* * Make local copy because in 16-bit world strrchr can only operate on * near pointers. */ lstrcpy (szFileName, pszFilePath); if (bStripPath) pszFileName = strrchr (szFileName, '\\'); /* * If found the last path delimiter, skip over it. */ if (pszFileName) pszFileName++; else pszFileName = szFileName; wsprintf ((LPSTR)szWindowName, (LPSTR)"%s -- %s", (LPSTR)WINDOW_NAME, (LPSTR)pszFileName); } else wsprintf ((LPSTR)szWindowName, (LPSTR)"%s", (LPSTR)WINDOW_NAME); SetWindowText (hwndMain, szWindowName); } /************************************************************************* Function: ResizeWindowToDIB () Purpose: Updates the window size to fit the given device-independent DIB Returns: none *************************************************************************/ static void ResizeWindowToDIB (HWND hwnd, LPVOID pDIB) { int iWidth, iHeight, iXOverhead, iYOverhead; int iScreenWidth, iScreenHeight, iXPos, iYPos; int iHScrollRange, iVScrollRange; LPBITMAPINFOHEADER pBmi = (LPBITMAPINFOHEADER)pDIB; HDC hDC; RECT rect; BOOL bHScroll, bVScroll; DWORD dwStyle; bHScroll = bVScroll = FALSE; GetWindowRect (hwnd, &rect); iXPos = rect.left; if (iXPos < 0) iXPos = 0; iYPos = rect.top; if (iYPos < 0) iYPos = 0; hDC = GetDC (hwnd); iScreenWidth = GetDeviceCaps (hDC, HORZRES); iScreenHeight = GetDeviceCaps (hDC, VERTRES); ReleaseDC (hwnd, hDC); iWidth = (int)pBmi->biWidth; iHeight = (int)pBmi->biHeight; iXOverhead = GetSystemMetrics (SM_CXFRAME) * 2; iYOverhead = GetSystemMetrics (SM_CYFRAME) * 2 + GetSystemMetrics (SM_CYCAPTION) + GetSystemMetrics (SM_CYMENU); if (iWidth + iXOverhead + iXPos > iScreenWidth) { iXPos = iScreenWidth - iWidth - iXOverhead; if (iXPos < 0) { iHScrollRange = -iXPos; iXPos = 0; bHScroll = TRUE; } } if (iHeight + iYOverhead + iYPos > iScreenHeight) { iYPos = iScreenHeight - iHeight - iYOverhead; if (iYPos < 0) { iVScrollRange = -iYPos; iYPos = 0; bVScroll = TRUE; } } dwStyle = GetWindowLong (hwnd, GWL_STYLE); if (bHScroll) { ShowScrollBar (hwndMain, SB_HORZ, TRUE); /* * Having the vertical scrollbar will "steal" some more pixels * from the client area. Check and adjust for it here. */ if (bVScroll) iHScrollRange += GetSystemMetrics (SM_CXVSCROLL); } else { /* * Remove the scrollbar */ if (dwStyle & WS_HSCROLL) { SetScrollPos (hwnd, SB_HORZ, 0, TRUE); ShowScrollBar (hwndMain, SB_HORZ, FALSE); } } if (bVScroll) { ShowScrollBar (hwndMain, SB_VERT, TRUE); /* * Having the horizontal scrollbar will "steal" some more pixels * from the client area. Check and adjust for it here. */ if (bHScroll) iVScrollRange += GetSystemMetrics (SM_CYHSCROLL); } else { /* * Remove the scrollbar */ if (dwStyle & WS_VSCROLL) { SetScrollPos (hwnd, SB_VERT, 0, TRUE); ShowScrollBar (hwndMain, SB_VERT, FALSE); } } /* * Having done all this checking, the following call may still cause the * addition of scrollbars in rare circumstances like the menu bar becoming * 2-line. */ SetWindowPos (hwnd, HWND_TOP, iXPos, iYPos, min (iXOverhead + iWidth, iScreenWidth), min (iYOverhead + iHeight, iScreenHeight), SWP_NOACTIVATE | SWP_NOZORDER); if (bHScroll) SetScrollRange (hwnd, SB_HORZ, 0, iHScrollRange, TRUE); if (bVScroll) SetScrollRange (hwnd, SB_VERT, 0, iVScrollRange, TRUE); InvalidateRect (hwnd, (LPRECT) (NULL), FALSE); } /************************************************************************* Function: HandleVerticalScroll () Purpose: Process the vertical scrollbar operations. Returns: none *************************************************************************/ static void HandleVerticalScroll (WPARAM wParam, LPARAM lParam) { int nScrollCode, iNewPos, iVScroll, iHScroll; int iCurrPos, iMinScroll, iMaxScroll, iClientHeight; RECT rect; UpdateWindow (hwndMain); #ifdef WIN32 nScrollCode = (int) LOWORD (wParam); iNewPos = (int) HIWORD (wParam); #else nScrollCode = (int) wParam; iNewPos = (int) LOWORD (lParam); #endif GetClientRect (hwndMain, &rect); iClientHeight = rect.bottom; iHScroll = iVScroll = 0; GetScrollRange (hwndMain, SB_VERT, &iMinScroll, &iMaxScroll); iCurrPos = GetScrollPos (hwndMain, SB_VERT); switch (nScrollCode) { case SB_BOTTOM: iVScroll = iMaxScroll - iCurrPos; break; case SB_PAGEDOWN: if (iCurrPos + iClientHeight <= iMaxScroll) iVScroll = -iClientHeight; else iVScroll = - (iMaxScroll - iCurrPos); break; case SB_PAGEUP: if (iCurrPos - iClientHeight >= 0) iVScroll = iClientHeight; else iVScroll = iCurrPos; break; case SB_THUMBTRACK: case SB_THUMBPOSITION: iVScroll = GetScrollPos (hwndMain, SB_VERT) - iNewPos; break; case SB_LINEDOWN: iVScroll = -1; break; case SB_LINEUP: iVScroll = 1; break; case SB_ENDSCROLL: return; } if (iCurrPos - iVScroll > iMaxScroll) iVScroll = iCurrPos - iMaxScroll; if (iCurrPos - iVScroll < iMinScroll) iVScroll = iCurrPos - iMinScroll; if (!iVScroll) return; ScrollWindow (hwndMain, iHScroll, iVScroll, NULL, &rect); SetScrollPos (hwndMain, SB_VERT, iCurrPos - iVScroll, TRUE); } /************************************************************************* Function: HandleHorizontalScroll () Purpose: Process the horozontal scrollbar operations. Returns: none *************************************************************************/ static void HandleHorizontalScroll (WPARAM wParam, LPARAM lParam) { int nScrollCode, iNewPos, iVScroll, iHScroll; int iCurrPos, iMinScroll, iMaxScroll, iClientWidth; RECT rect; UpdateWindow (hwndMain); #ifdef WIN32 nScrollCode = (int) LOWORD (wParam); iNewPos = (int) HIWORD (wParam); #else nScrollCode = (int) wParam; iNewPos = (int) LOWORD (lParam); #endif GetClientRect (hwndMain, &rect); iClientWidth = rect.right; iHScroll = iVScroll = 0; GetScrollRange (hwndMain, SB_HORZ, &iMinScroll, &iMaxScroll); iCurrPos = GetScrollPos (hwndMain, SB_HORZ); switch (nScrollCode) { case SB_BOTTOM: iHScroll = iMaxScroll - iCurrPos; break; case SB_PAGEDOWN: if (iCurrPos + iClientWidth <= iMaxScroll) iHScroll = -iClientWidth; else iHScroll = - (iMaxScroll - iCurrPos); break; case SB_PAGEUP: if (iCurrPos - iClientWidth >= 0) iHScroll = iClientWidth; else iHScroll = iCurrPos; break; case SB_THUMBTRACK: case SB_THUMBPOSITION: iHScroll = GetScrollPos (hwndMain, SB_HORZ) - iNewPos; break; case SB_LINEDOWN: iHScroll = -1; break; case SB_LINEUP: iHScroll = 1; break; case SB_ENDSCROLL: return; } if (iCurrPos - iHScroll > iMaxScroll) iHScroll = iCurrPos - iMaxScroll; if (iCurrPos - iHScroll < iMinScroll) iHScroll = iCurrPos - iMinScroll; if (!iHScroll) return; ScrollWindow (hwndMain, iHScroll, iVScroll, NULL, &rect); SetScrollPos (hwndMain, SB_HORZ, iCurrPos - iHScroll, TRUE); } /************************************************************************* Function: HandleWindowSizing () Purpose: Process the WM_SIZE messages. Returns: none *************************************************************************/ static void HandleWindowSizing (LPVOID pDIB, WPARAM wParam, LPARAM lParam) { LPBITMAPINFOHEADER pBmi = (LPBITMAPINFOHEADER)pDIB; BOOL bHScroll, bVScroll; DWORD dwStyle; int iNewWidth, iNewHeight; int iHScrollRange, iVScrollRange; int iPos; static BOOL bSizing; /* * Prevent resizing from infinitely recursing. This may be caused by having * to add or take away a scrollbar which in turn causes another WM_SIZE * message to be generated as the client area is affected by the scrollbars. */ if (bSizing) return; if (!pBmi) return; if (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXHIDE || wParam == SIZE_MAXSHOW) return; bSizing = TRUE; bHScroll = bVScroll = FALSE; iHScrollRange = iVScrollRange = 0; dwStyle = GetWindowLong (hwndMain, GWL_STYLE); iNewWidth = (int) LOWORD (lParam); iNewHeight = (int) HIWORD (lParam); if (dwStyle & WS_HSCROLL) iNewHeight += GetSystemMetrics (SM_CYHSCROLL); if (dwStyle & WS_VSCROLL) iNewWidth += GetSystemMetrics (SM_CXVSCROLL); /* * The following code determines if the scrollbars are required. * Adding a scrollbar "steals" pixels from client area, so the affected * dimension must be rechecked for a need of scrollbar. */ if (pBmi->biWidth > iNewWidth) { bHScroll = TRUE; iHScrollRange = (int)pBmi->biWidth - iNewWidth; iNewHeight -= GetSystemMetrics (SM_CYHSCROLL); } if (pBmi->biHeight > iNewHeight) { bVScroll = TRUE; iVScrollRange = (int)pBmi->biHeight - iNewHeight; iNewWidth -= GetSystemMetrics (SM_CXVSCROLL); /* * Recheck the width to see if a horizontal scrollbar may be ncecessary. */ if (pBmi->biWidth > iNewWidth && !bHScroll) { bHScroll = TRUE; iHScrollRange = (int)pBmi->biWidth - iNewWidth; iNewHeight -= GetSystemMetrics (SM_CYHSCROLL); iVScrollRange += GetSystemMetrics (SM_CYHSCROLL); } } if (!bHScroll && (dwStyle & WS_HSCROLL)) { /* * Remove the scrollbar */ SetScrollPos (hwndMain, SB_HORZ, 0, TRUE); ShowScrollBar (hwndMain, SB_HORZ, FALSE); } if (!bVScroll && (dwStyle & WS_VSCROLL)) { /* * Remove the scrollbar */ SetScrollPos (hwndMain, SB_VERT, 0, TRUE); ShowScrollBar (hwndMain, SB_VERT, FALSE); } /* * Update the scrollbar positions and ranges */ if (bHScroll) { ShowScrollBar (hwndMain, SB_HORZ, TRUE); iPos = GetScrollPos (hwndMain, SB_HORZ); if (iPos > iHScrollRange) { InvalidateRect (hwndMain, NULL, FALSE); SetScrollPos (hwndMain, SB_HORZ, iHScrollRange, TRUE); } SetScrollRange (hwndMain, SB_HORZ, 0, iHScrollRange, TRUE); } if (bVScroll) { ShowScrollBar (hwndMain, SB_VERT, TRUE); iPos = GetScrollPos (hwndMain, SB_VERT); if (iPos > iVScrollRange) { InvalidateRect (hwndMain, NULL, FALSE); SetScrollPos (hwndMain, SB_VERT, iVScrollRange, TRUE); } SetScrollRange (hwndMain, SB_VERT, 0, iVScrollRange, TRUE); } bSizing = FALSE; } /************************************************************************* Function: HandlePrinting () Purpose: Process the File/Print request. Returns: none *************************************************************************/ static void HandlePrinting (LPVOID lpDIB) { HDC hDC; LPDEVNAMES pDevNames; LPDEVMODE pDevMode; LPVOID lpDIBPrint = NULL; LPBITMAPINFOHEADER pBih; LPBITMAPINFO pBmi; char szTitle[128]; DOCINFO DocInfo; int iXMargin, iYMargin, iWidth, iHeight; if (!pPrintDlgStruct) { InitializePrintStruct (); if (!pPrintDlgStruct) return; } if (!DialogBoxParam (hInst, "IDD_PRINT", hwndMain, PrintProc, (LPARAM)lpDIB)) return; SetCursor (LoadCursor (NULL, IDC_WAIT)); pDevNames = (LPDEVNAMES)GlobalLock (pPrintDlgStruct->hDevNames); pDevMode = (LPDEVMODE)GlobalLock (pPrintDlgStruct->hDevMode); pDevMode->dmCopies = uPrintCopies; hDC = CreateDC ((LPCSTR)pDevNames + pDevNames->wDriverOffset, (LPCSTR)pDevNames + pDevNames->wDeviceOffset, (LPCSTR)pDevNames + pDevNames->wOutputOffset, pDevMode); if (bHalftoneImgLib) { lpDIBPrint = HalftoneDIB (lpDIB); pBih = (LPBITMAPINFOHEADER) lpDIBPrint; } else { pBih = (LPBITMAPINFOHEADER) lpDIB; } iXMargin = GetDeviceCaps (hDC, HORZRES) / 20; iYMargin = GetDeviceCaps (hDC, VERTRES) / 20; if (bFillPage) { iWidth = GetDeviceCaps (hDC, HORZRES) - iXMargin * 2; iHeight = GetDeviceCaps (hDC, VERTRES) - iYMargin * 2; if (iWidth / pBih->biWidth > iHeight / pBih->biHeight) iWidth = (int)pBih->biWidth * iHeight / (int)pBih->biHeight; else iHeight = (int)pBih->biHeight * iWidth / (int)pBih->biWidth; } else { iWidth = (int)pBih->biWidth; iHeight = (int)pBih->biHeight; /* * ImgLib halftonning increases the image size 4 times. To make the * output look the same size, size the output the same for GDI. */ if (!bHalftoneImgLib) { iWidth *= 4; iHeight *= 4; } } pBmi = (LPBITMAPINFO)pBih; GetWindowText (hwndMain, szTitle, sizeof (szTitle)); DocInfo.cbSize = sizeof (DocInfo); DocInfo.lpszDocName = szTitle; DocInfo.lpszOutput = NULL; StartDoc (hDC, &DocInfo); StartPage (hDC); StretchDIBits (hDC, iXMargin, iYMargin, iWidth, iHeight, 0, 0, (int)pBih->biWidth, (int)pBih->biHeight, (HPSTR)&pBmi->bmiColors[pBih->biClrUsed], pBmi, DIB_RGB_COLORS, SRCCOPY); EndPage (hDC); EndDoc (hDC); DeleteDC (hDC); if (lpDIBPrint) DIBFree (lpDIBPrint); GlobalUnlock (pPrintDlgStruct->hDevNames); GlobalUnlock (pPrintDlgStruct->hDevMode); SetCursor (LoadCursor (NULL, IDC_ARROW)); } /************************************************************************* Function: InitializePrintStruct () Purpose: Initialize the printing structure with default printer information. Returns: none *************************************************************************/ static void InitializePrintStruct (void) { if (pPrintDlgStruct) freemem (pPrintDlgStruct); pPrintDlgStruct = (LPPRINTDLG)allocmem (sizeof (PRINTDLG)); if (pPrintDlgStruct) { #ifdef WIN32 memset (pPrintDlgStruct, 0, sizeof (PRINTDLG)); #else _fmemset (pPrintDlgStruct, 0, sizeof (PRINTDLG)); #endif pPrintDlgStruct->lStructSize = sizeof (PRINTDLG); pPrintDlgStruct->hwndOwner = hwndMain; pPrintDlgStruct->Flags = PD_PRINTSETUP | PD_RETURNDEFAULT; if (PrintDlg (pPrintDlgStruct) == FALSE) { freemem (pPrintDlgStruct); pPrintDlgStruct = NULL; MessageBox (hwndMain, "Error getting the default printer information", WINDOW_NAME, MB_OK | MB_ICONSTOP); return; } } } /************************************************************************* Function: HandleMenuPopup () Purpose: Prepare a menu for display based on the current application state Returns: none *************************************************************************/ static void HandleMenuPopup (WPARAM wParam, LPARAM lParam) { HMENU hMenuParent, hMenuPopup; UINT uIndex; BOOL bSystemMenu; HDC hDC; LPBITMAPINFOHEADER pBmi; bSystemMenu = HIWORD (lParam); if (bSystemMenu) return; hMenuParent = GetMenu (hwndMain); hMenuPopup = (HMENU)wParam; uIndex = LOWORD (lParam); if (hMenuPopup == GetSubMenu (hMenuParent, 0)) { if (lpDIBDisplay) { EnableMenuItem (hMenuPopup, ID_FILE_SAVE, MF_BYCOMMAND | MF_ENABLED); EnableMenuItem (hMenuPopup, ID_FILE_PRINT, MF_BYCOMMAND | MF_ENABLED); } else { EnableMenuItem (hMenuPopup, ID_FILE_SAVE, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem (hMenuPopup, ID_FILE_PRINT, MF_BYCOMMAND | MF_GRAYED); } } else if (hMenuPopup == GetSubMenu (hMenuParent, 1)) { if (lpDIB1 && lpDIB2) EnableMenuItem (hMenuPopup, ID_EDIT_UNDO, MF_BYCOMMAND | MF_ENABLED); else EnableMenuItem (hMenuPopup, ID_EDIT_UNDO, MF_BYCOMMAND | MF_GRAYED); if (lpDIB1) EnableMenuItem (hMenuPopup, ID_EDIT_COPY, MF_BYCOMMAND | MF_ENABLED); else EnableMenuItem (hMenuPopup, ID_EDIT_COPY, MF_BYCOMMAND | MF_GRAYED); if (IsClipboardFormatAvailable (CF_BITMAP) || IsClipboardFormatAvailable (CF_DIB)) EnableMenuItem (hMenuPopup, ID_EDIT_PASTE, MF_BYCOMMAND | MF_ENABLED); else EnableMenuItem (hMenuPopup, ID_EDIT_PASTE, MF_BYCOMMAND | MF_GRAYED); if (bDrawSelection) EnableMenuItem (hMenuPopup, ID_EDIT_ZOOM, MF_BYCOMMAND | MF_ENABLED); else EnableMenuItem (hMenuPopup, ID_EDIT_ZOOM, MF_BYCOMMAND | MF_GRAYED); } else if (hMenuPopup == GetSubMenu (hMenuParent, 2)) { if (lpDIB1) { pBmi = (LPBITMAPINFOHEADER) lpDIBDisplay; /* * Disallow controlling brightness of monochrome bitmaps */ if (pBmi->biPlanes * pBmi->biBitCount > 1) EnableMenuItem (hMenuPopup, ID_PROCESS_BRIGHTNESS, MF_BYCOMMAND | MF_ENABLED); else EnableMenuItem (hMenuPopup, ID_PROCESS_BRIGHTNESS, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem (hMenuPopup, ID_PROCESS_SMOOTH, MF_BYCOMMAND | MF_ENABLED); EnableMenuItem (hMenuPopup, ID_PROCESS_HALFTONE, MF_BYCOMMAND | MF_ENABLED); EnableMenuItem (hMenuPopup, ID_PROCESS_GRAY, MF_BYCOMMAND | MF_ENABLED); if (pBmi->biPlanes * pBmi->biBitCount <= 8) EnableMenuItem (hMenuPopup, ID_PROCESS_EXPAND, MF_BYCOMMAND | MF_ENABLED); else EnableMenuItem (hMenuPopup, ID_PROCESS_EXPAND, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem (hMenuPopup, MENU_POSITION_ROTATE, MF_BYPOSITION | MF_ENABLED); EnableMenuItem (hMenuPopup, MENU_POSITION_MIRROR, MF_BYPOSITION | MF_ENABLED); } else { EnableMenuItem (hMenuPopup, ID_PROCESS_BRIGHTNESS, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem (hMenuPopup, ID_PROCESS_SMOOTH, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem (hMenuPopup, ID_PROCESS_HALFTONE, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem (hMenuPopup, ID_PROCESS_GRAY, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem (hMenuPopup, ID_PROCESS_EXPAND, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem (hMenuPopup, MENU_POSITION_ROTATE, MF_BYPOSITION | MF_GRAYED); EnableMenuItem (hMenuPopup, MENU_POSITION_MIRROR, MF_BYPOSITION | MF_GRAYED); } } else if (hMenuPopup == GetSubMenu (hMenuParent, 3)) { hDC = GetDC (NULL); if (GetDeviceCaps (hDC, BITSPIXEL) > 8) EnableMenuItem (hMenuPopup, MENU_POSITION_TC_OPT, MF_BYPOSITION | MF_GRAYED); else EnableMenuItem (hMenuPopup, MENU_POSITION_TC_OPT, MF_BYPOSITION | MF_ENABLED); ReleaseDC (NULL, hDC); } } /************************************************************************* Function: HandleLButtonDown () Purpose: Process the WM_LBUTTONDOWN message Returns: none *************************************************************************/ static void HandleLButtonDown (WPARAM wParam, LPARAM lParam) { SetCapture (hwndMain); if (!bPasting) { if (bDrawSelection) EraseSelectionBox (); else bDrawSelection = TRUE; ptAnchor.x = rcSelection.left = rcSelection.right = LOWORD (lParam); ptAnchor.y = rcSelection.top = rcSelection.bottom = HIWORD (lParam); DrawSelectionBox (); } } /************************************************************************* Function: HandleLButtonUp () Purpose: Process the WM_LBUTTONUP message Returns: none *************************************************************************/ static void HandleLButtonUp (WPARAM wParam, LPARAM lParam) { HANDLE hDIB; LPBITMAPINFOHEADER pBih; HBITMAP hBitmap; HPALETTE hPalTemp; LPVOID lpDIBNew, lpDIBTemp; if (bPasting) { if (OpenClipboard (hwndMain)) { SetCursor (LoadCursor (NULL, IDC_WAIT)); if (IsClipboardFormatAvailable (CF_DIB)) { hDIB = GetClipboardData (CF_DIB); pBih = (LPBITMAPINFOHEADER)GlobalLock (hDIB); lpDIBNew = MergeDIB (lpDIB1, pBih, rcSelection.left, rcSelection.top); GlobalUnlock (hDIB); } else if (IsClipboardFormatAvailable (CF_BITMAP)) { hBitmap = GetClipboardData (CF_BITMAP); hPalTemp = GetClipboardData (CF_PALETTE); lpDIBTemp = DDBToDIB (hBitmap, hPalTemp); if (lpDIBTemp) { lpDIBNew = MergeDIB (lpDIB1, lpDIBTemp, rcSelection.left, rcSelection.top); DIBFree (lpDIBTemp); } } else { CloseClipboard (); return; } CloseClipboard (); EraseSelectionBox (); bDrawSelection = FALSE; ProcessNewDIB (lpDIBNew); SetCursor (LoadCursor (NULL, IDC_ARROW)); } bPasting = FALSE; } else { if (rcSelection.right - rcSelection.left < 5 || rcSelection.bottom - rcSelection.top < 5) { EraseSelectionBox (); bDrawSelection = FALSE; } } ReleaseCapture (); } /************************************************************************* Function: HandleRButtonDown () Purpose: Process the WM_RBUTTONDOWN message Returns: none *************************************************************************/ static void HandleRButtonDown (WPARAM wParam, LPARAM lParam) { if (GetCapture () == hwndMain) { EraseSelectionBox (); bDrawSelection = FALSE; bPasting = FALSE; ReleaseCapture (); } } /************************************************************************* Function: HandleMouseMove () Purpose: Process the WM_MOUSEMOVE message Returns: none *************************************************************************/ static void HandleMouseMove (WPARAM wParam, LPARAM lParam) { LONG lX, lY, ldx, ldy; if (GetCapture () == hwndMain) { EraseSelectionBox (); lX = LOWORD (lParam); lY = HIWORD (lParam); if (lX < 0) lX = 0; if (lY < 0) lY = 0; if (bPasting) { ldx = lX - rcSelection.left; ldy = lY - rcSelection.top; OffsetRect (&rcSelection, (int)ldx, (int)ldy); } else { if (lX > ptAnchor.x) { rcSelection.right = (int)lX; rcSelection.left = ptAnchor.x; } else { rcSelection.left = (int)lX; rcSelection.right = ptAnchor.x; } if (lY > ptAnchor.y) { rcSelection.bottom = (int)lY; rcSelection.top = ptAnchor.y; } else { rcSelection.top = (int)lY; rcSelection.bottom = ptAnchor.y; } } DrawSelectionBox (); } } /************************************************************************* Function: HandleCharacter () Purpose: Process the WM_CHAR message Returns: none *************************************************************************/ static void HandleCharacter (WPARAM wParam, LPARAM lParam) { if (GetCapture () == hwndMain && wParam == VK_ESCAPE) { EraseSelectionBox (); bDrawSelection = FALSE; bPasting = FALSE; ReleaseCapture (); } } /************************************************************************* Function: HandlePasting () Purpose: Process the clipdoard paste Returns: none *************************************************************************/ static void HandlePasting (WPARAM wParam, LPARAM lParam) { HANDLE hDIB; LPBITMAPINFOHEADER pBih; long lWidth, lHeight; HBITMAP hBitmap; BITMAP bm; POINT ptCursor; LPVOID lpDIBNew; HPALETTE hPalTemp; if (OpenClipboard (hwndMain)) { if (lpDIB1) { if (IsClipboardFormatAvailable (CF_DIB)) { hDIB = GetClipboardData (CF_DIB); pBih = (LPBITMAPINFOHEADER)GlobalLock (hDIB); lWidth = pBih->biWidth; lHeight = pBih->biHeight; GlobalUnlock (hDIB); } else if (IsClipboardFormatAvailable (CF_BITMAP)) { hBitmap = GetClipboardData (CF_BITMAP); GetObject (hBitmap, sizeof (bm), &bm); lWidth = bm.bmWidth; lHeight = bm.bmHeight; } else { CloseClipboard (); return; } GetCursorPos (&ptCursor); ScreenToClient (hwndMain, &ptCursor); rcSelection.left = ptCursor.x; rcSelection.top = ptCursor.y; rcSelection.right = ptCursor.x + (int)lWidth; rcSelection.bottom = ptCursor.y + (int)lHeight; bDrawSelection = TRUE; bPasting = TRUE; DrawSelectionBox (); SetCapture (hwndMain); } else { if (IsClipboardFormatAvailable (CF_DIB)) { hDIB = GetClipboardData (CF_DIB); pBih = (LPBITMAPINFOHEADER)GlobalLock (hDIB); lpDIBNew = CopyDIB (pBih); GlobalUnlock (hDIB); } else if (IsClipboardFormatAvailable (CF_BITMAP)) { hBitmap = GetClipboardData (CF_BITMAP); hPalTemp = GetClipboardData (CF_PALETTE); lpDIBNew = DDBToDIB (hBitmap, hPalTemp); } else { CloseClipboard (); return; } ProcessNewDIB (lpDIBNew); } CloseClipboard (); } } /************************************************************************* Function: HandleCopying () Purpose: Process the clipdoard copy Returns: none *************************************************************************/ static void HandleCopying (WPARAM wParam, LPARAM lParam) { LPVOID lpDIBTemp, lpDIB; DWORD dwSize; HANDLE hDIB; if (lpDIB1) { if (OpenClipboard (hwndMain)) { if (bDrawSelection) { EraseSelectionBox (); bDrawSelection = FALSE; lpDIBTemp = ClipDIB (lpDIB1, rcSelection.left, rcSelection.top, rcSelection.right - rcSelection.left + 1, rcSelection.bottom - rcSelection.top + 1); } else lpDIBTemp = lpDIB1; if (lpDIBTemp) { dwSize = GetDIBSize (lpDIBTemp); hDIB = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, dwSize); lpDIB = GlobalLock (hDIB); if (lpDIB) { copymem (lpDIB, lpDIBTemp, dwSize); GlobalUnlock (hDIB); EmptyClipboard (); SetClipboardData (CF_DIB, hDIB); } if (bDrawSelection) DIBFree (lpDIBTemp); } CloseClipboard (); } } } /************************************************************************* Function: HandleZoomin () Purpose: Process the zoomin procedure Returns: none *************************************************************************/ static void HandleZoomin (WPARAM wParam, LPARAM lParam) { LPVOID lpDIBTemp, lpDIBNew; if (lpDIB1 && bDrawSelection) { SetCursor (LoadCursor (NULL, IDC_WAIT)); EraseSelectionBox (); bDrawSelection = FALSE; lpDIBTemp = ClipDIB (lpDIB1, rcSelection.left, rcSelection.top, rcSelection.right - rcSelection.left + 1, rcSelection.bottom - rcSelection.top + 1); if (lpDIBTemp) { lpDIBNew = ZoomDIB (lpDIBTemp, 500, 500); DIBFree (lpDIBTemp); if (lpDIBNew) ProcessNewDIB (lpDIBNew); } SetCursor (LoadCursor (NULL, IDC_ARROW)); } } /************************************************************************* Function: DrawSelectionBox () Purpose: Draw the selection Returns: none *************************************************************************/ static void DrawSelectionBox (void) { HDC hDC; UpdateWindow (hwndMain); hDC = GetDC (hwndMain); if (hDC) { SetROP2 (hDC, R2_XORPEN); SelectObject (hDC, GetStockObject (WHITE_PEN)); SelectObject (hDC, GetStockObject (HOLLOW_BRUSH)); Rectangle (hDC, rcSelection.left, rcSelection.top, rcSelection.right, rcSelection.bottom); ReleaseDC (hwndMain, hDC); } } /************************************************************************* Function: EraseSelectionBox () Purpose: Erase the selection Returns: none *************************************************************************/ static void EraseSelectionBox (void) { if (bDrawSelection) DrawSelectionBox (); } /************************************************************************* Function: ProcessNewDIB () Purpose: Set up to display a newly loaded/created DIB Returns: none *************************************************************************/ static void ProcessNewDIB (LPVOID lpDIBNew) { if (lpDIBNew && lpDIBNew != lpDIB1) { if (lpDIBDisplay && lpDIBDisplay != lpDIB1) DIBFree (lpDIBDisplay); if (lpDIB2) DIBFree (lpDIB2); lpDIB2 = lpDIB1; lpDIB1 = lpDIBNew; if (hPalette) { DeleteObject (hPalette); hPalette = NULL; } lpDIBDisplay = CreateDisplayDIB (hwndMain, &lpDIB1, &hPalette); if (lpDIBDisplay) ResizeWindowToDIB (hwndMain, lpDIBDisplay); } } /************************************************************************* Function: HandlePaintingAndUpdates () Purpose: Process image painting and palette management Returns: none *************************************************************************/ static LRESULT HandlePaintingAndUpdates (UINT message, WPARAM wParam, LPARAM lParam) { RECT rcClient; HPALETTE hPalOld; HDC hDC; int iCount, iXPos, iYPos, iYStart; PAINTSTRUCT PaintStruct; HPSTR hpBits; LPBITMAPINFO pBitmapInfo; switch (message) { case WM_QUERYNEWPALETTE: /* * If palette realization causes a palette change, * we need to do a full redraw. */ if (hPalette && wParam != (UINT)hwndMain) { hDC = GetDC (hwndMain); hPalOld = SelectPalette (hDC, hPalette, FALSE); iCount = RealizePalette (hDC); InvalidateRect (hwndMain, (LPRECT) (NULL), FALSE); UpdateWindow (hwndMain); SelectPalette (hDC, hPalOld, 0); ReleaseDC (hwndMain, hDC); return TRUE; } break; case WM_PALETTECHANGED: if (hPalette && wParam != (UINT)hwndMain) InvalidateRect (hwndMain, (LPRECT) (NULL), FALSE); break; case WM_PAINT: hDC = BeginPaint (hwndMain, &PaintStruct); if (lpDIBDisplay) { if (hPalette) { hPalOld = SelectPalette (hDC, hPalette, FALSE); RealizePalette (hDC); } GetClientRect (hwndMain, &rcClient); iXPos = GetScrollPos (hwndMain, SB_HORZ); iYPos = GetScrollPos (hwndMain, SB_VERT); pBitmapInfo = (LPBITMAPINFO) lpDIBDisplay; #ifdef USE_WING if (hWinGInst && hbmpWinG) { fpWinGStretchBlt (hDC, 0, 0, rcClient.right, rcClient.bottom, hdcWinG, iXPos, iYPos, rcClient.right, rcClient.bottom); } else #endif { iYStart = (int)pBitmapInfo->bmiHeader.biHeight - rcClient.bottom - iYPos; hpBits = (HPSTR)&pBitmapInfo->bmiColors[pBitmapInfo->bmiHeader.biClrUsed]; StretchDIBits (hDC, 0, 0, rcClient.right, rcClient.bottom, iXPos, iYStart, rcClient.right, rcClient.bottom, hpBits, pBitmapInfo, DIB_RGB_COLORS, SRCCOPY); } if (hPalette) SelectPalette (hDC, hPalOld, FALSE); } if (bDrawSelection) DrawSelectionBox (); EndPaint (hwndMain, &PaintStruct); break; } return (0); } #ifdef USE_WING /************************************************************************* Function: InitializeWinG () Purpose: Initializes WinG Returns: none *************************************************************************/ static void InitializeWinG () { fpWinGCreateDC = (WINGCREATEDC) GetProcAddress (hWinGInst, "WinGCreateDC"); fpWinGCreateBitmap = (WINGCREATEBITMAP) GetProcAddress (hWinGInst, "WinGCreateBitmap"); fpWinGStretchBlt = (WINGSTRETCHBLT) GetProcAddress (hWinGInst, "WinGStretchBlt"); hdcWinG = fpWinGCreateDC (); } /************************************************************************* Function: UpdateWinGBitmap () Purpose: Updates WinG bitmap used to draw DIBs Returns: none *************************************************************************/ static void UpdateWinGBitmap (LPVOID lpDIB) { LPBITMAPINFO pBiDIB = (LPBITMAPINFO) lpDIB; HPALETTE hpalTemp, hpalOld; HPSTR hpBits; if (hbmpWinG) { SelectObject (hdcWinG, hbmpWinGOld); DeleteObject (hbmpWinG); } /* * Create a new bitmap and put it in WinG DC for quick repaints. WinG * deals with 8-bit-per-pixel bitmaps only. */ hbmpWinG = fpWinGCreateBitmap (hdcWinG, pBiDIB, NULL); if (hbmpWinG) { hbmpWinGOld = SelectObject (hdcWinG, hbmpWinG); hpalTemp = CreateDIBPalette (lpDIB); hpalOld = SelectPalette (hdcWinG, hpalTemp, FALSE); RealizePalette (hdcWinG); hpBits = (HPSTR)&pBiDIB->bmiColors[pBiDIB->bmiHeader.biClrUsed]; StretchDIBits (hdcWinG, 0, 0, (int)pBiDIB->bmiHeader.biWidth, (int)pBiDIB->bmiHeader.biHeight, 0, 0, (int)pBiDIB->bmiHeader.biWidth, (int)pBiDIB->bmiHeader.biHeight, hpBits, pBiDIB, DIB_RGB_COLORS, SRCCOPY); SelectPalette (hdcWinG, hpalOld, FALSE); DeleteObject (hpalTemp); } } #endif