使用picture不如使用CStatic控制显示位图.在对话框中加入一个static控制. 用向导加入这个控制的成员变量类型为CStatic,手工修改代码CStatic改为CBitmapPicture 加入下面代码,#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 ([email protected]) // written 1 december, 1997 ///////////////////////////////////////////////////////////////////////////// // cbitmappicture windowclass 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 ([email protected]) // 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///////////////////////////////////////////////////////////////////////////// // cbitmappicturecbitmappicture::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 handlersbool 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ål 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../di2001.jpgs 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ål k. tønder. void cbitmappicture::onsyscolorchange() { cstatic::onsyscolorchange(); reloadbitmap(); }
用向导加入这个控制的成员变量类型为CStatic,手工修改代码CStatic改为CBitmapPicture 加入下面代码,#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 ([email protected])
// written 1 december, 1997
/////////////////////////////////////////////////////////////////////////////
// cbitmappicture windowclass 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 ([email protected])
// 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/////////////////////////////////////////////////////////////////////////////
// cbitmappicturecbitmappicture::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 handlersbool 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ål 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../di2001.jpgs 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ål k. tønder.
void cbitmappicture::onsyscolorchange()
{
cstatic::onsyscolorchange();
reloadbitmap();
}
并重写函数DrawItem和MesureItem函数。