📄 formview_background.shtml.htm
字号:
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Author" CONTENT="Zafir Anjum">
<TITLE>Bitmap - Painting the background for a CFormView derived class</TITLE>
</HEAD>
<body background="../fancyhome/back.gif" tppabs="http://www.codeguru.com/fancyhome/back.gif" bgcolor="#FFFFFF" link="#B50029" vlink="#8E2323" alink="#FF0000">
<table WIDTH="100%">
<tr WIDTH="100%">
<td><td>
</tr>
</table>
<CENTER>
<H3>
<FONT COLOR="#AOAO99">Painting the background for a CFormView derived class</FONT></H3></CENTER>
<CENTER>
<H3><HR></H3></CENTER>
This article was contributed by <A HREF="mailto:aroman@medanet.ro">Adrian Roman</A>.
<P>I wanted to paint bitmaps on forms, like Access does. So I wrote some code for that: First, add in your derived CFormView two members: </P>
<FONT COLOR="#800000"><TT><PRE>
CPalette m_palette;
CBitmap m_bitmap;</PRE>
</FONT></TT><P>Add the following functions to your derived class: OnDraw overrides the base class' function, and OnCtlColor is a handler for WM_CTLCOLOR message. Call in OnInitialUpdate the function: </P>
<FONT COLOR="#800000"><TT><PRE>
	GetBitmapAndPalette( IDB_BACK, m_bitmap, m_palette );</PRE>
</FONT></TT><P>where IDB_BACK is the identifier for the bitmap you want as background. </P>
<P>The code uses Keith Rule's CMemDC class. I added it here, so you don't have to search for it.</P>
<P>Add to your view a handler for WM_ERASEBKGND message:</P>
<FONT COLOR="#800000"><P>BOOL CMyView::OnEraseBkgnd(CDC* pDC) </P>
<P>{</P>
<P>	// TODO: Add your message handler code here and/or call default</P>
<P>	return FALSE;</P>
<P>}</P>
</FONT><P> </P>
<FONT COLOR="#800000"><TT><PRE>
void CMyFormView::OnDraw(CDC* pDC)
{
	// TODO: Add your specialized code here and/or call the base class
</TT>	::DrawTheBackground(this,pDC,&m_palette,&m_bitmap);
<TT>}
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;
}
</TT>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();	
}
<TT>
</TT>#ifndef _MEMDC_H_
#define _MEMDC_H_
//////////////////////////////////////////////////
// CMemDC - memory DC
//
// Author: Keith Rule
// Email: keithr@europa.com
// 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
<TT>
</PRE>
</FONT></TT>
<P>
<HR>
<TABLE BORDER=0 WIDTH="100%" >
<TR>
<TD WIDTH="33%"><FONT SIZE=-1><A HREF="../index.htm" tppabs="http://www.codeguru.com/">Goto HomePage</A></FONT></TD>
<TD WIDTH="33%">
<CENTER><FONT SIZE=-2>© 1997 Zafir Anjum</FONT> </CENTER>
</TD>
<TD WIDTH="34%">
<DIV ALIGN=right><FONT SIZE=-1>Contact me: <A HREF="mailto:zafir@home.com">zafir@home.com</A> </FONT></DIV>
</TD>
</TR>
</TABLE>
<CENTER><FONT SIZE=-2>8224</FONT></CENTER>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -