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