我想让按钮形状随位图的形状改变,按钮风格是自己绘制(BS_OWNERDRAW)
使用的方法是在初始化按钮时,用SetWindowRgn来改变其形状。
但是我无法改变窗口的形状??? BITMAP bminfo;
m_bmpDef.GetObject(sizeof(bminfo), &bminfo); CDC * pDC = this->GetDC();
CDC memDC;
memDC.CreateCompatibleDC(pDC);
memDC.SelectObject(&m_bmpDef);
this->ReleaseDC(pDC); // Create the rgn
CRgn rgnTemp;
COLORREF color, temp;
color = GetPixel(memDC.GetSafeHdc(), 0, 0);
m_rgnBgd.CreateRectRgn(0, 0, bminfo.bmWidth, bminfo.bmHeight);
int i, j;
for (i = 0; i < bminfo.bmWidth; i ++)
{
for (j = 0; j < bminfo.bmHeight; j ++)
{
temp = memDC.GetPixel(i, j);
if (color == temp)
{
rgnTemp.CreateRectRgn(i, j, i+1, j+1);
m_rgnBgd.CombineRgn(&m_rgnBgd, &rgnTemp, RGN_DIFF);
rgnTemp.DeleteObject();
}
}
}
this->SetWindowRgn(m_rgnBgd, TRUE);
//******************************************************************
以下是完整代码
#if !defined(AFX_HBITBUTTON_H__382B43A8_422E_453F_964E_37F057CF3CFE__INCLUDED_)
#define AFX_HBITBUTTON_H__382B43A8_422E_453F_964E_37F057CF3CFE__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// HBitButton.h : header file
///////////////////////////////////////////////////////////////////////////////
// CHBitButton windowclass CHBitButton : public CButton
{
// Construction
public:
CHBitButton();// Attributes
public:// Operations
public:
BOOL LoadBitmap(UINT nIDDef, UINT nIDMouseHover, UINT nIDMouseDown, UINT nIDDis);// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHBitButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL// Implementation
public:
BOOL LoadBitmap(char * strBmpDef, char * strBmpMouseHover, char * strBmpMouseDown, char * strBmpDisable);
virtual ~CHBitButton();protected:
CBitmap m_bmpDef;
CBitmap m_bmpMouseHover;
CBitmap m_bmpMouseDown;
CBitmap m_bmpDis;
CRgn m_rgnBgd; BOOL m_bHover; int m_nState; // 0: Default, 1:MouseHover, 2:MouseDown, 3:Disable HRGN m_ButtonRgn;
// Generated message map functions
protected:
//{{AFX_MSG(CHBitButton)
afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
afx_msg void OnMouseLeave(WPARAM wParam, LPARAM lParam);
afx_msg void OnMouseHover(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_HBITBUTTON_H__382B43A8_422E_453F_964E_37F057CF3CFE__INCLUDED_)
使用的方法是在初始化按钮时,用SetWindowRgn来改变其形状。
但是我无法改变窗口的形状??? BITMAP bminfo;
m_bmpDef.GetObject(sizeof(bminfo), &bminfo); CDC * pDC = this->GetDC();
CDC memDC;
memDC.CreateCompatibleDC(pDC);
memDC.SelectObject(&m_bmpDef);
this->ReleaseDC(pDC); // Create the rgn
CRgn rgnTemp;
COLORREF color, temp;
color = GetPixel(memDC.GetSafeHdc(), 0, 0);
m_rgnBgd.CreateRectRgn(0, 0, bminfo.bmWidth, bminfo.bmHeight);
int i, j;
for (i = 0; i < bminfo.bmWidth; i ++)
{
for (j = 0; j < bminfo.bmHeight; j ++)
{
temp = memDC.GetPixel(i, j);
if (color == temp)
{
rgnTemp.CreateRectRgn(i, j, i+1, j+1);
m_rgnBgd.CombineRgn(&m_rgnBgd, &rgnTemp, RGN_DIFF);
rgnTemp.DeleteObject();
}
}
}
this->SetWindowRgn(m_rgnBgd, TRUE);
//******************************************************************
以下是完整代码
#if !defined(AFX_HBITBUTTON_H__382B43A8_422E_453F_964E_37F057CF3CFE__INCLUDED_)
#define AFX_HBITBUTTON_H__382B43A8_422E_453F_964E_37F057CF3CFE__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// HBitButton.h : header file
///////////////////////////////////////////////////////////////////////////////
// CHBitButton windowclass CHBitButton : public CButton
{
// Construction
public:
CHBitButton();// Attributes
public:// Operations
public:
BOOL LoadBitmap(UINT nIDDef, UINT nIDMouseHover, UINT nIDMouseDown, UINT nIDDis);// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHBitButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL// Implementation
public:
BOOL LoadBitmap(char * strBmpDef, char * strBmpMouseHover, char * strBmpMouseDown, char * strBmpDisable);
virtual ~CHBitButton();protected:
CBitmap m_bmpDef;
CBitmap m_bmpMouseHover;
CBitmap m_bmpMouseDown;
CBitmap m_bmpDis;
CRgn m_rgnBgd; BOOL m_bHover; int m_nState; // 0: Default, 1:MouseHover, 2:MouseDown, 3:Disable HRGN m_ButtonRgn;
// Generated message map functions
protected:
//{{AFX_MSG(CHBitButton)
afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
afx_msg void OnMouseLeave(WPARAM wParam, LPARAM lParam);
afx_msg void OnMouseHover(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_HBITBUTTON_H__382B43A8_422E_453F_964E_37F057CF3CFE__INCLUDED_)
解决方案 »
- matlab的figure嵌入到vc的图像控件中
- 关于udp绑定操作对winpcap截包造成的影响的问题?
- [Help]AccessibleObjectFromWindow函数在WindowsService下无法使用么???
- 关于数据库的一个问题,一直想不明白
- DLL中的对话框,为什么位置老不对啊?
- 哪里有“选择路径”对话框的模板??
- 怎样关掉一个用ShellExecute启动的程序?
- 如何能查询到directX show 中的com组件的接口细节?
- 新版论坛已经上线,欢迎帮忙测试,散分
- 深入浅出二版P462-463对象动态生成?
- ASII码(含扩展)可以用一个字节表示,则可以表示的ASII码值的个数是?
- int nLen=SafeStrlen(lpsz); //SafeStrlen什么意思?与strlen什么区别?
//************************************************************************
// HBitButton.cpp : implementation file
//#include "stdafx.h"
#include "BitmapButton.h"
#include "HBitButton.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CHBitButtonCHBitButton::CHBitButton()
{
m_nState = 0;
m_bHover = FALSE;
}CHBitButton::~CHBitButton()
{
}
BEGIN_MESSAGE_MAP(CHBitButton, CButton)
//{{AFX_MSG_MAP(CHBitButton)
ON_WM_DRAWITEM()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_CREATE()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CHBitButton message handlers
BOOL CHBitButton::LoadBitmap(char *strBmpDef, char *strBmpMouseHover, char *strBmpMouseDown, char *strBmpDisable)
{
HBITMAP hbitmap;
if (strBmpDef != NULL)
{
hbitmap =
(HBITMAP)::LoadImage(NULL, strBmpDef,IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
m_bmpDef.Attach(hbitmap);
}
if (strBmpMouseHover != NULL)
{
hbitmap =
(HBITMAP)::LoadImage(NULL, strBmpMouseHover,IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
m_bmpMouseHover.Attach(hbitmap);
}
if (strBmpMouseDown != NULL)
{
hbitmap =
(HBITMAP)::LoadImage(NULL, strBmpMouseDown,IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
m_bmpMouseDown.Attach(hbitmap);
}
if (strBmpDisable != NULL)
{
hbitmap =
(HBITMAP)::LoadImage(NULL, strBmpDisable,IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
m_bmpDis.Attach(hbitmap);
}
return TRUE;
}BOOL CHBitButton::LoadBitmap(UINT nIDDef, UINT nIDMouseHover, UINT nIDMouseFocus, UINT nIDDis)
{
if (nIDDef)
{
m_bmpDef.LoadBitmap(nIDDef);
}
if (nIDMouseHover)
{
m_bmpMouseHover.LoadBitmap(nIDMouseHover);
}
if (nIDMouseFocus)
{
m_bmpMouseDown.LoadBitmap(nIDMouseFocus);
}
if (nIDDis)
{
m_bmpDis.LoadBitmap(nIDDis);
}
return TRUE;
}
void CHBitButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: Add your code to draw the specified item
CBitmap * pBitmap = NULL; switch(m_nState)
{
case 0:
pBitmap = &m_bmpDef;
break;
case 1:
pBitmap = &m_bmpMouseHover;
break;
case 2:
pBitmap = &m_bmpMouseDown;
break;
case 3:
pBitmap = &m_bmpDis;
break;
} CDC * pDC;
pDC = this->GetDC(); CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap* pOldBitmap = memDC.SelectObject(pBitmap);
BITMAP bminfo;
pBitmap->GetObject(sizeof(bminfo), &bminfo); pDC->BitBlt(0, 0, bminfo.bmWidth, bminfo.bmHeight, &memDC, 0, 0, SRCCOPY);
memDC.SelectObject(pOldBitmap);
this->ReleaseDC(pDC);
}void CHBitButton::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: Add your message handler code here and/or call default
CButton::OnDrawItem(nIDCtl, lpDrawItemStruct);
}void CHBitButton::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (!m_bHover)
{
TRACKMOUSEEVENT evntTrack;
evntTrack.cbSize = sizeof(TRACKMOUSEEVENT);
evntTrack.dwFlags = TME_HOVER | TME_LEAVE;
evntTrack.dwHoverTime = 1;
evntTrack.hwndTrack = this->m_hWnd;
_TrackMouseEvent(&evntTrack);
//this->Invalidate();
}
CButton::OnMouseMove(nFlags, point);
}void CHBitButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
m_bHover = FALSE;
m_nState = 0;
this->Invalidate();
}void CHBitButton::OnMouseHover(WPARAM wParam, LPARAM lParam)
{
m_bHover = TRUE;
m_nState = 1;
this->Invalidate();
}void CHBitButton::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_nState = 2;
this->Invalidate();
//CButton::OnLButtonDown(nFlags, point);
}void CHBitButton::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_nState = 1;
this->Invalidate();
CButton::OnLButtonUp(nFlags, point);
}int CHBitButton::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CButton::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
ModifyStyle(0, BS_OWNERDRAW); BITMAP bminfo;
m_bmpDef.GetObject(sizeof(bminfo), &bminfo); CDC * pDC = this->GetDC();
CDC memDC;
memDC.CreateCompatibleDC(pDC);
memDC.SelectObject(&m_bmpDef);
this->ReleaseDC(pDC); // Create the rgn
CRgn rgnTemp;
COLORREF color, temp;
color = GetPixel(memDC.GetSafeHdc(), 0, 0);
m_rgnBgd.CreateRectRgn(0, 0, bminfo.bmWidth, bminfo.bmHeight);
int i, j;
for (i = 0; i < bminfo.bmWidth; i ++)
{
for (j = 0; j < bminfo.bmHeight; j ++)
{
temp = memDC.GetPixel(i, j);
if (color == temp)
{
rgnTemp.CreateRectRgn(i, j, i+1, j+1);
m_rgnBgd.CombineRgn(&m_rgnBgd, &rgnTemp, RGN_DIFF);
rgnTemp.DeleteObject();
}
}
}
this->SetWindowRgn(m_rgnBgd, TRUE); return 0;
}
要画位图就要有一个内存DC呀!!
//=============================================问题解决了!!
绘制位图时,不仅要改变按钮本身的有效区域m_rgnBgd,
而且要改变相应的DC的裁减区域(需另增成员变量m_rgnDC)
在DrawItem中,BitBlt之前增加
pDC->SelectClipRgn(&m_rgnDC); //改变pDC的裁减区域
另外在OnCreate函数的for循环之后,增加
m_rgnDC.CombineRgn(&m_rgnDC, &m_rgnBgd, RGN_AND);//保存DC的裁减区域谢谢各位捧场!!