home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 17.ddi / SAMPLES / SHOWDIB / SHOWDIB.C_ / SHOWDIB.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  41.5 KB  |  1,114 lines

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