Delphi custom message handlers

半腔热情 提交于 2019-12-12 09:56:18

问题


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?


回答1:


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.




回答2:


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.




回答3:


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.




回答4:


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;



回答5:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!