Home > Blockchain >  TApplicationEvents.OnMessage does not capture the WM_CLIPBOARDUPDATE message
TApplicationEvents.OnMessage does not capture the WM_CLIPBOARDUPDATE message

Time:07-14

To be notified when the clipboard content changes in Windows 10, I usually use a TApplicationEvents component with this code:

procedure TformMain.AppEventsMainMessage(var Msg: tagMSG; var Handled: Boolean);
begin
  case Msg.message of
    Winapi.Messages.WM_CLIPBOARDUPDATE:
      begin
        CodeSite.Send('TformMain.AppEventsMainMessage: WM_CLIPBOARDUPDATE');
      end;
  end;
end;

And usually, it works. So I used this code also in an existing large project. But there, the WM_CLIPBOARDUPDATE message is not fired in the TApplicationEvents.OnMessage event handler!

What could prevent this message from being captured in the TApplicationEvents.OnMessage event handler?

EDIT: ONLY when using the AddClipboardFormatListener function, that DOES work in my project:

procedure TformMain.FormCreate(Sender: TObject);
begin
  Winapi.Windows.AddClipboardFormatListener(Handle);

procedure TformMain.FormDestroy(Sender: TObject);
begin
  Winapi.Windows.RemoveClipboardFormatListener(Handle);

Private
  procedure WMClipboardUpdate(var Msg: TMessage); message WM_CLIPBOARDUPDATE;

implementation

  procedure TformMain.WMClipboardUpdate(var Msg: TMessage);
  begin
    CodeSite.Send('TformMain.WMClipboardUpdate: WM_CLIPBOARDUPDATE');
  end;

But this does not answer the question "What could prevent this message from being captured in the TApplicationEvents.OnMessage event handler?"

CodePudding user response:

Windows doesn't broadcast WM_CLIPBOARDUPDATE to all windows when the clipboard is updated. Instead, you have to register your window if you want to be notified. From the documentation of AddClipboardFormatListener:

Places the given window in the system-maintained clipboard format listener list.

When a window has been added to the clipboard format listener list, it is posted a WM_CLIPBOARDUPDATE message whenever the contents of the clipboard have changed.

So after you have called

AddClipboardFormatListener(Handle)

the window with HWND Handle will be posted WM_CLIPBOARDUPDATE messages when the clipboard is changed. If you write

AddClipboardFormatListener(Handle)

in your TformMain.FormCreate, then Handle means Self.Handle, that is, the window associated with TformMain will be posted the messages. So they can be detected by your TformMain's

procedure WMClipboardUpdate(var Msg: TMessage); message WM_CLIPBOARDUPDATE;

But if you have a second form, TformSecond, it will not receive any such messages, because you did only register your TformMain.

Also, any message posted to a window in your application will pass through your TApplicationEvents. This means that if you have registered any window in your app using AddClipboardFormatListener, then any TApplicationEvents in your app will see this message.

  • Related