When a user double-clicks a dbgrid, I show a non-modal form.
When they close that form, I want to refresh the grid.
To accomplish that, I have tried the following:
1 - Define a custom message constant:
const
WM_REFRESH_MSG = WM_USER + 1; //defined in a globally available unit
2 - In the OnClose event of my non-modal form, I have this:
procedure TMyNonModalForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
PostMessage(Self.Handle,WM_REFRESH_MSG,0,0);
end;
3 - In the private declarations of the form that holds the dbGrid, I have this:
procedure OnRefreshRequest(var Msg: TMessage); message WM_REFRESH_MSG;
...
procedure TMyFormWithADBGrid.OnRefreshRequest(var Msg: TMessage);
begin
RefreshGrid;
end;
After doing these things, the PostMessage fires fine, but the OnRefreshRequest procedure never runs. What am I doing wrong?
Aside from the message name in the other answer, you are posting a message to Self.Handle while Self is going away. You probably meant to post to a different handle (the window that launched the modeless one). Give your modeless window access to that handle when you create it, and post the message there instead.
Note that WM_USER is not the correct constant to base your own messages on, unless you are writing a custom control directly descending from TWinControl. Use WM_APP instead.
Also, it's considered good style to use UM_ for User Message instead of WM_ because that prefix is supposed to be reserved for the Windows header files.
The post message needs to be sent to the other window handle, not the self.handle that you have listed. One way to do this would be to create a new property on your non-modal form and assign it the handle of the other form just before you show your non-modal one.
Other than that, and implementing the WM_REFRESH_MSG properly (CheGueVerra has it correct) it should work fine.
You might try and change the end of the declaration to match the message you are trying to send.
procedure OnRefreshRequest(var Msg: TMessage); message WM_CEA_REFRESH;
Should be this
procedure OnRefreshRequest(var Msg: TMessage); message WM_REFRESH_MSG;
I've uploaded an example of "What would Kevin do?" to Embarcadero's newsgroup forum embarcadero.public.attachments.
Basically it's a custom event that the main form (or whatever form/object you want) subscribes to when the non-modal form closes. In the main (or whatever) form...
var
NonModalForm :TfmNonModalForm;
begin
NonModalForm := TfmNonModalForm.Create(nil);
NonModalForm.Execute(NonModalFormClosingListener);
In the Execute method
procedure TfmNonModalForm.Execute(YourListenerMethod: THeyIClosedEvent);
begin
FHeyIClosedEvent := YourListenerMethod;
Show();
end;
If you can't get to the forum and need the additional code, leave a comment and I'll post the missing pieces.
Good luck
来源:https://stackoverflow.com/questions/860119/delphi-custom-message-handlers