65.9K
CodeProject 正在变化。 阅读更多。
Home

持久等待光标

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.70/5 (25投票s)

2003 年 1 月 8 日

3分钟阅读

viewsIcon

116558

downloadIcon

1618

在消息之间维护等待光标的简单方法。

引言

要使用CWaitCursor类来显示等待光标,只需创建一个该类的实例。销毁该对象会恢复正常光标。但是,文档说明虽然对象的生存期可能跨越消息,但仅保证等待光标在当前处理消息的期间保持在屏幕上。

本文的目的是描述一种简单而简洁的方法,允许等待光标跨消息持续存在。

背景

等待光标不能保证跨消息持续存在的原因是,除了我们的消息使用等待光标外,也可能处理WM_SETCURSOR消息。此消息的默认处理将导致光标更改。为了防止这种情况发生,需要处理WM_SETCURSOR,并且如果需要显示等待光标,我们需要调用CCmdTarget::RestoreWaitCursor(),因此

BOOL CMyWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
    if (WaitCursorShown())
    {
        // We are showing the wait cursor
        RestoreWaitCursor();
        return TRUE;
    }

    // Let the base class deal with this one
    return CWnd::OnSetCursor(pWnd, nHitTest, message);
}

WaitCursorShown()非常简单 - 我们需要做的就是在创建CWaitCursor时设置一个变量来指示这一点,然后当然,再次设置该变量以指示CWaitCursor的销毁。但是,这有可能变得有点混乱,特别是当我们可能需要在多个窗口中实现这一点时(例如,CFrameWndCView派生类)。它也相当容易出错,因为我们必须确保无论在何处销毁CWaitCursor对象(因为它超出范围),我们都会相应地更新变量。

CPersistentWaitCursor

CPersistentWaitCursor是一个从CWaitCursor派生的非常简单的类。构造一个CPersistentWaitCursor对象会增加一个引用计数,以指示要显示等待光标。类似地,销毁该对象会减少引用计数。作为从CWaitCursor派生的类,构造函数和析构函数会导致等待光标被适当显示和隐藏。

CPersistentWaitCursor只比CWaitCursor多提供一个方法,即CPersistentWaitCursor::WaitCursorShown()。这返回一个bool,以指示是否应显示等待光标,基于引用计数的值。

使用CPersistentWaitCursor非常简单

#include "PersistentWaitCursor.h"

void CMyWnd::DoSomeLengthyOperation()
{
    // Create and show the wait cursor
    CPersistentWaitCursor waitCursor;

    // Do some lengthy operation
    ...

    // waitCursor goes out of scope and cursor is restored
}

BOOL CMyWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
    if (CPersistentWaitCursor::WaitCursorShown())
    {
        // We are showing the wait cursor
        RestoreWaitCursor();
        return TRUE;
    }

    // Let the base class deal with this one
    return CWnd::OnSetCursor(pWnd, nHitTest, message);
}

引用计数使用CPersistentWaitCursorMonitor的单个实例执行,这是一个维护计数的简单类。使用临界区保护对计数的访问。

结论

由于该类的简单性,我没有包括其用法的演示。

该类已在我当前正在开发的应用程序中找到用途。此应用程序的风格与Windows资源管理器非常相似。树中的项目代表数据库中的行。展开这些项目执行两个工作 - 首先,从数据库加载子项目并将其放置在树中,其次,从子项目获取数据,进行处理,然后放入视图中。数据库项目的加载(树的功能)和处理(文档/视图的功能)都是耗时的操作,但对用户来说似乎是单个操作。CPersistentWaitCursor简化了在这些操作进行时显示和管理等待光标的过程。

历史

  • 2003年1月27日 - 更新以更正源文件中的编译器错误(包含不存在的文件!)
© . All rights reserved.