⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 logo_bitmap_in_client.shtml.htm

📁 mfc资料集合5
💻 HTM
字号:
<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
   <META NAME="Author" CONTENT="Zafir Anjum">
   <TITLE>Bitmap & Palette - A logo bitmap inside client frame</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><A HREF="http://209.66.99.126/cgi/ads.cgi?advert=myad2"><IMG SRC="../../209.66.99.126/advertise2.gif" tppabs="http://209.66.99.126/advertise2.gif" ALT="" BORDER=2></A><td>
</tr>
</table>


<CENTER>
<H3>
<FONT COLOR="#AOAO99">A logo bitmap inside client frame</FONT></H3></CENTER>
<HR>


<P>This article was contributed by <A HREF="mailto:aroman@medanet.ro">Adrian Roman</A>. </P>
 
<P>If you want to paint inside client area (a logo in the middle or even all background), this class should fit your needs. If you want to paint a logo, it will redraw only the rectangle, which cover the invalid rectangle, the old bitmap area, and the new logo area. Because I used the memory dc, it draws it very smoothly, even with "Show window contents while dragging" from Plus Pack.
<P>This class is not so original. It contains some code from codeguru, some from MSJ, and of course, some of mine. I made it as fast as I could, so I reused as much code I could found.
 
<P>In CMainFrame, override the OnCreateClient virtual function:
 
<PRE><TT><FONT COLOR="#990000">
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 
{
	// TODO: Add your specialized code here and/or call the base class
	if(CMDIFrameWnd::OnCreateClient(lpcs, pContext)){
		m_ClientFrame.SubclassWindow(m_hWndMDIClient) ;
		return TRUE;
	}else return FALSE; 
}
</FONT></TT></PRE>
 
Header file:

<PRE><TT><FONT COLOR="#990000"> 
#if !defined(AFX_CLIENTFRAME_H__9F201E20_8B54_11D1_87E4_00AA00242F4F__INCLUDED_)
#define AFX_CLIENTFRAME_H__9F201E20_8B54_11D1_87E4_00AA00242F4F__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// ClientFrame.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CClientFrame frame

class CClientFrame : public CWnd
{
	DECLARE_DYNCREATE(CClientFrame)
protected:
	
	// Attributes
public:
	CClientFrame(); // protected constructor used by dynamic creation
	virtual ~CClientFrame();
	static WNDPROC pfnSuper;
	
	// Operations
public:
	CPalette m_palette;
	CBitmap m_bitmap;
	virtual WNDPROC* GetSuperWndProcAddr() ;
	
	// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CClientFrame)
	//}}AFX_VIRTUAL
	
	// Implementation
protected:
	
	// Generated message map functions
	//{{AFX_MSG(CClientFrame)
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	afx_msg void OnPaint();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_CLIENTFRAME_H__9F201E20_8B54_11D1_87E4_00AA00242F4F__INCLUDED_)
 
Implementation frame:
 
// ClientFrame.cpp : implementation file
//
 
#include "stdafx.h"
#include "ClientFrame.h"
#include "helper.h"
 
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
 
 
extern CRect oldrect;
 
WNDPROC CClientFrame::pfnSuper = NULL;
 
/////////////////////////////////////////////////////////////////////////////
// CClientFrame
 
IMPLEMENT_DYNCREATE(CClientFrame, CWnd)
 
CClientFrame::CClientFrame()
{
	GetBitmapAndPalette( IDB_LOGO, m_bitmap, m_palette ); 
}
 
CClientFrame::~CClientFrame()
{
}

BEGIN_MESSAGE_MAP(CClientFrame, CWnd)
//{{AFX_MSG_MAP(CClientFrame)
ON_WM_ERASEBKGND()
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
 
/////////////////////////////////////////////////////////////////////////////
// CClientFrame message handlers
 
BOOL CClientFrame::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default
	return TRUE;
}




WNDPROC* CClientFrame::GetSuperWndProcAddr()
{
	return &pfnSuper;
}



void CClientFrame::OnPaint() 
{
	// Do not call CWnd::OnPaint() for painting messages
	// TODO: Add your message handler code here
	InvalidateRect(&oldrect);
	CRect newrect;
	GetClientRect(&newrect);
	//CDC *dc=GetDC();
	//dc->DPtoLP(newrect);
	//ReleaseDC(dc);
	BITMAP bm;
	m_bitmap.GetBitmap(&bm);
	newrect=CRect(newrect.Width()/2-bm.bmWidth/2,newrect.Height()/2-bm.bmHeight/2,newrect.Width()/2-bm.bmWidth/2+ bm.bmWidth,newrect.Height()/2-bm.bmHeight/2+ bm.bmHeight);
	InvalidateRect(&newrect);
	
	{
		CPaintDC dc(this); // device context for painting
		//dc.SelectClipRgn(NULL);
		DrawTheBackground(this,&dc,&m_palette,&m_bitmap,TRUE);
	}
}
 
 
 
#ifndef __HELPER_H_
#define __HELPER_H_
void DrawTheBackground(CWnd *view,CDC *pDC,CPalette *mp_palette,CBitmap *mp_bitmap,BOOL middle = FALSE);
BOOL GetBitmapAndPalette(UINT nIDResource, CBitmap &bitmap, CPalette &pal);
#endif
 
Helper implementation:
 
#include "stdafx.h"
#include "helper.h"
#include "memdc.h"
 
CRect oldrect(0,0,0,0);
 
 
 
void DrawTheBackground(CWnd *view,CDC *pDC,CPalette *mp_palette,CBitmap *mp_bitmap,BOOL middle)
{
	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);
	if(middle){
		CBrush* pOldBrush = (CBrush*)DC->SelectStockObject(GRAY_BRUSH);
		CRect crect;
		oldrect=CRect((rect.Width()-bm.bmWidth)/2,(rect.Height()-bm.bmHeight)/2,(rect.Width()-bm.bmWidth)/2+ bm.bmWidth,(rect.Height()-bm.bmHeight)/2+ bm.bmHeight);
		pDC->GetClipBox(&crect);
		DC->PatBlt( crect.left, crect.top, crect.Width(), crect.Height(),PATCOPY);
		DC->SelectObject(pOldBrush);
		DC->BitBlt(oldrect.left, oldrect.top, bm.bmWidth, bm.bmHeight, &dcImage, 0, 0, SRCCOPY);
	}else{
		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(); 
}



BOOL 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;
}
</FONT></TT></PRE>


CMemDC implementation (for those who don't have it yet):

<PRE><TT><FONT COLOR="#990000"> 
#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.
// 12/19/97 Adrian Roman - modified the constructor to take two parameters
//
// 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
	BOOL m_bMemDC; // TRUE if CDC really is a Memory DC.
public:
	CRect m_rect; // Rectangle of drawing area.
	
	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
</FONT></TT></PRE>









<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>&copy; 1997 Zafir Anjum</FONT>&nbsp;</CENTER>
</TD>

<TD WIDTH="34%">
<DIV ALIGN=right><FONT SIZE=-1>Contact me: <A HREF="mailto:zafir@home.com">zafir@home.com</A>&nbsp;</FONT></DIV>
</TD>
</TR>
</TABLE>
<CENTER><FONT SIZE=-2>4225</FONT></CENTER>
</BODY>
</HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -