I am trying to get the window handles to a Delphi application from an external application. I can see that there are a few windows created (TApplication, TFrmMain and a few others), and I know that TApplication is the "controller", but never visible. However, can I read what the value for the real window is? I know that it is TFrmMain (for this specific application), but is it possible to actually figure this out somehow? Is the information stored in the window properties,or somewhere else? Thanks!
The class name of any Delphi form is also the registered window classname of the underlying "Windows window". So you should be able to use the FindWindow() Windows API call to get the window handle of TFrmMain a little something like:
hWnd := FindWindow('TFrmMain', NIL);
If there are (potentially) multiple instances of a given form class name then you may be able to distinguish between them by using the 2nd parameter (Window Name, i.e. "caption" or title). If that still isn't enough then you may need to get a little bit more sophisticated and look at using the EnumWindows() function and checking the properties of the windows to find the one of interest.
To test the classname of an arbirary window handle (e.g. in your callback function that you use with EnumWindows()), use GetClassName(), e.g:
function GetWindowClassName(const aHWND: HWND): String;
var
buf: array[0..255] of Char; // Tip: Use a more appropriately sized array
begin
GetClassName(SomeHWND, @buf, Length(buf));
result := buf;
end;
...
if SameText(GetWindowClassName(hwnd), 'TFrmMain') then
...
etc
Without specific details of your particular implementation challenge it's difficult to say which is most likely to work best for you, but hopefully that should be enough pointers to get you heading down the right track.
No, there is no documented way to discover which of the windows represents Application.MainForm
from outside the application. In newer versions of Delphi, the main form's window handle isn't necessarily Application.MainForm.Handle
anyway; applications can handle the OnGetMainFormHandle
event to return whatever they want — that's used for choosing the parent window for modal dialogs.
You can guess by looking for windows with "main" in their class names, but even if you find one, there's no guarantee that there's only one instance of it. Applications can have multiple top-level windows, in which case it doesn't make much sense to designate any one of them as the "main" one.