dummzeuch
dummzeuch

Reputation: 11217

How can i draw to or add a custom button to every window of all applications?

I have seen several tools adding a custom button and/or drawing on the title bar of all windows of all applications in Windows. How is that done? Extra points for an example in Delphi.

EDIT: I found something for dotNET that does this: http://www.thecodeking.co.uk/2007/09/adding-caption-buttons-to-non-client.html#.VdmioEDenqQ

Upvotes: 8

Views: 1540

Answers (2)

David
David

Reputation: 13580

I haven't done this, so the following is what I would investigate if I were to try:

  • For each application / each top-level window:
  • Create a floating window and position it over the title bar wherever you want it to sit. Set up the parent / child relationship, but this window is part of your own process. (There are occasionally problems parenting a window from one process to one from another process, but try. I'd avoid injecting into other processes if possible.)
  • You can investigate the window flags to see if the window has a title bar (ie if you should add a button) via GetWindowLong with GWL_STYLE looking for WS_CAPTION. The same call will also let you see the type of caption / frame, which you can combine with GetSystemMetrics with, eg, SM_CYDLGFRAME to figure out the right size for your button on this specific window's title bar.
  • This window is now your button: paint, handle clicks etc as appropriate.
  • Make it a non-focusable window so that clicks to it don't take focus away from the window is is on the title bar of. You don't want clicking it to make the title bar change colour, for example. Do this by setting the WS_EX_NOACTIVATE window flag, something like: SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) orWS_EX_NOACTIVATE).
  • The main problem is to keep it positioned correctly when the window moves, is resized, etc. To do this, install a hook for the system move events. You can also hook minimize and restore via EVENT_SYSTEM_MINIMIZESTART and EVENT_SYSTEM_MINIMIZEEND. This will allow you to keep track of all windows moving around onscreen, such that you can adjust the button-window position if necessary.

That gives you a window which you can paint as a button (and respond to clicks etc), that visually is "attached" to other windows so it stays in the same place as the user drags the title bar, minimizes or maximises the app, etc, and that is in your own process without cross-process problems.

Upvotes: 3

Alex Egorov
Alex Egorov

Reputation: 937

How I see this job:

  1. First of all we should be able to paint this button on the our own window caption. This procedure will be used later
  2. This part of the program enumerates the active and visible windows
  3. This part of the program using injection attach our dll to enumerated windows
  4. From injected dll we can draw the button on the window caption
  5. Inside this dll we should process the click on the button
  6. We should have mechanism to send result to our main program

Upvotes: 5

Related Questions