code.screen, div.codescreen{
font-family: monospace;
font-size: 1em;
display: block;
padding: 10px;
border: 1px solid #bbb;
background-color: #eee;
color: #000;
overflow: auto;
border-radius: 2.5px;
-moz-border-radius: 2.5px;
margin: 0.5em 2em;
}
Although many people don’t like MFC, sometimes we have to use it. This article presents a sample to describe how to implement height adjustment and owner drawing for HeaderControl of ListControl.
Header file:
class CSkinManager; class COwnerDrawHeaderCtrl : public CHeaderCtrl { public: COwnerDrawHeaderCtrl(); protected: virtual void DrawItem(LPDRAWITEMSTRUCT); protected: //{{AFX_MSG(COwnerDrawHeaderCtrl) afx_msg LRESULT OnLayout(WPARAM wParam, LPARAM lParam); afx_msg void OnPaint(); afx_msg BOOL OnEraseBkgnd(CDC* pDC); //}}AFX_MSG DECLARE_MESSAGE_MAP() private: CSkinManager &m_skinManager; };
Source file:
COwnerDrawHeaderCtrl::COwnerDrawHeaderCtrl() :m_skinManager(CPootaoClientService::Instance().GetSkinManager()) { }; BEGIN_MESSAGE_MAP(COwnerDrawHeaderCtrl, CHeaderCtrl) //{{AFX_MSG_MAP(COwnerDrawHeaderCtrl) ON_MESSAGE(HDM_LAYOUT, OnLayout) ON_WM_PAINT() ON_WM_ERASEBKGND() //}}AFX_MSG_MAP END_MESSAGE_MAP() LRESULT COwnerDrawHeaderCtrl::OnLayout( WPARAM wParam, LPARAM lParam ) { HDLAYOUT* pLayout = ( HDLAYOUT* ) lParam; // cast the lParam pLayout->pwpos->hwnd = GetSafeHwnd (); // populate WINDOWPOS struct pLayout->pwpos->hwndInsertAfter = HWND_TOP; pLayout->pwpos->flags = SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED; int nHdrBottom = m_skinManager.m_sizeHeaderBackground.cy; pLayout->pwpos->x = pLayout->prc->left; pLayout->pwpos->y = 0; pLayout->pwpos->cx = pLayout->prc->right - pLayout->prc->left; pLayout->pwpos->cy = nHdrBottom; pLayout->prc->top = nHdrBottom; return TRUE; } void COwnerDrawHeaderCtrl::DrawItem(LPDRAWITEMSTRUCT) { } BOOL COwnerDrawHeaderCtrl::OnEraseBkgnd(CDC* pDC) { return FALSE; } void COwnerDrawHeaderCtrl::OnPaint() { CPaintDC dc(this); HDC dcMem = dc.m_hDC; CRect rectWindow; GetClientRect(&rectWindow); HFONT hOldFont = (HFONT)SelectObject(dcMem, GetStockObject(DEFAULT_GUI_FONT)); ::SetBkColor(dcMem, GetSysColor(COLOR_WINDOW)); SetBkMode(dcMem, TRANSPARENT); //draw the contents to a memory device context HDC dcMemBk = ::CreateCompatibleDC(dc.m_hDC); HBITMAP hOldBitmapBk = (HBITMAP)SelectObject(dcMemBk, m_skinManager.m_hBmpHeaderBackground); int rightMost = 0; for (int i=0; i<GetItemCount(); i++) { HDITEM hdi; TCHAR lpBuffer[256]; hdi.mask = HDI_TEXT | HDI_FORMAT | HDI_IMAGE | HDI_ORDER; hdi.pszText = lpBuffer; hdi.cchTextMax = 256; GetItem(i, &hdi); CRect rcItem; GetItemRect(i, &rcItem); SelectObject(dcMemBk, m_skinManager.m_hBmpHeaderSep); BitBlt(dcMem , rcItem.left, rcItem.top , m_skinManager.m_sizeHeaderSep.cx, m_skinManager.m_sizeHeaderSep.cy , dcMemBk, 0, 0, SRCCOPY); SelectObject(dcMemBk, m_skinManager.m_hBmpHeaderBackground); StretchBlt(dcMem , rcItem.left + 1, rcItem.top , rcItem.Width()-1, rcItem.Height() , dcMemBk , 0, 0, m_skinManager.m_sizeHeaderBackground.cx, m_skinManager.m_sizeHeaderBackground.cy , SRCCOPY); SelectObject(dcMemBk, m_skinManager.m_hBmpHeaderSep); BitBlt(dcMem , rcItem.right, rcItem.top , m_skinManager.m_sizeHeaderSep.cx, m_skinManager.m_sizeHeaderSep.cy , dcMemBk, 0, 0, SRCCOPY); rightMost = max(rightMost, rcItem.right); DRAWITEMSTRUCT DrawItemStruct; GetItemRect(i, &rcItem); DrawItemStruct.CtlType = 100; DrawItemStruct.hDC = dc.GetSafeHdc(); DrawItemStruct.itemAction = ODA_DRAWENTIRE; DrawItemStruct.hwndItem = GetSafeHwnd(); DrawItemStruct.rcItem = rcItem; DrawItemStruct.itemID = i; DrawItem(&DrawItemStruct); // Draw the items text using the text color. COLORREF crOldColor = ::SetTextColor(dcMem, RGB(0x4f,0x4f,0x4f)); SetBkMode(dcMem, TRANSPARENT); UINT uFormat = DT_SINGLELINE|DT_VCENTER|DT_NOPREFIX|DT_END_ELLIPSIS; if( hdi.fmt & HDF_CENTER) uFormat |= DT_CENTER; else if( hdi.fmt & HDF_RIGHT) uFormat |= DT_RIGHT; else uFormat |= DT_LEFT; CRect rectText(rcItem); CPoint ptImage(0, 0); CImageList *imageList = NULL; if (hdi.fmt & HDF_IMAGE && (imageList = GetImageList()) != NULL) { IMAGEINFO imageInfo; if (imageList->GetImageInfo(hdi.iImage, &imageInfo)) { if (!(hdi.fmt & HDF_BITMAP_ON_RIGHT)) { ptImage = rcItem.TopLeft(); ptImage.x += 4; ptImage.y = rcItem.top + (rcItem.Height()-(imageInfo.rcImage.bottom-imageInfo.rcImage.top))/2; imageList->Draw(&dc, hdi.iImage, ptImage, ILD_TRANSPARENT); rectText.left += imageInfo.rcImage.right-imageInfo.rcImage.left+4; } else { rectText.right -= imageInfo.rcImage.right-imageInfo.rcImage.left+4; } } ::SetTextColor(dcMem, RGB(0x00,0x00,0x00)); } rectText.DeflateRect(4, 2, 4, 2); int nTextSize = ::DrawText(dcMem, lpBuffer, lstrlen(lpBuffer), &rectText, uFormat); ::SetTextColor(dcMem, crOldColor); if (hdi.fmt & HDF_IMAGE && imageList != NULL) { IMAGEINFO imageInfo; if (hdi.fmt & HDF_BITMAP_ON_RIGHT && imageList->GetImageInfo(hdi.iImage, &imageInfo)) { CSize sizeText; GetTextExtentPoint(dcMem, lpBuffer, lstrlen(lpBuffer), &sizeText); ptImage = CPoint(min(rectText.right + sizeText.cx + 16, rcItem.left + rcItem.Width()-(imageInfo.rcImage.right-imageInfo.rcImage.left)-4) , (rcItem.Height()-(imageInfo.rcImage.bottom-imageInfo.rcImage.top))/2); imageList->Draw(&dc, hdi.iImage, ptImage, ILD_TRANSPARENT); } } } SelectObject(dcMemBk, m_skinManager.m_hBmpHeaderBackground); StretchBlt(dcMem , rightMost+1, 0 , rectWindow.Width()-rightMost-1, rectWindow.Height() , dcMemBk , 0, 0, m_skinManager.m_sizeHeaderBackground.cx, m_skinManager.m_sizeHeaderBackground.cy , SRCCOPY); SelectObject(dcMemBk, hOldBitmapBk); DeleteDC(dcMemBk); }