关于各种图片加载,使用统一的函数,从资源加载
#pragma once #include <atlimage.h> BOOL LoadCImageFromResourse(CImage *pImage, UINT nResID, LPCTSTR lpTyp, HMODULE hModule) { if (pImage == NULL) return FALSE; pImage->Destroy(); if (lpTyp == _T("BMP")) { pImage->LoadFromResource(hModule, MAKEINTRESOURCE(nResID)); return TRUE; } // 查找资源 HRSRC hRsrc = ::FindResource(hModule, MAKEINTRESOURCE(nResID), lpTyp); if (hRsrc == NULL) return FALSE; // 加载资源 HGLOBAL hImgData = ::LoadResource(hModule, hRsrc); if (hImgData == NULL) { ::FreeResource(hImgData); return FALSE; } // 锁定内存中的指定资源 LPVOID lpVoid = ::LockResource(hImgData); LPSTREAM pStream = NULL; DWORD dwSize = ::SizeofResource(hModule, hRsrc); HGLOBAL hNew = ::GlobalAlloc(GHND, dwSize); LPBYTE lpByte = (LPBYTE)::GlobalLock(hNew); ::memcpy(lpByte, lpVoid, dwSize); // 解除内存中的指定资源 ::GlobalUnlock(hNew); // 从指定内存创建流对象 HRESULT ht = ::CreateStreamOnHGlobal(hNew, TRUE, &pStream); if (ht != S_OK) { GlobalFree(hNew); } else { // 加载图片 pImage->Load(pStream); if (pImage->GetBPP() == 32) //确认该图片包含Alpha通道 { for (int i = 0; i < pImage->GetWidth(); i++) for (int j = 0; j < pImage->GetHeight(); j++) { byte* pByte = (byte*)pImage->GetPixelAddress(i, j); pByte[0] = pByte[0] * pByte[3] / 255; pByte[1] = pByte[1] * pByte[3] / 255; pByte[2] = pByte[2] * pByte[3] / 255; } } GlobalFree(hNew); } // 释放资源 ::FreeResource(hImgData); return TRUE; }
1、对话框背景绘图
BOOL CMFCTest1Dlg::OnEraseBkgnd(CDC* pDC) { CRect rect; GetClientRect(rect); CDC mdc; mdc.CreateCompatibleDC(pDC); CImage img; LoadCImageFromResourse(&img,IDB_PNG2,L"PNG",AfxGetInstanceHandle()); CBitmap bmp; bmp.CreateCompatibleBitmap(pDC,img.GetWidth(),img.GetHeight()); mdc.SelectObject(&bmp); img.Draw(mdc, CRect(0,0, img.GetWidth(), img.GetHeight())); //pDC->BitBlt(0,0,rect.Width(),rect.Height(),&mdc,0,0, SRCCOPY); pDC->SetStretchBltMode(STRETCH_HALFTONE);//防止失真 pDC->StretchBlt(0,0,rect.Width()-200,rect.Height()-100,&mdc,0,0, img.GetWidth(), img.GetHeight(),SRCCOPY); return TRUE; }
HBRUSH CMFCTest1Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { //pDC是控件文字颜色和背景的DC HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); // 根据控件ID来决定颜色 switch (pWnd->GetDlgCtrlID()) { case IDC_STATIC: { //和SetBkColor只能存一,透明时只能传回空画刷 pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(RGB(255, 255, 255)); //pDC->SetBkColor(RGB(0,255,0)); return (HBRUSH)(GetStockObject(NULL_BRUSH)); } case IDC_EDIT1: { pDC->SetTextColor(RGB(255, 0, 0)); pDC->SetBkMode(TRANSPARENT); static CBrush br(RGB(255,255,0)); return br; } default: return hbr; break; } }
3、按钮的简单自绘
void CButtonEx::DrawItem(LPDRAWITEMSTRUCT lpDIS) { CDC dc; dc.Attach(lpDIS->hDC);//或者用FromHandle CRect rect(lpDIS->rcItem); CString btnText; GetWindowText(btnText); // 绘制按钮的选中动态 COLORREF bkColor; if (lpDIS->itemState & ODS_SELECTED) { bkColor = GetSysColor(COLOR_BTNFACE); dc.DrawEdge(rect,BDR_SUNKENINNER,BF_RECT); rect.OffsetRect(2, 2); } else { bkColor = RGB(200, 200, 200); dc.DrawEdge(rect, BDR_RAISEDINNER, BF_RECT); } // 填充绘制背景色 dc.FillSolidRect(rect, bkColor); // 双缓冲绘制按钮图标png图片 CImage img; LoadCImageFromResourse(&img, m_hIconId, _T("PNG"), AfxGetInstanceHandle()); img.Draw(dc,CRect(10, (rect.Height() - 20) / 2, 20, 20), CRect(0, 0, img.GetWidth(), img.GetHeight())); // 绘制获得焦点的边框 if (lpDIS->itemState & ODS_FOCUS) { rect.DeflateRect(1, 1); dc.DrawFocusRect(rect); } // 绘制文字 COLORREF crOldColor = dc.SetTextColor(RGB(255, 0, 0)); dc.SetBkMode(TRANSPARENT);//文字背景透明 dc.DrawText(btnText, btnText.GetLength(), rect, DT_SINGLELINE | DT_VCENTER | DT_CENTER); dc.SetTextColor(crOldColor); dc.Detach(); }
4、对话框标题栏自绘
在OnInitDialog里设置标题文字,及任务栏的样式
SetWindowText(L"测试"); ModifyStyle(NULL, WS_SYSMENU | WS_MINIMIZEBOX);
LRESULT CMFCTest1Dlg::OnNcHitTest(CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 UINT nRet = CDialog::OnNcHitTest(point); ScreenToClient(&point); if (HTCLIENT == nRet && point.y < 25) { return HTCAPTION; } return nRet; }
5、下拉列表自绘
void CMyComboBox::DrawItem(LPDRAWITEMSTRUCT lpDIS) { CDC dc; dc.Attach(lpDIS->hDC); CString str; GetLBText(lpDIS->itemID, str); COLORREF cor; if (ODS_SELECTED & lpDIS->itemState) { cor = GetSysColor(COLOR_HIGHLIGHT); dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT)); dc.FillSolidRect(&lpDIS->rcItem, cor); if (lpDIS->itemAction & ODA_FOCUS) { //dc.DrawFocusRect(&lpDIS->rcItem); } } else { cor = GetSysColor(COLOR_WINDOW); dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT)); dc.FillSolidRect(&lpDIS->rcItem, cor); } //dc.SetBkMode(TRANSPARENT); //dc.SetTextColor(RGB(0,0,0)); // 双缓冲绘制按钮图标png图片 CImage img; LoadCImageFromResourse(&img, GetImage(lpDIS->itemID), _T("PNG"), AfxGetInstanceHandle()); img.Draw(dc,CRect(4, (lpDIS->rcItem).top +((lpDIS->rcItem).bottom- (lpDIS->rcItem).top - 16) / 2, 16, 16) , CRect(0, 0, img.GetWidth(), img.GetHeight())); CRect rcc(lpDIS->rcItem); rcc.left += 4 + 16 + 4; dc.DrawText(str, rcc,DT_LEFT|DT_VCENTER|DT_SINGLELINE); dc.Detach(); } void CMyComboBox::AddItem(LPCTSTR szText, int nImage) { sData* pData = new sData; pData->nImage = nImage; pData->szText = szText; int i = GetCount(); AddString(szText); SetItemData(i,(DWORD)pData); } void CMyComboBox::GetLBText(int nIndex, CString& rString) const { ASSERT(nIndex < GetCount()); sData* pData = (sData*)GetItemData(nIndex); rString = pData->szText; } UINT CMyComboBox::GetImage(int nIndex) const { ASSERT(nIndex < GetCount()); sData* pData = (sData*)GetItemData(nIndex); return pData->nImage; }
6、CListCtrl的颜色和字体的自绘
void CMyListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDIS) { CDC dc; dc.Attach(lpDIS->hDC); CRect rect = lpDIS->rcItem,rc; int nItem = lpDIS->itemID; CHeaderCtrl* pHeader = GetHeaderCtrl(); // 假设排序列是1 int sortlist = 1; int i = 0, nCount = pHeader->GetItemCount(); while (i < nCount) { pHeader->GetItemRect(i, rc); rc.top = rect.top; rc.bottom = rect.bottom; if (ODS_SELECTED & lpDIS->itemState) { dc.FillSolidRect(rc, GetSysColor(COLOR_HIGHLIGHT)); dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT)); } else { if (sortlist == i) { // 如果选中的列和当前列相等,就颜色加深 if (nItem % 2) dc.FillSolidRect(rc, RGB(180, 190, 176)); else dc.FillSolidRect(rc, RGB(140, 190, 176)); dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT)); } else { if (nItem % 2) dc.FillSolidRect(rc, RGB(200, 210, 196)); else dc.FillSolidRect(rc, RGB(165, 210, 196)); dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT)); } } CString str = GetItemText(nItem, i); dc.DrawText(str, rc, DT_VCENTER | DT_SINGLELINE|DT_CENTER); ++i; } dc.Detach(); }