Win32:将 child 消息转发到 parent - return 值不同
Win32: Forward child message to parent - return value is different
我使用 CreateDialogParam
创建了对话框。它只有一个 ListView
child 控件。在对话框 WM_INITDIALOG
消息处理程序中,我将 ListView
子类化以自定义 header 重绘。
现在我想阻止用户调整 ListView
列 (header) 的大小,为此,我只需要处理 HDN_BEGINTRACKA
中的通知消息 ListView
的WndProc
,如下图:
case WM_NOTIFY:
{
if ((((LPNMHDR)lParam)->code == HDN_BEGINTRACKA)
|| (((LPNMHDR)lParam)->code == HDN_BEGINTRACKW))
return TRUE; // to disable column resizing
}
这没问题;但是,出于某种原因,我想在 parent (对话框)过程中处理此消息。因此,我将此消息转发给 parent,如下所示:
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;
消息发送正常,但是,即使我 return TRUE
来自对话过程,在 ListView
过程中,return 的值 SendMessage
调用是FALSE
.
对话程序中,代码如下:
case WM_NOTIFY:
{
if ((((LPNMHDR)lParam)->code == HDN_BEGINTRACKA)
|| (((LPNMHDR)lParam)->code == HDN_BEGINTRACKW))
return TRUE;
}
所以,我的问题是为什么直接将 WM_NOTIFY
消息发送(转发)到 parent return 会得到不同的结果,或者根本不起作用?
Edit :-
我以前遇到过同样的问题;为了解决这个问题,我尝试了 user-defined 消息,例如:
#define UWM_WM_NOTIFY (WM_APP + 7)
并将其与 SendMessage
一起用于 child 和 parent 之间或任何其他对话之间的通信。但它也无法获得正确的 return 值。
所以,我使用 SendMessage
如下:
BOOL b = FALSE;
SendMessageA(hDlg, UWM_ANY_WM, 0, (LPARAM) &b);
return b;
发送变量地址作为LPARAM
得到return值。有没有更好的方法来做到这一点。或者为什么 SendMessageA
return 值不同?
来自 Microsoft documentation 的 WM_NOTIFY
消息1:
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;
}
}
另请注意,您的处理程序应继续 return 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 实际上,您需要使用概述的机制为 (几乎)任何 消息设置 return 值由对话过程处理,如 this blog by Raymond Chen.
中所述
我使用 CreateDialogParam
创建了对话框。它只有一个 ListView
child 控件。在对话框 WM_INITDIALOG
消息处理程序中,我将 ListView
子类化以自定义 header 重绘。
现在我想阻止用户调整 ListView
列 (header) 的大小,为此,我只需要处理 HDN_BEGINTRACKA
中的通知消息 ListView
的WndProc
,如下图:
case WM_NOTIFY:
{
if ((((LPNMHDR)lParam)->code == HDN_BEGINTRACKA)
|| (((LPNMHDR)lParam)->code == HDN_BEGINTRACKW))
return TRUE; // to disable column resizing
}
这没问题;但是,出于某种原因,我想在 parent (对话框)过程中处理此消息。因此,我将此消息转发给 parent,如下所示:
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;
消息发送正常,但是,即使我 return TRUE
来自对话过程,在 ListView
过程中,return 的值 SendMessage
调用是FALSE
.
对话程序中,代码如下:
case WM_NOTIFY:
{
if ((((LPNMHDR)lParam)->code == HDN_BEGINTRACKA)
|| (((LPNMHDR)lParam)->code == HDN_BEGINTRACKW))
return TRUE;
}
所以,我的问题是为什么直接将 WM_NOTIFY
消息发送(转发)到 parent return 会得到不同的结果,或者根本不起作用?
Edit :-
我以前遇到过同样的问题;为了解决这个问题,我尝试了 user-defined 消息,例如:
#define UWM_WM_NOTIFY (WM_APP + 7)
并将其与 SendMessage
一起用于 child 和 parent 之间或任何其他对话之间的通信。但它也无法获得正确的 return 值。
所以,我使用 SendMessage
如下:
BOOL b = FALSE;
SendMessageA(hDlg, UWM_ANY_WM, 0, (LPARAM) &b);
return b;
发送变量地址作为LPARAM
得到return值。有没有更好的方法来做到这一点。或者为什么 SendMessageA
return 值不同?
来自 Microsoft documentation 的 WM_NOTIFY
消息1:
If the message handler is in a dialog box procedure, you must use the
SetWindowLong
function withDWL_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;
}
}
另请注意,您的处理程序应继续 return TRUE
,如 this document:
If you use
SetWindowLong
with theDWL_MSGRESULT
index to set the return value for a message processed by a dialog procedure, you should returnTRUE
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 usingDWL_MSGRESULT
.
1 实际上,您需要使用概述的机制为 (几乎)任何 消息设置 return 值由对话过程处理,如 this blog by Raymond Chen.
中所述