I have a third party component that displays a print preview form. I would like to change the caption of the preview form to something more appropriate. Unfortunately I do not have the source for the third party component and the component does not provide the functionality.
Is it possible to somehow catch the modal form as it is being displayed and set it's properties before it is shown?
The modal form will cause the calling form to deactivate, you can listen for WM_ACTIVATE
messages on the form that is active before the modal form is shown. You'll have the activating window's handle in the message handler, you can test that if it is of a form of the type of the modal form. Below example tests for the class name, which you can get with something like Spy++. Note that deactivation happens briefly after the modal form has become visible, but I don't think it would be possible to notice the differing caption.
type
TForm1 = class(TForm)
..
protected
procedure WMActivate(var Message: TWMActivate); message WM_ACTIVATE;
end;
procedure TForm1.WMActivate(var Message: TWMActivate);
var
Form: TWinControl;
begin
if Message.Active = WA_INACTIVE then begin
Form := FindControl(Message.ActiveWindow);
if Form is TCustomForm then begin
if TCustomForm(Form).ClassName = 'TThirdPartyModalForm' then
TCustomForm(Form).Caption := 'My caption';
end;
end;
inherited;
end;
Try using the TScreen.OnActiveFormChange
event, using the TScreen.ActiveCustomForm
or TScreen.ActiveForm
property to know which TForm
has the focus:
procedure TMainForm.DoSomething;
begin
Screen.OnActiveFormChange := ActiveFormChanged;
try
// do something that triggers the modal form ...
finally
Screen.OnActiveFormChange := nil;
end;
end;
procedure TMainForm.ActiveFormChanged(Sender: TObject);
var
Form: TCustomForm;
begin
Form := Screen.ActiveCustomForm;
if (Form <> nil) and (Form.ClassName = 'TModalFormClassName') then
Form.Caption := 'My caption';
end;
You can install a WH_CBT
hook using the SetWindowsHookEx
function.
var
hhk: HHOOK;
function CBT_FUNC(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
const
ClassNameBufferSize = 1024;
var
hTemp : HWND;
i : Integer;
RetVal : Integer;
ClassNameBuffer: Array[0..ClassNameBufferSize-1] of Char;
begin
case nCode of
HCBT_ACTIVATE:
begin
hTemp := HWND(wParam);
if (Screen<>nil) and (hTemp>0) then
begin
RetVal := GetClassName(wParam, ClassNameBuffer, SizeOf(ClassNameBuffer));
//check for the class
if (RetVal>0) and SameText(ClassNameBuffer,'TForm2') then
begin
Assert(RetVal < ClassNameBufferSize, 'Class name larger than fixed buffer size');
for i := 0 to Screen.FormCount-1 do
if Screen.Forms[i].Handle=hTemp then
begin
//set the caption
Screen.Forms[i].Caption:='Hello';
Break;
end;
end;
end;
end;
end;
Result := CallNextHookEx(hhk, nCode, wParam, lParam);
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With