Change the mouse pointer for a window in MFC by using Visual C++
本文介绍如何使用 Visual C++ 更改 MFC 中窗口的鼠标指针。 本文中的信息仅适用于非托管的 Visual C++ 代码。
原始产品版本: Visual C++
原始 KB 数: 131991
总结
在基于 Windows 的应用程序中,始终基于窗口类创建窗口。 窗口类基于窗口标识多个特征,包括默认鼠标指针(光标)。 在某些情况下,应用程序可能需要更改与它创建的某些窗口关联的指针。 本文介绍 MFC 应用程序可用于在不同时间显示不同指针的三种方法。
MFC 应用程序显示不同指针的情况
在一些情况下,你可能希望 MFC 应用程序在不同时间显示不同的指针:
- 当默认指针不是特定应用程序的好用户界面对象时。 例如,I-beam 指针比记事本中的文本编辑器窗口的箭头更合适。 这可能涉及更改应用程序的整个运行的指针。
- 当应用程序执行长时间的操作(如磁盘 I/O)时,沙漏指针比箭头更合适。 通过更改指向沙漏的指针,可以为用户提供良好的视觉反馈。 这可能涉及在有限的时间段内更改指针。
在窗口中更改鼠标指针的三种方法
下面是应用程序可以在窗口中更改鼠标指针的三种方式:
- 方法 1:重写
CWnd::OnSetCursor()
函数。 调用 Windows APISetCursor()
函数以更改指针。 - 方法 2:使用所需的鼠标指针注册自己的窗口类,重写
CWnd::PreCreateWindow()
函数,并使用新注册的窗口类创建窗口。 - 方法 3:若要显示标准沙漏指针,应用程序可以调用
CCmdTarget::BeginWaitCursor()
显示沙漏,并调用CmdTarget::EndWaitCursor()
以恢复为默认指针。 此方案仅适用于单个消息的持续时间。 如果在调用EndWaitCursor
之前移动鼠标,Windows 会将消息发送到WM_SETCURSOR
指针下方的窗口。 此消息的默认处理将指针重置为默认类型、向类注册的指针,因此需要对该窗口重写CWnd::OnSetCursor()
,并将指针重置回沙漏。
以下代码示例通过示例演示如何使用三种方法更改派生类窗口的 CView
鼠标指针。
m_ChangeCursor
是类的成员 CMyView
变量,属于类型 BOOL
。 它指示是否需要显示其他指针类型。
方法 1 的代码
通过重写CWnd::OnSetCursor()
函数更改对象的鼠标指针CMyView
。 使用类向导为 Windows 消息WM_SETCURSOR
建立消息映射函数CMyView::OnSetCursor()
,并提供函数正文,如下所示:
BOOL CMyView::OnSetCursor(CWnd *pWnd, UINT nHitTest, UINT message)
{
if (m_ChangeCursor)
{
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
return TRUE;
}
return CView::OnSetCursor(pWnd, nHitTest, message);
}
方法 2 的代码
使用 AfxRegisterClass()
或 AfxRegisterWndClass()
函数注册自己的窗口类,其中包含所需的鼠标指针。 然后基于已注册的窗口类创建视图窗口。 有关在 MFC 中注册窗口类的详细信息,请参阅 MFC 技术说明 1 中的窗口类注册 。
BOOL CMyView::PreCreateWindow(CREATESTRUCT &cs)
{
cs.lpszClass = AfxRegisterWndClass(
CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, // use any window styles
AfxGetApp()->LoadStandardCursor(IDC_WAIT),
(HBRUSH)(COLOR_WINDOW + 1)); // background brush
return CView::PreCreateWindow(cs)
}
方法 3 的代码
BeginWaitCursor()
调用和EndWaitCursor()
函数以更改鼠标指针。
注意
CWinApp::DoWaitCursor(1)
BeginWaitCursor()
和CWinApp::DoWaitCursor(-1)
分别工作,以及EndWaitCursor()
分别工作。
void CMyView::PerformLengthyOperation()
{
BeginWaitCursor(); // or AfxGetApp()->DoWaitCursor(1)
//...
EndWaitCursor(); // or AfxGetApp()->DoWaitCursor(-1)
}
如果调用 BeginWaitCursor()
且 EndWaitCursor()
不在同一处理程序中,则必须按如下所示重写 OnSetCursor
:
BOOL CMyView::OnSetCursor(CWnd *pWnd, UINT nHitTest, UINT message)
{
if (m_ChangeCursor)
{
RestoreWaitCursor();
return TRUE;
}
return CView::OnSetCursor(pWnd, nHitTest, message);
}
在此示例中,在调用前设置为 m_ChangeCursor
TRUE,并在调用EndWaitCursor()
后将其设置为 FALSE。BeginWaitCursor()