通过上一篇,我们已经知道 MFC 对沙漏光标的几种操作方式最终都是通过调用 CWinApp::DoWaitCursor() 来实现的。以下是 CWinApp::DoWaitCursor() 的实现代码:
{
// 0 => restore, 1=> begin, -1=> end
ASSERT(nCode == 0 || nCode == 1 || nCode == - 1 );
ASSERT(afxData.hcurWait != NULL);
AfxLockGlobals(CRIT_WAITCURSOR);
m_nWaitCursorCount += nCode;
if (m_nWaitCursorCount > 0 )
{
HCURSOR hcurPrev = ::SetCursor(afxData.hcurWait);
if (nCode > 0 && m_nWaitCursorCount == 1 )
m_hcurWaitCursorRestore = hcurPrev;
}
else
{
// turn everything off
m_nWaitCursorCount = 0 ; // prevent underflow
::SetCursor(m_hcurWaitCursorRestore);
}
AfxUnlockGlobals(CRIT_WAITCURSOR);
}
根据上面的代码,我们至少可以分析出以下知识点:
(1)afxData 是一个全局的结构,CWinApp 把沙漏光标的句柄存放在它一个成员变量 afxData.hcurWait 当中,同时 CWinApp::DoWaitCursor() 是一个虚函数,如果我们需要实现自定义沙漏光标的话,直接修改 afxData.hcurWait 的值或者重载 CWinApp::DoWaitCursor() 应该都是可以率先考虑的做法;
(2)CWinApp 对沙漏光标的打开、关闭和刷新操作,是通过其成员变量 CWinApp::m_nWaitCursorCount 来控制的,CWinApp 实际上是对沙漏光标作一个引用计数的管理,引用计数操作的类型由函数参数 nCode 的值决定;
(3)CWinApp::DoWaitCursor() 的代码实现中包含了对 API 函数 SetCursor() 的调用,这跟《修改鼠标光标的形状(二)》中所涉及的内容是相吻合的;
*想查看某个 MFC 函数的实现代码,(我知道的)一般有以下三种方法,为弥补本人表达能力和部分读者理解能力的不足,我举例稍微说明一下,比方说要查 CWinApp::DoWaitCursor() 的实现代码:
方法1:通过 VC 的查找功能进行定位;
(1.1)先在通过主菜单 Edit->Find in Files... 调出查找窗口;
(1.2)Find What 里面填入查找关键字:CWinApp::DoWaitCursor;
(1.3)In Folder 里面填入查找 MFC 代码的存放路径:C:/PROGRAM FILES/MICROSOFT VISUAL STUDIO/VC98/MFC;
(1.4)其它查找选项根据实际情况填写;
(1.5)按“Find”按钮开始查找
方法2:安装 Visual Assist,利用它的代码跳转功能进行定位;
根据我多年的使用体会,Visual Assist 的确可以提高代码编写的速度,作为一名 VC 程序员,如果你还没有用过的话,推荐安装使用。在 www.VCKbase.com 上有个叫程序员工具箱的栏目,里面的“辅助开发工具”分类中有最新版本下载。
方法3:在代码中函数被调用的地方设置断点,通过 Debug 进行定位。
沿用之前的代码例子,在 CMyDialog::OnInitDialog() 函数中添加以下代码:
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
AfxGetApp() -> DoWaitCursor( 0 );
return TRUE; // return TRUE unless you set the focus to a control
}
按 F9 在 DoWaitCursor() 所在行设置断点,Debug 模式下使程序运行到断点处,依次按下 F11、Shift+F11和F11,CWinApp::DoWaitCursor() 的实现代码就展现在你面前了。
本文详细解析了MFC中沙漏光标的操作机制,包括CWinApp::DoWaitCursor()函数的具体实现,以及如何通过不同的方法查看该函数的源代码。
2427

被折叠的 条评论
为什么被折叠?



