home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / Chapt_11 / AdvBitmap / AdvBitmap.cpp next >
Encoding:
C/C++ Source or Header  |  2000-05-24  |  26.7 KB  |  1,051 lines

  1. //-----------------------------------------------------------------------------------//
  2. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  3. //                             ISBN  0-13-086985-6                                   //
  4. //                                                                                   //
  5. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  6. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  7. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  8. //                                                                                   //
  9. //  FileName   : advbitmap.cpp                                                         //
  10. //  Description: Advanced bitmap demo program, Chapter 11                            //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define STRICT
  15. #define _WIN32_WINNT 0x0500
  16. #define NOCRYPT
  17.  
  18. #include <windows.h>
  19. #include <assert.h>
  20. #include <tchar.h>
  21. #include <math.h>
  22.  
  23. #include "..\..\include\wingraph.h"
  24. #include "Resource.h"
  25.  
  26.  
  27. class KDIBView : public KScrollCanvas
  28. {
  29.     typedef enum { GAP = 16 };
  30.  
  31.     virtual void    OnDraw(HDC hDC, const RECT * rcPaint);
  32.     virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  33.     void            GetWndClassEx(WNDCLASSEX & wc);
  34.     
  35.     HMENU            m_hViewMenu;
  36.     int                m_nViewOpt;
  37.     HWND            m_hFrame;
  38.  
  39. public:
  40.  
  41.     HINSTANCE        m_hInst;
  42.     KDIB            m_DIB;
  43.  
  44.     KDIBView(void)
  45.     {
  46.         m_hViewMenu = NULL;
  47.         m_nViewOpt  = IDM_VIEW_STRETCHDIBITS;
  48.     }
  49.  
  50.     bool Initialize(const TCHAR * pFileName, HINSTANCE hInstance, KStatusWindow * pStatus, HWND hFrame)
  51.     {
  52.         m_hFrame = hFrame;
  53.  
  54.         if ( m_DIB.LoadFile(pFileName) )
  55.         {
  56.             SetSize(m_DIB.GetWidth()  + GAP*2,
  57.                     m_DIB.GetHeight() + GAP*2, 5, 5);
  58.  
  59.             m_hInst   = hInstance;
  60.             m_pStatus = pStatus;
  61.  
  62.             RegisterClass(_T("DIBView"), hInstance);
  63.             
  64.             return true;
  65.         }
  66.         else
  67.             return false;
  68.     }
  69.  
  70.     bool Initialize(BITMAPINFO * pDIB, HINSTANCE hInstance, KStatusWindow * pStatus, HWND hFrame)
  71.     {
  72.         m_hFrame = hFrame;
  73.  
  74.         if ( m_DIB.AttachDIB(pDIB, NULL, DIB_BMI_NEEDFREE) )
  75.         {
  76.             SetSize(m_DIB.GetWidth()  + GAP*2,
  77.                     m_DIB.GetHeight() + GAP*2, 5, 5);
  78.  
  79.             m_hInst   = hInstance;
  80.             m_pStatus = pStatus;
  81.  
  82.             RegisterClass(_T("DIBView"), hInstance);
  83.             
  84.             return true;
  85.         }
  86.         else
  87.             return false;
  88.     }
  89.  
  90.     bool GetTitle(const TCHAR * pFileName, TCHAR * pTitle)
  91.     {
  92.         if ( pFileName )
  93.         {
  94.             wsprintf(pTitle, "%s, %d x %d pixel, %d bits", pFileName,
  95.                 m_DIB.GetWidth(), m_DIB.GetHeight(), m_DIB.GetDepth());
  96.  
  97.             return true;
  98.         }
  99.         else
  100.             return false;
  101.     }
  102.  
  103.     void CreateNewView(BITMAPINFO * pDIB, TCHAR * pTitle);
  104. };
  105.  
  106.  
  107. void KDIBView::GetWndClassEx(WNDCLASSEX & wc)
  108. {
  109.     memset(& wc, 0, sizeof(wc));
  110.  
  111.     wc.cbSize         = sizeof(WNDCLASSEX);
  112.     wc.style          = CS_HREDRAW | CS_VREDRAW;
  113.     wc.lpfnWndProc    = WindowProc;
  114.     wc.cbClsExtra     = 0;
  115.     wc.cbWndExtra     = 0;       
  116.     wc.hInstance      = NULL;
  117.     wc.hIcon          = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_IMAGE));
  118.     wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
  119.     wc.hbrBackground  = (HBRUSH) (COLOR_GRAYTEXT + 1);
  120.     wc.lpszMenuName   = NULL;
  121.     wc.lpszClassName  = NULL;
  122.     wc.hIconSm        = NULL;
  123. }
  124.  
  125.  
  126. // Let the main frame window handle it
  127. void KDIBView::CreateNewView(BITMAPINFO * pDIB, TCHAR * pTitle)
  128. {
  129.     if ( pDIB )
  130.         SendMessage(m_hFrame, WM_USER, (WPARAM) pDIB, (LPARAM) pTitle);
  131. }
  132.  
  133.  
  134. LRESULT KDIBView::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  135. {
  136.     switch( uMsg )
  137.     {
  138.         case WM_CREATE:
  139.             m_hWnd        = hWnd;
  140.             m_hViewMenu = LoadMenu(m_hInst, MAKEINTRESOURCE(IDR_DIBVIEW));
  141.             return 0;
  142.  
  143.         case WM_PAINT:
  144.             return KScrollCanvas::WndProc(hWnd, uMsg, wParam, lParam);
  145.  
  146.         case WM_SIZE:
  147.         case WM_HSCROLL:
  148.         case WM_VSCROLL:
  149.         {
  150.             LRESULT lr = KScrollCanvas::WndProc(hWnd, uMsg, wParam, lParam);
  151.  
  152.             int nMin, nMax, nPos;
  153.  
  154.             GetScrollRange(m_hWnd, SB_VERT, &nMin, &nMax);
  155.  
  156.             nPos = GetScrollPos(m_hWnd, SB_VERT);
  157.  
  158.             TCHAR mess[32];
  159.             wsprintf(mess, "%d %d %d", nMin, nPos, nMax);
  160.             m_pStatus->SetText(0, mess);
  161.  
  162.             return lr;
  163.         }
  164.  
  165.         case WM_COMMAND:
  166.             switch ( LOWORD(wParam) )
  167.             {
  168.                 case IDM_VIEW_OVALMASK:
  169.                 case IDM_VIEW_STRETCHDIBCLIP:
  170.                 case IDM_VIEW_STRETCHBLTOVAL:
  171.                 case IDM_VIEW_STRETCHDIBITS:
  172.                 case IDM_VIEW_STRETCHDIBITS4:
  173.                 case IDM_VIEW_SETDIBITSTODEVICE:
  174.                 case IDM_VIEW_FITWINDOW:
  175.  
  176.                 case IDM_VIEW_MASKRED:
  177.                 case IDM_VIEW_MASKGREEN:
  178.                 case IDM_VIEW_MASKBLUE:
  179.                 case IDM_VIEW_FADEIN:                    
  180.                 case IDM_VIEW_ALPHAFADE:
  181.                 case IDM_VIEW_CUBE:
  182.                 case IDM_VIEW_CUBEPIXEL:
  183.                 case IDM_VIEW_SIMUPLGBLT:
  184.                     if ( LOWORD(wParam)!= m_nViewOpt )
  185.                     {
  186.                         m_nViewOpt = LOWORD(wParam);
  187.  
  188.                         switch ( LOWORD(wParam) )
  189.                         {
  190.                             case IDM_VIEW_STRETCHDIBCLIP:
  191.                             case IDM_VIEW_OVALMASK:
  192.                             case IDM_VIEW_STRETCHBLTOVAL:
  193.                             case IDM_VIEW_STRETCHDIBITS:
  194.                             case IDM_VIEW_SETDIBITSTODEVICE:
  195.                             case IDM_VIEW_FADEIN:
  196.                             case IDM_VIEW_ALPHAFADE:
  197.                                 SetSize(m_DIB.GetWidth() + GAP*2, m_DIB.GetHeight() + GAP*2, 5, 5, true);
  198.                                 break;
  199.  
  200.                             case IDM_VIEW_CUBE:
  201.                             case IDM_VIEW_CUBEPIXEL:
  202.                             case IDM_VIEW_SIMUPLGBLT:
  203.                             case IDM_VIEW_STRETCHDIBITS4:
  204.                                 SetSize(m_DIB.GetWidth()*2 + GAP*3, m_DIB.GetHeight()*2 + GAP*3, 5, 5, true);
  205.                                 break;
  206.                         }
  207.  
  208.                         InvalidateRect(hWnd, NULL, TRUE);
  209.                     }
  210.                     return 0;
  211.  
  212.                 case IDM_VIEW_DIBHEXDUMP:
  213.                     SendMessage(GetParent(GetParent(hWnd)), WM_USER+1, (WPARAM) & m_DIB, 0);    
  214.             }
  215.             return 0;
  216.  
  217.         default:
  218.             return CommonMDIChildProc(hWnd, uMsg, wParam, lParam, m_hViewMenu, 3);
  219.     }
  220. }
  221.  
  222.  
  223. void TransparentBltDrawIcon(HDC hDC, int x, int y, HICON hIcon)
  224. {
  225.     ICONINFO iconinfo;
  226.     GetIconInfo(hIcon, & iconinfo);
  227.  
  228.     BITMAP bmp;
  229.     GetObject(iconinfo.hbmMask, sizeof(bmp), & bmp);
  230.  
  231.     HDC hMemDC = CreateCompatibleDC(NULL);
  232.     HGDIOBJ hOld = SelectObject(hMemDC, iconinfo.hbmColor);
  233.  
  234.     COLORREF crTrans = GetPixel(hMemDC, 0, 0);
  235.  
  236.     G_TransparentBlt(hDC,    x, y, bmp.bmWidth, bmp.bmHeight, 
  237.                    hMemDC, 0, 0, bmp.bmWidth, bmp.bmHeight,
  238.                    crTrans);
  239.  
  240.     SelectObject(hMemDC, hOld);
  241.     DeleteObject(iconinfo.hbmMask);
  242.     DeleteObject(iconinfo.hbmColor);
  243.     DeleteObject(hMemDC);
  244. }
  245.  
  246.  
  247. void TestPlgBlt(HDC hDC, int x, int y, int w, int h, const BITMAPINFO * pBMI, const void * pBits, HINSTANCE hInstance, bool bSimulate)
  248. {
  249.     HBITMAP hBmp   = CreateDIBSection(hDC, pBMI, DIB_RGB_COLORS, NULL, NULL, NULL);
  250.     HDC     hMemDC = CreateCompatibleDC(hDC);
  251.  
  252.     SelectObject(hMemDC, hBmp);
  253.     StretchDIBits(hMemDC, 0, 0, w, h, 0, 0, w, h, pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);
  254.     
  255.     HBITMAP hBack = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_WOOD01));
  256.     BITMAP bmp;
  257.     GetObject(hBack, sizeof(bmp), & bmp);
  258.     MaskCube(hDC, 200, x, y, bmp.bmWidth, bmp.bmHeight, hBack, hMemDC, false, bSimulate);
  259.     DeleteObject(hBack);
  260.  
  261.     MaskCube(hDC, 200, x, y, w, h, hBmp, hMemDC, true, bSimulate);
  262.  
  263.     DeleteObject(hMemDC);
  264.     DeleteObject(hBmp);
  265. }
  266.  
  267.  
  268. void TestDIBTransform(HDC hDC, int x, int y, int w, int h, KDIB * pSrc)
  269. {
  270.     KAffine affine;
  271.  
  272.     affine.Rotate(-15);
  273.  
  274.     HBITMAP hBitmap = pSrc->TransformBitmap(& affine.m_xm, RGB(0xFF, 0xFF, 0), KDIB::method_direct);
  275.  
  276.     HDC hMemDC = CreateCompatibleDC(hDC);
  277.     SelectObject(hMemDC, hBitmap);
  278.     
  279.     BITMAP bmp;
  280.  
  281.     GetObject(hBitmap, sizeof(BITMAP), & bmp);
  282.     BitBlt(hDC, x, y, bmp.bmWidth, bmp.bmHeight, hMemDC, 0, 0, SRCCOPY);
  283.     DeleteObject(hMemDC);
  284.     DeleteObject(hBitmap);
  285. }
  286.  
  287.  
  288. BOOL OvalStretchDIBits(HDC hDC, int XDest, int YDest, int nDestWidth, int nDestHeight, 
  289.               int XSrc, int YSrc, int nSrcWidth, int nSrcHeight,
  290.               const void *pBits, const BITMAPINFO *pBMI, UINT iUsage)
  291. {
  292.     StretchDIBits(hDC, XDest, YDest, nDestWidth, nDestHeight, XSrc, YSrc, 
  293.         nSrcWidth, nSrcHeight, pBits, pBMI, iUsage, SRCINVERT);
  294.  
  295.     SaveDC(hDC);
  296.     SelectObject(hDC, GetStockObject(BLACK_BRUSH));
  297.     SelectObject(hDC, GetStockObject(BLACK_PEN));
  298.     Ellipse(hDC, XDest, YDest, XDest + nDestWidth, YDest + nDestHeight);
  299.     RestoreDC(hDC, -1);
  300.  
  301.     return StretchDIBits(hDC, XDest, YDest, nDestWidth, nDestHeight, XSrc, YSrc, 
  302.         nSrcWidth, nSrcHeight, pBits, pBMI, iUsage, SRCINVERT);
  303. }
  304.  
  305.  
  306. BOOL ClipOvalStretchDIBits(HDC hDC, int XDest, int YDest, int nDestWidth, int nDestHeight, 
  307.               int XSrc, int YSrc, int nSrcWidth, int nSrcHeight,
  308.               const void *pBits, const BITMAPINFO *pBMI, UINT iUsage)
  309. {
  310.     RECT rect = { XDest, YDest, XDest + nDestWidth, YDest + nDestHeight };
  311.     LPtoDP(hDC, (POINT *) & rect, 2);
  312.  
  313.     HRGN hRgn = CreateEllipticRgnIndirect(& rect);
  314.  
  315.     SaveDC(hDC);
  316.  
  317.     SelectClipRgn(hDC, hRgn);
  318.     DeleteObject(hRgn);
  319.  
  320.     BOOL rslt = StretchDIBits(hDC, XDest, YDest, nDestWidth, nDestHeight, XSrc, YSrc, 
  321.         nSrcWidth, nSrcHeight, pBits, pBMI, iUsage, SRCCOPY);
  322.     
  323.     RestoreDC(hDC, -1);
  324.  
  325.     return rslt;
  326. }
  327.  
  328.  
  329. BOOL AlphaFade(HDC hDCDst, int XDst, int YDst, int nDstWidth, int nDstHeight,
  330.                HDC hDCSrc, int XSrc, int YSrc, int nSrcWidth, int nSrcHeight)
  331. {
  332.     for (int i=5; i>=1; i--)
  333.     {
  334.         // 1/5, 1/4, 1/3, 1/2, 1/1
  335.         BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255 / i , 0 };
  336.  
  337.         AlphaBlend(hDCDst, XDst, YDst, nDstWidth, nDstHeight,
  338.                    hDCSrc, YSrc, YSrc, nSrcWidth, nSrcHeight,
  339.                    blend);
  340.     }
  341.  
  342.     return TRUE;
  343. }
  344.  
  345.  
  346. BOOL OvalStretchBlt(HDC hDC,    int XDest, int YDest, int nDestWidth, int nDestHeight, 
  347.                     HDC hDCSrc, int XSrc,  int YSrc,  int nSrcWidth,  int nSrcHeight)
  348. {
  349.     // Make the region outside the ellipse be BLACK in source surface
  350.     SaveDC(hDCSrc);
  351.     BeginPath(hDCSrc);
  352.     Rectangle(hDCSrc, XSrc, YSrc, XSrc + nSrcWidth+1, YSrc + nSrcHeight+1);
  353.     Ellipse(hDCSrc, XSrc, YSrc, XSrc + nSrcWidth, YSrc + nSrcHeight);
  354.     EndPath(hDCSrc);
  355.     SelectObject(hDCSrc, GetStockObject(BLACK_BRUSH));
  356.     SelectObject(hDCSrc, GetStockObject(BLACK_PEN));
  357.     FillPath(hDCSrc);
  358.     RestoreDC(hDCSrc, -1);
  359.     
  360.     // Draw a BLACK ellipse in destination surface
  361.     SaveDC(hDC);
  362.     SelectObject(hDC, GetStockObject(BLACK_BRUSH));
  363.     SelectObject(hDC, GetStockObject(BLACK_PEN));
  364.     Ellipse(hDC, XDest, YDest, XDest + nDestWidth, YDest + nDestHeight);
  365.     RestoreDC(hDC, -1);
  366.  
  367.     // Merge source surface to destination
  368.     return StretchBlt(hDC, XDest, YDest, nDestWidth, nDestHeight, hDCSrc, XSrc, YSrc, 
  369.         nSrcWidth, nSrcHeight, SRCPAINT);
  370. }
  371.  
  372.  
  373. extern DWORD dibtick;
  374.  
  375.  
  376. void KDIBView::OnDraw(HDC hDC, const RECT * rcPaint)
  377. {
  378.     DWORD tm = GetTickCount();
  379.     
  380.     dibtick = 0;
  381.     int w = m_DIB.GetWidth();
  382.     int h = m_DIB.GetHeight();
  383.  
  384.     switch ( m_nViewOpt )
  385.     {
  386.         case IDM_VIEW_FITWINDOW:
  387.             {
  388.                 RECT rect;
  389.  
  390.                 GetClientRect(m_hWnd, & rect);
  391.                 m_DIB.DrawDIB(hDC, 0, 0, rect.right, rect.bottom, 0, 0, w, h, SRCCOPY);
  392.             }
  393.             break;
  394.  
  395.         case IDM_VIEW_MASKRED:
  396.             {
  397.                 HDC     hMemDC = CreateCompatibleDC(NULL);
  398.                 HBITMAP hBmp = ChannelSplit(m_DIB.GetBMI(), m_DIB.GetBits(), RGB(0xFF, 0, 0), hMemDC);
  399.  
  400.                 BitBlt(hDC, 0, 0, w, h, hMemDC, 0, 0, SRCCOPY);
  401.                 DeleteObject(hBmp);
  402.                 DeleteObject(hMemDC);
  403.  
  404.             //    CGDIObject red(hDC, CreateSolidBrush(RGB(0xFF, 0, 0)));
  405.             //    m_DIB.DrawDIB(hDC, GAP,   GAP,    w, h, 0, 0,  w,  h, MERGECOPY);
  406.             }
  407.             break;
  408.  
  409.         case IDM_VIEW_MASKGREEN:
  410.             {
  411.                 KGDIObject red(hDC, CreateSolidBrush(RGB(0, 0xFF, 0)));
  412.                 m_DIB.DrawDIB(hDC, GAP,   GAP,    w, h, 0, 0,  w,  h, MERGECOPY);
  413.             }
  414.             break;
  415.  
  416.         case IDM_VIEW_MASKBLUE:
  417.             {
  418.                 KGDIObject red(hDC, CreateSolidBrush(RGB(0, 0, 0xFF )));
  419.                 m_DIB.DrawDIB(hDC, GAP,   GAP,    w, h, 0, 0,  w,  h, MERGECOPY);
  420.             }
  421.             break;
  422.  
  423.         case IDM_VIEW_FADEIN:
  424.             FadeIn(hDC, GAP, GAP, w, h, m_DIB.GetBMI(), m_DIB.GetBits());
  425.             break;
  426.  
  427.         case IDM_VIEW_OVALMASK:
  428.             OvalStretchDIBits(hDC, GAP, GAP, w, h, 0, 0, w, h, m_DIB.GetBits(), m_DIB.GetBMI(), DIB_RGB_COLORS);
  429.             break;
  430.  
  431.         case IDM_VIEW_STRETCHDIBCLIP:
  432.             ClipOvalStretchDIBits(hDC, GAP, GAP, w, h, 0, 0, w, h, m_DIB.GetBits(), m_DIB.GetBMI(), DIB_RGB_COLORS);
  433.             break;
  434.  
  435.         case IDM_VIEW_ALPHAFADE:
  436.             {
  437.                 HBITMAP hBmp = m_DIB.ConvertToDDB(hDC);
  438.                 HDC hMemDC   = CreateCompatibleDC(hDC);
  439.                 SelectObject(hMemDC, hBmp);
  440.  
  441.                 AlphaFade(hDC, GAP, GAP, w, h, hMemDC, 0, 0, w, h);
  442.                 
  443.                 DeleteObject(hMemDC);
  444.                 DeleteObject(hBmp);
  445.             }
  446.             break;
  447.  
  448.         case IDM_VIEW_STRETCHBLTOVAL:
  449.             {
  450.                 HBITMAP hBmp = m_DIB.ConvertToDDB(hDC);
  451.                 HDC hMemDC   = CreateCompatibleDC(hDC);
  452.                 SelectObject(hMemDC, hBmp);
  453.  
  454.                 OvalStretchBlt(hDC, GAP, GAP, w, h, hMemDC, 0, 0, w, h);
  455.                 
  456.                 DeleteObject(hMemDC);
  457.                 DeleteObject(hBmp);
  458.             }
  459.             break;
  460.  
  461.         case IDM_VIEW_STRETCHDIBITS:
  462.             m_DIB.DrawDIB(hDC, GAP,   GAP,    w, h, 0, 0,  w,  h, SRCCOPY);
  463.             break;
  464.  
  465.         case IDM_VIEW_STRETCHDIBITS4:
  466.             m_DIB.DrawDIB(hDC, GAP,     GAP,     w, h, 0, 0,  w,  h, SRCCOPY);
  467.             m_DIB.DrawDIB(hDC, GAP*2+w, GAP,     w, h, w, 0, -w,  h, SRCCOPY);
  468.             m_DIB.DrawDIB(hDC, GAP,     GAP*2+h, w, h, 0, h,  w, -h, SRCCOPY);
  469.             m_DIB.DrawDIB(hDC, GAP*2+w, GAP*2+h, w, h, w, h, -w, -h, SRCCOPY);
  470.             break;
  471.  
  472.         case IDM_VIEW_SETDIBITSTODEVICE:
  473.             if ( ! m_DIB.IsCompressed() )
  474.             {
  475.                 int  bps      = m_DIB.GetBPS();
  476.                 BYTE * buffer = new BYTE[bps];
  477.  
  478.                 for (int i=0; i<m_DIB.GetHeight(); i++)
  479.                 {
  480.                     memcpy(buffer, m_DIB.GetBits() + bps*i, bps);
  481.  
  482.                     for (int j=0; j<bps; j++)
  483.                         buffer[j] = ~ buffer[j];
  484.  
  485.                     m_DIB.SetDIB(hDC, GAP, GAP, i, 1, buffer);
  486.                 }
  487.                 delete [] buffer;
  488.             }
  489.             break;
  490.  
  491.         case IDM_VIEW_CUBE:
  492.             TestPlgBlt(hDC, GAP, GAP, w, h, m_DIB.GetBMI(), m_DIB.GetBits(), m_hInst, false);
  493.             break;
  494.  
  495.         case IDM_VIEW_SIMUPLGBLT:
  496.             TestPlgBlt(hDC, GAP, GAP, w, h, m_DIB.GetBMI(), m_DIB.GetBits(), m_hInst, true);
  497.             break;
  498.  
  499.         case IDM_VIEW_CUBEPIXEL:
  500.             TestDIBTransform(hDC, GAP, GAP, w, h, & m_DIB);
  501.             break;
  502.  
  503.     }
  504.     RestoreDC(hDC, -1);
  505.  
  506.     tm = GetTickCount() - tm;
  507.  
  508.     if ( dibtick )
  509.         tm = dibtick;
  510.  
  511.     TCHAR mess[32];
  512.     wsprintf(mess, "Time %d ms", tm);
  513.     m_pStatus->SetText(1, mess);
  514. }
  515.  
  516. //////////////////////////////////////////////
  517.  
  518. void TestRop3(HINSTANCE hInstance, HDC hDC);
  519.  
  520. void TestIcons(HDC hDC)
  521. {
  522.     static HINSTANCE hMod = NULL;
  523.     
  524.     if ( hMod==NULL )
  525.         hMod = LoadLibrary("Shell32.dll");
  526.  
  527.     int n = 0;
  528.  
  529.     HDC hMemDC = CreateCompatibleDC(hDC);
  530.  
  531.     for (int resid=3; resid<=100; resid++)
  532.     {
  533.         HICON hIcon = (HICON) LoadImage(hMod, MAKEINTRESOURCE(resid), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
  534.  
  535.         if ( hIcon )
  536.         {
  537.             int x = (n%2)*420 + 20;
  538.             int y = (n/2)*60  + 20;
  539.  
  540.             DrawIcon(hDC, x, y, hIcon); n++;
  541.             
  542.             MaskBltDrawIcon(hDC, x+56*5, y, hIcon);
  543.             TransparentBltDrawIcon(hDC, x+56*6, y, hIcon);
  544.             
  545.             ICONINFO iconinfo;
  546.             GetIconInfo(hIcon, & iconinfo);
  547.             DestroyIcon(hIcon);
  548.  
  549.             BITMAP bmp;
  550.             GetObject(iconinfo.hbmMask, sizeof(bmp), & bmp);
  551.  
  552.             HGDIOBJ hOld = SelectObject(hMemDC, iconinfo.hbmMask);
  553.             BitBlt(hDC, x+56, y, bmp.bmWidth, bmp.bmHeight, hMemDC, 0, 0, SRCCOPY);
  554.             SelectObject(hMemDC, iconinfo.hbmColor);
  555.             BitBlt(hDC, x+56*2, y, bmp.bmWidth, bmp.bmHeight, hMemDC, 0, 0, SRCCOPY);
  556.  
  557.             SelectObject(hMemDC, iconinfo.hbmMask);
  558.             BitBlt(hDC, x+56*3, y, bmp.bmWidth, bmp.bmHeight, hMemDC, 0, 0, SRCAND);
  559.             SelectObject(hMemDC, iconinfo.hbmColor);
  560.             BitBlt(hDC, x+56*3, y, bmp.bmWidth, bmp.bmHeight, hMemDC, 0, 0, SRCINVERT);
  561.             
  562.             MaskBitmapNT(hDC, x+56*4, y, bmp.bmWidth, bmp.bmHeight, iconinfo.hbmMask, hMemDC);
  563.  
  564.         
  565.             SelectObject(hMemDC, hOld);
  566.             DeleteObject(iconinfo.hbmMask);
  567.             DeleteObject(iconinfo.hbmColor);
  568.         }
  569.     }
  570.  
  571.     DeleteObject(hMemDC);
  572. }
  573.  
  574.  
  575. void ColorBitmap(HDC hDC, int x, int y, int w, int h, HDC hMemDC, HBRUSH hBrush)
  576. {
  577.     // P^(S&(P^D)), if (S) D else P
  578.     HGDIOBJ hOldBrush = SelectObject(hDC, hBrush);
  579.     BitBlt(hDC, x, y, w, h, hMemDC, 0, 0, 0xB8074A);
  580.     SelectObject(hDC, hOldBrush);
  581. }
  582.  
  583.  
  584. void TestColoring(HDC hDC, HINSTANCE hInstance)
  585. {
  586.     HBITMAP hPttrn;
  587.     HBITMAP hBitmap = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_CONFUSE));
  588.     BITMAP  bmp;
  589.     GetObject(hBitmap, sizeof(bmp), & bmp);
  590.  
  591.     SetTextColor(hDC, RGB(0, 0, 0));
  592.     SetBkColor(hDC, RGB(0xFF, 0xFF, 0xFF));
  593.  
  594.     HDC hMemDC   = CreateCompatibleDC(NULL);
  595.     HGDIOBJ hOld = SelectObject(hMemDC, hBitmap);
  596.  
  597.     for (int i=0; i<5; i++)
  598.     {
  599.         HBRUSH hBrush;
  600.         switch (i)
  601.         {
  602.             case 0: hBrush = CreateSolidBrush(RGB(0xFF, 0, 0)); break;
  603.             case 1: hBrush = CreateSolidBrush(RGB(0, 0xFF, 0)); break;
  604.             case 2: hPttrn = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_PATTERN01));
  605.                     hBrush = CreatePatternBrush(hPttrn);
  606.                     DeleteObject(hPttrn);
  607.                     break;
  608.             case 3: hBrush = CreateHatchBrush(HS_DIAGCROSS, RGB(0, 0, 0xFF)); break;
  609.             case 4: hPttrn = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_WOOD01));
  610.                     hBrush = CreatePatternBrush(hPttrn);
  611.                     DeleteObject(hPttrn);
  612.         }
  613.  
  614.         ColorBitmap(hDC, i*30+10-2, i*5+10-2, bmp.bmWidth, bmp.bmHeight, hMemDC, (HBRUSH)GetStockObject(WHITE_BRUSH));
  615.         ColorBitmap(hDC, i*30+10+2, i*5+10+2, bmp.bmWidth, bmp.bmHeight, hMemDC, (HBRUSH)GetStockObject(DKGRAY_BRUSH));
  616.         ColorBitmap(hDC, i*30+10, i*5+10, bmp.bmWidth, bmp.bmHeight, hMemDC, hBrush);
  617.         DeleteObject(hBrush);
  618.     }
  619.  
  620.     BitBlt(hDC, 240, 25, bmp.bmWidth, bmp.bmHeight, hMemDC, 0, 0, SRCCOPY);
  621.  
  622.     SelectObject(hMemDC, hOld);
  623.     DeleteObject(hBitmap);
  624.     DeleteObject(hMemDC);
  625. }
  626.  
  627.  
  628.  
  629. void TestLoadImage(HDC hDC, HINSTANCE hInstance)
  630. {
  631.     HBITMAP hBitmap[3];
  632.     
  633.     const nID [] = { IDB_MOSQUIT1, IDB_MOSQUIT2, IDB_MOSQUIT3 };
  634.  
  635.     for (int i=0; i<3; i++)
  636.         hBitmap[i] = (HBITMAP) LoadImage(hInstance, MAKEINTRESOURCE(nID[i]), IMAGE_BITMAP, 0, 0,
  637.                             LR_LOADTRANSPARENT | LR_CREATEDIBSECTION );
  638.  
  639.     BITMAP bmp;
  640.     GetObject(hBitmap[0], sizeof(bmp), & bmp);
  641.  
  642.     HDC hMemDC = CreateCompatibleDC(hDC);
  643.  
  644.     SelectObject(hDC, GetSysColorBrush(COLOR_WINDOW));
  645.  
  646.     int lastx = -1;
  647.     int lasty = -1;
  648.  
  649.     HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
  650.     for (i=0; i<600; i++)
  651.     {
  652.         SelectObject(hMemDC, hBitmap[i%3]); 
  653.         
  654.         int newx = i;
  655.         int newy = abs(200-i%400);
  656.  
  657.         if ( lastx!=-1 )
  658.         {
  659.             SetRectRgn(hRgn, newx, newy, newx+bmp.bmWidth, newy + bmp.bmHeight);
  660.             ExtSelectClipRgn(hDC, hRgn, RGN_DIFF);
  661.             PatBlt(hDC, lastx, lasty, bmp.bmWidth, bmp.bmHeight, PATCOPY);
  662.             SelectClipRgn(hDC, NULL);
  663.         }
  664.         BitBlt(hDC, newx, newy, bmp.bmWidth, bmp.bmHeight, hMemDC, 0, 0, SRCCOPY);
  665.  
  666.         lastx = newx; lasty = newy;
  667.     }
  668.     DeleteObject(hRgn);
  669.     DeleteObject(hMemDC);
  670.     DeleteObject(hBitmap[0]);
  671.     DeleteObject(hBitmap[1]);
  672.     DeleteObject(hBitmap[2]);
  673. }
  674.  
  675.  
  676. void TestAlphaBlending(HDC hDC, HINSTANCE hInstance)
  677. {
  678.     const int size = 100;
  679.  
  680.     // Solid block constant alpha blending
  681.     for (int i=0; i<3; i++)
  682.     {
  683.         RECT  rect    = { i*(size+10) + 20, 20+size/3, i*(size+10) + 20 + size, 20+size/3 + size };
  684.  
  685.         const COLORREF Color[] = { RGB(0xFF, 0, 0), RGB(0, 0xFF, 0), RGB(0, 0, 0xFF)  };
  686.         
  687.         HBRUSH hBrush = CreateSolidBrush(Color[i]);
  688.         FillRect(hDC, & rect, hBrush);                // three original solid rectangle
  689.         DeleteObject(hBrush);
  690.  
  691.         BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255/2, 0 }; // constant alpha 0.5
  692.  
  693.         AlphaBlend(hDC, 360+((3-i)%3)*size/3, 20+i*size/3, size, size, // blend destination
  694.                    hDC, i*(size+10)+20, 20+size/3, size, size, blend);    // original solid rectangle
  695.     }
  696.  
  697. //    HBRUSH hBrush = CreateSolidBrush(RGB(0, 0, 1));
  698. //    RECT  rect = { 100, 100, 500, 200 };
  699. //    FillRect(hDC, & rect, hBrush);
  700. //    DeleteObject(hDC);
  701. }
  702.  
  703.  
  704. void Label(HDC hDC, int x, int y, const TCHAR * mess)
  705. {
  706.     TextOut(hDC, x, y, mess, _tcslen(mess));
  707. }
  708.  
  709.  
  710. void TestPalette(HDC hDC, HINSTANCE hInstance)
  711. {
  712.     TCHAR temp[64];
  713.  
  714.     if ( GetDeviceCaps(hDC, RASTERCAPS ) && RC_PALETTE )
  715.         Label(hDC, 10, 10, "Palette Supported");
  716.     else
  717.         Label(hDC, 10, 10, "Palette not supported");
  718.  
  719.     wsprintf(temp, "SIZEPALETTE %d", GetDeviceCaps(hDC, SIZEPALETTE));
  720.     Label(hDC, 10, 30, temp);
  721.  
  722.     wsprintf(temp, "NUMRESERVED %d", GetDeviceCaps(hDC, NUMRESERVED));
  723.     Label(hDC, 10, 50, temp);
  724.  
  725.     wsprintf(temp, "COLORRES    %d", GetDeviceCaps(hDC, COLORRES));
  726.     Label(hDC, 10, 70, temp);
  727.  
  728.     PALETTEENTRY entries[256];
  729.  
  730.     int no = GetSystemPaletteEntries(hDC, 0, 256, entries);
  731.     for (int i=0; i<no; i++)
  732.     {
  733.         wsprintf(temp, "%02x %02x %02x %02x", entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags);
  734.         Label(hDC, 10 + ( i % 8) * 100, 100 + (i/8) * 20, temp);
  735.     }
  736. }
  737.  
  738.  
  739. class KTestView : public KScrollCanvas
  740. {
  741.     KAirBrush brush;
  742.  
  743.     void AirBrush(HWND hWnd, int x, int y)
  744.     {
  745.         HDC hDC = GetDC(hWnd);
  746.  
  747.         brush.Apply(hDC, x, y);
  748.  
  749.         ReleaseDC(hWnd, hDC);
  750.     }
  751.  
  752.     virtual void OnDraw(HDC hDC, const RECT * rcPaint)
  753.     {
  754.         switch ( m_nViewOpt )
  755.         {
  756.             case IDM_VIEW_ROPCHART:
  757.                 TestRop3(m_hInst, hDC);
  758.                 break;
  759.  
  760.             case IDM_VIEW_ICON:
  761.                 TestIcons(hDC);
  762.                 break;
  763.  
  764.             case IDM_VIEW_COLORBITMAP:
  765.                 TestColoring(hDC, m_hInst);
  766.                 break;
  767.  
  768.             case IDM_VIEW_LOADIMAGE:
  769.                 TestLoadImage(hDC, m_hInst);
  770.                 break;
  771.  
  772.             case IDM_VIEW_ALPHABLEND:
  773.                 TestAlphaBlending(hDC, m_hInst);
  774.                 break;
  775.  
  776.             case IDM_VIEW_PALETTE:
  777.                 TestPalette(hDC, m_hInst);
  778.         }
  779.     }
  780.  
  781.     virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  782.     {
  783.         switch( uMsg )
  784.         {
  785.             case WM_CREATE:
  786.                 m_hWnd        = hWnd;
  787.                 m_hViewMenu = LoadMenu(m_hInst, MAKEINTRESOURCE(IDR_DIBVIEW));
  788.                 SetSize(1200, 1200, 5, 5, true);
  789.  
  790.                 return 0;
  791.  
  792.             case WM_LBUTTONDOWN:
  793.                 AirBrush(hWnd, LOWORD(lParam), HIWORD(lParam));
  794.                 return 0;
  795.  
  796.             case WM_MOUSEMOVE:
  797.                 if ( wParam & MK_LBUTTON )
  798.                     AirBrush(hWnd, LOWORD(lParam), HIWORD(lParam));        
  799.                 else
  800.                 {
  801.                     HDC hDC = GetDC(hWnd);
  802.  
  803.                     COLORREF cr = GetPixel(hDC, LOWORD(lParam), HIWORD(lParam));
  804.                     TCHAR mess[32];
  805.  
  806.                     wsprintf(mess, "RGB(%02x, %02x, %02x)", GetRValue(cr), GetGValue(cr), GetBValue(cr));
  807.                     m_pStatus->SetText(1, mess);
  808.                     ReleaseDC(hWnd, hDC);
  809.                 }
  810.                 return 0;
  811.  
  812.             case WM_PAINT:
  813.             case WM_SIZE:
  814.             case WM_HSCROLL:
  815.             case WM_VSCROLL:
  816.                 return KScrollCanvas::WndProc(hWnd, uMsg, wParam, lParam);
  817.  
  818.             case WM_COMMAND:
  819.                 switch ( LOWORD(wParam) )
  820.                 {
  821.                     case IDM_VIEW_ROPCHART:
  822.                     case IDM_VIEW_ICON:
  823.                     case IDM_VIEW_COLORBITMAP:
  824.                     case IDM_VIEW_LOADIMAGE:
  825.                     case IDM_VIEW_ALPHABLEND:
  826.                     case IDM_VIEW_PALETTE:
  827.                         if ( LOWORD(wParam)!= m_nViewOpt )
  828.                         {
  829.                             m_nViewOpt = LOWORD(wParam);
  830.                             SetSize(700, 800, 5, 5, true);
  831.                             InvalidateRect(hWnd, NULL, TRUE);
  832.                         }
  833.                         return 0;
  834.                 }
  835.                 return 0;
  836.  
  837.             default:
  838.                 return CommonMDIChildProc(hWnd, uMsg, wParam, lParam, m_hViewMenu, 3);
  839.         }
  840.     }
  841.  
  842.     void GetWndClassEx(WNDCLASSEX & wc)
  843.     {
  844.         memset(& wc, 0, sizeof(wc));
  845.  
  846.         wc.cbSize         = sizeof(WNDCLASSEX);
  847.         wc.style          = CS_HREDRAW | CS_VREDRAW;
  848.         wc.lpfnWndProc    = WindowProc;
  849.         wc.cbClsExtra     = 0;
  850.         wc.cbWndExtra     = 0;       
  851.         wc.hInstance      = NULL;
  852.         wc.hIcon          = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_IMAGE));
  853.         wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
  854.         wc.hbrBackground  = (HBRUSH) (COLOR_WINDOW + 1);
  855.         wc.lpszMenuName   = NULL;
  856.         wc.lpszClassName  = NULL;
  857.         wc.hIconSm        = NULL;
  858.     }
  859.  
  860.  
  861.     HMENU            m_hViewMenu;
  862.     int                m_nViewOpt;
  863.  
  864. public:
  865.  
  866.     KTestView(void)
  867.     {
  868.         m_hViewMenu = NULL;
  869.         m_nViewOpt  = IDM_VIEW_ROPCHART;
  870.     }
  871.  
  872.     bool Initialize(HINSTANCE hInstance, KStatusWindow * pStatus)
  873.     {
  874.         m_hInst   = hInstance;
  875.         m_pStatus = pStatus;
  876.  
  877.         RegisterClass(_T("TestView"), hInstance);
  878.  
  879.         brush.Create(32, 32, RGB(0xC0, 0x80, 0));
  880.         return true;
  881.     }
  882.  
  883. };
  884.  
  885.  
  886. const int Translate[] =
  887. {
  888.     IDM_FILE_CLOSE,
  889.     IDM_FILE_EXIT,
  890.     IDM_WINDOW_TILE,
  891.     IDM_WINDOW_CASCADE,
  892.     IDM_WINDOW_ARRANGE,
  893.     IDM_WINDOW_CLOSEALL
  894. };
  895.  
  896.  
  897. class KMyMDIFRame : public KMDIFrame
  898. {
  899.     int                m_nCount;
  900.  
  901.     void CreateMDIChild(KScrollCanvas * canvas, const TCHAR * klass, const TCHAR * filename, const TCHAR * title)
  902.     {
  903.         MDICREATESTRUCT mdic;
  904.  
  905.         TCHAR Temp[MAX_PATH];
  906.  
  907.         if ( ! canvas->GetTitle(filename, Temp) )
  908.         {
  909.             m_nCount ++;
  910.             wsprintf(Temp, title, m_nCount);
  911.         }
  912.  
  913.         mdic.szClass = klass;
  914.         mdic.szTitle = Temp;
  915.         mdic.hOwner  = m_hInst;
  916.         mdic.x       = CW_USEDEFAULT;
  917.         mdic.y       = CW_USEDEFAULT;
  918.         mdic.cx      = CW_USEDEFAULT;
  919.         mdic.cy      = CW_USEDEFAULT;
  920.         mdic.style   = WS_VISIBLE | WS_BORDER;
  921.         mdic.lParam  = (LPARAM) canvas;
  922.  
  923.         SendMessage(m_hMDIClient, WM_MDICREATE, 0, (LPARAM) & mdic);
  924.     }
  925.  
  926.     void CreateDIBView(const TCHAR * pFileName)
  927.     {
  928.         KDIBView * pDIBView = new KDIBView();
  929.  
  930.         if ( pDIBView )
  931.             if ( pDIBView->Initialize(pFileName, m_hInst, m_pStatus, m_hWnd) )
  932.                 CreateMDIChild(pDIBView, _T("DIBView"), pFileName, _T("DIB %d"));
  933.             else
  934.                 delete pDIBView;
  935.     }
  936.  
  937.     void CreateDIBView(BITMAPINFO * pDIB, const TCHAR * pTitle)
  938.     {
  939.         KDIBView * pDIBView = new KDIBView();
  940.  
  941.         if ( pDIBView )
  942.             if ( pDIBView->Initialize(pDIB, m_hInst, m_pStatus, m_hWnd) )
  943.                 CreateMDIChild(pDIBView, _T("DIBView"), pTitle, _T("DIB %d"));
  944.             else
  945.                 delete pDIBView;
  946.     }
  947.  
  948.  
  949.     void CreateTestView(void)
  950.     {
  951.         KTestView * pTestView = new KTestView();
  952.  
  953.         if ( pTestView )
  954.             if ( pTestView->Initialize(m_hInst, m_pStatus) )
  955.                 CreateMDIChild(pTestView, _T("TestView"), NULL, _T("Test %d"));
  956.             else
  957.                 delete pTestView;
  958.     }
  959.     
  960.     virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam)
  961.     {
  962.         switch ( LOWORD(wParam) )
  963.         {
  964.             case IDM_FILE_NEW:
  965.                 CreateDIBView(NULL);
  966.                 return TRUE;
  967.  
  968.             case IDM_FILE_TEST:
  969.                 CreateTestView();
  970.                 return TRUE;
  971.  
  972.             case IDM_FILE_OPEN:
  973.             {
  974.                 KFileDialog fo;
  975.  
  976.                 if ( fo.GetOpenFileName(m_hWnd, "bmp", "Bitmap Files") )
  977.                     CreateDIBView(fo.m_TitleName);
  978.                 
  979.                 return TRUE;
  980.             }
  981.         }
  982.  
  983.         return FALSE;
  984.     }
  985.  
  986.     virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  987.     {
  988.         LRESULT lr = KMDIFrame::WndProc(hWnd, uMsg, wParam, lParam);
  989.  
  990.         if ( uMsg == WM_USER )
  991.         {
  992.             CreateDIBView((BITMAPINFO *) wParam, (const TCHAR *) lParam);
  993.         }
  994.  
  995. //        if ( uMsg == WM_CREATE )
  996. //        {
  997. //            SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED); 
  998. //            SetLayeredWindowAttributes(m_hWnd, 0, 0xC0, LWA_ALPHA);
  999. //        }
  1000.  
  1001.         return lr;
  1002.     }
  1003.  
  1004.     void GetWndClassEx(WNDCLASSEX & wc)
  1005.     {
  1006.         KMDIFrame::GetWndClassEx(wc);
  1007.  
  1008.         wc.hIcon = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_IMAGE));
  1009.     }
  1010.  
  1011. public:
  1012.     KMyMDIFRame(HINSTANCE hInstance, const TBBUTTON * pButtons, int nCount,
  1013.         KToolbar * pToolbar, KStatusWindow * pStatus) :
  1014.         KMDIFrame(hInstance, pButtons, nCount, pToolbar, pStatus, Translate)
  1015.     {
  1016.         m_nCount = 0;
  1017.     }
  1018. };
  1019.  
  1020. const TBBUTTON tbButtons[] =
  1021. {
  1022.     { STD_FILENEW,     IDM_FILE_NEW,   TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, IDS_FILENEW,  0 },
  1023.     { STD_FILEOPEN,  IDM_FILE_OPEN,  TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, IDS_FILEOPEN, 0 }
  1024. };
  1025.  
  1026.  
  1027. int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int nShow)
  1028. {
  1029.     KToolbar      toolbar;
  1030.     KStatusWindow status;
  1031.  
  1032.     KMyMDIFRame frame(hInst, tbButtons, 2, & toolbar, & status);
  1033.  
  1034.     TCHAR title[MAX_PATH];
  1035.  
  1036.     _tcscpy(title, "AdvBitmap");
  1037.  
  1038.     frame.CreateEx(0, _T("ClassName"), title,
  1039.         WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  1040.         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
  1041.         NULL, LoadMenu(hInst, MAKEINTRESOURCE(IDR_MAIN)), hInst);
  1042.     
  1043.     frame.ShowWindow(nShow);
  1044.     frame.UpdateWindow();
  1045.  
  1046.     frame.MessageLoop();
  1047.  
  1048.     return 0;
  1049. }
  1050.  
  1051.