|
|
1.1.1.4 ! root 1: ! 2: /******************************************************************************\ ! 3: * This is a part of the Microsoft Source Code Samples. ! 4: * Copyright (C) 1993 Microsoft Corporation. ! 5: * All rights reserved. ! 6: * This source code is only intended as a supplement to ! 7: * Microsoft Development Tools and/or WinHelp documentation. ! 8: * See these sources for detailed information regarding the ! 9: * Microsoft samples programs. ! 10: \******************************************************************************/ ! 11: 1.1 root 12: /******************************************************************************* 1.1.1.4 ! root 13: * * ! 14: * PROGRAM : ShowDIB.c * ! 15: * * ! 16: * PURPOSE : Application to illustrate the use of the GDI * ! 17: * DIB (Device Independent Bitmap) and Palette manager * ! 18: * functions. * ! 19: * * ! 20: * FUNCTIONS : WinMain () - Creates the app. window and enters * ! 21: * the message loop. * ! 22: * * ! 23: * WndProc() - Processes app. window messages. * ! 24: * * ! 25: * MenuCommand() - Processes menu commands. * ! 26: * * ! 27: * FreeDIB() - Frees currently active objects. * ! 28: * * ! 29: * InitDIB() - Reads DIB from a file and loads it.* ! 30: * * 1.1 root 31: *******************************************************************************/ 32: 33: #include <windows.h> 34: #include <io.h> 35: #include <stdio.h> 36: #include "showdib.h" 37: #include <commdlg.h> 38: 1.1.1.4 ! root 39: DIBPARAMS DIBParams; /* params for the SETSCALING escape */ ! 40: CHAR achFileName[128]; 1.1 root 41: DWORD dwOffset; 42: NPLOGPALETTE pLogPal; 43: HPALETTE hpalSave = NULL; 1.1.1.4 ! root 44: HANDLE hInst ; ! 45: RECT rcClip; ! 46: static HCURSOR hcurSave; ! 47: ! 48: BOOL fPalColors = FALSE; /* TRUE if the current DIB's color table */ ! 49: /* contains palette indexes not rgb values */ ! 50: UINT nAnimating = 0; /* Palette animation count */ ! 51: WORD UpdateCount = 0; ! 52: ! 53: BOOL bUpdateColors = TRUE; /* Directly update screen colors */ ! 54: BOOL bDIBToDevice = FALSE; /* Use SetDIBitsToDevice() to BLT data. */ ! 55: BOOL bNoUgly = FALSE; /* Make window black on a WM_PALETTEISCHANGING */ ! 56: BOOL bLegitDraw = FALSE; /* We have a valid bitmap to draw */ ! 57: ! 58: CHAR szBitmapExt[] = "*.BMP; *.DIB; *.RLE"; /* possible file extensions */ ! 59: WORD wTransparent = TRANSPARENT; /* Mode of DC */ ! 60: CHAR szAppName[] = "ShowDIB" ; /* App. name */ ! 61: ! 62: HPALETTE hpalCurrent = NULL; /* Handle to current palette */ ! 63: HANDLE hdibCurrent = NULL; /* Handle to current memory DIB */ ! 64: HBITMAP hbmCurrent = NULL; /* Handle to current memory BITMAP */ ! 65: HANDLE hbiCurrent = NULL; /* Handle to current bitmap info struct */ ! 66: HWND hWndApp; /* Handle to app. window */ 1.1 root 67: 68: /* Styles of app. window */ 1.1.1.4 ! root 69: DWORD dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | ! 70: WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME; 1.1 root 71: 72: VOID PrintDIB (HWND hWnd, HDC hDC, INT x, INT y, INT dx, INT dy); 73: /**************************************************************************** 1.1.1.4 ! root 74: * * ! 75: * FUNCTION : WinMain(HANDLE, HANDLE, LPSTR, int) * ! 76: * * ! 77: * PURPOSE : Creates the app. window and enters the message loop. * ! 78: * * 1.1 root 79: ****************************************************************************/ 80: int APIENTRY WinMain( 81: HANDLE hInstance, 82: HANDLE hPrevInstance, 83: LPSTR lpCmdLine, 84: int nCmdShow 85: ) 86: { 1.1.1.4 ! root 87: HWND hWnd ; ! 88: WNDCLASS wndclass ; ! 89: MSG msg ; ! 90: int xScreen, yScreen ; ! 91: CHAR ach[40]; 1.1 root 92: 93: hInst = hInstance ; 94: 95: /* Initialize clip rectangle */ 96: SetRectEmpty(&rcClip); 97: 98: if (!hPrevInstance) { 1.1.1.4 ! root 99: wndclass.style = CS_DBLCLKS; ! 100: wndclass.lpfnWndProc = (WNDPROC) WndProc ; ! 101: wndclass.cbClsExtra = 0 ; ! 102: wndclass.cbWndExtra = 0 ; ! 103: wndclass.hInstance = hInstance ; ! 104: wndclass.hIcon = LoadIcon(hInst, "SHOWICON"); ! 105: wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; ! 106: wndclass.hbrBackground = GetStockObject (BLACK_BRUSH) ; ! 107: wndclass.lpszMenuName = szAppName ; ! 108: wndclass.lpszClassName = szAppName ; 1.1 root 109: 1.1.1.4 ! root 110: if (!RegisterClass (&wndclass)) ! 111: return FALSE ; 1.1 root 112: } 113: 114: if (!GetProfileString("extensions", "bmp", "", ach, sizeof(ach))) 1.1.1.4 ! root 115: WriteProfileString("extensions", "bmp", "showdib.exe ^.bmp"); 1.1 root 116: if (!GetProfileString("extensions", "dib", "", ach, sizeof(ach))) 1.1.1.4 ! root 117: WriteProfileString("extensions", "dib", "showdib.exe ^.dib"); 1.1 root 118: 119: /* Save the pointer to the command line */ 120: lstrcpy(achFileName, lpCmdLine); 121: 122: xScreen = GetSystemMetrics (SM_CXSCREEN) ; 123: yScreen = GetSystemMetrics (SM_CYSCREEN) ; 124: 125: /* Create the app. window */ 126: hWnd = CreateWindow( szAppName, 1.1.1.4 ! root 127: szAppName, ! 128: dwStyle, ! 129: CW_USEDEFAULT, ! 130: 0, ! 131: xScreen / 2, ! 132: yScreen / 2, ! 133: NULL, ! 134: NULL, ! 135: hInstance, ! 136: NULL) ; 1.1 root 137: 138: ShowWindow (hWndApp = hWnd, nCmdShow) ; 139: 140: /* Enter message loop */ 141: while (GetMessage (&msg, NULL, 0, 0)) { 1.1.1.4 ! root 142: TranslateMessage (&msg) ; ! 143: DispatchMessage (&msg) ; 1.1 root 144: } 145: 146: return msg.wParam ; 147: } 148: 149: /**************************************************************************** 1.1.1.4 ! root 150: * * ! 151: * FUNCTION : WndProc (hWnd, iMessage, wParam, lParam) * ! 152: * * ! 153: * PURPOSE : Processes window messages. * ! 154: * * 1.1 root 155: ****************************************************************************/ 1.1.1.4 ! root 156: LONG APIENTRY WndProc ( 1.1 root 157: HWND hWnd , 158: UINT iMessage , 159: UINT wParam , 160: LONG lParam ) 161: 162: { 163: PAINTSTRUCT ps; 1.1.1.4 ! root 164: HDC hDC; ! 165: HANDLE h; ! 166: INT i; ! 167: INT iMax; ! 168: INT iMin; ! 169: INT iPos; ! 170: INT dn; ! 171: RECT rc,Rect; ! 172: HPALETTE hOldPal; ! 173: HMENU hMenu; 1.1 root 174: 175: switch (iMessage) { 1.1.1.4 ! root 176: case WM_DESTROY: ! 177: /* Clean up and quit */ ! 178: FreeDib(); ! 179: PostQuitMessage(0); ! 180: break ; ! 181: ! 182: case WM_CREATE: ! 183: /* Allocate space for our logical palette */ ! 184: pLogPal = (NPLOGPALETTE) LocalAlloc( LMEM_FIXED, ! 185: (sizeof(LOGPALETTE) + ! 186: (sizeof(PALETTEENTRY)*(MAXPALETTE)))); 1.1 root 187: if(!pLogPal){ 188: MessageBox(hWnd, "<WM_CREATE> Not enough memory for palette.", NULL, MB_OK | MB_ICONHAND); 1.1.1.4 ! root 189: PostQuitMessage (0) ; 1.1 root 190: break; 191: } 192: 193: // Temporary workaround. lpCmdLine points to exe name, not first parameter 1.1.1.4 ! root 194: /* If DIB initialization fails, quit */ ! 195: // if (achFileName[0] && !InitDIB(hWnd)) ! 196: // PostQuitMessage (3) ; ! 197: ! 198: /* fall through */ ! 199: ! 200: case WM_WININICHANGE: ! 201: ! 202: hMenu = GetMenu(hWnd); ! 203: if ( hDC = GetPrinterDC1() ) { ! 204: EnableMenuItem( hMenu, ! 205: IDM_PRINT, ! 206: (RC_DIBTODEV & ! 207: GetDeviceCaps(hDC, RASTERCAPS)) ? ! 208: MF_ENABLED : ! 209: MF_GRAYED | MF_DISABLED); ! 210: DeleteDC(hDC); ! 211: } ! 212: break; ! 213: ! 214: case WM_PALETTEISCHANGING: ! 215: /* if SHOWDIB was not responsible for palette change and if ! 216: * ok to hide changes, paint app. window black. ! 217: */ ! 218: if (wParam != (UINT)(hWnd && bNoUgly)) { ! 219: GetClientRect(hWnd, &Rect); ! 220: ! 221: hDC = GetDC(hWnd); ! 222: FillRect( hDC, (LPRECT) &Rect, GetStockObject(BLACK_BRUSH)); ! 223: ReleaseDC(hWnd, hDC); ! 224: } ! 225: break; ! 226: ! 227: case WM_ACTIVATE: ! 228: if (!GET_WM_ACTIVATE_STATE(wParam, lParam)) /* app. is being de-activated */ ! 229: break; ! 230: /* If the app. is moving to the foreground, fall through and ! 231: * redraw full client area with the newly realized palette, ! 232: * if the palette has changed. ! 233: */ ! 234: ! 235: case WM_QUERYNEWPALETTE: ! 236: /* If palette realization causes a palette change, ! 237: * we need to do a full redraw. ! 238: */ ! 239: if (bLegitDraw) { ! 240: hDC = GetDC (hWnd); ! 241: hOldPal = SelectPalette (hDC, hpalCurrent, 0); ! 242: ! 243: i = RealizePalette(hDC); ! 244: ! 245: SelectPalette (hDC, hOldPal, 0); ! 246: ReleaseDC (hWnd, hDC); ! 247: ! 248: if (i) { ! 249: InvalidateRect (hWnd, (LPRECT) (NULL), 1); ! 250: UpdateCount = 0; ! 251: return 1; ! 252: } else ! 253: return FALSE; ! 254: } ! 255: else ! 256: return FALSE; ! 257: break; ! 258: ! 259: case WM_PALETTECHANGED: ! 260: /* if SHOWDIB was not responsible for palette change and if ! 261: * palette realization causes a palette change, do a redraw. ! 262: */ ! 263: if ((HWND)wParam != hWnd){ ! 264: if (bLegitDraw){ ! 265: hDC = GetDC (hWnd); ! 266: hOldPal = SelectPalette (hDC, hpalCurrent, 0); ! 267: ! 268: i = RealizePalette (hDC); ! 269: ! 270: if (i){ ! 271: if (bUpdateColors){ ! 272: UpdateColors (hDC); ! 273: UpdateCount++; ! 274: } ! 275: else ! 276: InvalidateRect (hWnd, (LPRECT) (NULL), 1); ! 277: } ! 278: ! 279: SelectPalette (hDC, hOldPal, 0); ! 280: ReleaseDC (hWnd, hDC); ! 281: } ! 282: } ! 283: break; ! 284: ! 285: case WM_RENDERALLFORMATS: ! 286: /* Ensure that clipboard data can be rendered even tho' ! 287: * app. is being destroyed. ! 288: */ ! 289: SendMessage(hWnd,WM_RENDERFORMAT,CF_DIB,0L); ! 290: SendMessage(hWnd,WM_RENDERFORMAT,CF_BITMAP,0L); ! 291: SendMessage(hWnd,WM_RENDERFORMAT,CF_PALETTE,0L); ! 292: break; ! 293: ! 294: case WM_RENDERFORMAT: ! 295: /* Format data in manner specified and pass the data ! 296: * handle to clipboard. ! 297: */ ! 298: if (h = RenderFormat(wParam)) ! 299: SetClipboardData((WORD)wParam,h); ! 300: break; 1.1 root 301: 302: case WM_COMMAND: 1.1.1.4 ! root 303: /* Process menu commands */ ! 304: return MenuCommand(hWnd, LOWORD(wParam)); ! 305: break; ! 306: ! 307: case WM_TIMER: ! 308: /* Signal for palette animation */ ! 309: hDC = GetDC(hWnd); ! 310: hOldPal = SelectPalette(hDC, hpalCurrent, 0); ! 311: { ! 312: PALETTEENTRY peTemp; ! 313: ! 314: /* Shift all palette entries left by one position and wrap ! 315: * around the first entry ! 316: */ ! 317: peTemp = pLogPal->palPalEntry[0]; ! 318: for (i = 0; i < (pLogPal->palNumEntries - 1); i++) ! 319: pLogPal->palPalEntry[i] = pLogPal->palPalEntry[i+1]; ! 320: pLogPal->palPalEntry[i] = peTemp; ! 321: } ! 322: /* Replace entries in logical palette with new entries*/ ! 323: AnimatePalette(hpalCurrent, 0, pLogPal->palNumEntries, pLogPal->palPalEntry); ! 324: ! 325: SelectPalette(hDC, hOldPal, 0); ! 326: ReleaseDC(hWnd, hDC); ! 327: ! 328: /* Decrement animation count and terminate animation ! 329: * if it reaches zero ! 330: */ ! 331: if (!(--nAnimating)) ! 332: PostMessage(hWnd,WM_COMMAND,IDM_ANIMATE0,0L); ! 333: break; ! 334: ! 335: case WM_PAINT: ! 336: /* If we have updated more than once, the rest of our ! 337: * window is not in some level of degradation worse than ! 338: * our redraw... we need to redraw the whole area ! 339: */ ! 340: if (UpdateCount > 1) { ! 341: BeginPaint(hWnd, &ps); ! 342: EndPaint(hWnd, &ps); ! 343: UpdateCount = 0; ! 344: InvalidateRect(hWnd, (LPRECT) (NULL), 1); ! 345: break; ! 346: } ! 347: ! 348: hDC = BeginPaint(hWnd, &ps); ! 349: AppPaint(hWnd, ! 350: hDC, ! 351: GetScrollPos(hWnd,SB_HORZ), ! 352: GetScrollPos(hWnd,SB_VERT) ); ! 353: EndPaint(hWnd, &ps); ! 354: break ; ! 355: ! 356: case WM_SIZE: ! 357: SetScrollRanges(hWnd); ! 358: break; ! 359: ! 360: case WM_KEYDOWN: ! 361: /* Translate keyboard messages to scroll commands */ ! 362: switch (wParam) { ! 363: case VK_UP: ! 364: PostMessage (hWnd, WM_VSCROLL, SB_LINEUP, 0L); ! 365: break; ! 366: ! 367: case VK_DOWN: ! 368: PostMessage (hWnd, WM_VSCROLL, SB_LINEDOWN, 0L); ! 369: break; ! 370: ! 371: case VK_PRIOR: ! 372: PostMessage (hWnd, WM_VSCROLL, SB_PAGEUP, 0L); ! 373: break; ! 374: ! 375: case VK_NEXT: ! 376: PostMessage (hWnd, WM_VSCROLL, SB_PAGEDOWN, 0L); ! 377: break; ! 378: ! 379: case VK_HOME: ! 380: PostMessage (hWnd, WM_HSCROLL, SB_PAGEUP, 0L); ! 381: break; ! 382: ! 383: case VK_END: ! 384: PostMessage (hWnd, WM_HSCROLL, SB_PAGEDOWN, 0L); ! 385: break; ! 386: ! 387: case VK_LEFT: ! 388: PostMessage (hWnd, WM_HSCROLL, SB_LINEUP, 0L); ! 389: break; ! 390: ! 391: case VK_RIGHT: ! 392: PostMessage (hWnd, WM_HSCROLL, SB_LINEDOWN, 0L); ! 393: break; ! 394: } ! 395: break; ! 396: ! 397: case WM_KEYUP: ! 398: switch (wParam) { ! 399: case VK_UP: ! 400: case VK_DOWN: ! 401: case VK_PRIOR: ! 402: case VK_NEXT: ! 403: PostMessage (hWnd, WM_VSCROLL, SB_ENDSCROLL, 0L); ! 404: break; ! 405: ! 406: case VK_HOME: ! 407: case VK_END: ! 408: case VK_LEFT: ! 409: case VK_RIGHT: ! 410: PostMessage (hWnd, WM_HSCROLL, SB_ENDSCROLL, 0L); ! 411: break; ! 412: } ! 413: break; ! 414: ! 415: case WM_VSCROLL: ! 416: /* Calculate new vertical scroll position */ ! 417: GetScrollRange (hWnd, SB_VERT, &iMin, &iMax); ! 418: iPos = GetScrollPos (hWnd, SB_VERT); ! 419: GetClientRect (hWnd, &rc); ! 420: ! 421: switch (GET_WM_VSCROLL_CODE(wParam, lParam)) { ! 422: case SB_LINEDOWN: ! 423: dn = rc.bottom / 16 + 1; ! 424: break; ! 425: ! 426: case SB_LINEUP: ! 427: dn = -rc.bottom / 16 + 1; ! 428: break; ! 429: ! 430: case SB_PAGEDOWN: ! 431: dn = rc.bottom / 2 + 1; ! 432: break; ! 433: ! 434: case SB_PAGEUP: ! 435: dn = -rc.bottom / 2 + 1; ! 436: break; ! 437: ! 438: case SB_THUMBTRACK: ! 439: case SB_THUMBPOSITION: ! 440: dn = GET_WM_VSCROLL_POS(wParam, lParam)-iPos; ! 441: break; ! 442: ! 443: default: ! 444: dn = 0; ! 445: break; ! 446: } ! 447: /* Limit scrolling to current scroll range */ ! 448: if (dn = BOUND (iPos + dn, iMin, iMax) - iPos) { ! 449: ScrollWindow (hWnd, 0, -dn, NULL, NULL); ! 450: SetScrollPos (hWnd, SB_VERT, iPos + dn, TRUE); ! 451: } ! 452: break; ! 453: ! 454: case WM_HSCROLL: ! 455: /* Calculate new horizontal scroll position */ ! 456: GetScrollRange (hWnd, SB_HORZ, &iMin, &iMax); ! 457: iPos = GetScrollPos (hWnd, SB_HORZ); ! 458: GetClientRect (hWnd, &rc); ! 459: ! 460: switch (GET_WM_HSCROLL_CODE(wParam, lParam)) { ! 461: case SB_LINEDOWN: ! 462: dn = rc.right / 16 + 1; ! 463: break; ! 464: ! 465: case SB_LINEUP: ! 466: dn = -rc.right / 16 + 1; ! 467: break; ! 468: ! 469: case SB_PAGEDOWN: ! 470: dn = rc.right / 2 + 1; ! 471: break; ! 472: ! 473: case SB_PAGEUP: ! 474: dn = -rc.right / 2 + 1; ! 475: break; ! 476: ! 477: case SB_THUMBTRACK: ! 478: case SB_THUMBPOSITION: ! 479: dn = GET_WM_HSCROLL_POS(wParam, lParam)-iPos; ! 480: break; ! 481: ! 482: default: ! 483: dn = 0; ! 484: break; ! 485: } ! 486: /* Limit scrolling to current scroll range */ ! 487: if (dn = BOUND (iPos + dn, iMin, iMax) - iPos) { ! 488: ScrollWindow (hWnd, -dn, 0, NULL, NULL); ! 489: SetScrollPos (hWnd, SB_HORZ, iPos + dn, TRUE); ! 490: } ! 491: break; ! 492: ! 493: case WM_LBUTTONDOWN: ! 494: /* Start rubberbanding a rect. and track it's dimensions. ! 495: * set the clip rectangle to it's dimensions. ! 496: */ ! 497: TrackMouse (hWnd, MAKEMPOINT(lParam)); ! 498: break; ! 499: ! 500: case WM_LBUTTONDBLCLK: ! 501: break; ! 502: ! 503: case WM_INITMENU: ! 504: /* check/uncheck menu items depending on state of related ! 505: * flags ! 506: */ ! 507: ! 508: CheckMenuItem((HMENU)wParam, IDM_UPDATECOL, ! 509: (bUpdateColors ? MF_CHECKED : MF_UNCHECKED)); ! 510: CheckMenuItem((HMENU)wParam, IDM_TRANSPARENT, ! 511: (wTransparent == TRANSPARENT ? MF_CHECKED : MF_UNCHECKED)); ! 512: CheckMenuItem((HMENU)wParam, IDM_DIBSCREEN, ! 513: (bDIBToDevice ? MF_CHECKED : MF_UNCHECKED)); ! 514: CheckMenuItem((HMENU)wParam, IDM_NOUGLY, ! 515: (bNoUgly ? MF_CHECKED : MF_UNCHECKED)); ! 516: CheckMenuItem((HMENU)wParam, IDM_MEMORYDIB, MF_CHECKED); ! 517: EnableMenuItem((HMENU)wParam, IDM_PASTEDIB, ! 518: IsClipboardFormatAvailable(CF_DIB)?MF_ENABLED:MF_GRAYED); ! 519: EnableMenuItem((HMENU)wParam, IDM_PASTEDDB, ! 520: IsClipboardFormatAvailable(CF_BITMAP)?MF_ENABLED:MF_GRAYED); ! 521: EnableMenuItem((HMENU)wParam, IDM_PASTEPAL, ! 522: IsClipboardFormatAvailable(CF_PALETTE)?MF_ENABLED:MF_GRAYED); ! 523: EnableMenuItem((HMENU)wParam, IDM_PRINT, ! 524: bLegitDraw ? MF_ENABLED : MF_GRAYED); ! 525: EnableMenuItem((HMENU)wParam, IDM_SAVE, ! 526: bLegitDraw ? MF_ENABLED : MF_GRAYED); ! 527: EnableMenuItem((HMENU)wParam, IDM_COPY, ! 528: bLegitDraw ? MF_ENABLED : MF_GRAYED); ! 529: ! 530: EnableMenuItem((HMENU)wParam, IDM_ANIMATE0, ! 531: bLegitDraw ? MF_ENABLED : MF_GRAYED); ! 532: EnableMenuItem((HMENU)wParam, IDM_ANIMATE5, ! 533: bLegitDraw ? MF_ENABLED : MF_GRAYED); ! 534: EnableMenuItem((HMENU)wParam, IDM_ANIMATE50, ! 535: bLegitDraw ? MF_ENABLED : MF_GRAYED); ! 536: EnableMenuItem((HMENU)wParam, IDM_ANIMATE100, ! 537: bLegitDraw ? MF_ENABLED : MF_GRAYED); ! 538: EnableMenuItem((HMENU)wParam, IDM_ANIMATE200, ! 539: bLegitDraw ? MF_ENABLED : MF_GRAYED); ! 540: EnableMenuItem((HMENU)wParam, IDM_ANIMATE201, ! 541: bLegitDraw ? MF_ENABLED : MF_GRAYED); ! 542: EnableMenuItem((HMENU)wParam, IDM_STEALCOL, ! 543: bLegitDraw ? MF_ENABLED : MF_GRAYED); ! 544: break; 1.1 root 545: 1.1.1.4 ! root 546: default: ! 547: return DefWindowProc (hWnd, iMessage, wParam, lParam) ; 1.1 root 548: 549: } 550: return 0L ; 551: 552: } 553: /**************************************************************************** 1.1.1.4 ! root 554: * * ! 555: * FUNCTION : MenuCommand ( HWND hWnd, WPARAM wParam) * ! 556: * * ! 557: * PURPOSE : Processes menu commands. * ! 558: * * ! 559: * RETURNS : TRUE - if command could be processed. * ! 560: * FALSE - otherwise * ! 561: * * 1.1 root 562: ****************************************************************************/ 563: BOOL MenuCommand ( 564: HWND hWnd, 565: UINT id) 566: 567: { 568: BITMAPINFOHEADER bi; 1.1.1.4 ! root 569: HDC hDC; ! 570: HANDLE h; ! 571: HBITMAP hbm; ! 572: HPALETTE hpal; ! 573: WORD i; ! 574: CHAR Name[40]; ! 575: BOOL bSave; ! 576: INT xSize, ySize, xRes, yRes, dx, dy; ! 577: RECT Rect; ! 578: HFILE fh; ! 579: WORD fFileOptions; 1.1 root 580: 581: switch (id) { 1.1.1.4 ! root 582: case IDM_ABOUT: ! 583: /* Show About .. box */ ! 584: fDialog ((INT)ABOUTBOX, hWnd,(FARPROC)AppAbout); ! 585: break; ! 586: ! 587: case IDM_COPY: ! 588: if (!bLegitDraw) ! 589: return 0L; ! 590: ! 591: /* Clean clipboard of contents */ ! 592: if (OpenClipboard(hWnd)) { ! 593: EmptyClipboard (); ! 594: SetClipboardData (CF_DIB ,NULL); ! 595: SetClipboardData (CF_BITMAP ,NULL); ! 596: SetClipboardData (CF_PALETTE ,NULL); ! 597: CloseClipboard (); ! 598: } ! 599: break; ! 600: ! 601: case IDM_PASTEPAL: ! 602: if (OpenClipboard (hWnd)) { ! 603: if (h = GetClipboardData (CF_PALETTE)) { ! 604: /* Delete current palette and get the CF_PALETTE data ! 605: * from the clipboard ! 606: */ ! 607: if (hpalCurrent) ! 608: DeleteObject (hpalCurrent); ! 609: ! 610: hpalCurrent = CopyPalette (h); ! 611: ! 612: /* ! 613: * If we have a bitmap realized against the old palette ! 614: * delete the bitmap and rebuild it using the new palette. ! 615: */ ! 616: if (hbmCurrent){ ! 617: DeleteObject (hbmCurrent); ! 618: hbmCurrent = NULL; ! 619: ! 620: if (hdibCurrent) ! 621: hbmCurrent = BitmapFromDib (hdibCurrent, hpalCurrent); ! 622: } ! 623: } ! 624: CloseClipboard(); ! 625: } ! 626: break; ! 627: ! 628: case IDM_PASTEDIB: ! 629: if (OpenClipboard (hWnd)) { ! 630: if (h = GetClipboardData (CF_DIB)) { ! 631: /* Delete current DIB and get CF_DIB and ! 632: * CF_PALETTE format data from the clipboard ! 633: */ ! 634: hpal = GetClipboardData (CF_PALETTE); ! 635: ! 636: FreeDib(); ! 637: hdibCurrent = CopyHandle (h); ! 638: if (hdibCurrent) { ! 639: bLegitDraw = TRUE; ! 640: lstrcpy(achFileName,"<Clipboard>"); ! 641: hbiCurrent = hdibCurrent; ! 642: ! 643: /* If there is a CF_PALETTE object in the ! 644: * clipboard, this is the palette to assume ! 645: * the DIB should be realized against, otherwise ! 646: * create a palette for it. ! 647: */ ! 648: if (hpal) ! 649: hpalCurrent = CopyPalette (hpal); ! 650: else ! 651: hpalCurrent = CreateDibPalette (hdibCurrent); ! 652: ! 653: SizeWindow(hWnd); ! 654: } ! 655: else { ! 656: bLegitDraw = FALSE; ! 657: ErrMsg("No Memory Available!"); ! 658: } ! 659: } ! 660: CloseClipboard(); ! 661: } ! 662: break; ! 663: ! 664: case IDM_PASTEDDB: ! 665: if (OpenClipboard (hWnd)) { ! 666: if (hbm = GetClipboardData(CF_BITMAP)) { ! 667: hpal = GetClipboardData(CF_PALETTE); ! 668: FreeDib(); ! 669: ! 670: /* ! 671: * If there is a CF_PALETTE object in the ! 672: * clipboard, this is the palette to assume ! 673: * the bitmap is realized against. ! 674: */ ! 675: if (hpal) ! 676: hpalCurrent = CopyPalette(hpal); ! 677: else ! 678: hpalCurrent = GetStockObject(DEFAULT_PALETTE); ! 679: ! 680: hdibCurrent = DibFromBitmap(hbm,BI_RGB,0,hpalCurrent); ! 681: ! 682: if (hdibCurrent) { ! 683: bLegitDraw = TRUE; ! 684: lstrcpy(achFileName,"<Clipboard>"); ! 685: hbiCurrent = hdibCurrent; ! 686: ! 687: hbmCurrent = BitmapFromDib(hdibCurrent,hpalCurrent); ! 688: ! 689: SizeWindow(hWnd); ! 690: } ! 691: else { ! 692: bLegitDraw = FALSE; ! 693: ErrMsg("No Memory Available!"); ! 694: } ! 695: } ! 696: CloseClipboard (); ! 697: } ! 698: break; ! 699: ! 700: case IDM_PRINT: ! 701: GetWindowText(hWnd, Name, sizeof(Name)); ! 702: ! 703: DibInfo(hbiCurrent, &bi); ! 704: ! 705: if (!IsRectEmpty(&rcClip)) ! 706: { ! 707: bi.biWidth = rcClip.right - rcClip.left; ! 708: bi.biHeight = rcClip.bottom - rcClip.top; ! 709: } ! 710: ! 711: /* Initialise printer stuff */ ! 712: if (!(hDC = GetPrinterDC())) ! 713: break; ! 714: ! 715: xSize = GetDeviceCaps(hDC, HORZRES); ! 716: ySize = GetDeviceCaps(hDC, VERTRES); ! 717: xRes = GetDeviceCaps(hDC, LOGPIXELSX); ! 718: yRes = GetDeviceCaps(hDC, LOGPIXELSY); ! 719: ! 720: /* Use half inch margins on left and right ! 721: * and one inch on top. Maintain the same aspect ratio. ! 722: */ ! 723: ! 724: dx = xSize - xRes; ! 725: dy = (INT)((LONG)dx * bi.biHeight/bi.biWidth); ! 726: ! 727: /* Fix bounding rectangle for the picture .. */ ! 728: Rect.top = yRes; ! 729: Rect.left = xRes / 2; ! 730: Rect.bottom = yRes + dy; ! 731: Rect.right = xRes / 2 + dx; ! 732: ! 733: /* ... and inform the driver */ ! 734: Escape(hDC, SET_BOUNDS, sizeof(RECT), (LPSTR)&Rect, NULL); ! 735: ! 736: bSave = TRUE; ! 737: ! 738: // ! 739: // Use new Windows NT printing APIs...Petrus Wong 12-May-1993 ! 740: // ! 741: if (InitPrinting(hDC, hWnd, hInst, Name)) { ! 742: ! 743: StartPage(hDC); ! 744: PrintDIB(hWnd, hDC, xRes/2, yRes, dx, dy); ! 745: ! 746: /* Signal to the driver to begin translating the drawing ! 747: * commands to printer output... ! 748: */ ! 749: EndPage(hDC); ! 750: TermPrinting(hDC); ! 751: } ! 752: ! 753: DeleteDC(hDC); ! 754: break; ! 755: ! 756: case IDM_OPEN: ! 757: { ! 758: ! 759: /* Bring up File/Open ... dialog */ ! 760: fh = DlgOpenFile (hWnd, ! 761: "Select a DIB to display", ! 762: (LONG)OF_EXIST | OF_MUSTEXIST | OF_NOOPTIONS, ! 763: szBitmapExt, ! 764: achFileName, ! 765: NULL ! 766: ); ! 767: /* Load up the DIB if the user did not press cancel */ ! 768: if (fh > 0) { ! 769: StartWait(); ! 770: if (InitDIB (hWnd)) ! 771: InvalidateRect (hWnd, NULL, FALSE); ! 772: else ! 773: bLegitDraw = FALSE; ! 774: EndWait(); ! 775: } ! 776: break; ! 777: } ! 778: case IDM_SAVE: ! 779: DibInfo(hbiCurrent,&bi); ! 780: fFileOptions = 0; ! 781: ! 782: /* Depending on compression type for current DIB, ! 783: * set the appropriate bit in the fFileOptions flag ! 784: */ ! 785: if (bi.biCompression == BI_RGB) ! 786: fFileOptions |= F_RGB; ! 787: else if (bi.biCompression == BI_RLE4) ! 788: fFileOptions |= F_RLE4; ! 789: else if (bi.biCompression == BI_RLE8) ! 790: fFileOptions |= F_RLE8; ! 791: ! 792: /* Depending on bits/pixel type for current DIB, ! 793: * set the appropriate bit in the fFileOptions flag ! 794: */ ! 795: switch (bi.biBitCount){ ! 796: case 1: ! 797: fFileOptions |= F_1BPP; ! 798: break; ! 799: ! 800: case 4: ! 801: fFileOptions |= F_4BPP; ! 802: break; ! 803: ! 804: case 8: ! 805: fFileOptions |= F_8BPP; ! 806: break; ! 807: ! 808: case 24: ! 809: fFileOptions |= F_24BPP; ! 810: } ! 811: ! 812: /* Bring up File/Save... dialog and get info. about filename, ! 813: * compression, and bits/pix. of DIB to be written. ! 814: */ ! 815: fh = DlgOpenFile (hWnd, ! 816: "Select File to save DIB to", ! 817: (LONG)OF_EXIST | OF_SAVE | OF_NOSHOWSPEC, ! 818: szBitmapExt, ! 819: achFileName, ! 820: &fFileOptions); ! 821: ! 822: /* Extract DIB specs. if the user did not press cancel */ ! 823: if (fh != 0){ ! 824: if (fFileOptions & F_RGB) ! 825: bi.biCompression = BI_RGB; ! 826: ! 827: if (fFileOptions & F_RLE4) ! 828: bi.biCompression = BI_RLE4; ! 829: ! 830: if (fFileOptions & F_RLE8) ! 831: bi.biCompression = BI_RLE8; ! 832: ! 833: if (fFileOptions & F_1BPP) ! 834: bi.biBitCount = 1; ! 835: ! 836: if (fFileOptions & F_4BPP) ! 837: bi.biBitCount = 4; ! 838: ! 839: if (fFileOptions & F_8BPP) ! 840: bi.biBitCount = 8; ! 841: ! 842: if (fFileOptions & F_24BPP) ! 843: bi.biBitCount = 24; ! 844: ! 845: /* Realize a DIB in the specified format and obtain a ! 846: * handle to it. ! 847: */ ! 848: hdibCurrent = RealizeDibFormat(bi.biCompression,bi.biBitCount); ! 849: if (!hdibCurrent){ ! 850: ErrMsg("Unable to save the specified file"); ! 851: return 0L; ! 852: } ! 853: ! 854: /* Write the DIB */ ! 855: StartWait(); ! 856: if (!WriteDIB(achFileName,hdibCurrent)) ! 857: ErrMsg("Unable to save the specified file"); ! 858: EndWait(); ! 859: } ! 860: break; ! 861: ! 862: case IDM_EXIT: ! 863: PostMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0L); ! 864: break; ! 865: ! 866: case IDM_UPDATECOL: ! 867: /* Toggle state of "update screen colors" flag. If it is ! 868: * off, clear the "hide changes" flag ! 869: */ ! 870: bUpdateColors = !bUpdateColors; ! 871: if (bUpdateColors) ! 872: bNoUgly = 0; ! 873: break; ! 874: ! 875: case IDM_DIBSCREEN: ! 876: bDIBToDevice = !bDIBToDevice; ! 877: InvalidateRect(hWnd, (LPRECT) (NULL), 1); ! 878: break; ! 879: ! 880: case IDM_MEMORYDIB: ! 881: break; ! 882: ! 883: case IDM_NOUGLY: ! 884: /* Toggle state of "hide changes" flag. If it is off, clear ! 885: * the "update screen colors" flag. This will tell SHOWDIB ! 886: * to paint itself black while the palette is changing. ! 887: */ ! 888: bNoUgly = !bNoUgly; ! 889: if (bNoUgly) ! 890: bUpdateColors = 0; ! 891: break; ! 892: ! 893: case IDM_TRANSPARENT: ! 894: /* Toggle DC mode */ ! 895: wTransparent = (WORD) (wTransparent == TRANSPARENT ? ! 896: OPAQUE : TRANSPARENT); ! 897: break; ! 898: ! 899: case IDM_ANIMATE0: ! 900: if (!hpalSave) ! 901: break; ! 902: ! 903: /* Reset animation count and stop timer */ ! 904: KillTimer(hWnd, 1); ! 905: nAnimating = 0; ! 906: ! 907: /* Restore palette which existed before animation started */ ! 908: DeleteObject(hpalCurrent); ! 909: hpalCurrent = hpalSave; ! 910: ! 911: /* Rebuild bitmap based on newly realized information */ ! 912: hDC = GetDC (hWnd); ! 913: SelectPalette (hDC, hpalCurrent, 0); ! 914: RealizePalette (hDC); ! 915: ReleaseDC (hWnd, hDC); ! 916: ! 917: if (hbmCurrent){ ! 918: DeleteObject (hbmCurrent); ! 919: hbmCurrent = NULL; ! 920: ! 921: if (hdibCurrent) ! 922: hbmCurrent = BitmapFromDib (hdibCurrent, hpalCurrent); ! 923: } ! 924: hpalSave = NULL; ! 925: ! 926: /* Force redraw with new palette for everyone */ ! 927: InvalidateRect(hWnd, NULL, TRUE); ! 928: break; ! 929: ! 930: case IDM_STEALCOL: ! 931: case IDM_ANIMATE5: ! 932: case IDM_ANIMATE20: ! 933: case IDM_ANIMATE50: ! 934: case IDM_ANIMATE100: ! 935: case IDM_ANIMATE200: ! 936: case IDM_ANIMATE201: ! 937: /* Set animation count i.e number of times animation is to ! 938: * take place. ! 939: */ ! 940: nAnimating = id; ! 941: if (id == IDM_STEALCOL) ! 942: nAnimating = 0; ! 943: ! 944: /* Save current palette */ ! 945: hpalSave = CopyPalette(hpalCurrent); ! 946: ! 947: GetObject(hpalCurrent, sizeof(INT), (LPSTR)&pLogPal->palNumEntries); ! 948: GetPaletteEntries(hpalCurrent, 0, pLogPal->palNumEntries, pLogPal->palPalEntry); ! 949: ! 950: /* Reserve all entries in the palette otherwise AnimatePalette() ! 951: * will not modify them ! 952: */ ! 953: for (i = 0; i < pLogPal->palNumEntries; i++) { ! 954: pLogPal->palPalEntry[i].peFlags = (BYTE)PC_RESERVED; ! 955: } ! 956: ! 957: SetPaletteEntries(hpalCurrent, 0, pLogPal->palNumEntries, pLogPal->palPalEntry); ! 958: ! 959: /* Rebuild bitmap based on newly realized information */ ! 960: if (hbmCurrent){ ! 961: DeleteObject (hbmCurrent); ! 962: hbmCurrent = NULL; ! 963: ! 964: if (hdibCurrent) ! 965: hbmCurrent = BitmapFromDib (hdibCurrent, hpalCurrent); ! 966: } ! 967: ! 968: /* Force redraw with new palette for everyone */ ! 969: InvalidateRect(hWnd, NULL, TRUE); ! 970: ! 971: /* Initiate the timer so that palette can be animated in ! 972: * response to a WM_TIMER message ! 973: */ ! 974: if (nAnimating && !SetTimer(hWnd, 1, 250, (TIMERPROC)(LPSTR) NULL)) ! 975: nAnimating = 0; 1.1 root 976: 1.1.1.4 ! root 977: default: ! 978: break; 1.1 root 979: } 980: 981: return TRUE; 982: } 983: 984: /**************************************************************************** 1.1.1.4 ! root 985: * * ! 986: * FUNCTION : InitDIB(hWnd) * ! 987: * * 1.1 root 988: * PURPOSE : Reads a DIB from a file, obtains a handle to it's * 1.1.1.4 ! root 989: * BITMAPINFO struct., sets up the palette and loads the DIB. * ! 990: * * ! 991: * RETURNS : TRUE - DIB loads ok * ! 992: * FALSE - otherwise * ! 993: * * 1.1 root 994: ****************************************************************************/ 995: INT InitDIB(HWND hWnd) 996: { 1.1.1.4 ! root 997: HFILE fh; 1.1 root 998: LPBITMAPINFOHEADER lpbi; 1.1.1.4 ! root 999: WORD FAR * pw; ! 1000: INT i; 1.1 root 1001: BITMAPINFOHEADER bi; 1.1.1.4 ! root 1002: OFSTRUCT of; 1.1 root 1003: 1004: FreeDib(); 1005: 1006: /* Open the file and get a handle to it's BITMAPINFO */ 1007: 1008: fh = OpenFile(achFileName, (LPOFSTRUCT)&of, (UINT)OF_READ); 1009: if (fh == -1) { 1.1.1.4 ! root 1010: ErrMsg("Can't open file '%ls'", (LPSTR)achFileName); ! 1011: return FALSE; 1.1 root 1012: } 1013: hbiCurrent = ReadDibBitmapInfo(fh); 1014: 1015: dwOffset = _llseek(fh, 0L, (UINT)SEEK_CUR); 1016: _lclose(fh); 1017: 1018: if (hbiCurrent == NULL) { 1.1.1.4 ! root 1019: ErrMsg("%ls is not a Legitimate DIB File!", (LPSTR)achFileName); ! 1020: return FALSE; 1.1 root 1021: } 1022: DibInfo(hbiCurrent,&bi); 1023: 1024: /* Set up the palette */ 1025: hpalCurrent = CreateDibPalette(hbiCurrent); 1026: if (hpalCurrent == NULL) { 1.1.1.4 ! root 1027: ErrMsg("CreatePalette() Failed"); ! 1028: return FALSE; 1.1 root 1029: } 1030: 1.1.1.4 ! root 1031: /* Convert the DIB color table to palette relative indexes, so ! 1032: * SetDIBits() and SetDIBitsToDevice() can avoid color matching. ! 1033: * We can do this because the palette we realize is identical ! 1034: * to the color table of the bitmap, ie the indexes match 1 to 1 1.1 root 1035: * 1.1.1.4 ! root 1036: * Now that the DIB color table is palette indexes not RGB values ! 1037: * we must use DIB_PAL_COLORS as the wUsage parameter to SetDIBits() 1.1 root 1038: */ 1039: lpbi = (VOID FAR *)GlobalLock(hbiCurrent); 1040: if (lpbi->biBitCount != 24) { 1.1.1.4 ! root 1041: fPalColors = TRUE; 1.1 root 1042: 1.1.1.4 ! root 1043: pw = (WORD FAR *)((LPSTR)lpbi + lpbi->biSize); 1.1 root 1044: 1.1.1.4 ! root 1045: for (i=0; i<(INT)lpbi->biClrUsed; i++) ! 1046: *pw++ = (WORD)i; 1.1 root 1047: } 1048: GlobalUnlock(hbiCurrent); 1049: bLegitDraw = TRUE; 1050: 1.1.1.4 ! root 1051: /* If the input bitmap is not in RGB FORMAT the banding code will ! 1052: * not work! we need to load the DIB bits into memory. ! 1053: * if memory DIB, load it all NOW! This will avoid calling the ! 1054: * banding code. 1.1 root 1055: */ 1056: hdibCurrent = OpenDIB(achFileName); 1057: 1.1.1.4 ! root 1058: /* If the RLE could not be loaded all at once, exit gracefully NOW, ! 1059: * to avoid calling the banding code 1.1 root 1060: */ 1061: if ((bi.biCompression != BI_RGB) && !hdibCurrent){ 1.1.1.4 ! root 1062: ErrMsg ("Could not load RLE!"); ! 1063: FreeDib(); ! 1064: return FALSE; 1.1 root 1065: } 1066: 1067: if (hdibCurrent && !bDIBToDevice){ 1.1.1.4 ! root 1068: hbmCurrent = BitmapFromDib(hdibCurrent,hpalCurrent); ! 1069: if (!hbmCurrent){ ! 1070: ErrMsg ("Could not create bitmap!"); ! 1071: FreeDib(); ! 1072: return FALSE; ! 1073: } 1.1 root 1074: } 1075: 1076: SizeWindow(hWnd); 1077: 1078: return TRUE; 1079: } 1080: /**************************************************************************** 1.1.1.4 ! root 1081: * * ! 1082: * FUNCTION : FreeDib(void) * ! 1083: * * 1.1 root 1084: * PURPOSE : Frees all currently active bitmap, DIB and palette objects * 1.1.1.4 ! root 1085: * and initializes their handles. * ! 1086: * * 1.1 root 1087: ****************************************************************************/ 1088: VOID FreeDib() 1089: { 1090: if (hpalCurrent) 1.1.1.4 ! root 1091: DeleteObject(hpalCurrent); 1.1 root 1092: 1093: if (hbmCurrent) 1.1.1.4 ! root 1094: DeleteObject(hbmCurrent); 1.1 root 1095: 1096: if (hdibCurrent) 1.1.1.4 ! root 1097: GlobalFree(hdibCurrent); 1.1 root 1098: 1099: if (hbiCurrent && hbiCurrent != hdibCurrent) 1.1.1.4 ! root 1100: GlobalFree(hbiCurrent); 1.1 root 1101: 1.1.1.4 ! root 1102: fPalColors = FALSE; ! 1103: bLegitDraw = FALSE; 1.1 root 1104: hpalCurrent = NULL; 1105: hdibCurrent = NULL; 1.1.1.4 ! root 1106: hbmCurrent = NULL; ! 1107: hbiCurrent = NULL; 1.1 root 1108: SetRectEmpty (&rcClip); 1109: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.