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

📄 bitmap_picture.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 - An auto-sizing bitmap picture control</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">An auto-sizing bitmap picture control</FONT></H3></CENTER>
<HR>

This article was contributed by <A HREF="mailto:Chris.Maunder@cbr.clw.csiro.au">Chris Maunder</A>.

<P><IMG SRC="BitmapPicture.gif" tppabs="http://www.codeguru.com/bitmap/BitmapPicture.gif" ALT="BitmapPicture image" BORDER=0  ALIGN=BOTTOM>
Download <A HREF="BitmapPicture.zip" tppabs="http://www.codeguru.com/bitmap/BitmapPicture.zip">source</A> files (2.8Kb) or 
<A HREF="DialogBitmap.zip" tppabs="http://www.codeguru.com/bitmap/DialogBitmap.zip">sample</A> project (20.7Kb)

<P>The Picture control available from the dialog editor component bar is
great for quickly displaying a picture in a dialog, but it only displays
the picture at the original picture's size. A problem occurs if you want to
display a bitmap which must be aligned with other controls (eg. a bitmap
of an arrow). If you change the size of the dialog box font, then the size
and position of each control will also change, but the size of the displayed
bitmap will not, resulting in a mis-aligned picture. The problem also occurs
if the system font size is changed (The matrox millenium drivers allow you
to do this).

<p>To overcome this problem I wrote a CStatic derived class that displays
a bitmap according to the size of the underlying CStatic window. When the
font size changes, the CStatic window size changes, and the bitmap will
be StretchBlt'd to the new size. This allows images to be displayed smaller
and larger than their original size.

<p>The easist way to use this class is to add the CBitmapPicture class to
your project then create a CStatic object to yuour dialog, and attach a member
variable of type CBitmapPicture to the object. Then in your OnInitDialog
function, call CBitmapPicture::SetBitmap() to set the bitmap to be used.

<PRE><TT><FONT COLOR="#990000">
    BOOL SetBitmap(UINT nIDResource);           // Loads bitmap from resource ID
    BOOL SetBitmap(LPCTSTR lpszResourceName);   // Loads bitmap from resource name
    BOOL SetBitmap(HBITMAP hBitmap);            // Not recommended, as reloads can't be done
</PRE></TT></FONT>

<p>The implementation handles the SYSCOLORCHANGE message as described by
<a HREF="mailto:pal.k.tonder@matek.sintef.no">P錶 K. T鴑der</a> in his article 
<a href="http://www.codeguru.com/misc/syscol_static.shtml"> CStatic with bitmap 
sensitive to change in system colours</a>.

<br><br><b>Source:</b>
<PRE><TT><FONT COLOR="#990000">
#if !defined(AFX_BITMAPPICTURE_H__A4BE2021_689E_11D1_ABBA_00A0243D1382__INCLUDED_)
#define AFX_BITMAPPICTURE_H__A4BE2021_689E_11D1_ABBA_00A0243D1382__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

// BitmapPicture.h : header file
//
// Copyright (c) Chris Maunder (Chris.Maunder@cbr.clw.csiro.au) 
// Written 1 December, 1997


/////////////////////////////////////////////////////////////////////////////
// CBitmapPicture window

class CBitmapPicture : public CStatic
{
// Construction
public:
    CBitmapPicture();
    
// Operations
public:
    BOOL SetBitmap(HBITMAP hBitmap);            // Not recommended
    BOOL SetBitmap(UINT nIDResource);
    BOOL SetBitmap(LPCTSTR lpszResourceName);
    BOOL ReloadBitmap();

// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CBitmapPicture)
    protected:
    virtual void PreSubclassWindow();
    virtual void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
    //}}AFX_VIRTUAL

// Implementation
public:
    virtual ~CBitmapPicture();

// Attributes
protected:
    HBITMAP  m_hBitmap;
    BITMAP   m_bmInfo;

private:
    int     m_nResourceID;
    CString m_strResourceName;

// Generated message map functions
protected:
    //{{AFX_MSG(CBitmapPicture)
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    afx_msg void OnSysColorChange();
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

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

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

#endif // !defined(AFX_BITMAPPICTURE_H__A4BE2021_689E_11D1_ABBA_00A0243D1382__INCLUDED_)


// BitmapPicture.cpp : implementation file
//
// Copyright (c) 1997 Chris Maunder (Chris.Maunder@cbr.clw.csiro.au)
// Written 1 December, 1997

#include "stdafx.h"
#include "BitmapPicture.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// if UPDATE_ENTIRE_CLIENT_AREA is not defined then only the update region of
// the bitmap is updated. Otherwise, on each update, the whole client area of
// the bitmap is drawn. UPDATE_ENTIRE_CLIENT_AREA is slower, but distortion 
// of the picture may occur if it is not defined.

#define UPDATE_ENTIRE_CLIENT_AREA

/////////////////////////////////////////////////////////////////////////////
// CBitmapPicture

CBitmapPicture::CBitmapPicture()
{
    m_hBitmap = NULL;

    m_nResourceID = -1;
    m_strResourceName.Empty();
}

CBitmapPicture::~CBitmapPicture()
{
    if (m_hBitmap) ::DeleteObject(m_hBitmap);
}

BEGIN_MESSAGE_MAP(CBitmapPicture, CStatic)
    //{{AFX_MSG_MAP(CBitmapPicture)
    ON_WM_ERASEBKGND()
    ON_WM_DRAWITEM_REFLECT()
    ON_WM_SYSCOLORCHANGE()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBitmapPicture message handlers

BOOL CBitmapPicture::SetBitmap(HBITMAP hBitmap)
{
    ::DeleteObject(m_hBitmap);
    m_hBitmap = hBitmap;
    return ::GetObject(m_hBitmap, sizeof(BITMAP), &m_bmInfo);
}

BOOL CBitmapPicture::SetBitmap(UINT nIDResource)
{
    m_nResourceID = nIDResource;
    m_strResourceName.Empty();

    HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), 
                                        MAKEINTRESOURCE(nIDResource),
                                        IMAGE_BITMAP, 
                                        0,0, 
                                        LR_LOADMAP3DCOLORS);
    if (!hBmp) return FALSE;
    return CBitmapPicture::SetBitmap(hBmp);
}

