別のアプリにシェルを実行し、それを Delphi フォームに表示する方法

StackOverflow https://stackoverflow.com/questions/796883

  •  18-09-2019
  •  | 
  •  

質問

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;
役に立ちましたか?

解決

すべてのエラーを省略チェックが、これはあなたが始める必要があります:

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()の戻りです。

他のヒント

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); 

たとえそれが可能だったとしても、それは難しいことになるだろう。

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

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

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

  • バッファ内の任意の文字を要求します。そして
  • 任意のキーストロークをプログラムに送信します。あなたは運がよければ、

確かに面倒なことですが、メモ帳ウィンドウを継続的に監視して、常にフォーム クライアント領域に重ねて表示されるようにするのも 1 つのオプションです。移動、サイズ変更、最小化などを停止しなければならないので、これはかなりひどいことです。 そして Z オーダーをアプリケーションのすぐ上に維持してください。最悪の敵にそのような要求をされることは望まない。

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top