home *** CD-ROM | disk | FTP | other *** search
/ On Hand / On_Hand_From_Softbank_1994_Release_2_Disc_2_1994.iso / 00202 / s / disk3 / pictblt.c_ / pictblt.bin
Text File  |  1993-04-28  |  6KB  |  195 lines

  1. //---------------------------------------------------------------------------
  2. //        Copyright (C) 1992-93, Microsoft Corporation
  3. //
  4. // You have a royalty-free right to use, modify, reproduce and distribute
  5. // the Sample Custom Control Files (and/or any modified version) in any way
  6. // you find useful, provided that you agree that Microsoft has no warranty,
  7. // obligation or liability for any Custom Control File.
  8. //---------------------------------------------------------------------------
  9. // PictBlt.c
  10. //---------------------------------------------------------------------------
  11. // This file contains routines that are needed to support custom controls
  12. // that display palette bitmaps to print correctly.  The routime
  13. // PictStretchBlt is a substitute to the Windows API StretchBlt and BitBlt.
  14. // Those Windows routines do now correctly trasfer the color information
  15. // to the destination device context when the destination device context
  16. // is a memory device context. To get around this limitation, PictStretchBlt
  17. // calls GetDIBits and StretchDIBits.
  18. //
  19. // To print forms, VB forces the form and all the controls on the form
  20. // to paint themselves to a memory device context, that contains a bitmap
  21. // that will eventually get printed.
  22. //---------------------------------------------------------------------------
  23. #include <windows.h>
  24. #include "pictblt.h"
  25.  
  26.  
  27. //---------------------------------------------------------------------------
  28. // Helpful Macros
  29. //---------------------------------------------------------------------------
  30. #define WIDTHBYTES(i)    ((i+31)/32*4)       /* ULONG aligned ! */
  31.  
  32.  
  33. //---------------------------------------------------------------------------
  34. // Returns the windows stock bitmap.  Once the stock bitmap has been
  35. // obtained, it is stored in a static for future reference.
  36. // Assumes that CreateCompatibleDC and CreateBitmap will not fail.
  37. //---------------------------------------------------------------------------
  38. HBITMAP PicthbmpStock
  39. (
  40.     VOID
  41. )
  42. {
  43.     static HBITMAP hbmpStock = NULL;
  44.  
  45.     if (!hbmpStock)
  46.     {
  47.     HBITMAP hbmpTmp;
  48.     HDC    hdcMem;
  49.  
  50.     hdcMem = CreateCompatibleDC(NULL);
  51.     hbmpTmp = CreateBitmap(1,1,1,1, NULL);
  52.  
  53.     // Select the temporary bitmap into the memory DC to get access to
  54.     // Windows stock object.
  55.     hbmpStock = SelectObject(hdcMem, hbmpTmp);
  56.  
  57.     SelectObject(hdcMem, hbmpStock);
  58.     DeleteObject(hbmpTmp);
  59.     DeleteDC(hdcMem);
  60.     }
  61.  
  62.     return hbmpStock;
  63. }
  64.  
  65.  
  66. //---------------------------------------------------------------------------
  67. // Given an hdc, determine if the hdc is a memory hdc or a screen hdc.
  68. // Return TRUE iff the hdc is a Memory hdc.
  69. //---------------------------------------------------------------------------
  70. BOOL PictFMemDC
  71. (
  72.     HDC hdc
  73. )
  74. {
  75.     HBITMAP hbmpSave;
  76.  
  77.     hbmpSave = SelectObject(hdc, PicthbmpStock());
  78.     if (hbmpSave)
  79.     {
  80.     SelectObject(hdc, hbmpSave);
  81.     return TRUE;
  82.     }
  83.     return FALSE;
  84. }
  85.  
  86.  
  87. //---------------------------------------------------------------------------
  88. // This is a replacement to StretchBlt.  StretchBlt does not work correctly
  89. // with palettes when the destination hdc is a memory device context.  In that case,
  90. // StretchBlt seems to copy the pixel values from the source to the
  91. // destination without taking the palette of the device context into account.  To
  92. // get around this problem, we need to call GetDIBits and StretchDIBits.
  93. //
  94. // If this routine detects that the destination hdc is not a memory device context, then
  95. // it calls StretchBlt directly.
  96. //
  97. // Return TRUE if bitmap is drawn
  98. //---------------------------------------------------------------------------
  99. BOOL PictStretchBlt
  100. (
  101.     HDC   hdcDest,
  102.     int   x,
  103.     int   y,
  104.     int   cx,
  105.     int   cy,
  106.     HDC   hdcSrc,
  107.     int   xSrc,
  108.     int   ySrc,
  109.     int   cxSrc,
  110.     int   cySrc,
  111.     DWORD dwRop
  112. )
  113. {
  114.     if (PictFMemDC(hdcDest))
  115.     {
  116.     HBITMAP hBitmap;
  117.     LONG    lcbBits;
  118.     HANDLE    hdib;
  119.     HANDLE    hBits;
  120.     LPSTR    lpBits;
  121.     BITMAP    bm;
  122.     BITMAPINFOHEADER FAR *lpbi;
  123.     BOOL    fRet = FALSE;
  124.  
  125.     // Get the source bitmap out of the source hdc
  126.     hBitmap = SelectObject(hdcSrc, PicthbmpStock());
  127.  
  128.     GetObject(hBitmap,sizeof(bm),(LPSTR)&bm);
  129.  
  130.     hdib = GlobalAlloc(GHND,(DWORD)(sizeof(BITMAPINFOHEADER) + 256L*sizeof(RGBQUAD)));
  131.     if (!hdib)
  132.         goto q1;
  133.  
  134.     lpbi = (VOID FAR *)GlobalLock(hdib);
  135.  
  136.     lpbi->biSize          = sizeof(BITMAPINFOHEADER);
  137.     lpbi->biWidth          = bm.bmWidth;
  138.     lpbi->biHeight          = bm.bmHeight;
  139.     lpbi->biPlanes          = 1;
  140.     lpbi->biBitCount      = bm.bmPlanes * bm.bmBitsPixel;
  141.     lpbi->biCompression   = BI_RGB;
  142.     lpbi->biSizeImage     = 0;
  143.     lpbi->biXPelsPerMeter = 0;
  144.     lpbi->biYPelsPerMeter = 0;
  145.     lpbi->biClrUsed       = 0;
  146.     lpbi->biClrImportant  = 0;
  147.  
  148.     // Allocate memory and fetch the DIB image so we can use
  149.     // StretchDIBits rather than StretchBlt, for better quality
  150.     lcbBits = WIDTHBYTES((LONG)lpbi->biBitCount * (LONG)bm.bmWidth)
  151.           * (LONG)bm.bmHeight;
  152.  
  153.     hBits = GlobalAlloc(GMEM_MOVEABLE, lcbBits);
  154.     if (!hBits)
  155.         goto q2;
  156.  
  157.     lpBits = (LPSTR)GlobalLock(hBits);
  158.  
  159.     GetDIBits(hdcSrc, hBitmap, 0, bm.bmHeight, lpBits,
  160.         (LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
  161.  
  162.     // StretchDIBits works from the bottom and goes up, as a result the
  163.     // source Y location is relative the bottom of the bitmap, not the top.
  164.     fRet = (0 != StretchDIBits(
  165.             hdcDest, x, y, cx, cy,
  166.             xSrc, bm.bmHeight - (ySrc + cySrc), cxSrc, cySrc,
  167.             lpBits, (LPBITMAPINFO)lpbi, DIB_RGB_COLORS,
  168.             dwRop));
  169.  
  170.     // Release the DIB bits
  171.     GlobalUnlock(hBits);
  172.     GlobalFree(hBits);
  173. q2:
  174.     GlobalUnlock(hdib);
  175.     GlobalFree(hdib);
  176.  
  177. q1:
  178.     // Put bitmap back into the source hdc
  179.     SelectObject(hdcSrc, hBitmap);
  180.  
  181.     return fRet;
  182.     }
  183.     else
  184.     {
  185.     // Destination is not a Mem DC, safe to call StretchBlt.
  186.     // *** NOTE ****
  187.     // Note that Windows will map StretchBlt onto BilBlt, if
  188.     // cx == cxSrc && cy == cySrc.
  189.     return StretchBlt(hdcDest, x, y, cx, cy, hdcSrc, xSrc, ySrc,
  190.               cxSrc, cySrc, dwRop);
  191.     }
  192. }
  193.  
  194. //---------------------------------------------------------------------------
  195.