BOOL CBitmapPicture::SetBitmap(LPCTSTR lpszResourceName)
{
    m_nResourceID = -1;
    m_strResourceName = lpszResourceName;

    HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), 
                                        lpszResourceName,
                                        IMAGE_BITMAP, 
                                        0,0, 
                                        LR_LOADMAP3DCOLORS);
    if (!hBmp) return FALSE;
    return CBitmapPicture::SetBitmap(hBmp);
}

// Suggested by P錶 K. Used to reload the bitmap on system colour changes.
BOOL CBitmapPicture::ReloadBitmap()
{
    if (m_nResourceID > 0) 
        return SetBitmap(m_nResourceID);
    else if (!m_strResourceName.IsEmpty())
        return SetBitmap(m_strResourceName);
    else    // if SetBitmap(HBITMAP hBitmap) was used directly then we can't reload.
        return FALSE;
}

void CBitmapPicture::PreSubclassWindow() 
{
    CStatic::PreSubclassWindow();
    ModifyStyle(0, SS_OWNERDRAW);
}

BOOL CBitmapPicture::OnEraseBkgnd(CDC* pDC) 
{
    CRect rect;
    GetClientRect(rect);

    // If no bitmap selected, simply erase the background as per normal and return
    if (!m_hBitmap)
    {
        CBrush backBrush(::GetSysColor(COLOR_3DFACE)); // (this is meant for dialogs)
        CBrush* pOldBrush = pDC->SelectObject(&backBrush);

        pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
        pDC->SelectObject(pOldBrush);

        return TRUE;
    }

    // We have a bitmap - draw it.

    // Create compatible memory DC using the controls DC
    CDC dcMem;
    VERIFY( dcMem.CreateCompatibleDC(pDC));
    
    // Select bitmap into memory DC.
    HBITMAP* pBmpOld = (HBITMAP*) ::SelectObject(dcMem.m_hDC, m_hBitmap);

    // StretchBlt bitmap onto static's client area
#ifdef UPDATE_ENTIRE_CLIENT_AREA
    pDC->StretchBlt(rect.left, rect.top, rect.Width(), rect.Height(), 
                     &dcMem, 0, 0, m_bmInfo.bmWidth-1, m_bmInfo.bmHeight-1,
                     SRCCOPY);
#else
    CRect TargetRect;                // Region on screen to be updated
    pDC->GetClipBox(&TargetRect);
    TargetRect.IntersectRect(TargetRect, rect);

    CRect SrcRect;                    // Region from bitmap to be painted
    SrcRect.left    = MulDiv(TargetRect.left,   m_bmInfo.bmWidth,  rect.Width());
    SrcRect.top     = MulDiv(TargetRect.top,    m_bmInfo.bmHeight, rect.Height());
    SrcRect.right   = MulDiv(TargetRect.right,  m_bmInfo.bmWidth,  rect.Width());
    SrcRect.bottom  = MulDiv(TargetRect.bottom, m_bmInfo.bmHeight, rect.Height());    

    pDC->StretchBlt(TargetRect.left, TargetRect.top, TargetRect.Width(), TargetRect.Height(), 
                    &dcMem, 
                    SrcRect.left, SrcRect.top, SrcRect.Width(), SrcRect.Height(),
                    SRCCOPY);
#endif

    ::SelectObject(dcMem.m_hDC, pBmpOld);

    return TRUE;
}

void CBitmapPicture::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    ASSERT(lpDrawItemStruct != NULL);
    
    CString str;
    GetWindowText(str);
    if (!str.GetLength()) return;

    CDC*  pDC     = CDC::FromHandle(lpDrawItemStruct->hDC);
    CRect rect    = lpDrawItemStruct->rcItem;
    DWORD dwStyle = GetStyle();
    int   nFormat = DT_NOPREFIX | DT_NOCLIP | DT_WORDBREAK | DT_SINGLELINE;

    if (dwStyle & SS_CENTERIMAGE) nFormat |= DT_VCENTER;
    if (dwStyle & SS_CENTER)      nFormat |= DT_CENTER;
    else if (dwStyle & SS_RIGHT)  nFormat |= DT_RIGHT;
    else                          nFormat |= DT_LEFT;

    int nOldMode = pDC->SetBkMode(TRANSPARENT);
    pDC->DrawText(str, rect, nFormat);
    pDC->SetBkMode(nOldMode);
}

// Suggested by P錶 K. T鴑der.
void CBitmapPicture::OnSysColorChange() 
{
    CStatic::OnSysColorChange();
    ReloadBitmap(); 
}

</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><IMG SRC="../cgi/Count.cgi-ft=2&dd=E-df=bmp_ddb_to_dib.cnt" tppabs="http://www.codeguru.com/cgi/Count.cgi?ft=2&dd=E%7cdf=bmp_ddb_to_dib.cnt" ALIGN="BOTTOM" BORDER="0"></CENTER>
</BODY>
</HTML>

⌨️ 快捷键说明

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