В статье мы рассмотрим проблему обновления dbGrid при закрытии всплывающей формы после двойного щелчка в Delphi. Мы рассмотрим подход с использованием пользовательских сообщений и разберемся, почему процедура обработки сообщений не запускается в данном случае. Кроме того, мы предложим альтернативное решение с использованием событий.
Проблема с пользовательскими сообщениями
Рассмотрим следующий код, в котором пытаются обновить dbGrid при закрытии всплывающей формы после двойного щелчка с помощью пользовательских сообщений:
const
WM_REFRESH_MSG = WM_USER + 1; //defined in a globally available unit
procedure TMyNonModalForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
PostMessage(Self.Handle, WM_REFRESH_MSG, 0, 0);
end;
procedure TMyFormWithADBGrid.OnRefreshRequest(var Msg: TMessage);
begin
RefreshGrid;
end;
В данном случае, процедура OnRefreshRequest не запускается, когда всплывающая форма закрывается. Это происходит из-за того, что Self.Handle уже недействительно, когда форма закрывается, и сообщение не доставляется до destinataria.
Решение проблемы с пользовательскими сообщениями
Чтобы решить проблему, нужно передать правильный THandle для окна, которое должно получать сообщение. Это можно сделать, изменив конструктор всплывающей формы и передавая в него THandle окна, которое должно получать сообщение:
type
TMyNonModalForm = class(TForm)
...
private
{ Private declarations }
FTargetHandle: THandle;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
public
constructor Create(AOwner: TComponent; ATargetHandle: THandle);
...
end;
constructor TMyNonModalForm.Create(AOwner: TComponent; ATargetHandle: THandle);
begin
inherited Create(AOwner);
FTargetHandle := ATargetHandle;
end;
procedure TMyNonModalForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
PostMessage(FTargetHandle, WM_REFRESH_MSG, 0, 0);
end;
Теперь, при создании всплывающей формы, нужно передать правильный THandle в конструктор:
var
MyNonModalForm: TMyNonModalForm;
begin
MyNonModalForm := TMyNonModalForm.Create(Self, Self.Handle);
MyNonModalForm.Show;
end;
Альтернативное решение с использованием событий
Вместо пользовательских сообщений, можно использовать события для обновления dbGrid при закрытии всплывающей формы. Для этого, можно создать пользовательское событие в всплывающей форме и подписаться на него в форме, содержащей dbGrid:
type
TMyNonModalForm = class(TForm)
...
private
{ Private declarations }
FOnFormClosed: TNotifyEvent;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
public
property OnFormClosed: TNotifyEvent read FOnFormClosed write FOnFormClosed;
end;
procedure TMyNonModalForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if Assigned(FOnFormClosed) then
FOnFormClosed(Sender);
inherited;
end;
В форме, содержащей dbGrid, подписываемся на событие OnFormClosed и обновляем dbGrid:
var
MyNonModalForm: TMyNonModalForm;
begin
MyNonModalForm := TMyNonModalForm.Create(Self);
MyNonModalForm.OnFormClosed := UpdateGrid;
MyNonModalForm.Show;
end;
procedure TMyFormWithADBGrid.UpdateGrid(Sender: TObject);
begin
RefreshGrid;
end;
Использование событий является более гибким и простым решением, чем пользовательские сообщения, так как не требует правильной передачи THandle и не зависит от состояния окон.
В статье описывается проблема обновления dbGrid при закрытии всплывающей формы после двойного щелчка в Delphi с использованием пользовательских сообщений и предлагается альтернативное решение с использованием событий.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS