Delphi processing all Windows messages
Posted by jpluimers on 2020/12/30
Since I had captures messages inside the main message loop, I forgot it is straightforward: create a [WayBack] TApplicationEvents instance, then use the [WayBack] OnMessage event and hook it to a method like
procedure TMainForm.ApplicationEventsMessage(var Msg: TMsg; var Handled: Boolean); begin // figure out if the TMsg should be handled; set Handled to True if you do not want it to be processed by your application any further // if you do not handle it: bail out as quickly as possible // for performance reasons, it might be wise to have only the decision in this method, and all actual handling (including any managed variables) inside another method. end;
Capturing these messages is limited to the ones processed through the main message loop (or message pump): these are the asynchronous ones either put there by PostMessage or related functions (like PostQuitMessage), or generated by Windows.
This means you will not see any synchronous messages sent to specific Windows using SendMessage.
Unlike the documentation for the OnMessage event, the type inside the method is TMsg from the unit [WayBack]WinApi.Windows, which is an alias for the (documentation mentioned) tagMSG in the same unit; neither type is documented at docs.embarcadero.com or docwiki.embarcadero.com. Luckily, it is documented in the Windows SDK as the structure [WayBack] tagMSG.
That structure is not the same as the [WayBack] TMessage type inside the unit WinApi.Messages [WayBack], as TMessage omits these fields from TMsg:
HWND hwnd;DWORD time;POINT pt;DWORD lPrivate;
Luckily the [WayBack] TMessageEvent (that describes the type of the signature of the event method) is better in this regard:
TMessageEvent = procedure (var Msg: TMsg; var Handled: Boolean) of object;
TMessageEventincludes the following parameters:
Msgidentifies the Windows message that triggered the event.Handledindicates whether the event handler responded to the message. If the event handler setsHandledtoTrue, the application assumes that the message has been completely handled and halts any subsequent processing of the message.
TApplicationEvents is actually a multi-cast component (one of the very few multi-casting things parts of the Delphi VCL): an undocumented TMultiCaster class inside the unit Vcl.AppEvnts [WayBack].
A bit reminder though: ALL queued (not sent!) Windows messages flow through this method, so make it as short and efficient as possible, so from the OnMessage documentation:
OnMessageonly receives messages that are posted to the message queue, not those sent directly with the Windows APISendMessagefunction.…
Warning: Caution:Thousands of messages per second flow though this event. Be careful when coding the handler, because it can affect the performance of the entire application.Tip: Call theCancelDispatchmethod from anOnMessageevent handler to prevent the application from forwarding the event to any other application events objects.
TCustomApplicationEvents.CancelDispatch to be documented:Prevents other TCustomApplicationEvents objects from receiving the current event.
A few more relevant links if you want to also hook SendMessage based messages:
- [WayBack] delphi – Let form catch all messages – Stack Overflow
- [WayBack] delphi – How do I catch certain events of a form from outside the form? – Stack Overflow
- [WayBack] Trapping Windows Messages in Delphi – Embarcadero Community
- Technical Information Database
- TI1487D.txt
- Trapping Windows Messages in Delphi
- Category :General Programming
- Platform :All
- Product :Delphi All
- Description: While Delphi provides many ways to trap the incoming messages to VCL controls, you may require a quick and effective method of…
- [WayBack] Handling Messages | Adventures in Delphi 6 Messaging | InformIT
As a Delphi component developer, you have to directly handle many Windows messages and then invoke events corresponding to those messages. Xavier Pacheco and Steve Teixeira discuss how the Windows message system works.
- [WayBack] Intercept Windows Messages … all or one by one – delphi
- [WayBack] Capture All Windows messages
How can I catch all Windows messages? For example , my active window is Microsoft Word and when I click on it I want to catch this message with my DELPHI program, which is not active in this moment.
The answer describes using [WayBack] SetWindowsHookExA function | Microsoft Docs.
An alternative is to overwrite the WndProc of TComponent instances. For both you need to have the window handles of all components first.
- [WayBack] how to list all windows Messages???!! – Delphi Pages Forums which has a unit that can hook messages for the main window based on:
- [WayBack] Handling Windows Messages the Delphi way
- [WayBack] SendMessage, PostMessage, and Related Functions – Windows applications | Microsoft Docs
- Overwriting (and saving for later restore!) the [WayBack]
TControl.WindowProcof any control: [WayBack] delphi – How do I catch certain events of a form from outside the form? – Stack Overflow - [WayBack] projects/Hooks.pas at master · hypfvieh/projects · GitHub
–jeroen






Leave a comment