Изменение указателя мыши для окна в MFC с помощью Visual C++

В этой статье описывается изменение указателя мыши на окно в MFC с помощью Visual C++. Сведения, приведенные в этой статье, относятся только к неуправляемой коду Visual C++.

Исходная версия продукта: Visual C++
Исходный номер базы знаний: 131991

Сводка

В приложении под управлением Windows всегда создается окно на основе класса окна. Класс окна определяет несколько характеристик окон, основанных на нем, включая указатель мыши по умолчанию (курсор). В некоторых случаях приложению может потребоваться изменить указатель, связанный с определенными окнами, которые он создает. В этой статье описываются три метода, которые приложение MFC может использовать для отображения разных указателей в разное время.

Ситуации, когда приложения MFC отображают разные указатели

Ниже приведены некоторые ситуации, когда может потребоваться, чтобы приложение MFC отображалось различными указателями в разное время:

  • Если указатель по умолчанию не является хорошим объектом пользовательского интерфейса для определенного приложения. Например, указатель I-луча более подходит, чем стрелка для окна текстового редактора в Блокноте. Это может включать изменение указателя для всего запуска приложения.
  • Когда приложение выполняет продолжительную операцию, например операцию ввода-вывода с диска, указатель в виде песочных часов более уместен, чем стрелка. Изменив указатель на песочные часы, вы предоставляете пользователю хорошую визуальную обратную связь. Это может включать изменение указателя в течение ограниченного периода времени.

Три метода изменения указателя мыши в окне

Ниже приведено три способа изменения указателя мыши в окне:

  • Метод 1. Переопределите функцию CWnd::OnSetCursor() . Вызовите функцию API SetCursor() Windows, чтобы изменить указатель.
  • Метод 2. Зарегистрируйте собственный класс окна с нужным указателем мыши, переопределите CWnd::PreCreateWindow() функцию и используйте только что зарегистрированный класс окна для создания окна.
  • Метод 3: Для отображения стандартного указателя в виде песочных часов приложение может вызвать метод CCmdTarget::BeginWaitCursor(), который отображает указатель в виде песочных часов, и затем вызывать CmdTarget::EndWaitCursor(), чтобы вернуться к стандартному указателю. Эта схема работает только в течение одного сообщения. Если мышь перемещается перед вызовом EndWaitCursor , Windows отправляет WM_SETCURSOR сообщение в окно под указателем. Обработка этого сообщения по умолчанию сбрасывает указатель на зарегистрированный в классе тип по умолчанию, поэтому необходимо переопределить CWnd::OnSetCursor() для этого окна и установить указатель обратно на песочные часы.

В следующих примерах кода показано, как изменить указатель CView мыши окна производного класса с помощью трех методов.

m_ChangeCursor является переменной CMyView члена класса и имеет тип BOOL. Указывает, должен ли отображаться другой тип указателя.

Код метода 1

Измените указатель мыши для CMyView объекта, переопределив CWnd::OnSetCursor() функцию. Используйте Мастер классов, чтобы установить функцию карты сообщений CMyView::OnSetCursor() для сообщения Windows WM_SETCURSOR и предоставить содержимое функции следующим образом:

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 см. в разделе "Регистрация классов окон " в техническом примечание 1 MFC.

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) и CWinApp::DoWaitCursor(-1) работают аналогично BeginWaitCursor() и 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 непосредственно перед вызовом BeginWaitCursor()и присвойте ему значение FALSE после вызова EndWaitCursor().