使用时在编辑资源时要设置BS_OWNERDRAW属性,并且CCoolButton将忽略WS_TABSTOP属性
(按钮不获得输入焦点)。
// CCoolButton is a class derived from CButton.
// Most codes are copied from CBitmapButton.
// The usage is just like CBitmapButton:
// You declare a CCoolButton variable, and use AutoLoad class
// member to load the bitmaps. The only difference is that
// the four bitmaps have postfixes "N"(normal), "U"(Up),
// "D"(Down) and "X"(Disabled).
// You need to set the style OWNERDRAW and had better
// unset the style TABSTOP when you edit the button resource.
//
// Designed by Scott Zhong, March 1998
// CoolButton.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CCoolButton window
#ifndef _COOLBUTTON_H
#define _COOLBUTTON_H
#define CBS_NORMAL 0x0
#define CBS_POPUP 0x1
#define CBS_PUSHDOWN 0x2
#define CBS_DISABLED 0x4
// CCoolButton - push-button with 1->4 bitmap images
class CCoolButton : public CButton
{
// Construction
DECLARE_DYNAMIC(CCoolButton)
public:
CCoolButton();
BOOL LoadBitmaps(LPCTSTR lpszBitmapResource,
LPCTSTR lpszBitmapResourceUp = NULL,
LPCTSTR lpszBitmapResourceDown = NULL,
LPCTSTR lpszBitmapResourceDisabled = NULL);
BOOL AutoLoad(UINT nID, CWnd* pParent);
// Attributes
protected:
UINT m_state;
void SetBitmapMode(UINT action = 0, UINT mode = 0);
// all bitmaps must be the same size
CBitmap m_bitmap; // normal image (REQUIRED)
CBitmap m_bitmapUp; // pop up image (OPTIONAL)
CBitmap m_bitmapDown; // push down image (OPTIONAL)
CBitmap m_bitmapDisabled; // disabled bitmap (OPTIONAL)
CRect m_clientRect;
public:
// Operations
void SizeToContent();
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCoolButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL
// Implementation
public:
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
virtual ~CCoolButton();
// Generated message map functions
protected:
//{{AFX_MSG(CCoolButton)
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnCancelMode();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif
/////////////////////////////////////////////////////////////////////////////
// CoolButton.cpp : implementation file
//
#include "stdafx.h"
#include "CoolButton.h"
#ifdef AFX_AUX_SEG
#pragma code_seg(AFX_AUX_SEG)
#endif
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCoolButton
CCoolButton::CCoolButton()
{
m_state = CBS_NORMAL;
}
CCoolButton::~CCoolButton()
{
}
// LoadBitmaps will load in one, two, three or all four bitmaps
// returns TRUE if all specified images are loaded
BOOL CCoolButton::LoadBitmaps(LPCTSTR lpszBitmapResource,
LPCTSTR lpszBitmapResourceUp,
LPCTSTR lpszBitmapResourceDown,
LPCTSTR lpszBitmapResourceDisabled)
{
// delete old bitmaps (if present)
m_bitmap.DeleteObject();
m_bitmapUp.DeleteObject();
m_bitmapDown.DeleteObject();
m_bitmapDisabled.DeleteObject();
if (!m_bitmap.LoadBitmap(lpszBitmapResource))
{
TRACE0("Failed to load bitmap for normal image.\n");
return FALSE; // need this one image
}
BOOL bAllLoaded = TRUE;
if (lpszBitmapResourceUp != NULL)
{
if (!m_bitmapUp.LoadBitmap(lpszBitmapResourceUp))
{
TRACE0("Failed to load bitmap for pop-up image.\n");
bAllLoaded = FALSE;
}
}
if (lpszBitmapResourceDown != NULL)
{
if (!m_bitmapDown.LoadBitmap(lpszBitmapResourceDown))
{
TRACE0("Failed to load bitmap for push-down image.\n");
bAllLoaded = FALSE;
}
}
if (lpszBitmapResourceDisabled != NULL)
{
if (!m_bitmapDisabled.LoadBitmap(lpszBitmapResourceDisabled))
bAllLoaded = FALSE;
}
return bAllLoaded;
}
// SizeToContent will resize the button to the size of the bitmap
void CCoolButton::SizeToContent()
{
ASSERT(m_bitmap.m_hObject != NULL);
CSize bitmapSize;
BITMAP bmInfo;
VERIFY(m_bitmap.GetObject(sizeof(bmInfo), &bmInfo) == sizeof(bmInfo));
m_clientRect = CRect(0, 0, bmInfo.bmWidth, bmInfo.bmHeight);
VERIFY(SetWindowPos(NULL, -1, -1, bmInfo.bmWidth, bmInfo.bmHeight,
SWP_NOMOVE|SWP_NOZORDER|SWP_NOREDRAW|SWP_NOACTIVATE));
}
// Autoload will load the bitmap resources based on the text of
// the button
// Using suffices "N", "U", "D" and "X" for normal/up/down/disabled
BOOL CCoolButton::AutoLoad(UINT nID, CWnd* pParent)
{
// first attach the CCoolButton to the dialog control
if (!SubclassDlgItem(nID, pParent))
return FALSE;
ASSERT(GetStyle() & BS_OWNERDRAW);
ModifyStyle(WS_TABSTOP, 0);
CString buttonName;
GetWindowText(buttonName);
ASSERT(!buttonName.IsEmpty()); // must provide a title
LoadBitmaps(buttonName + _T("N"), buttonName + _T("U"),
buttonName + _T("D"), buttonName + _T("X"));
// we need at least the primary
if (m_bitmap.m_hObject == NULL)
return FALSE;
// size to content
SizeToContent();
return TRUE;
}
// Draw the appropriate bitmap
void CCoolButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
ASSERT(lpDIS != NULL);
// must have at least the first bitmap loaded before calling DrawItem
ASSERT(m_bitmap.m_hObject != NULL); // required
// use the main bitmap for normal, the selected bitmap for push-down
CBitmap* pBitmap = &m_bitmap;
m_state = CBS_NORMAL;
UINT state = lpDIS->itemState;
if ((state & ODS_SELECTED) && m_bitmapDown.m_hObject != NULL)
{
pBitmap = &m_bitmapDown;
m_state = CBS_PUSHDOWN;
}
else if ((state & ODS_FOCUS) && m_bitmapUp.m_hObject != NULL)
{
pBitmap = &m_bitmapUp; // third image for pop-up
m_state = CBS_POPUP;
}
else if ((state & ODS_DISABLED) && m_bitmapDisabled.m_hObject != NULL)
{
pBitmap = &m_bitmapDisabled; // last image for disabled
m_state = CBS_DISABLED;
}
// draw the whole button
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap* pOld = memDC.SelectObject(pBitmap);
if (pOld == NULL)
return; // destructors will clean up
CRect rect;
rect.CopyRect(&lpDIS->rcItem);
pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),
&memDC, 0, 0, SRCCOPY);
memDC.SelectObject(pOld);
}
void CCoolButton::SetBitmapMode(UINT action, UINT mode)
{
DRAWITEMSTRUCT DIS;
DIS.CtlType = ODT_BUTTON;
DIS.CtlID = GetDlgCtrlID();
DIS.itemAction = action;
DIS.itemState = mode;
DIS.hwndItem = GetSafeHwnd();
DIS.hDC = GetDC()->GetSafeHdc();
GetClientRect(&(DIS.rcItem));
SendMessage(WM_DRAWITEM, (WPARAM)GetSafeHwnd(), (LPARAM)&DIS);
ReleaseDC(CDC::FromHandle(DIS.hDC));
}
/////////////////////////////////////////////////////////////////////////////
// CCoolButton diagnostics
#ifdef _DEBUG
void CCoolButton::AssertValid() const
{
CButton::AssertValid();
m_bitmap.AssertValid();
m_bitmapUp.AssertValid();
m_bitmapDown.AssertValid();
m_bitmapDisabled.AssertValid();
}
void CCoolButton::Dump(CDumpContext& dc) const
{
CButton::Dump(dc);
dc << "m_bitmap = " << (UINT)m_bitmap.m_hObject;
dc << "\nm_bitmapUp = " << (UINT)m_bitmapUp.m_hObject;
dc << "\nm_bitmapDown = " << (UINT)m_bitmapDown.m_hObject;
dc << "\nm_bitmapDisabled = " << (UINT)m_bitmapDisabled.m_hObject;
dc << "\n";
}
#endif
#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif
IMPLEMENT_DYNAMIC(CCoolButton, CButton)
/////////////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP(CCoolButton, CButton)
//{{AFX_MSG_MAP(CCoolButton)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDOWN()
ON_WM_CANCELMODE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCoolButton message handlers
void CCoolButton::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (m_clientRect.PtInRect(point))
{
if (m_state == CBS_NORMAL)
{
// sets pop-up state
SetBitmapMode(ODA_FOCUS, ODS_FOCUS);
SetCapture();
}
}
else
{
// if moving out of the button
ReleaseCapture();
SetBitmapMode();
}
CWnd::OnMouseMove(nFlags, point);
}
void CCoolButton::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if ((m_state == CBS_PUSHDOWN) || (m_clientRect.PtInRect(point)))
// if having been pressed and now released
// emulates a BN_CLICKED message
{
ReleaseCapture();
SetBitmapMode(ODA_SELECT);
GetParent()->SendMessage(WM_COMMAND, MAKELPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)GetSafeHwnd());
}
}
void CCoolButton::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
SetBitmapMode(ODA_SELECT, ODS_SELECTED);
}
void CCoolButton::OnCancelMode()
{
CButton::OnCancelMode();
// TODO: Add your message handler code here
// When another window switchs to the foreground
// reset the button state because of losing mouse capture
SetBitmapMode();
}
(按钮不获得输入焦点)。
// CCoolButton is a class derived from CButton.
// Most codes are copied from CBitmapButton.
// The usage is just like CBitmapButton:
// You declare a CCoolButton variable, and use AutoLoad class
// member to load the bitmaps. The only difference is that
// the four bitmaps have postfixes "N"(normal), "U"(Up),
// "D"(Down) and "X"(Disabled).
// You need to set the style OWNERDRAW and had better
// unset the style TABSTOP when you edit the button resource.
//
// Designed by Scott Zhong, March 1998
// CoolButton.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CCoolButton window
#ifndef _COOLBUTTON_H
#define _COOLBUTTON_H
#define CBS_NORMAL 0x0
#define CBS_POPUP 0x1
#define CBS_PUSHDOWN 0x2
#define CBS_DISABLED 0x4
// CCoolButton - push-button with 1->4 bitmap images
class CCoolButton : public CButton
{
// Construction
DECLARE_DYNAMIC(CCoolButton)
public:
CCoolButton();
BOOL LoadBitmaps(LPCTSTR lpszBitmapResource,
LPCTSTR lpszBitmapResourceUp = NULL,
LPCTSTR lpszBitmapResourceDown = NULL,
LPCTSTR lpszBitmapResourceDisabled = NULL);
BOOL AutoLoad(UINT nID, CWnd* pParent);
// Attributes
protected:
UINT m_state;
void SetBitmapMode(UINT action = 0, UINT mode = 0);
// all bitmaps must be the same size
CBitmap m_bitmap; // normal image (REQUIRED)
CBitmap m_bitmapUp; // pop up image (OPTIONAL)
CBitmap m_bitmapDown; // push down image (OPTIONAL)
CBitmap m_bitmapDisabled; // disabled bitmap (OPTIONAL)
CRect m_clientRect;
public:
// Operations
void SizeToContent();
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCoolButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL
// Implementation
public:
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
virtual ~CCoolButton();
// Generated message map functions
protected:
//{{AFX_MSG(CCoolButton)
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnCancelMode();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif
/////////////////////////////////////////////////////////////////////////////
// CoolButton.cpp : implementation file
//
#include "stdafx.h"
#include "CoolButton.h"
#ifdef AFX_AUX_SEG
#pragma code_seg(AFX_AUX_SEG)
#endif
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCoolButton
CCoolButton::CCoolButton()
{
m_state = CBS_NORMAL;
}
CCoolButton::~CCoolButton()
{
}
// LoadBitmaps will load in one, two, three or all four bitmaps
// returns TRUE if all specified images are loaded
BOOL CCoolButton::LoadBitmaps(LPCTSTR lpszBitmapResource,
LPCTSTR lpszBitmapResourceUp,
LPCTSTR lpszBitmapResourceDown,
LPCTSTR lpszBitmapResourceDisabled)
{
// delete old bitmaps (if present)
m_bitmap.DeleteObject();
m_bitmapUp.DeleteObject();
m_bitmapDown.DeleteObject();
m_bitmapDisabled.DeleteObject();
if (!m_bitmap.LoadBitmap(lpszBitmapResource))
{
TRACE0("Failed to load bitmap for normal image.\n");
return FALSE; // need this one image
}
BOOL bAllLoaded = TRUE;
if (lpszBitmapResourceUp != NULL)
{
if (!m_bitmapUp.LoadBitmap(lpszBitmapResourceUp))
{
TRACE0("Failed to load bitmap for pop-up image.\n");
bAllLoaded = FALSE;
}
}
if (lpszBitmapResourceDown != NULL)
{
if (!m_bitmapDown.LoadBitmap(lpszBitmapResourceDown))
{
TRACE0("Failed to load bitmap for push-down image.\n");
bAllLoaded = FALSE;
}
}
if (lpszBitmapResourceDisabled != NULL)
{
if (!m_bitmapDisabled.LoadBitmap(lpszBitmapResourceDisabled))
bAllLoaded = FALSE;
}
return bAllLoaded;
}
// SizeToContent will resize the button to the size of the bitmap
void CCoolButton::SizeToContent()
{
ASSERT(m_bitmap.m_hObject != NULL);
CSize bitmapSize;
BITMAP bmInfo;
VERIFY(m_bitmap.GetObject(sizeof(bmInfo), &bmInfo) == sizeof(bmInfo));
m_clientRect = CRect(0, 0, bmInfo.bmWidth, bmInfo.bmHeight);
VERIFY(SetWindowPos(NULL, -1, -1, bmInfo.bmWidth, bmInfo.bmHeight,
SWP_NOMOVE|SWP_NOZORDER|SWP_NOREDRAW|SWP_NOACTIVATE));
}
// Autoload will load the bitmap resources based on the text of
// the button
// Using suffices "N", "U", "D" and "X" for normal/up/down/disabled
BOOL CCoolButton::AutoLoad(UINT nID, CWnd* pParent)
{
// first attach the CCoolButton to the dialog control
if (!SubclassDlgItem(nID, pParent))
return FALSE;
ASSERT(GetStyle() & BS_OWNERDRAW);
ModifyStyle(WS_TABSTOP, 0);
CString buttonName;
GetWindowText(buttonName);
ASSERT(!buttonName.IsEmpty()); // must provide a title
LoadBitmaps(buttonName + _T("N"), buttonName + _T("U"),
buttonName + _T("D"), buttonName + _T("X"));
// we need at least the primary
if (m_bitmap.m_hObject == NULL)
return FALSE;
// size to content
SizeToContent();
return TRUE;
}
// Draw the appropriate bitmap
void CCoolButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
ASSERT(lpDIS != NULL);
// must have at least the first bitmap loaded before calling DrawItem
ASSERT(m_bitmap.m_hObject != NULL); // required
// use the main bitmap for normal, the selected bitmap for push-down
CBitmap* pBitmap = &m_bitmap;
m_state = CBS_NORMAL;
UINT state = lpDIS->itemState;
if ((state & ODS_SELECTED) && m_bitmapDown.m_hObject != NULL)
{
pBitmap = &m_bitmapDown;
m_state = CBS_PUSHDOWN;
}
else if ((state & ODS_FOCUS) && m_bitmapUp.m_hObject != NULL)
{
pBitmap = &m_bitmapUp; // third image for pop-up
m_state = CBS_POPUP;
}
else if ((state & ODS_DISABLED) && m_bitmapDisabled.m_hObject != NULL)
{
pBitmap = &m_bitmapDisabled; // last image for disabled
m_state = CBS_DISABLED;
}
// draw the whole button
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap* pOld = memDC.SelectObject(pBitmap);
if (pOld == NULL)
return; // destructors will clean up
CRect rect;
rect.CopyRect(&lpDIS->rcItem);
pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),
&memDC, 0, 0, SRCCOPY);
memDC.SelectObject(pOld);
}
void CCoolButton::SetBitmapMode(UINT action, UINT mode)
{
DRAWITEMSTRUCT DIS;
DIS.CtlType = ODT_BUTTON;
DIS.CtlID = GetDlgCtrlID();
DIS.itemAction = action;
DIS.itemState = mode;
DIS.hwndItem = GetSafeHwnd();
DIS.hDC = GetDC()->GetSafeHdc();
GetClientRect(&(DIS.rcItem));
SendMessage(WM_DRAWITEM, (WPARAM)GetSafeHwnd(), (LPARAM)&DIS);
ReleaseDC(CDC::FromHandle(DIS.hDC));
}
/////////////////////////////////////////////////////////////////////////////
// CCoolButton diagnostics
#ifdef _DEBUG
void CCoolButton::AssertValid() const
{
CButton::AssertValid();
m_bitmap.AssertValid();
m_bitmapUp.AssertValid();
m_bitmapDown.AssertValid();
m_bitmapDisabled.AssertValid();
}
void CCoolButton::Dump(CDumpContext& dc) const
{
CButton::Dump(dc);
dc << "m_bitmap = " << (UINT)m_bitmap.m_hObject;
dc << "\nm_bitmapUp = " << (UINT)m_bitmapUp.m_hObject;
dc << "\nm_bitmapDown = " << (UINT)m_bitmapDown.m_hObject;
dc << "\nm_bitmapDisabled = " << (UINT)m_bitmapDisabled.m_hObject;
dc << "\n";
}
#endif
#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif
IMPLEMENT_DYNAMIC(CCoolButton, CButton)
/////////////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP(CCoolButton, CButton)
//{{AFX_MSG_MAP(CCoolButton)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDOWN()
ON_WM_CANCELMODE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCoolButton message handlers
void CCoolButton::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (m_clientRect.PtInRect(point))
{
if (m_state == CBS_NORMAL)
{
// sets pop-up state
SetBitmapMode(ODA_FOCUS, ODS_FOCUS);
SetCapture();
}
}
else
{
// if moving out of the button
ReleaseCapture();
SetBitmapMode();
}
CWnd::OnMouseMove(nFlags, point);
}
void CCoolButton::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if ((m_state == CBS_PUSHDOWN) || (m_clientRect.PtInRect(point)))
// if having been pressed and now released
// emulates a BN_CLICKED message
{
ReleaseCapture();
SetBitmapMode(ODA_SELECT);
GetParent()->SendMessage(WM_COMMAND, MAKELPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)GetSafeHwnd());
}
}
void CCoolButton::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
SetBitmapMode(ODA_SELECT, ODS_SELECTED);
}
void CCoolButton::OnCancelMode()
{
CButton::OnCancelMode();
// TODO: Add your message handler code here
// When another window switchs to the foreground
// reset the button state because of losing mouse capture
SetBitmapMode();
}
BOOL CFocusDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if(pWnd==&m_btn)
{
m_btn.SetFocus();
}
else
{
SetFocus();
}
return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
在OnInitDialog中加入以下两行:
m_btn.LoadBitmaps(Button1U,Button1D,Button1D);
m_btn.SizeToContent();
简单吧
两三句话就可以了!:关键字CButton
获得按钮指针,
判断鼠标消息;
设置响应效果;
希望把代码贴出来
if(pWnd==&m_btn)
m_btn.SetFocus();
else
SetFocus();
后,Dlg得到了焦点,m_btn闪来闪去,我只好加了一个不可见的IDC_STATIC,然后改代码为:
if(pWnd==&m_btn)
m_btn.SetFocus();
else
GetDlgItem(IDC_STATIC)->SetFocus();还有,运行后只有鼠标在Dlg上触发OnSetCursor后m_btn的位图才变成正常时的样子,否则一直是SetFocus时的位图,即使在OnInitDialog函数的最后加上
GetDlgItem(IDC_STATIC)->SetFocus();
也不行,我总觉得这个方法有点蹩脚,特别是把监测代码放在OnSetCursor中特别不舒服,还有其他办法吗?
To dingsg:可以给出详细代码吗?
上次回复的方法不适用于只有一个按钮的对话框,我认为把鼠标不在按钮上时的状态设为Disable更好一些,代码做如下修改:
//IDB_IN,IDB_OUT分别为鼠标在不在按钮上所对应的位图
加入成员变量m_bIn代表按钮状态
m_btn.LoadBitmaps(IDB_OUT);
m_bIn=false;//这两句话加入到OnInitDialog中
BOOL CFocusDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if(pWnd==&m_btn)
{
if(!m_bIn)
{
m_btn.LoadBitmaps(IDB_IN);
m_btn.Invalidate();
m_bIn=true;
}
}
else if(m_bIn)
{
m_btn.LoadBitmaps(IDB_OUT);
m_btn.Invalidate();
m_bIn=false;
}
return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
处理WM_MOUSEMOVE消息很有点不好,鼠标移动到按钮上时,主窗口将接受不到消息,消息只发给按钮,所以要在按钮类中处理消息,即从CBitmapButton类中派生一个自己的类,然后处理WM_MOUSE消息,在主窗口中也要处理这一消息,太麻烦。坐标转换可以用MapWindowPoints函数。不知你说的“特别不舒服”是什么意思?鼠标移动到不同的窗口必定有WM_SETCURSOR消息,这就是我们所要的。