修改鼠标光标的形状(四)
2007-05-14 09:40
429 查看
方法三:沙漏光标为 Windows 操作系统本身默认支持之特性,微软已经把对沙漏光标的支持封装在 MFC 框架当中,开发人员可以不需要为此而在程序中引入 Cursor 资源。在 MFC 程序中,可以使用以下三种方式来操作沙漏光标:
(1)CWinApp::DoWaitCursor();
(2)CCmdTarget::BeginWaitCursor(),CCmdTarget::EndWaitCursor()和CCmdTarget::RestoreWaitCursor();
(3)CWaitCursor 封装类。
通过 Debug 跟踪可知,(2)和(3)的封装最终还是通过调用(1)来实现的。它们存在以下的对应关系:
下面列举几个实例场景以作说明:
场景1:在开始执行长操作之前打开沙漏光标,在长操作操作结束之后关闭沙漏光标。长操作在这里是指那些相对需要比较长的时间才能执行完毕的操作,比如说大文件的复制粘贴。
void CMyDialog::DoSomeLengthyOperation()
{
BeginWaitCursor(); // or AfxGetApp()->DoWaitCursor(1)
//... 执行长操作
EndWaitCursor(); // or AfxGetApp()->DoWaitCursor(-1)
}
如果在长操作的执行过程中,通过 DoModal() 方式显示了其他窗口的话,需要在 DoModal() 执行完毕之后进行沙漏光标的操作,以下代码修改自 MSDN :
void CMyDialog::DoSomeLengthyOperation( )
{
CWaitCursor wait; // display wait cursor
// do some lengthy processing
// The dialog box will normally change the cursor to
// the standard arrow cursor.
CSomeDialog dlg;
dlg.DoModal( );
// It is necessary to call Restore here in order
// to change the cursor back to the wait cursor.
wait.Restore( );
// do some more lengthy processing
// destructor automatically removes the wait cursor
}
场景2:有一些操作或者调用,用户不可以马上从 UI 上感觉到操作已经执行,此时我们可以把光标切换沙漏光标,并且保持显示1到2秒,以提示用户操作已被执行。我所遇到最经典的案例就是客户端程序调用 IE 进行网页的跳转操作。
void CMyDialog::JumpWebSite(LPCTSTR lpszUrl)
{
CWaitCursor wait;
::ShellExecute(GetSafeHwnd(), _T("open"), _T("iexplore.exe"), lpszUrl, NULL, SW_SHOWNORMAL);
// 保持沙漏光标至少 1 秒
::Sleep(1000);
}
在场景1和场景2里面,沙漏光标的打开和关闭都是在同一段连续的处理过程中进行的(在示例代码中,“同一段连续的处理过程中”其实就是“同一个函数里面”的意思),长操作会造成程序短时间内 UI 无响应,它们的实现原理实际上是在 UI 无响应之前(即长操作开始之前)先把光标置成沙漏,从而使得在 UI 无响应的这段时间内(即长操作执行过程中)光标一直呈沙漏形状。这种情况下,沙漏光标的显示时间很大程度上取决于长操作执行完毕所需要的时间,这是我们应该意识到的。
场景3:要实现对沙漏光标的精确控制,MSDN 提供了以下的示例代码:
step1:在 CMyDialog 中增加成员变量 BOOL m_bShowWaitCurosr,并在 CMyDialog 构造函数中将其初始化;
m_bShowWaitCurosr = FALSE;
step2:增加成员函数 ShowWaitCursor() 来控制沙漏光标的打开和关闭;
//////////////////////////////////////////////////////
//
// 函数名: CMyDialog::ShowWaitCursor
//
// 访问权: public
//
// 描述: 控制沙漏光标的打开和关闭
//
// 参数:
// bShow
// TRUE:打开沙漏光标
// FALSE:关闭沙漏光标
//
//////////////////////////////////////////////////////
void CMyDialog::ShowWaitCursor(BOOL bShow)
{
if (bShow)
{
m_bShowWaitCurosr = TRUE;
BeginWaitCursor();
}
else
{
EndWaitCursor();
m_bShowWaitCurosr = FALSE;
}
}
step3:处理 WM_SETCURSOR 消息。
ON_WM_SETCURSOR()
BOOL CMyDialog::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (m_bShowWaitCurosr)
{
RestoreWaitCursor();
return TRUE;
}
return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
(1)CWinApp::DoWaitCursor();
(2)CCmdTarget::BeginWaitCursor(),CCmdTarget::EndWaitCursor()和CCmdTarget::RestoreWaitCursor();
(3)CWaitCursor 封装类。
通过 Debug 跟踪可知,(2)和(3)的封装最终还是通过调用(1)来实现的。它们存在以下的对应关系:
说明 | (1) | (2) | (3) |
打开沙漏光标 | CWinApp::DoWaitCursor(1) | CCmdTarget::BeginWaitCursor() | CWaitCursor 构造函数 |
关闭沙漏光标 | CWinApp::DoWaitCursor(-1) | CCmdTarget::EndWaitCursor() | CWaitCursor 析构函数 |
刷新沙漏光标 | CWinApp::DoWaitCursor(0) | CCmdTarget::RestoreWaitCursor() | CWaitCursor::Restore() |
场景1:在开始执行长操作之前打开沙漏光标,在长操作操作结束之后关闭沙漏光标。长操作在这里是指那些相对需要比较长的时间才能执行完毕的操作,比如说大文件的复制粘贴。
void CMyDialog::DoSomeLengthyOperation()
{
BeginWaitCursor(); // or AfxGetApp()->DoWaitCursor(1)
//... 执行长操作
EndWaitCursor(); // or AfxGetApp()->DoWaitCursor(-1)
}
如果在长操作的执行过程中,通过 DoModal() 方式显示了其他窗口的话,需要在 DoModal() 执行完毕之后进行沙漏光标的操作,以下代码修改自 MSDN :
void CMyDialog::DoSomeLengthyOperation( )
{
CWaitCursor wait; // display wait cursor
// do some lengthy processing
// The dialog box will normally change the cursor to
// the standard arrow cursor.
CSomeDialog dlg;
dlg.DoModal( );
// It is necessary to call Restore here in order
// to change the cursor back to the wait cursor.
wait.Restore( );
// do some more lengthy processing
// destructor automatically removes the wait cursor
}
场景2:有一些操作或者调用,用户不可以马上从 UI 上感觉到操作已经执行,此时我们可以把光标切换沙漏光标,并且保持显示1到2秒,以提示用户操作已被执行。我所遇到最经典的案例就是客户端程序调用 IE 进行网页的跳转操作。
void CMyDialog::JumpWebSite(LPCTSTR lpszUrl)
{
CWaitCursor wait;
::ShellExecute(GetSafeHwnd(), _T("open"), _T("iexplore.exe"), lpszUrl, NULL, SW_SHOWNORMAL);
// 保持沙漏光标至少 1 秒
::Sleep(1000);
}
在场景1和场景2里面,沙漏光标的打开和关闭都是在同一段连续的处理过程中进行的(在示例代码中,“同一段连续的处理过程中”其实就是“同一个函数里面”的意思),长操作会造成程序短时间内 UI 无响应,它们的实现原理实际上是在 UI 无响应之前(即长操作开始之前)先把光标置成沙漏,从而使得在 UI 无响应的这段时间内(即长操作执行过程中)光标一直呈沙漏形状。这种情况下,沙漏光标的显示时间很大程度上取决于长操作执行完毕所需要的时间,这是我们应该意识到的。
场景3:要实现对沙漏光标的精确控制,MSDN 提供了以下的示例代码:
step1:在 CMyDialog 中增加成员变量 BOOL m_bShowWaitCurosr,并在 CMyDialog 构造函数中将其初始化;
m_bShowWaitCurosr = FALSE;
step2:增加成员函数 ShowWaitCursor() 来控制沙漏光标的打开和关闭;
//////////////////////////////////////////////////////
//
// 函数名: CMyDialog::ShowWaitCursor
//
// 访问权: public
//
// 描述: 控制沙漏光标的打开和关闭
//
// 参数:
// bShow
// TRUE:打开沙漏光标
// FALSE:关闭沙漏光标
//
//////////////////////////////////////////////////////
void CMyDialog::ShowWaitCursor(BOOL bShow)
{
if (bShow)
{
m_bShowWaitCurosr = TRUE;
BeginWaitCursor();
}
else
{
EndWaitCursor();
m_bShowWaitCurosr = FALSE;
}
}
step3:处理 WM_SETCURSOR 消息。
ON_WM_SETCURSOR()
BOOL CMyDialog::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (m_bShowWaitCurosr)
{
RestoreWaitCursor();
return TRUE;
}
return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
相关文章推荐
- 修改鼠标光标的形状
- 修改鼠标光标的形状
- 修改鼠标光标的形状(三)
- 修改鼠标光标的形状(一)
- 修改鼠标光标的形状(二)
- 修改鼠标光标的形状(五)
- [学习笔记]Java窗体中如何改变鼠标光标的形状
- MFC 如何设置鼠标的形状 如何设置光标热区
- C#设置鼠标在控件上面时,改变光标形状
- MFC 如何设置鼠标的形状 如何设置光标热区
- 改变光标(鼠标形状)后如何消防闪烁
- 修改Android系统的鼠标光标
- VC6.0实现鼠标光标形状及大小的定制
- VC:设置光标(鼠标)形状
- 改变鼠标光标形状
- 改变光标(鼠标形状)后如何消防闪烁
- Windows鼠标光标形状
- canvas 修改光标形状 滑过事件 点击事件
- 鼠标触及形状问题(自定义鼠标光标类型)
- VC6.0实现鼠标光标形状及大小的定制