Пользовательские обработчики сообщений Delphi
-
21-08-2019 - |
Вопрос
Когда пользователь дважды щелкает базу данных, я показываю немодальную форму.
Когда они закроют эту форму, я хочу обновить сетку.
Для этого я попробовал следующее:
1 — Определите константу пользовательского сообщения:
const
WM_REFRESH_MSG = WM_USER + 1; //defined in a globally available unit
2. В событии OnClose моей немодальной формы у меня есть следующее:
procedure TMyNonModalForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
PostMessage(Self.Handle,WM_REFRESH_MSG,0,0);
end;
3. В частных объявлениях формы, содержащей dbGrid, у меня есть следующее:
procedure OnRefreshRequest(var Msg: TMessage); message WM_REFRESH_MSG;
...
procedure TMyFormWithADBGrid.OnRefreshRequest(var Msg: TMessage);
begin
RefreshGrid;
end;
После этих действий PostMessage срабатывает нормально, но процедура OnRefreshRequest никогда не запускается.Что я делаю не так?
Решение
Помимо имени сообщения в другом ответе, вы публикуете сообщение в Self.Handle, пока Self уходит.Вероятно, вы хотели отправить сообщение в другой дескриптор (окно, которое запустило немодальное окно).Предоставьте своему немодальному окну доступ к этому дескриптору при его создании и вместо этого опубликуйте сообщение там.
Другие советы
Обратите внимание, что WM_USER не является подходящей константой для создания собственных сообщений, если только вы не пишете собственный элемент управления, непосредственно наследуемый от TWinControl.Вместо этого используйте WM_APP.
Кроме того, считается хорошим тоном использовать UM_ для сообщения пользователя вместо WM_, поскольку этот префикс предполагается зарезервировать для файлов заголовков Windows.
Почтовое сообщение необходимо отправить на другой дескриптор окна, а не на указанный вами self.handle.Один из способов сделать это — создать новое свойство в вашей немодальной форме и назначить ему дескриптор другой формы непосредственно перед тем, как вы покажете свою немодальную форму.
В остальном, при правильной реализации WM_REFRESH_MSG (у CheGueVerra все правильно), все должно работать нормально.
Вы можете попробовать изменить конец объявления, чтобы он соответствовал сообщению, которое вы пытаетесь отправить.
procedure OnRefreshRequest(var Msg: TMessage); message WM_CEA_REFRESH;
Должно быть это
procedure OnRefreshRequest(var Msg: TMessage); message WM_REFRESH_MSG;
Я загрузил пример «Что бы сделал Кевин?» к форуму новостных групп Embarcadero Embarcadero.public.attachments.
По сути, это пользовательское событие, на которое подписывается основная форма (или любая другая форма/объект), когда немодальная форма закрывается.В основной (или какой-то другой) форме...
var
NonModalForm :TfmNonModalForm;
begin
NonModalForm := TfmNonModalForm.Create(nil);
NonModalForm.Execute(NonModalFormClosingListener);
В методе «Выполнить»
procedure TfmNonModalForm.Execute(YourListenerMethod: THeyIClosedEvent);
begin
FHeyIClosedEvent := YourListenerMethod;
Show();
end;
Если вы не можете попасть на форум и вам нужен дополнительный код, оставьте комментарий, и я выложу недостающие фрагменты.
Удачи