bool CPicShowCtrl::SaveFile(CString strPath) { int width=180; int height=180; CPaintDC dc(this); CxImage img; img.CreateFromHBITMAP(m_hBmp); CBitmap bitmapmem; CBitmap *pOldBit; CDC m_pMemDC; m_pMemDC.CreateCompatibleDC(&dc); bitmapmem.CreateCompatibleBitmap(&dc, width, height); pOldBit=m_pMemDC.SelectObject(&bitmapmem); CRect rect(0,0,width,height); HBRUSH bgBrush = ::CreateSolidBrush(RGB(255,255,255)); FillRect(m_pMemDC,&rect,bgBrush); DeleteObject(bgBrush); img.Draw(m_pMemDC,m_iStartx,m_iStarty,img.GetWidth(),img.GetHeight(),&rect); CBitmap* pBmp=m_pMemDC.SelectObject(pOldBit); CxImage xImagebmp; xImagebmp.CreateFromHBITMAP((HBITMAP)bitmapmem.m_hObject); xImagebmp.Resample(100,100,0); bitmapmem.DeleteObject(); m_pMemDC.DeleteDC(); if(xImagebmp.Save(common::utility::stringhelper::UnicodeToAscii(strPath.GetBuffer()).c_str(), CXIMAGE_FORMAT_JPG)) { return true; } return false; }
//鼠标在窗口上移动时需要进行的更新 void CEmotionButton::UpdateSelectedFace(int curPage, int curSel, int curFrame, int pvstatus) { HGDIOBJ hOldBrush = NULL, hOldPen = NULL, hTempPen, hTempBrush; HPEN hPen1 = NULL; HPEN hPen2 = NULL; LPRECT lpRect = NULL; RECT rc; int index; //贴背景 BitBlt(m_hMemDC, 0, 0, QQFACEDLG_WIDTH, QQFACEDLG_HEIGHT, m_hMemDCBkGnd, 0, 0, SRCCOPY); //绘制蓝色选中框 if(curSel >= 0) { hPen1 = CreatePen(PS_SOLID, 1, RGB(0, 0, 255)); hTempPen = SelectObject(m_hMemDC, hPen1); hTempBrush = SelectObject(m_hMemDC, GetStockObject(NULL_BRUSH)); GetBlueRect(curSel, &rc); Rectangle(m_hMemDC, rc.left, rc.top, rc.right, rc.bottom); if(hOldPen == NULL) hOldPen = hTempPen; if(hOldBrush == NULL) hOldBrush = hTempBrush; } //绘制左侧或者右侧的预览图 if(pvstatus == _PVStatus::Left) lpRect = &rcLeft; else if(pvstatus == _PVStatus::Right) lpRect = &rcRight; if(lpRect != NULL) { index = curPage * CELLCOUNT_PAGE + curSel; //从页内相对索引计算出绝对索引。 hPen2 = CreatePen(PS_SOLID, 1, RGB(0, 138, 255)); //淡蓝色画笔 hTempPen = SelectObject(m_hMemDC, hPen2); hTempBrush = SelectObject(m_hMemDC, GetStockObject(WHITE_BRUSH)); //白色画刷 Rectangle(m_hMemDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); //居中绘制 int left = (lpRect->left + lpRect->right - m_CxImages[index].GetWidth())/2; int top = (lpRect->top + lpRect->bottom - m_CxImages[index].GetHeight())/2; //设置帧 if(curFrame < m_CxImages[index].GetNumFrames()) { CxImage* pFrame = m_CxImages[index].GetFrame(curFrame); if(pFrame) pFrame->Draw(m_hMemDC, left, top); //m_CxImages[index].Draw(m_hMemDC, left, top); } if(hOldBrush == NULL) hOldBrush = hTempBrush; if(hOldPen == NULL) hOldPen = hTempPen; } //恢复画刷,画笔 if(hOldBrush != NULL) SelectObject(m_hMemDC, hOldBrush); if(hOldPen != NULL) SelectObject(m_hMemDC, hOldPen); if(hPen1 != NULL) DeleteObject(hPen1); if(hPen2 != NULL) DeleteObject(hPen2); }
BOOL CSonicImage::Load(HGLOBAL hGlobal, DWORD dwSize) { if(m_gif.LoadGif(hGlobal, dwSize) == 1) { if(PrepareMemDC(m_gif.GetWidth(), m_gif.GetHeight()) == FALSE) { m_gif.Clear(); return FALSE; } m_gif.Draw(m_Dib.GetSafeHdc()); } else { BYTE * pData = (BYTE *)GlobalLock(hGlobal); CxImage img; img.Decode(pData, dwSize, 0); GlobalUnlock(hGlobal); if(PrepareMemDC(img.GetWidth(), img.GetHeight()) == FALSE) { img.Clear(); return FALSE; } if(!img.AlphaIsValid()) { img.Draw(m_Dib.GetSafeHdc()); CSSE::DoOr(0xff000000, m_Dib.GetBits(), m_Dib.GetSize()); } else { if(img.GetBpp() != 24) { img.Clear(); return FALSE; } BYTE * pSrc = img.GetBits(); BYTE * pAlpha = img.AlphaGetBits(); BYTE * pMyBits = m_Dib.GetBits(); int nLineTail = m_nWidth % 4; for(int i = 0; i < m_nHeight; i++) { for(int j = 0; j < m_nWidth; j++) { *pMyBits++ = *pSrc++; *pMyBits++ = *pSrc++; *pMyBits++ = *pSrc++; *pMyBits++ = *pAlpha++; } pSrc += nLineTail; } EnableAlphaChannel(); } img.Clear(); } return TRUE; }
STDMETHODIMP CContextMenu::MenuMessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult) { TRACE("CContextMenu::MenuMessageHandler()"); CRASH_PROTECT_START; switch (uMsg) { case WM_MEASUREITEM: { LPMEASUREITEMSTRUCT itemInfo = (LPMEASUREITEMSTRUCT)lParam; MatroskaAttachmentMenuItem *currentAttachmentStruct = (MatroskaAttachmentMenuItem *)itemInfo->itemData; MatroskaAttachmentItem *currentAttachment = currentAttachmentStruct->attachmentSource; if (currentAttachment != NULL) { // An image attachment CxImage *attachedImage = currentAttachment->GetCxImage(); if (attachedImage != NULL) { //TCHAR track_txt[256]; //_sntprintf(track_txt, 255, _T("%i x %i, %i bits"), attachedImage->GetWidth(), attachedImage->GetHeight(), attachedImage->GetBpp()); ModifyMenuA(currentAttachmentStruct->hmAttachmentItem, currentAttachmentStruct->uIDNewItem, MF_STRING|MF_BYCOMMAND, currentAttachmentStruct->uIDNewItem, currentAttachment->GetImageInfo().c_str()); SIZE correctSize = SmartResize(attachedImage->GetWidth(), attachedImage->GetHeight(), 100, 100); attachedImage->Resample(correctSize.cx, correctSize.cy, MatroskaShellExt_GetRegistryValue(_T("ThumbnailResizeMethod"), 0)); itemInfo->itemWidth = correctSize.cx; itemInfo->itemHeight = correctSize.cy; } } break; } case WM_DRAWITEM: { LPDRAWITEMSTRUCT itemInfo = (LPDRAWITEMSTRUCT)lParam; MatroskaAttachmentMenuItem *currentAttachmentStruct = (MatroskaAttachmentMenuItem *)itemInfo->itemData; MatroskaAttachmentItem *currentAttachment = currentAttachmentStruct->attachmentSource; if (currentAttachment != NULL) { // An image attachment CxImage *attachedImage = currentAttachment->GetCxImage(); if (attachedImage != NULL) { long leftPos = (itemInfo->rcItem.right - itemInfo->rcItem.left - attachedImage->GetWidth()) / 2 + itemInfo->rcItem.left; long topPos = itemInfo->rcItem.top; attachedImage->Draw(itemInfo->hDC, leftPos, topPos); } } break; } } CRASH_PROTECT_END; return S_OK; };
void EditToolbarUI::onPaint(__in HWND hWnd, __in WPARAM wParam, __in LPARAM lParam) { static CxImage toolBarImg; static CxImage toolBarHoverImg; static CxImage toolBarSelImg; BOOL bLoadResult = FALSE; if (!bLoadResult) { toolBarImg.Load(m_sToolbarInfo.m_strPicPath.c_str(), CXIMAGE_SUPPORT_PNG); toolBarHoverImg.Load(m_sToolbarInfo.m_strHoverPicPath.c_str(), CXIMAGE_SUPPORT_PNG); toolBarSelImg.Load(m_sToolbarInfo.m_strSelPicPath.c_str(), CXIMAGE_SUPPORT_PNG); bLoadResult = TRUE; } //draw background HDC hPaintDC = GetDC(m_hwnd); RECT rcWnd = {0}; GetClientRect(m_hwnd, &rcWnd); toolBarImg.Draw(hPaintDC, rcWnd); if (m_iMouseMoveIdx >= 0) { //draw mouse move RECT &rcClip = m_sToolbarInfo.m_sItemRect[m_iMouseMoveIdx]; toolBarHoverImg.Draw(hPaintDC, rcWnd, &rcClip, true); } if (m_iSelectIdx >= 0) { //draw selected RECT &rcClip = m_sToolbarInfo.m_sItemRect[m_iSelectIdx]; toolBarSelImg.Draw(hPaintDC, rcWnd, &rcClip, true); } ReleaseDC(m_hwnd, hPaintDC); }
void CPicShowCtrl::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: 在此处添加消息处理程序代码 common::ui::CClientRect rcThis(this); if (m_hBmp == NULL) { //还没有选择图片,则绘制白色背景 HBRUSH bgBrush = ::CreateSolidBrush(RGB(255,255,255)); CRect rect; GetWindowRect(&rcThis); ScreenToClient(&rcThis); FillRect(dc,&rcThis,bgBrush); ::DeleteObject(bgBrush); } else { int width=180; int height=180; CxImage img; img.CreateFromHBITMAP(m_hBmp); CBitmap bitmapmem; CBitmap *pOldBit; CDC m_pMemDC; m_pMemDC.CreateCompatibleDC(&dc); bitmapmem.CreateCompatibleBitmap(&dc, width, height); pOldBit=m_pMemDC.SelectObject(&bitmapmem); CRect rect(0,0,width,height); HBRUSH bgBrush = ::CreateSolidBrush(RGB(255,255,255)); FillRect(m_pMemDC,&rect,bgBrush); DeleteObject(bgBrush); img.Draw(m_pMemDC,m_iStartx,m_iStarty,img.GetWidth(),img.GetHeight(),&rect); dc.SetStretchBltMode(HALFTONE); dc.StretchBlt(rcThis.left,rcThis.top,rcThis.Width(),rcThis.Height(),&m_pMemDC,0,0,width,height,SRCCOPY); m_pMemDC.SelectObject(pOldBit); m_pMemDC.DeleteDC(); bitmapmem.DeleteObject(); } }
//============================================================================= // // The framework calls this member function when a child control is about to // be drawn. All the bitmaps are created here on the first call. Every thing // is done with a memory DC except the background, which get's it's information // from the parent. The background is needed for transparent portions of PNG // images. An always on top app (such as Task Manager) that is in the way can // cause it to get an incorrect background. To avoid this, the parent should // call the SetBkGnd function with a memory DC when it creates the background. // //============================================================================= HBRUSH CButtonBT::CtlColor(CDC* pScreenDC, UINT nCtlColor) { if(!m_bHaveBitmaps) { if(!m_imgStd.IsValid()) { return NULL; // Load the standard image with LoadStdImage() } CBitmap bmp, *pOldBitmap; CRect rect; GetClientRect(rect); // do everything with mem dc CMemDCEx memdc(pScreenDC, rect); //CGDIPMemDC pDC(pScreenDC, rect); //Gdiplus::Graphics graphics(pDC->m_hDC); // background if (m_dcBk.m_hDC == NULL) { CRect rect1; CClientDC clDC(GetParent()); GetWindowRect(rect1); GetParent()->ScreenToClient(rect1); m_dcBk.CreateCompatibleDC(&clDC); bmp.CreateCompatibleBitmap(&clDC, rect.Width(), rect.Height()); pOldBitmap = m_dcBk.SelectObject(&bmp); m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, rect1.left, rect1.top, SRCCOPY); bmp.DeleteObject(); } // standard image if (m_dcStd.m_hDC == NULL) { PaintBk(&memdc); //graphics.DrawImage(*m_pStdImage, 0, 0); m_imgStd.Draw(memdc.GetSafeHdc()); m_dcStd.CreateCompatibleDC(&memdc); bmp.CreateCompatibleBitmap(&memdc, rect.Width(), rect.Height()); pOldBitmap = m_dcStd.SelectObject(&bmp); m_dcStd.BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY); bmp.DeleteObject(); // standard image pressed if (m_dcStdP.m_hDC == NULL) { PaintBk(&memdc); if (m_bISMove) { //graphics.DrawImage(*m_pStdImage, 1, 1); m_imgStd.Draw(memdc.GetSafeHdc(), 1, 1); } else { //graphics.DrawImage(*m_pStdImage, 0, 0); m_imgStd.Draw(memdc.GetSafeHdc()); } m_dcStdP.CreateCompatibleDC(&memdc); bmp.CreateCompatibleBitmap(&memdc, rect.Width(), rect.Height()); pOldBitmap = m_dcStdP.SelectObject(&bmp); m_dcStdP.BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY); bmp.DeleteObject(); } // standard image hot if(m_dcStdH.m_hDC == NULL) { PaintBk(&memdc); CxImage imgtemp = m_imgStd; imgtemp.ShiftRGB(20,20,20); imgtemp.Draw(memdc.GetSafeHdc()); m_dcStdH.CreateCompatibleDC(&memdc); bmp.CreateCompatibleBitmap(&memdc, rect.Width(), rect.Height()); pOldBitmap = m_dcStdH.SelectObject(&bmp); m_dcStdH.BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY); bmp.DeleteObject(); } // grayscale image if(m_dcGS.m_hDC == NULL) { PaintBk(&memdc); CxImage imgtemp = m_imgStd; imgtemp.GrayScale(); imgtemp.Draw(memdc.GetSafeHdc()); m_dcGS.CreateCompatibleDC(&memdc); bmp.CreateCompatibleBitmap(&memdc, rect.Width(), rect.Height()); pOldBitmap = m_dcGS.SelectObject(&bmp); m_dcGS.BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY); bmp.DeleteObject(); } } // alternate image if( (m_dcAlt.m_hDC == NULL) && m_bHaveAltImage ) { PaintBk(&memdc); //graphics.DrawImage(*m_pAltImage, 0, 0); m_imgAlt.Draw(memdc.GetSafeHdc()); m_dcAlt.CreateCompatibleDC(&memdc); bmp.CreateCompatibleBitmap(&memdc, rect.Width(), rect.Height()); pOldBitmap = m_dcAlt.SelectObject(&bmp); m_dcAlt.BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY); bmp.DeleteObject(); // alternate image pressed if( (m_dcAltP.m_hDC == NULL) && m_bHaveAltImage ) { PaintBk(&memdc); if (m_bISMove) { //graphics.DrawImage(*m_pAltImage, 1, 1); m_imgAlt.Draw(memdc.GetSafeHdc(), 1, 1); } else { //graphics.DrawImage(*m_pAltImage, 0, 0); m_imgAlt.Draw(memdc.GetSafeHdc()); } m_dcAltP.CreateCompatibleDC(&memdc); bmp.CreateCompatibleBitmap(&memdc, rect.Width(), rect.Height()); pOldBitmap = m_dcAltP.SelectObject(&bmp); m_dcAltP.BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY); bmp.DeleteObject(); } // alternate image hot if(m_dcAltH.m_hDC == NULL) { PaintBk(&memdc); CxImage imgtemp = m_imgAlt; imgtemp.ShiftRGB(20,20,20); imgtemp.Draw(memdc.GetSafeHdc()); m_dcAltH.CreateCompatibleDC(&memdc); bmp.CreateCompatibleBitmap(&memdc, rect.Width(), rect.Height()); pOldBitmap = m_dcAltH.SelectObject(&bmp); m_dcAltH.BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY); bmp.DeleteObject(); } } if(m_pCurBtn == NULL) { m_pCurBtn = &m_dcStd; } m_bHaveBitmaps = TRUE; } return NULL; }
////////////////////////////////////////////////////////////////////////////// // CDemoView drawing void CDemoView::OnDraw(CDC* pDC) { CDemoDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); BOOL bPrinting = pDC->IsPrinting(); CMemDC* pMemDC = NULL; if (!bPrinting) pDC = pMemDC = new CMemDC(pDC); if (!bPrinting && m_brHatch.m_hObject){ CRect rect; GetClientRect(&rect); rect.right = max(rect.right , m_totalDev.cx); rect.bottom = max(rect.bottom, m_totalDev.cy); m_brHatch.UnrealizeObject(); CPoint pt(0, 0); pDC->LPtoDP(&pt); pt = pDC->SetBrushOrg(pt.x % 8, pt.y % 8); CBrush* old = pDC->SelectObject(&m_brHatch); pDC->FillRect(&rect, &m_brHatch); pDC->SelectObject(old); } CxImage* ima = pDoc->GetImage(); if (ima) { if (bPrinting) { // get size of printer page (in pixels) int cxPage = pDC->GetDeviceCaps(HORZRES); int cyPage = pDC->GetDeviceCaps(VERTRES); //int dcbpp = pDC->GetDeviceCaps(BITSPIXEL); //int dcnc = pDC->GetDeviceCaps(NUMCOLORS); //int dcp = pDC->GetDeviceCaps(PLANES); // get printer pixels per inch int cxInch = pDC->GetDeviceCaps(LOGPIXELSX); int cyInch = pDC->GetDeviceCaps(LOGPIXELSY); // Best Fit case: create a rectangle which preserves the aspect ratio int cx = ima->GetXDPI() ? (ima->GetWidth()*cxInch)/ima->GetXDPI():ima->GetWidth()*cxInch/96; int cy = ima->GetYDPI() ? (ima->GetHeight()*cyInch)/ima->GetYDPI():ima->GetHeight()*cyInch/96; // print it! /*HDC TmpDC=CreateCompatibleDC(pDC->GetSafeHdc()); HBITMAP bm =::CreateCompatibleBitmap(pDC->GetSafeHdc(), cx, cy); HBITMAP oldbm = (HBITMAP)::SelectObject(TmpDC,bm); BitBlt(TmpDC,0,0,cx,cy,0,0,0,WHITENESS); ima->Draw(TmpDC,CRect(0,0,cx,cy)); BitBlt(pDC->GetSafeHdc(),100,100,cx,cy,TmpDC,0,0,SRCCOPY); DeleteObject(SelectObject(TmpDC,oldbm)); DeleteDC(TmpDC);*/ CxImage tmp; tmp.Copy(*ima); RGBQUAD c={255,255,255,0}; if (tmp.GetTransIndex()>=0) tmp.SetPaletteColor((BYTE)tmp.GetTransIndex(),c); tmp.SetTransColor(c); tmp.AlphaStrip(); tmp.Stretch(pDC->GetSafeHdc(), CRect(100,100,cx,cy)); } else { if (pDoc->GetStretchMode()) { CRect rect; GetClientRect(&rect); ima->Draw(pDC->GetSafeHdc(), rect,0,pDoc->GetSmoothMode()!=0); } else { float zoom=pDoc->GetZoomFactor(); if (zoom==1) ima->Draw(pDC->GetSafeHdc()); else ima->Draw(pDC->GetSafeHdc(), CRect(0,0,(int)(ima->GetWidth()*zoom),(int)(ima->GetHeight()*zoom)), 0,pDoc->GetSmoothMode()!=0); } if ( m_tracker.m_rect.Width()>0 && m_tracker.m_rect.Height()>0 ) m_tracker.Draw(pDC); } } delete pMemDC; }
void CCxImageARDlg::OnBnClickedBtnTemplate() { // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다. if(cxImageARDoc.GetImage() != NULL){ CxImage* cropImage = new CxImage; CxImage* templateImage = new CxImage; CxImage* buffer = cxImageARDoc.Binarization(original); TCHAR* templatePath[4]; templatePath[0] = _T("..\\template\\template01.bmp"); templatePath[1] = _T("..\\template\\template02.bmp"); templatePath[2] = _T("..\\template\\template03.bmp"); templatePath[3] = _T("..\\template\\template04.bmp"); int width = original->GetWidth(); int height = original->GetHeight(); bool findmarker = false; const int search_window = 243; for(int k = 0; k < 1; k++){ for(int y = 1; y < height-search_window; y+=4){ for(int x = 1; x < width-search_window; x+=4){ /* load template Image */ templateImage->Load(templatePath[k], cxImageARDoc.FindType(templatePath[k])); templateImage = cxImageARDoc.Binarization(templateImage); /* extract the region of search window */ cropImage = cxImageARDoc.extractRegion(CPointInt(x, y), CPointInt(x+search_window, y+search_window), buffer); /* Draw template and search window */ CDC* pDC1, *pDC2; CRect rect1, rect2; pDC1 = m_pic_search.GetDC(); m_pic_search.GetClientRect(&rect1); cropImage->Draw(pDC1->m_hDC, rect1); pDC2 = m_pic_template.GetDC(); m_pic_template.GetClientRect(&rect2); templateImage->Draw(pDC2->m_hDC, rect2); ReleaseDC(pDC1); ReleaseDC(pDC2); /* template matching processing */ cropImage->Resample(64, 64); if(cxImageARDoc.templateMatching(templateImage, cropImage)){ /* if template matching is true, then draw the rect of matched area */ RGBQUAD color; color.rgbBlue = 0; color.rgbGreen = 255; color.rgbRed = 0; cxImageARDoc.drawRect(CPointInt(x, y), CPointInt(x+search_window, y+search_window), result, color); findmarker = true; break; } } if(findmarker) break; } if(findmarker) break; } delete buffer; delete cropImage; delete templateImage; } }
void CToolBarCtrlZ::DrawItem(CDC *pDC, int iIndex, const CRect &rtItem, BOOL bHover) { UINT uItemId; UINT uItemState; TBBUTTON tbb; TCHAR szText[1024]; TBBUTTONINFO tbi; CArray<CxImage*, CxImage*> *parrImgs = NULL; CxImage *pIconImg = NULL; int iIconTop; CRect rtDraw; CRect rtText; COLORREF clrText; CClientRect rtClient(this); rtDraw = rtItem; rtDraw.top = rtClient.top; rtDraw.bottom = rtClient.bottom; if (!GetButton(iIndex, &tbb)) return; uItemId = tbb.idCommand; uItemState = GetState(uItemId); parrImgs = &m_arrImgs; if ( !IsButtonEnabled(uItemId) ) { clrText = RGB(204, 128, 128); if (0 != m_arrDisableImgs.GetCount()) parrImgs = &m_arrDisableImgs; } else { clrText = RGB(255, 254, 253); if (TBSTATE_PRESSED & uItemState/*IsButtonPressed(uItemId)*/) rtDraw.OffsetRect(1, 1); else if (bHover/*iIndex == GetHotItem()*/) rtDraw.OffsetRect(-1, -2); } ZeroMemory(&tbi, sizeof(TBBUTTONINFO)); tbi.cbSize = sizeof(TBBUTTONINFO); tbi.dwMask = TBIF_TEXT | TBIF_IMAGE; tbi.pszText = szText; tbi.cchText = 1024; //if (GetButtonInfo(p->nmcd.dwItemSpec, &tbi)) GetButtonInfo(uItemId, &tbi); { rtText = rtDraw; if (tbi.iImage < parrImgs->GetCount()) { pIconImg = parrImgs->GetAt(tbi.iImage); if (NULL != pIconImg) { iIconTop = rtDraw.Height() - pIconImg->GetHeight(); iIconTop /= 2; iIconTop += rtDraw.top; pIconImg->Draw(pDC->GetSafeHdc(), rtDraw.left, iIconTop); rtText.left += pIconImg->GetWidth() + 4; } } { CWndFontDC fontDC(pDC->GetSafeHdc(), GetSafeHwnd()); CTextDC textDC(pDC->GetSafeHdc(), clrText); pDC->DrawText(tbi.pszText, -1, &rtText, DT_LEFT | DT_VCENTER | DT_SINGLELINE); } } }