Cambiar el puntero del mouse para una ventana en MFC mediante Visual C++

En este artículo se presenta cómo cambiar el puntero del mouse para una ventana de MFC mediante Visual C++. La información de este artículo solo se aplica al código de Visual C++ no administrado.

Versión original del producto: Visual C++
Número de KB original: 131991

Resumen

En una aplicación basada en Windows, siempre se crea una ventana basada en una clase de ventana. La clase window identifica varias características de las ventanas basadas en ella, incluido el puntero predeterminado del mouse (cursor). En algunos casos, es posible que una aplicación quiera cambiar el puntero asociado a determinadas ventanas que crea. En este artículo se describen tres métodos que una aplicación MFC puede usar para mostrar punteros diferentes en momentos diferentes.

Situaciones en las que las aplicaciones MFC muestran punteros diferentes

Estas son algunas situaciones en las que es posible que desee que una aplicación MFC muestre punteros diferentes en momentos diferentes:

  • Cuando el puntero predeterminado no es un buen objeto de interfaz de usuario para una aplicación determinada. Por ejemplo, un puntero de haz de I es más adecuado que la flecha de una ventana del editor de texto en el Bloc de notas. Esto podría implicar el cambio del puntero para toda la ejecución de la aplicación.
  • Cuando una aplicación realiza una operación larga, como E/S de disco, un puntero de reloj de arena es más adecuado que la flecha. Al cambiar el puntero a un reloj de arena, se proporcionan buenos comentarios visuales al usuario. Esto podría implicar el cambio del puntero durante un período de tiempo limitado.

Tres métodos para cambiar el puntero del mouse en una ventana

Estas son tres maneras en las que una aplicación puede cambiar el puntero del mouse en una ventana:

  • Método 1: invalidar la CWnd::OnSetCursor() función. Llame a la función de API SetCursor() de Windows para cambiar el puntero.
  • Método 2: registre su propia clase de ventana con el puntero del mouse deseado, invalide la CWnd::PreCreateWindow() función y use la clase de ventana recién registrada para crear la ventana.
  • Método 3: para mostrar el puntero de reloj de arena estándar, una aplicación puede llamar a CCmdTarget::BeginWaitCursor(), que muestra el reloj de arena, y llamar CmdTarget::EndWaitCursor() a para revertir al puntero predeterminado. Este esquema solo funciona mientras dure un único mensaje. Si el mouse se mueve antes de realizar una llamada a EndWaitCursor , Windows envía un WM_SETCURSOR mensaje a la ventana debajo del puntero. El control predeterminado de este mensaje restablece el puntero al tipo predeterminado, el registrado con la clase , por lo que debe invalidar CWnd::OnSetCursor() para esa ventana y restablecer el puntero al reloj de arena.

En los ejemplos de código siguientes se muestra por ejemplo cómo cambiar el puntero del mouse de una CView ventana de clase derivada mediante los tres métodos.

m_ChangeCursor es una variable miembro de la CMyView clase y es de tipo BOOL. Indica si se debe mostrar un tipo de puntero diferente.

Código para el método 1

Cambie el puntero del mouse para el CMyView objeto reemplazando la CWnd::OnSetCursor() función . Use el Asistente para clases para establecer la función CMyView::OnSetCursor() de asignación de mensajes para el mensaje WM_SETCURSOR de Windows y proporcionar el cuerpo de la función de la siguiente manera:

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);
}

Código para el método 2

Registre su propia clase de ventana que contiene el puntero del mouse deseado mediante la AfxRegisterClass() función o AfxRegisterWndClass() . A continuación, cree la ventana de vista en función de la clase de ventana registrada. Para obtener más información sobre el registro de clases de ventana en MFC, vea Registro de clases de ventana en la nota técnica 1 de 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)
}

Código para el método 3

Llame a las BeginWaitCursor() funciones y EndWaitCursor() para cambiar el puntero del mouse.

Nota:

CWinApp::DoWaitCursor(1) y CWinApp::DoWaitCursor(-1) funcionan de forma similar a BeginWaitCursor() y EndWaitCursor(), respectivamente.

void CMyView::PerformLengthyOperation()
{
    BeginWaitCursor(); // or AfxGetApp()->DoWaitCursor(1)
    //...
    EndWaitCursor(); // or AfxGetApp()->DoWaitCursor(-1)
}

Si las llamadas a y EndWaitCursor() no están en el mismo controlador, debe invalidar OnSetCursor como se indica a BeginWaitCursor() continuación:

BOOL CMyView::OnSetCursor(CWnd *pWnd, UINT nHitTest, UINT message)
{
    if (m_ChangeCursor)
    {
        RestoreWaitCursor();
        return TRUE;
    }
    return CView::OnSetCursor(pWnd, nHitTest, message);
}

En este ejemplo, establezca en m_ChangeCursorTRUE justo antes de la llamada a BeginWaitCursor()y establézcala en FALSE después de la llamada a EndWaitCursor().