11

Delphi では、ShellExecute を何年も使用して、他のアプリケーションを起動 (およびオプションで待機) してきました。ただし、これらのアプリケーションの 1 つを Delphi アプリ フォームの 1 つに表示する必要があります。以下のコードを簡単なテストとして、メモ帳を開き (開く)、フォームの PAnel1 内に結果を表示する (表示しない) ことを試しました。親切な人が私を正しい軌道に乗せることができますか? ありがとう

var
  Rec          : TShellExecuteInfo;
  wnd : HWnd;
const
  AVerb = 'open';
  AParams = '';
  AFileName = 'Notepad.exe';
  ADir = '';
begin
  FillChar(Rec, SizeOf(Rec), #0);

  Rec.cbSize       := SizeOf(Rec);
  Rec.fMask        := SEE_MASK_NOCLOSEPROCESS;
  Rec.lpVerb       := PChar( AVerb );
  Rec.lpFile       := PChar( AfileName );
  Rec.lpParameters := PChar( AParams );
  Rec.lpDirectory  := PChar( Adir );
  Rec.nShow        := sw_Show;

  ShellExecuteEx(@Rec);

  wnd := Windows.FindWindow( 'Notepad', nil );
  Windows.SetParent( Wnd, PAnel1.Handle );

end;
4

3 に答える 3

16

すべてのエラー チェックは省略されていますが、これで作業を開始できます。

procedure TForm1.Button1Click(Sender: TObject);
var
  Rec: TShellExecuteInfo;
const
  AVerb = 'open';
  AParams = '';
  AFileName = 'Notepad.exe';
  ADir = '';
begin
  FillChar(Rec, SizeOf(Rec), #0);

  Rec.cbSize       := SizeOf(Rec);
  Rec.fMask        := SEE_MASK_NOCLOSEPROCESS;
  Rec.lpVerb       := PChar( AVerb );
  Rec.lpFile       := PChar( AfileName );
  Rec.lpParameters := PChar( AParams );
  Rec.lpDirectory  := PChar( Adir );
  Rec.nShow        := SW_HIDE;

  ShellExecuteEx(@Rec);
  WaitForInputIdle(Rec.hProcess, 5000);

  fNotepadHandle := Windows.FindWindow( 'Notepad', nil );
  Windows.SetParent( fNotepadHandle, Handle );

  Resize;
  ShowWindow(fNotepadHandle, SW_SHOW);
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  if IsWindow(fNotepadHandle) then begin
    SetWindowPos(fNotepadHandle, 0, 0, 0, ClientWidth, ClientHeight,
      SWP_ASYNCWINDOWPOS);
  end;
end;

FindWindow()が返すウィンドウ ハンドルを単純に使用するのではなく、必ず新しいプロセスのウィンドウを列挙する必要があります。

于 2009-04-28T09:06:06.660 に答える
1
var
  URL: string;
begin
  URL:= DBMemoURL.Text;
  // ShellExecute(self.WindowHandle,'open', PChar(URL), nil, nil, SW_SHOW); //default browser
     ShellExecute(self.WindowHandle,'open','chrome.exe', PChar(URL), nil, SW_SHOW); 
于 2011-11-04T16:05:18.160 に答える
0

それが可能であったとしても、それは難しいものです。

テキストベースのアプリケーションで機能するアプローチを見てきました。それらは通常、プロセスの標準出力が発生したときにそれをキャプチャし、それをテキスト コントロールに入れます。

しかし、あなたが話しているのは、本格的なグラフィカルアプリケーションです(メモ帳、テキストで作業しているにもかかわらず、文字コードではなくピクセルを表示します)。

したがって、メモ帳が次のことができるインターフェイスを提供しない限り:

  • バッファ内の任意の文字を要求します。と
  • プログラムに任意のキーストロークを送信することはできません。運が悪いと思います。

確かに面倒ですが、1 つのオプションは、メモ帳ウィンドウを継続的に監視し、常にフォーム クライアント領域に重なるようにすることです。移動、サイズ変更、最小化などを停止し、z オーダーをアプリケーションのすぐ上に維持する必要があるため、これは非常に恐ろしいことです。私は最悪の敵にそれらの要件を望んでいません.

Delphi 専用に構築されたエディタ コントロール(または組み込み可能な ActiveX エディタ)の使用を考えたことはありますか。それはより良いアプローチかもしれません。

于 2009-04-28T09:05:18.487 に答える