c - Win32 : Forward child message to parent - return value is different

标签 c winapi sendmessage

我使用 CreateDialogParam 创建了对话框。它只有一个 ListView child 控制。在对话框中WM_INITDIALOG消息处理程序,我将 ListView 进行子类化自定义标题重绘。

现在我想阻止用户调整 ListView 的大小列(标题),为此,我只需要处理 HDN_BEGINTRACKA ListView中的通知消息的WndProc ,如下所示:

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

这工作正常;但是,出于某种原因,我想在父(对话框)过程中处理此消息。因此,我将此消息转发给该家长,如下所示:

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; // to disable column resizing return TRUE;
            }
        }
        break;

消息发送正常,但是,即使我返回 TRUE从对话过程中,在 ListView 中过程中,返回值SendMessage调用电话是FALSE .

在对话框程序中,代码如下:

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

所以,我的问题是为什么直接发送(转发)WM_NOTIFY给父级的消息返回不同的结果,或者根本不起作用?

Edit :-

过去,我也遇到过同样的问题;为了解决这个问题,我尝试了用户定义的消息,例如:

#define UWM_WM_NOTIFY (WM_APP + 7)

并将其与 SendMessage 一起使用在 child 和 parent 之间或任何其他对话之间进行通信。但它也无法获得正确的返回值。

所以,我正在使用SendMessage如下:

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

发送变量地址为LPARAM来获取返回值。有没有更好的方法来做到这一点。或者为什么 SendMessageA返回值不同?

最佳答案

来自 WM_NOTIFY 消息的 Microsoft documentation1:

If the message handler is in a dialog box procedure, you must use the SetWindowLong function with DWL_MSGRESULT to set a return value.

因此,使用最新的 SetWindowLongPtr 函数,您的父级(对话框)对 WM_NOTIFY 消息的处理应如下所示:

case WM_NOTIFY:
    {
        if ((((LPNMHDR)lParam)->code == HDN_BEGINTRACKA)
            || (((LPNMHDR)lParam)->code == HDN_BEGINTRACKW))
        {
            SetWindowLongPtr(hWnd, DWL_MSGRESULT, TRUE); // hWnd is dialog's HWND
            return TRUE;
        }
    }

另请注意,您的处理程序应继续返回 TRUE,如 this document 中所述:

If you use SetWindowLong with the DWL_MSGRESULT index to set the return value for a message processed by a dialog procedure, you should return TRUE directly afterward. Otherwise, if you call any function that results in your dialog procedure receiving a window message, the nested window message could overwrite the return value you set using DWL_MSGRESULT.


1 实际上,您需要使用概述的机制来设置对话过程处理的(几乎)任何消息的返回值,如 this blog by Raymond Chen 中所述。

关于c - Win32 : Forward child message to parent - return value is different,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70170916/

相关文章:

c# - 通过 C# 使用 winapi 从 "net use"获取状态列

windows - 两个应用程序之间相互的SendMessage-ing如何工作?

java - 来自 Java 应用程序的 SendMessage

c# - 将右键单击发送到窗口

c - Openssl如何找出X509证书中公钥的位大小是多少

c - 用于套接字客户端通信的每个线程的状态机

c - OpenGL,物体移动时闪烁

c - 使用 pipe() : How do I allow multiple child processes to execute simultaneously

asp.net - 使用httpSendRequest c++上传文件

c - WM_KEYDOWN到达,WM_CHAR被跳过