印刷プレビュー フォームを表示するサード パーティ コンポーネントがあります。プレビュー フォームのキャプションをより適切なものに変更したいと考えています。残念ながら、サードパーティ コンポーネントのソースがなく、そのコンポーネントは機能を提供していません。
モーダルフォームが表示されているときに何とかキャッチし、表示する前にそのプロパティを設定することは可能ですか?
印刷プレビュー フォームを表示するサード パーティ コンポーネントがあります。プレビュー フォームのキャプションをより適切なものに変更したいと考えています。残念ながら、サードパーティ コンポーネントのソースがなく、そのコンポーネントは機能を提供していません。
モーダルフォームが表示されているときに何とかキャッチし、表示する前にそのプロパティを設定することは可能ですか?
モーダル フォームは、呼び出し元のフォームを無効にしますWM_ACTIVATE
。モーダル フォームが表示される前に、アクティブなフォームでメッセージをリッスンできます。メッセージ ハンドラーにアクティブ化ウィンドウのハンドルがあり、それがモーダル フォームのタイプのフォームであるかどうかをテストできます。以下の例では、Spy++ などで取得できるクラス名をテストします。モーダル フォームが表示された直後に非アクティブ化が発生することに注意してください。ただし、キャプションの違いに気付くことはできないと思います。
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;
またはプロパティを使用して、どちらがフォーカスされているかを知るために、TScreen.OnActiveFormChange
イベントを使用してみてください。TScreen.ActiveCustomForm
TScreen.ActiveForm
TForm
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;
WH_CBT
関数を使用してフックを取り付けることができSetWindowsHookEx
ます。
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.
これは、試すことができる「疑似」コードです(テストされていません):
const
MY_PRINT_PREVIEW_MSG = WM_USER + 200;
type
TForm1 = class(TForm)
procedure MyPrintPreviewMsg(var Msg: TMessage); message MY_PRINT_PREVIEW_MSG;
procedure MyPrintPreview;
end;
...
procedure TForm1.MyPrintPreviewMsg(var Msg: TMessage);
var
h: HWND;
begin
h := Screen.Forms[0].Handle; // if the modal dialog is VCL dialog (verify it with spy++)
// h := FindWindow(<class name>, <caption>); // non VCL window
if (h <> 0) then
begin
SetWindowText(h, 'new caption');
end;
end;
procedure TForm1.MyPrintPreview;
begin
PostMessage(Handle, MY_PRINT_PREVIEW_MSG, 0, 0);
ThirdPartyPrintPreview;
end;