Delphi: Detect when a new form has been created
delphi, vcl
Solution
You can use the `SetWindowsHookEx` function to install a `WH_CBT` Hook, then you must implement a CBTProc callback function and finally intercept one of the possible code values for this hook. in this case you can try with `HCBT_ACTIVATE` or `HCBT_CREATEWND`.
Check this sample for the `HCBT_ACTIVATE` Code.
var
hhk: HHOOK;
function CBT_FUNC(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
const
ClassNameBufferSize = 1024;
var
hWindow: HWND;
RetVal : Integer;
ClassNameBuffer: Array[0..ClassNameBufferSize-1] of Char;
begin
Result := CallNextHookEx(hhk, nCode, wParam, lParam);
if nCode<0 then exit;
case nCode of
HCBT_ACTIVATE:
begin
hWindow := HWND(wParam);
if (hWindow>0) then
begin
RetVal := GetClassName(wParam, ClassNameBuffer, SizeOf(ClassNameBuffer));
if RetVal>0 then
begin
//do something
OutputDebugString(ClassNameBuffer);
end;
end;
end;
end;
end;
Procedure InitHook();
var
dwThreadID : DWORD;
begin
dwThreadID := GetCurrentThreadId;
hhk := SetWindowsHookEx(WH_CBT, @CBT_FUNC, hInstance, dwThreadID);
if hhk=0 then RaiseLastOSError;
end;
Procedure KillHook();
begin
if (hhk <> 0) then
UnhookWindowsHookEx(hhk);
end;
initialization
InitHook();
finalization
KillHook();
end.
Note : if you uses the `HCBT_CREATEWND` code instead you will intercept any window created by the system not just "forms".
Problem
I'd like to detect when a new form has been created. Now I use the `Screen.ActiveFormChange` event and check for new forms in `Screen.CustomForms` but `ActiveFormChange` is fired after the `OnShow` event of the form. I'd like to detect the form even before `OnShow` was fired. Is there any way to do this without modifying the `Vcl.Forms` unit? I'd like to detect all forms (also Delphi modal messages etc.) therefore inheriting all forms from a custom class is not possible (correct me if I am wrong). Alternatively, is it possible to detect that a new component was added to some `TComponent.FComponents` list?