在CFormView派生类中绘制背景图如果你需要在表单中绘制位图,象Access那样,本程序可能对你有帮助。首先,在CFormView中添加下面成员:CPalette m_palette; CBitmap m_bitmap; 增加下面函数到派生类中,重载OnDraw函数,增加WM_CTLCOLOR消息的处理函数 OnCtlColor,在 OnInitialUpdate中调用下面函数: GetBitmapAndPalette( IDB_BACK, m_bitmap, m_palette ); 其中,IDB_BACK是要作为背景位图的标识。增加WM_ERASEBKGND消息的处理函数:BOOL CMyView::OnEraseBkgnd(CDC* pDC) {// TODO: Add your message handler code here and/or call defaultreturn FALSE;} void CMyFormView::OnDraw(CDC* pDC) { // TODO: Add your specialized code here and/or call the base class ::DrawTheBackground(this,pDC,&m_palette,&m_bitmap); }
HBRUSH CMyFormView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDaoRecordView::OnCtlColor(pDC, pWnd, nCtlColor); //replace with your own base class
// TODO: Change any attributes of the DC here if(nCtlColor==CTLCOLOR_STATIC){ //this is only an example - you may have to modify here the code in order to work properly for you if(pWnd->GetDlgCtrlID()==IDC_STATIC){ pDC->SetBkMode(TRANSPARENT); //pDC->SetTextColor(RGB(255,255,255)); //you can change here the color of static text return (HBRUSH)::GetStockObject(NULL_BRUSH); } }else pDC->SetBkMode(OPAQUE);
// TODO: Return a different brush if the default is not desired return hbr; }
BOOL CMyFormView::GetBitmapAndPalette(UINT nIDResource, CBitmap &bitmap, CPalette &pal) { LPCTSTR lpszResourceName = (LPCTSTR)nIDResource; HBITMAP hBmp = (HBITMAP)::LoadImage( AfxGetInstanceHandle(), lpszResourceName, IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION ); if( hBmp == NULL )return FALSE; bitmap.Attach( hBmp ); // Create a logical palette for the bitmap DIBSECTION ds; BITMAPINFOHEADER &bmInfo = ds.dsBmih; bitmap.GetObject( sizeof(ds), &ds ); int nColors = bmInfo.biClrUsed ? bmInfo.biClrUsed : 1 << bmInfo.biBitCount; // Create a halftone palette if colors > 256. CClientDC dc(NULL); // Desktop DC if( nColors > 256 ) pal.CreateHalftonePalette( &dc ); else{ // Create the palette RGBQUAD *pRGB = new RGBQUAD[nColors]; CDC memDC; memDC.CreateCompatibleDC(&dc); memDC.SelectObject( &bitmap ); ::GetDIBColorTable( memDC, 0, nColors, pRGB ); UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors); LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize]; pLP->palVersion = 0x300; pLP->palNumEntries = nColors; for( int i=0; i < nColors; i++){ pLP->palPalEntry[i].peRed = pRGB[i].rgbRed; pLP->palPalEntry[i].peGreen = pRGB[i].rgbGreen; pLP->palPalEntry[i].peBlue = pRGB[i].rgbBlue; pLP->palPalEntry[i].peFlags = 0; } pal.CreatePalette( pLP ); delete[] pLP; delete[] pRGB; } return TRUE; } void DrawTheBackground(CDaoRecordView *view,CDC *pDC,CPalette *mp_palette,CBitmap *mp_bitmap) { if(pDC->IsPrinting())return; CRect rect; CPalette *old_palette=NULL; // Select and realize the palette if( pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE && mp_palette->m_hObject != NULL ){ old_palette=pDC->SelectPalette( mp_palette, FALSE ); pDC->RealizePalette(); } view->GetClientRect(rect); pDC->DPtoLP(rect); CMemDC DC(pDC,rect); CDC dcImage; if (!dcImage.CreateCompatibleDC(pDC))return; BITMAP bm; mp_bitmap->GetBitmap(&bm); // Paint the image. CBitmap* pOldBitmap = dcImage.SelectObject(mp_bitmap); for(int i=((int)floor((double)rect.left/bm.bmWidth))*bm.bmWidth;i<=rect.right/*rect.Width()*/;i+=bm.bmWidth) for(int j=((int)floor((double)rect.top/bm.bmHeight))*bm.bmHeight;j<=rect.bottom/*rect.Height()*/;j+=bm.bmHeight) DC->BitBlt(i, j, bm.bmWidth, bm.bmHeight, &dcImage, 0, 0, SRCCOPY); dcImage.SelectObject(pOldBitmap); pDC->SelectPalette(old_palette,FALSE); pDC->RealizePalette(); }#ifndef _MEMDC_H_ #define _MEMDC_H_ ////////////////////////////////////////////////// // CMemDC - memory DC // // Author: Keith Rule // Email: [email protected] // Copyright 1996-1997, Keith Rule // // You may freely use or modify this code provided this // Copyright is included in all derived versions. // // History - 10/3/97 Fixed scrolling bug. // Added print support. // // This class implements a memory Device Context class CMemDC : public CDC { private: CBitmap m_bitmap; // Offscreen bitmap CBitmap* m_oldBitmap; // bitmap originally found in CMemDC CDC* m_pDC; // Saves CDC passed in constructor CRect m_rect; // Rectangle of drawing area. BOOL m_bMemDC; // TRUE if CDC really is a Memory DC. public: CMemDC(CDC* pDC, CRect &rect) : CDC(), m_oldBitmap(NULL), m_pDC(pDC) { ASSERT(m_pDC != NULL); // If you asserted here, you passed in a NULL CDC. m_bMemDC = !pDC->IsPrinting(); m_rect=rect; if (m_bMemDC){ // Create a Memory DC CreateCompatibleDC(pDC); pDC->GetClipBox(&m_rect); m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height()); m_oldBitmap = SelectObject(&m_bitmap); SetWindowOrg(m_rect.left, m_rect.top); } else { // Make a copy of the relevent parts of the current DC for printing m_bPrinting = pDC->m_bPrinting; m_hDC = pDC->m_hDC; m_hAttribDC = pDC->m_hAttribDC; } } ~CMemDC() { if (m_bMemDC) { // Copy the offscreen bitmap onto the screen. m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(), this, m_rect.left, m_rect.top, SRCCOPY); //Swap back the original bitmap. SelectObject(m_oldBitmap); } else { // All we need to do is replace the DC with an illegal value, // this keeps us from accidently deleting the handles associated with // the CDC that was passed to the constructor. m_hDC = m_hAttribDC = NULL; } } // Allow usage as a pointer CMemDC* operator->() {return this;} // Allow usage as a pointer operator CMemDC*() {return this;} }; #endif
ListCtrl贴图 BOOL CSwithListCtrl::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default RECT rcClient; //if backup is fill color if(BKMode==BK_IS_COLOR) { GetClientRect(&rcClient); pDC->FillRect(&rcClient,&CBrush(BKColor)); return TRUE; } //if background is picture if( m_bitmap.m_hObject != NULL ) { CDC tempDC; tempDC.CreateCompatibleDC(pDC); tempDC.SelectObject( &m_bitmap ); //rCtrlList.GetClientRect(&rcClient); GetClientRect(&rcClient); CRgn rgnBitmap; CRect rcTmpBmp;//( rcItem );
rcTmpBmp.right = rcClient.right; // We also need to check whether it is the last item // The update region has to be extended to the bottom if it is //if( nItem == rCtrlList.GetItemCount() - 1 ) rcTmpBmp.bottom = rcClient.bottom; rgnBitmap.CreateRectRgnIndirect(&rcTmpBmp); pDC->SelectClipRgn(&rgnBitmap); rgnBitmap.DeleteObject();
if( pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE && m_pal.m_hObject != NULL ) { pDC->SelectPalette( &m_pal, FALSE ); pDC->RealizePalette(); } for( int i = 0; i < rcClient.right; i += m_cxBitmap ) for( int j = 0; j < rcClient.bottom; j += m_cyBitmap ) pDC->BitBlt( i, j, m_cxBitmap, m_cyBitmap, &tempDC, 0, 0, SRCCOPY ); return TRUE; } return CListCtrl::OnEraseBkgnd(pDC); }
BOOL CSDIOutlookView::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CRect rectbk;
CBitmap bmbk;
CDC dcMen;
bmbk.LoadBitmap(IDC_CJ_LOGO);
BITMAP stBitmap;
bmbk.GetObject(sizeof(BITMAP),&stBitmap);
CSize bmsize(stBitmap.bmWidth,stBitmap.bmHeight);
dcMen.CreateCompatibleDC(pDC);
CBitmap *pold=dcMen.SelectObject(&bmbk);
GetClientRect(&rectbk);
pDC->StretchBlt(rectbk.left,rectbk.top,rectbk.Width(),rectbk.Height(),&dcMen,0,0,bmsize.cx,bmsize.cy,SRCCOPY);
dcMen.SelectObject(pold);
dcMen.DeleteDC();
return true;
}How to use thumbnail images in a list control
http://www.codeproject.com/listctrl/thumbnail.asp
CBitmap m_bitmap;
增加下面函数到派生类中,重载OnDraw函数,增加WM_CTLCOLOR消息的处理函数 OnCtlColor,在 OnInitialUpdate中调用下面函数: GetBitmapAndPalette( IDB_BACK, m_bitmap, m_palette );
其中,IDB_BACK是要作为背景位图的标识。增加WM_ERASEBKGND消息的处理函数:BOOL CMyView::OnEraseBkgnd(CDC* pDC) {// TODO: Add your message handler code here and/or call defaultreturn FALSE;} void CMyFormView::OnDraw(CDC* pDC)
{
// TODO: Add your specialized code here and/or call the base class
::DrawTheBackground(this,pDC,&m_palette,&m_bitmap);
}
HBRUSH CMyFormView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDaoRecordView::OnCtlColor(pDC, pWnd, nCtlColor); //replace with your own base class
// TODO: Change any attributes of the DC here
if(nCtlColor==CTLCOLOR_STATIC){
//this is only an example - you may have to modify here the code in order to work properly for you
if(pWnd->GetDlgCtrlID()==IDC_STATIC){
pDC->SetBkMode(TRANSPARENT);
//pDC->SetTextColor(RGB(255,255,255)); //you can change here the color of static text
return (HBRUSH)::GetStockObject(NULL_BRUSH);
}
}else pDC->SetBkMode(OPAQUE);
// TODO: Return a different brush if the default is not desired
return hbr;
}
BOOL CMyFormView::GetBitmapAndPalette(UINT nIDResource, CBitmap &bitmap, CPalette &pal)
{
LPCTSTR lpszResourceName = (LPCTSTR)nIDResource;
HBITMAP hBmp = (HBITMAP)::LoadImage( AfxGetInstanceHandle(),
lpszResourceName, IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION );
if( hBmp == NULL )return FALSE;
bitmap.Attach( hBmp );
// Create a logical palette for the bitmap
DIBSECTION ds;
BITMAPINFOHEADER &bmInfo = ds.dsBmih;
bitmap.GetObject( sizeof(ds), &ds );
int nColors = bmInfo.biClrUsed ? bmInfo.biClrUsed : 1 << bmInfo.biBitCount;
// Create a halftone palette if colors > 256.
CClientDC dc(NULL); // Desktop DC
if( nColors > 256 ) pal.CreateHalftonePalette( &dc );
else{
// Create the palette
RGBQUAD *pRGB = new RGBQUAD[nColors];
CDC memDC;
memDC.CreateCompatibleDC(&dc);
memDC.SelectObject( &bitmap );
::GetDIBColorTable( memDC, 0, nColors, pRGB );
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
pLP->palVersion = 0x300;
pLP->palNumEntries = nColors;
for( int i=0; i < nColors; i++){
pLP->palPalEntry[i].peRed = pRGB[i].rgbRed;
pLP->palPalEntry[i].peGreen = pRGB[i].rgbGreen;
pLP->palPalEntry[i].peBlue = pRGB[i].rgbBlue;
pLP->palPalEntry[i].peFlags = 0;
}
pal.CreatePalette( pLP );
delete[] pLP;
delete[] pRGB;
}
return TRUE;
}
void DrawTheBackground(CDaoRecordView *view,CDC *pDC,CPalette *mp_palette,CBitmap *mp_bitmap)
{
if(pDC->IsPrinting())return;
CRect rect;
CPalette *old_palette=NULL;
// Select and realize the palette
if( pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE && mp_palette->m_hObject != NULL ){
old_palette=pDC->SelectPalette( mp_palette, FALSE );
pDC->RealizePalette();
}
view->GetClientRect(rect);
pDC->DPtoLP(rect);
CMemDC DC(pDC,rect);
CDC dcImage;
if (!dcImage.CreateCompatibleDC(pDC))return;
BITMAP bm;
mp_bitmap->GetBitmap(&bm);
// Paint the image.
CBitmap* pOldBitmap = dcImage.SelectObject(mp_bitmap);
for(int i=((int)floor((double)rect.left/bm.bmWidth))*bm.bmWidth;i<=rect.right/*rect.Width()*/;i+=bm.bmWidth)
for(int j=((int)floor((double)rect.top/bm.bmHeight))*bm.bmHeight;j<=rect.bottom/*rect.Height()*/;j+=bm.bmHeight)
DC->BitBlt(i, j, bm.bmWidth, bm.bmHeight, &dcImage, 0, 0, SRCCOPY);
dcImage.SelectObject(pOldBitmap);
pDC->SelectPalette(old_palette,FALSE);
pDC->RealizePalette();
}#ifndef _MEMDC_H_
#define _MEMDC_H_
//////////////////////////////////////////////////
// CMemDC - memory DC
//
// Author: Keith Rule
// Email: [email protected]
// Copyright 1996-1997, Keith Rule
//
// You may freely use or modify this code provided this
// Copyright is included in all derived versions.
//
// History - 10/3/97 Fixed scrolling bug.
// Added print support.
//
// This class implements a memory Device Context
class CMemDC : public CDC {
private:
CBitmap m_bitmap; // Offscreen bitmap
CBitmap* m_oldBitmap; // bitmap originally found in CMemDC
CDC* m_pDC; // Saves CDC passed in constructor
CRect m_rect; // Rectangle of drawing area.
BOOL m_bMemDC; // TRUE if CDC really is a Memory DC.
public:
CMemDC(CDC* pDC, CRect &rect) : CDC(), m_oldBitmap(NULL), m_pDC(pDC)
{
ASSERT(m_pDC != NULL); // If you asserted here, you passed in a NULL CDC.
m_bMemDC = !pDC->IsPrinting();
m_rect=rect;
if (m_bMemDC){
// Create a Memory DC
CreateCompatibleDC(pDC);
pDC->GetClipBox(&m_rect);
m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
m_oldBitmap = SelectObject(&m_bitmap);
SetWindowOrg(m_rect.left, m_rect.top);
} else {
// Make a copy of the relevent parts of the current DC for printing
m_bPrinting = pDC->m_bPrinting;
m_hDC = pDC->m_hDC;
m_hAttribDC = pDC->m_hAttribDC;
}
}
~CMemDC()
{
if (m_bMemDC) {
// Copy the offscreen bitmap onto the screen.
m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
this, m_rect.left, m_rect.top, SRCCOPY);
//Swap back the original bitmap.
SelectObject(m_oldBitmap);
} else {
// All we need to do is replace the DC with an illegal value,
// this keeps us from accidently deleting the handles associated with
// the CDC that was passed to the constructor.
m_hDC = m_hAttribDC = NULL;
}
}
// Allow usage as a pointer
CMemDC* operator->() {return this;}
// Allow usage as a pointer
operator CMemDC*() {return this;}
};
#endif
BOOL CSwithListCtrl::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
RECT rcClient; //if backup is fill color
if(BKMode==BK_IS_COLOR)
{
GetClientRect(&rcClient);
pDC->FillRect(&rcClient,&CBrush(BKColor));
return TRUE;
}
//if background is picture
if( m_bitmap.m_hObject != NULL )
{
CDC tempDC;
tempDC.CreateCompatibleDC(pDC);
tempDC.SelectObject( &m_bitmap ); //rCtrlList.GetClientRect(&rcClient);
GetClientRect(&rcClient);
CRgn rgnBitmap;
CRect rcTmpBmp;//( rcItem );
rcTmpBmp.right = rcClient.right; // We also need to check whether it is the last item
// The update region has to be extended to the bottom if it is
//if( nItem == rCtrlList.GetItemCount() - 1 )
rcTmpBmp.bottom = rcClient.bottom; rgnBitmap.CreateRectRgnIndirect(&rcTmpBmp);
pDC->SelectClipRgn(&rgnBitmap);
rgnBitmap.DeleteObject();
if( pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE && m_pal.m_hObject != NULL )
{
pDC->SelectPalette( &m_pal, FALSE );
pDC->RealizePalette();
} for( int i = 0; i < rcClient.right; i += m_cxBitmap )
for( int j = 0; j < rcClient.bottom; j += m_cyBitmap )
pDC->BitBlt( i, j, m_cxBitmap, m_cyBitmap, &tempDC,
0, 0, SRCCOPY );
return TRUE;
}
return CListCtrl::OnEraseBkgnd(pDC);
}
BOOL CSwithListCtrl::SetBkImage(LPCTSTR lpszResourceName)
{
if( m_bitmap.m_hObject != NULL )
m_bitmap.DeleteObject();
if( m_pal.m_hObject != NULL )
m_pal.DeleteObject();
HBITMAP hBmp = (HBITMAP)::LoadImage( AfxGetInstanceHandle(),
lpszResourceName, IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION ); if( hBmp == NULL )
return FALSE; m_bitmap.Attach( hBmp );
BITMAP bm;
m_bitmap.GetBitmap( &bm );
m_cxBitmap = bm.bmWidth;
m_cyBitmap = bm.bmHeight;
// Create a logical palette for the bitmap
DIBSECTION ds;
BITMAPINFOHEADER &bmInfo = ds.dsBmih;
m_bitmap.GetObject( sizeof(ds), &ds ); int nColors = bmInfo.biClrUsed ? bmInfo.biClrUsed : 1 << bmInfo.biBitCount; // Create a halftone palette if colors > 256.
CClientDC dc(NULL); // Desktop DC
if( nColors > 256 )
m_pal.CreateHalftonePalette( &dc );
else
{
// Create the palette RGBQUAD *pRGB = new RGBQUAD[nColors];
CDC memDC;
memDC.CreateCompatibleDC(&dc); memDC.SelectObject( &m_bitmap );
::GetDIBColorTable( memDC, 0, nColors, pRGB ); UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize]; pLP->palVersion = 0x300;
pLP->palNumEntries = nColors; for( int i=0; i < nColors; i++)
{
pLP->palPalEntry[i].peRed = pRGB[i].rgbRed;
pLP->palPalEntry[i].peGreen = pRGB[i].rgbGreen;
pLP->palPalEntry[i].peBlue = pRGB[i].rgbBlue;
pLP->palPalEntry[i].peFlags = 0;
} m_pal.CreatePalette( pLP ); delete[] pLP;
delete[] pRGB;
}
Invalidate(); return TRUE;
}BOOL CSwithListCtrl::SetBkImage(UINT nIDResource)
{
return SetBkImage( (LPCTSTR)nIDResource );
}由于ListView是ListCtrl的派生类,照猫画虎即可