📄 logo_bitmap_in_client.shtml.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>© 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>4225</FONT></CENTER>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -