Пользовательские обработчики сообщений Delphi

StackOverflow https://stackoverflow.com/questions/860119

  •  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;

Если вы не можете попасть на форум и вам нужен дополнительный код, оставьте комментарий, и я выложу недостающие фрагменты.

Удачи

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top