6

印刷プレビュー フォームを表示するサード パーティ コンポーネントがあります。プレビュー フォームのキャプションをより適切なものに変更したいと考えています。残念ながら、サードパーティ コンポーネントのソースがなく、そのコンポーネントは機能を提供していません。

モーダルフォームが表示されているときに何とかキャッチし、表示する前にそのプロパティを設定することは可能ですか?

4

4 に答える 4

10

モーダル フォームは、呼び出し元のフォームを無効にします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;
于 2012-10-23T20:27:44.117 に答える
6

またはプロパティを使用して、どちらがフォーカスされているかを知るために、TScreen.OnActiveFormChangeイベントを使用してみてください。TScreen.ActiveCustomFormTScreen.ActiveFormTForm

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;
于 2012-10-24T01:41:07.017 に答える
2

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.
于 2012-10-23T20:28:37.753 に答える
2

これは、試すことができる「疑似」コードです(テストされていません):

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;
于 2012-10-23T20:34:31.427 に答える