es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Win32: Redirigir mensaje hijo al padre – el valor de retorno es diferente

Tengo un diálogo creado usando CreateDialogParam. Solo tiene un control secundario de tipo ListView. En el controlador de mensajes WM_INITDIALOG del diálogo, subclasifico el ListView para personalizar el dibujado del encabezado.

Ahora quiero evitar que el usuario redimensione la columna (encabezado) del ListView y, para hacer esto, solo necesito manejar el mensaje de notificación HDN_BEGINTRACKA en el WndProc del ListView, así:

case WM_NOTIFY:
    {
        if ((((LPNMHDR)lParam)->code == HDN_BEGINTRACKA)
            || (((LPNMHDR)lParam)->code == HDN_BEGINTRACKW))
            return TRUE; // para deshabilitar el cambio de tamaño de la columna
    }

Esto funciona bien, pero por alguna razón quiero manejar este mensaje en el procedimiento del padre (diálogo). Así que envío este mensaje al padre como se muestra a continuación:

case WM_NOTIFY:
        {
            if ((((LPNMHDR)lParam)->code == HDN_BEGINTRACKA)
                || (((LPNMHDR)lParam)->code == HDN_BEGINTRACKW)) 
            {
                BOOL b = FALSE;
                HWND hParent = GetRealParent(hwnd);
                if (hParent) b = SendMessage(hParent, msg, wParam, lParam);
                return b; // para deshabilitar el cambio de tamaño de la columna, devuelve TRUE
            }
        }
        break;

El mensaje se envía correctamente, pero aunque devuelvo TRUE desde el procedimiento del diálogo, aquí en el procedimiento ListView, el valor devuelto de la llamada SendMessage es FALSE.

En el procedimiento del diálogo, el código es el siguiente:

case WM_NOTIFY:
    {
        if ((((LPNMHDR)lParam)->code == HDN_BEGINTRACKA)
            || (((LPNMHDR)lParam)->code == HDN_BEGINTRACKW))
            return TRUE;
    }

Así que mi pregunta es por qué enviar (reenviar) directamente el mensaje WM_NOTIFY al padre devuelve un resultado diferente, o simplemente no funciona.

Edición: En el pasado, me he enfrentado al mismo problema; para solucionarlo, intenté con un mensaje definido por el usuario, así:

#define UWM_WM_NOTIFY (WM_APP + 7)

y lo usé con SendMessage para comunicar entre el hijo y el padre, o entre cualquier otro diálogo. Pero también falla al obtener valores de retorno adecuados.

Así que estoy usando SendMessage de la siguiente manera:

BOOL b = FALSE;
SendMessageA(hDlg, UWM_ANY_WM, 0, (LPARAM) &b);
return b;

Envío la dirección de la variable como LPARAM para obtener el valor de retorno. ¿Hay alguna manera mejor de hacer esto? ¿O por qué el valor de retorno de SendMessageA es diferente?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    La razón por la cual el reenvío directo del mensaje WM_NOTIFY al padre no funciona como se espera se debe al hecho de que el procedimiento de ventana padre puede no estar esperando o manejando el mensaje HDN_BEGINTRACKA. Como resultado, es posible que no esté devolviendo un valor significativo, y la llamada SendMessage devuelve FALSE por defecto si la ventana receptora no maneja el mensaje.

    En cuanto al enfoque alternativo de usar un mensaje definido por el usuario y pasar un puntero a una variable BOOL como el parámetro LPARAM para obtener el valor de retorno, esto puede funcionar pero también puede provocar problemas potenciales con el acceso concurrente y la sincronización de la ubicación de memoria. Un enfoque mejor sería usar SendMessageCallback en lugar de SendMessage, lo que permite que se invoque una función de devolución de llamada cuando se ha procesado el mensaje. Esto evitaría la necesidad de memoria compartida y posibles conflictos de carrera.

Comments are closed.