#c #winapi #sendmessage
#c #winapi #отправить сообщение
Вопрос:
У меня есть диалоговое окно, созданное с помощью CreateDialogParam
. Он имеет только один ListView
дочерний элемент управления. В обработчике диалоговых WM_INITDIALOG
сообщений я подкласс ListView
для настройки перерисовки заголовка.
Теперь я хочу запретить пользователю изменять размер ListView
столбца (заголовка), и для этого мне просто нужно обработать HDN_BEGINTRACKA
уведомление в ListView
‘s 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
сообщения родительскому устройству возвращает другой результат или просто просто не работает?
Редактировать :-
В прошлом я сталкивался с той же проблемой; чтобы решить ее, я попробовал пользовательское сообщение, например:
#define UWM_WM_NOTIFY (WM_APP 7)
и используйте это SendMessage
для связи между дочерним и родительским или между любыми другими диалогами. Но также не удается получить правильные возвращаемые значения.
Итак, я использую SendMessage
следующее:
BOOL b = FALSE;
SendMessageA(hDlg, UWM_ANY_WM, 0, (LPARAM) amp;b);
return b;
Отправка адреса переменной LPARAM
для получения возвращаемого значения. Есть ли лучший способ сделать это. Или почему SendMessageA
возвращаемое значение отличается?
Ответ №1:
Из документации Microsoft для WM_NOTIFY
сообщения 1:
Если обработчик сообщения находится в процедуре диалогового окна, вы должны использовать
SetWindowLong
функцию withDWL_MSGRESULT
для установки возвращаемого значения.
Итак, используя более современную 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
, как указано в этом документе:
Если вы используете
SetWindowLong
сDWL_MSGRESULT
индексом для установки возвращаемого значения для сообщения, обработанного диалоговой процедурой, вы должны вернутьсяTRUE
непосредственно после этого. В противном случае, если вы вызовете какую-либо функцию, в результате которой ваша диалоговая процедура получит сообщение window, сообщение вложенного окна может перезаписать возвращаемое значение, которое вы задали с помощьюDWL_MSGRESULT
.
1 На самом деле, вам нужно использовать описанный механизм для установки возвращаемого значения для (почти) любого сообщения, обрабатываемого диалоговой процедурой, как красиво описано в этом блоге Раймондом Ченом.
Комментарии:
1. Спасибо за ответ. это действительно полезно. Но все же я в замешательстве, как вы можете видеть, я отредактировал свой вопрос, чтобы исправить ошибку. Поскольку пользователь определяет сообщение, это не решило проблему, но я использовал
LPARAM
для получения возвращаемого значения. Проблема, похоже, не только вWM_NOTIFY
сообщении, но и в каждом сообщении.2. @vkchavda: Действительно,
DWL_MSGRESULT
используется для возврата любого сообщения из диалоговой процедуры. Ссылка на документациюWM_NOTIFY
приведена потому, что это заметное сообщение, используемое в диалоговых окнах, которое возвращает значение.3. @rodrigo — Да, действительно. Смотрите Мое редактирование и связанный блог Раймонда.