949 views
首页 > WTL, 技术心得 > WTL 一个绘制 MDI 客户区的类

WTL 一个绘制 MDI 客户区的类

2010年1月12日

使用相当简单:

  1. 在工程内创建一个资源 ID 为 IDB_BK_LOG 的位图
  2. 在 mdi 的主框架窗口类内部创建变量.
    CMdiClientDraw m_wndMdiClinetX;
  3. 然后在 OnCreate 函数内子类化 MDI Client.
    m_wndMdiClinetX.SubclassWindow(m_hWndMDIClient);

完成.
以下是类的源码

  1. #ifndef __TB_MDI_CLIENT_H__
  2. #define __TB_MDI_CLIENT_H__ 1
  3.  
  4. //
  5. // based on "Automatic Tab Bar for MDI Frameworks"
  6. // http://www.codeproject.com/KB/docview/mditab.aspx
  7. //
  8.  
  9. #pragma once
  10.  
  11. #ifndef __ATLMISC_H__
  12. #error tbmdiclient.h requires atlmisc.h to be included first
  13. #endif
  14.  
  15. #ifndef IDB_BK_LOG
  16. #define IDB_BK_LOG    300
  17. #endif
  18.  
  19. #define szLogoString _T("Tiny Browser, wonderful world")
  20.  
  21. template <class T, class TBase = CWindow, class TWinTraits = CControlWinTraits>
  22. class ATL_NO_VTABLE CMdiClientDrawT 
  23.     : public CWindowImpl< T, TBase, TWinTraits>
  24. {
  25. public:
  26.     typedef CWindowImpl<TBase, TWinTraits> baseClass;
  27.  
  28.     typedef enum DispType 
  29.     {
  30.         DISPTILE,
  31.         DISPCENTER,
  32.         DISPSTRETCH 
  33.     } DispType;
  34.  
  35.     CSize m_sizeClient;
  36.  
  37.     DECLARE_WND_CLASS( _T("CMdiClientDrawT") )
  38.  
  39.     CMdiClientDrawT() : m_sizeClient(0, 0)
  40.     {
  41.         // Do defaults settings
  42.         Defaults();
  43.  
  44.         // Load the logo font
  45.         /*
  46.         {
  47.             BOOL bSuccess = FALSE;
  48.             LOGFONT* plf  = NULL;
  49.             UINT dwSize   = sizeof(LOGFONT);
  50.             bSuccess = pApp->GetProfileBinary(szSection, szLogoFont, (BYTE**)&plf, &dwSize);
  51.  
  52.             if (bSuccess)
  53.             {
  54.                 m_fontLogo.DeleteObject();
  55.                 m_fontLogo.CreateFontIndirect(plf);
  56.             }
  57.             delete plf;
  58.         }
  59.         //*/
  60.  
  61.         m_strLogo = szLogoString;
  62.         m_bBkBitmap   = TRUE;
  63.         m_crLogoColor = RGB(0xff, 0xff, 0xff);
  64.         m_crBkColor   = RGB(0x80, 0x80, 0x80);
  65.         SetBkColor(m_crBkColor);
  66.         m_enuDispType = (DispType)DISPCENTER;
  67.         SetDispType(m_enuDispType);
  68.  
  69.         // SetBitmap(MAKEINTRESOURCE(IDB_BK_LOG));
  70.         SetBitmap(IDB_BK_LOG);
  71.     }
  72.  
  73.     BEGIN_MSG_MAP(thisClass)
  74.         MESSAGE_HANDLER(WM_PAINT, OnPaint)
  75.         MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
  76.         MESSAGE_HANDLER(WM_SIZE, OnSize)
  77.     END_MSG_MAP()
  78.  
  79.     LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  80.     {
  81.         T* pThis = static_cast<T *> (this);
  82.         CPaintDC dc(pThis->m_hWnd);
  83.         CRect rc;
  84.         pThis->GetClientRect(rc);
  85.  
  86.         BOOL bDoBitBlt = TRUE;
  87.  
  88.         if (!(HBITMAP)m_bkBitmap)
  89.             dc.FillRect(rc, m_bkBrush);
  90.  
  91.         if ((HBITMAP)m_bkBitmap)
  92.         {
  93.             CDCHandle pDC;
  94.             CDC memDC;
  95.             CBitmap bmp;
  96.  
  97.             BOOL bUseMemDC =(GetDispType() != DISPTILE) ? TRUE : FALSE;
  98.             if (bUseMemDC)
  99.             {
  100.                 if (GetDispType() != DISPSTRETCH)
  101.                     bmp.CreateCompatibleBitmap(dc, rc.right, rc.bottom);
  102.                 else
  103.                     bmp.CreateCompatibleBitmap(dc, m_sizImage.cx, m_sizImage.cy);
  104.                 memDC.CreateCompatibleDC(dc);
  105.                 memDC.SelectBitmap(bmp);
  106.                 pDC = memDC;
  107.             }
  108.             else
  109.                 pDC = dc;
  110.  
  111.             switch (GetDispType())
  112.             {
  113.             case DISPTILE:
  114.                 {
  115.                     CPoint point;
  116.                     for (point.y = 0; point.y < rc.Height(); point.y += m_sizImage.cy)
  117.                         for (point.x = 0; point.x < rc.Width(); point.x += m_sizImage.cx)
  118.                             pDC.DrawState(point, m_sizImage, m_bkBitmap, DST_BITMAP | DSS_NORMAL);
  119.                 }
  120.                 break;
  121.  
  122.             case DISPCENTER:
  123.                 {
  124.                     pDC.FillRect(rc, m_bkBrush);
  125.                     CPoint point((rc.Width() - m_sizImage.cx) / 2,
  126.                         (rc.Height() - m_sizImage.cy) / 2);
  127.                     pDC.DrawState(point, m_sizImage, m_bkBitmap, DST_BITMAP | DSS_NORMAL);
  128.                 }
  129.                 break;
  130.  
  131.             case DISPSTRETCH:
  132.                 {
  133.                     memDC.DrawState(CPoint(0, 0), m_sizImage, m_bkBitmap, DST_BITMAP | DSS_NORMAL);
  134.                     dc.SetStretchBltMode(COLORONCOLOR);
  135.                     dc.StretchBlt(0, 0, rc.right, rc.bottom, memDC,
  136.                         0, 0, m_sizImage.cx, m_sizImage.cy, SRCCOPY);
  137.                     bDoBitBlt = FALSE;
  138.                 }
  139.                 break;
  140.             }
  141.  
  142.             // Now is the time to draw the logo text at the bottom
  143.             if (!bDoBitBlt)       // If not using memory DC, then grab a DC here
  144.                 pDC = dc;
  145.  
  146.             PaintLogo(pDC);
  147.             if ((bUseMemDC == TRUE) && bDoBitBlt)
  148.                 dc.BitBlt(0, 0, rc.right, rc.bottom, pDC, 0, 0, SRCCOPY);
  149.         }
  150.         else
  151.         {
  152.             CDCHandle pDC;
  153.             pDC = dc;
  154.             PaintLogo(pDC);
  155.         }
  156.         return 0;
  157.     }
  158.  
  159.     LRESULT OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  160.     {
  161.         T* pThis = static_cast<T *> (this);
  162.         return pThis->OnMDIClientEraseBkgnd(uMsg, wParam, lParam, bHandled);
  163.     }
  164.  
  165.     LRESULT OnMDIClientEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  166.     {
  167.         BOOL bMaximized = FALSE;
  168.         HWND hWndActive = (HWND)::SendMessage(m_hWnd, WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized);
  169.         if (bMaximized) {
  170.             return TRUE;// no need to erase it
  171.         }
  172.         bHandled = FALSE;
  173.         return FALSE;
  174.     }
  175.  
  176.  
  177.     LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  178.     {
  179.         T* pThis = static_cast<T *> (this);
  180.         return pThis->OnMDIClientSize(uMsg, wParam, lParam, bHandled);
  181.     }
  182.  
  183.     LRESULT OnMDIClientSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  184.     {
  185.         T* pThis = static_cast<T *> (this);
  186.  
  187.         BOOL bMaximized = FALSE;
  188.         HWND hWndActive = (HWND)::SendMessage(m_hWnd, WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized);
  189.         if (bMaximized) 
  190.         {
  191.             // NOTE. If you do the following, you can avoid the flicker on resizing.
  192.             //       I can't understand why it is effective...
  193.             //
  194.             //       But still you can get a glimpse of other mdi child window's frames.
  195.             //       I guess it's MDI's bug, but I can't get the way MFC fixed.
  196.             CWindow wndActive(hWndActive);
  197.             CWindow wndView = wndActive.GetWindow(GW_CHILD);
  198.             ATLASSERT(wndView.IsWindow());
  199.             wndActive.ModifyStyle(0, WS_CLIPCHILDREN);// add WS_CLIPCHILDREN
  200.             wndView.ModifyStyle(0, WS_CLIPCHILDREN);
  201.             LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
  202.             UpdateWindow();
  203.             wndActive.ModifyStyle(WS_CLIPCHILDREN, 0);
  204.             wndView.ModifyStyle(WS_CLIPCHILDREN, 0);
  205.             return lRet;
  206.         }
  207.  
  208.         pThis->DefWindowProc(uMsg, wParam, lParam);
  209.         int cx = LOWORD(lParam);
  210.         int cy = HIWORD(lParam);
  211.  
  212.         // if the app is just starting up, save the window
  213.         // dimensions and get out
  214.         if ((m_sizeClient.cx == 0) &&(m_sizeClient.cy == 0))
  215.         {
  216.             m_sizeClient.cx = cx;
  217.             m_sizeClient.cy = cy;
  218.             return 0;
  219.         }
  220.  
  221.         // if the size hasn't changed, break and pass to default
  222.         if ((m_sizeClient.cx == cx) &&(m_sizeClient.cy == cy)) {
  223.             return 0;
  224.         }
  225.  
  226.         // window size has changed so save new dimensions and force
  227.         // entire background to redraw, including icon backgrounds
  228.         m_sizeClient.cx = cx;
  229.         m_sizeClient.cy = cy;
  230.  
  231.         pThis->RedrawWindow(NULL, NULL,
  232.             RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW /*| RDW_ALLCHILDREN */);
  233.  
  234.         return 0;
  235.     }
  236.  
  237.     // Set background color
  238.     void SetBkColor(COLORREF crBkValue)
  239.     {
  240.         T* pThis = static_cast<T *> (this);
  241.         m_crBkColor = crBkValue;
  242.         if (FALSE == m_bkBrush.IsNull()) {
  243.             m_bkBrush.DeleteObject();
  244.         }
  245.         m_bkBrush.CreateSolidBrush(m_crBkColor);
  246.         if (pThis->IsWindow())
  247.             pThis->Invalidate();
  248.     }
  249.  
  250.     COLORREF GetBkColor() const
  251.     {
  252.         return m_crBkColor;
  253.     }
  254.  
  255.     // Set Logo Text color
  256.     void SetLogoColor(COLORREF crValue)
  257.     {
  258.         m_crLogoColor = crValue;
  259.         if (IsWindow())
  260.             Invalidate();
  261.     }
  262.  
  263.     COLORREF GetLogoColor() const
  264.     {
  265.         return m_crLogoColor;
  266.     }
  267.  
  268.     void SetDispType(DispType enuDispType)
  269.     {
  270.         T* pThis = static_cast<T *> (this);
  271.         m_enuDispType = enuDispType;
  272.         if (pThis->IsWindow()) {
  273.             pThis->Invalidate();
  274.         }
  275.     }
  276.  
  277.     DispType GetDispType() const
  278.     {
  279.         return m_enuDispType;
  280.     }
  281.  
  282.     // Load background bitmap from given file
  283.     BOOL SetBitmap(LPCTSTR lpszFileName, UINT uFlags = LR_LOADMAP3DCOLORS)
  284.     {
  285.         T* pThis = static_cast<T *> (this);
  286.  
  287.         if ( (((DWORD)lpszFileName) >> 16) != 0 ) {
  288.             uFlags |= LR_LOADFROMFILE;
  289.         }
  290.         HANDLE hBitmap = ::LoadImage(_Module.GetResourceInstance(), lpszFileName,
  291.             IMAGE_BITMAP, 0, 0, uFlags );
  292.  
  293.         if (!hBitmap)    // There were some problems during loading the image
  294.             return FALSE;
  295.  
  296.         if (FALSE == m_bkBitmap.IsNull()) {
  297.             m_bkBitmap.DeleteObject();
  298.         }
  299.         m_bkBitmap.Attach((HBITMAP)hBitmap);
  300.         if (pThis->IsWindow()) {
  301.             pThis->Invalidate();
  302.         }
  303.         m_strFileName.Empty();
  304.         if (uFlags & LR_LOADFROMFILE) {
  305.             m_strFileName = lpszFileName;
  306.         }
  307.  
  308.         BITMAP bi;
  309.         m_bkBitmap.GetBitmap(&bi);
  310.         m_sizImage.cx = bi.bmWidth;
  311.         m_sizImage.cy = bi.bmHeight;
  312.  
  313.         return TRUE;
  314.     }
  315.  
  316.     // Load background bitmap from resource.
  317.     BOOL SetBitmap(UINT nBmpID, COLORMAP* pClrMap = NULL, int nCount = 0)
  318.     {
  319.         T* pThis = static_cast<T *> (this);
  320.         if (FALSE == m_bkBitmap.IsNull()) {
  321.             m_bkBitmap.DeleteObject();
  322.         }
  323.         if (pClrMap == NULL)
  324.         {
  325.             if (m_bkBitmap.LoadBitmap(nBmpID) == FALSE) {
  326.                 return FALSE;
  327.             }
  328.         }
  329.         else
  330.         {
  331.             if (m_bkBitmap.LoadMappedBitmap(nBmpID, 0, pClrMap, nCount) == FALSE) {
  332.                 return FALSE;
  333.             }
  334.         }
  335.  
  336.         BITMAP bi = { 0 };
  337.         m_bkBitmap.GetBitmap(&bi);
  338.         m_sizImage.cx = bi.bmWidth;
  339.         m_sizImage.cy = bi.bmHeight;
  340.  
  341.         if (pThis->IsWindow())
  342.             pThis->Invalidate();
  343.         return TRUE;
  344.     }
  345.  
  346.     // Load background bitmap from resource.
  347.     BOOL SetDefBitmap(UINT nBmpID, COLORMAP* pClrMap = NULL, int nCount = 0)
  348.     {
  349.         T* pThis = static_cast<T *> (this);
  350.         if (FALSE == m_bkDefBitmap.IsNull()) {
  351.             m_bkDefBitmap.DeleteObject();
  352.         }
  353.         if (pClrMap == NULL)
  354.         {
  355.             if (m_bkDefBitmap.LoadBitmap(nBmpID) == FALSE)
  356.                 return FALSE;
  357.         }
  358.         else
  359.         {
  360.             if (m_bkDefBitmap.LoadMappedBitmap(nBmpID, 0, pClrMap, nCount) == FALSE)
  361.                 return FALSE;
  362.         }
  363.  
  364.         BITMAP bi = { 0 };
  365.         m_bkDefBitmap.GetBitmap(&bi);
  366.         m_sizDefImage.cx = bi.bmWidth;
  367.         m_sizDefImage.cy = bi.bmHeight;
  368.  
  369.         if (pThis->IsWindow()) {
  370.             pThis->Invalidate();
  371.         }
  372.         return TRUE;
  373.     }
  374.  
  375.     // Set the logo text font...
  376.     void SetLogoFont(HFONT pLogoFont)
  377.     {
  378.         T* pThis = static_cast<T *> (this);
  379.         ATLASSERT(pLogoFont);
  380.  
  381.         if (FALSE == m_fontLogo.IsNull()) {
  382.             m_fontLogo.DeleteObject();
  383.         }
  384.  
  385.         LOGFONT lFont = { 0 };
  386.         CFontHandle fnt(pLogoFont);
  387.         fnt->GetLogFont(&lFont);
  388.  
  389.         m_fontLogo.CreateFontIndirect(&lFont);
  390.  
  391.         pThis->SetFont(m_fontLogo);
  392.         if (pThis->IsWindow())
  393.             pThis->Invalidate();
  394.     }
  395.  
  396.     void SetLogoFont(int nLogoWeight = FW_SEMIBOLD, BOOL bLogoItalic = FALSE,
  397.         BOOL bLogoUnderline = FALSE)
  398.     {
  399.         T* pThis = static_cast<T *> (this);
  400.         // Free any memory currently used by the fonts.
  401.         if (FALSE == m_fontLogo.IsNull()) {
  402.             m_fontLogo.DeleteObject();
  403.         }
  404.  
  405.         // Get the current font
  406.         LOGFONT lFont = { 0 };
  407.         CFontHandle pFont = pThis->GetFont();
  408.         if (FALSE == pFont.IsNull()) {
  409.             pFont.GetLogFont(&lFont);
  410.         } else {
  411.             NONCLIENTMETRICS ncm = { 0 };
  412.             ncm.cbSize = sizeof(NONCLIENTMETRICS);
  413.             ATLVERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
  414.                 sizeof(NONCLIENTMETRICS), &ncm, 0));
  415.             lFont = ncm.lfMessageFont;
  416.         }
  417.  
  418.         // Create the Logo font
  419.         lFont.lfWeight    = static_cast<LONG>(nLogoWeight);
  420.         lFont.lfItalic    = static_cast<BYTE>(bLogoItalic);
  421.         lFont.lfUnderline = static_cast<BYTE>(bLogoUnderline);
  422.         m_fontLogo.CreateFontIndirect(&lFont);
  423.  
  424.         pThis->SetFont(m_fontLogo);
  425.         if (pThis->IsWindow()) {
  426.             pThis->Invalidate();
  427.         }
  428.     }
  429.  
  430.     HFONT GetLogoFont()
  431.     {
  432.         return m_fontLogo;
  433.     }
  434.  
  435.     CString GetLogoText(void)
  436.     {
  437.         return m_strLogo;
  438.     }
  439.  
  440.     void SetLogoText(const CString & str)
  441.     {
  442.         m_strLogo = str;
  443.     }
  444.  
  445.     // Return the current image size.
  446.     const CSize& GetImageSize() const
  447.     {
  448.         return m_sizImage;
  449.     }
  450.  
  451.     // Return the filename of the bitmap
  452.     const CString & GetFileName() const
  453.     {
  454.         return m_strFileName;
  455.     }
  456.  
  457.  
  458. protected:
  459.     COLORREF m_crBkColor;          // Background color
  460.     COLORREF m_crLogoColor;        // Right logo text color
  461.     CBitmap  m_bkBitmap;           // background bitmap
  462.     CBitmap  m_bkDefBitmap;        // Default background bitmap
  463.     CBrush   m_bkBrush;            // Brush used for background painting
  464.     CString  m_strFileName;        // Filename of any bitmap loaded from a file
  465.     CSize    m_sizImage;           // Bitmap image size
  466.     CSize    m_sizDefImage;        // Default Bitmap image size
  467.     DispType m_enuDispType;        // Current display type
  468.     CFont    m_fontLogo;           // Font for drawing the logo text
  469.     CString  m_strLogo;
  470.  
  471.     BOOL m_bBkBitmap;
  472.  
  473.     // Generated message map functions
  474. protected:
  475.     void PaintLogo(CDCHandle pDC)
  476.     {
  477.         T* pThis = static_cast<T *> (this);
  478.         CRect      rcDataBox;
  479.         TEXTMETRIC tm = { 0 };
  480.  
  481.         pDC.SetBkMode(OPAQUE);
  482.  
  483.         CFontHandle oldFont = pDC.SelectFont( m_fontLogo );
  484.         CRect st(0, 0, 0, 0);
  485.  
  486.         CSize sz;
  487.         pDC.GetTextExtent(m_strLogo, m_strLogo.GetLength(), &sz);
  488.         // GetTextExtent calculates the size of the displayed logo
  489.         // which depends on the device context....
  490.         pDC.GetTextMetrics(&tm);
  491.  
  492.         // Calculate the box size by subtracting the text width and height from the
  493.         // window size.  Also subtract 20% of the average character size to keep the
  494.         // logo from printing into the borders...
  495.         pThis->GetClientRect(&rcDataBox);
  496.  
  497.         rcDataBox.left = rcDataBox.right  - sz.cx - tm.tmAveCharWidth / 2;
  498.         rcDataBox.top  = rcDataBox.bottom - sz.cy - st.bottom - tm.tmHeight / 5;
  499.  
  500.         CRect rcSave = rcDataBox;
  501.  
  502.         pDC.SetBkMode(TRANSPARENT);
  503.         rcSave = rcDataBox;
  504.  
  505.         // shift logo box right, and print black...
  506.         rcDataBox.left   += tm.tmAveCharWidth / 5;
  507.         COLORREF oldColor = pDC.SetTextColor(RGB(0, 0, 0));
  508.         pDC.DrawText(m_strLogo, m_strLogo.GetLength(), &rcDataBox,
  509.             DT_VCENTER | DT_SINGLELINE | DT_CENTER);
  510.  
  511.         rcDataBox = rcSave;
  512.  
  513.         // shift logo box left and print white
  514.         rcDataBox.left -= tm.tmAveCharWidth / 5;
  515.         pDC.SetTextColor(RGB(255, 255, 255));
  516.         pDC.DrawText(m_strLogo, m_strLogo.GetLength(), &rcDataBox,
  517.             DT_VCENTER | DT_SINGLELINE | DT_CENTER);
  518.  
  519.         // Restore original location and print in the button face color
  520.         rcDataBox = rcSave;
  521.         pDC.SetTextColor(m_crLogoColor);
  522.         pDC.DrawText(m_strLogo, m_strLogo.GetLength(), &rcDataBox,
  523.             DT_VCENTER | DT_SINGLELINE | DT_CENTER);
  524.  
  525.         // restore the original properties and release resources...
  526.         pDC.SelectFont(oldFont);
  527.         pDC.SetTextColor(oldColor);
  528.         pDC.SetBkMode(OPAQUE);
  529.     }
  530.  
  531.     void Defaults(BOOL bBkBitmap = TRUE, BOOL bDelBkBitmap = TRUE)
  532.     {
  533.         T* pThis = static_cast<T *> (this);
  534.         // m_bBkBitmap           = bBkBitmap;
  535.  
  536.         m_crBkColor           = GetSysColor(COLOR_APPWORKSPACE);
  537.         m_crLogoColor         = GetSysColor(COLOR_BTNFACE);
  538.  
  539.         m_enuDispType         = DISPCENTER;
  540.         m_strFileName.Empty();
  541.  
  542.         // Create the default font, Times New Roman is most common
  543.         CWindowDC wndDC(::GetDesktopWindow());
  544.         int nFontSize = -MulDiv(18, wndDC.GetDeviceCaps(LOGPIXELSY), 72);
  545.         if (FALSE == m_fontLogo.IsNull()) {
  546.             m_fontLogo.DeleteObject();
  547.         }
  548.         m_fontLogo.CreateFont(nFontSize,
  549.             0, 0, 0,
  550.             FW_BOLD,
  551.             FALSE, FALSE, FALSE,
  552.             ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
  553.             FIXED_PITCH | FF_ROMAN,
  554.             // _T("微软雅黑"));
  555.             _T("Times New Roman"));
  556.  
  557.         if (pThis->IsWindow()) {
  558.             pThis->SetFont(m_fontLogo);
  559.         }
  560.  
  561.         SetBkColor(m_crBkColor);
  562.         if (bDelBkBitmap)
  563.         {
  564.             if (FALSE == m_bkBitmap.IsNull()) {
  565.                 m_bkBitmap.DeleteObject();
  566.             }
  567.             m_sizImage.cx = m_sizImage.cy = 0;
  568.             if (bBkBitmap && (HBITMAP)m_bkDefBitmap)
  569.             {
  570.                 m_sizImage = m_sizDefImage;
  571.                 //            m_bkBitmap& = CBitmap::FromHandle((HBITMAP)m_bkDefBitmap);
  572.                 //            BITMAP* bmpDef = new BITMAP;
  573.                 //            m_bkDefBitmap.GetBitmap(bmpDef);
  574.                 //            VERIFY(m_bkBitmap.CreateBitmapIndirect(bmpDef));
  575.                 //            delete bmpDef;
  576.             }
  577.         }
  578.         if (pThis->IsWindow()) {
  579.             pThis->Invalidate();
  580.         }
  581.     }
  582. };
  583.  
  584. class CMdiClientDraw : public CMdiClientDrawT<CMdiClientDraw>
  585. {
  586. public:
  587.     DECLARE_WND_CLASS(_T("CMdiClientDraw"));
  588. };
  589.  
  590.  
  591. #endif    // __TB_MDI_CLIENT_H__

WTL, 技术心得 , , ,

  1. 目前还没有任何评论.
  1. 目前还没有任何 trackbacks 和 pingbacks.