Comment débourser à une autre application et le faire apparaître sous une forme delphi

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

  •  18-09-2019
  •  | 
  •  

Question

Dans Delphi Je l'ai utilisé pendant des années ShellExecute pour lancer (et éventuellement attendre pour d'autres applications). Maintenant, cependant, je dois avoir une de ces applications apparaissent dans une de mes formes d'applications Delphi. J'ai essayé le code ci-dessous comme test simple pour ouvrir le bloc-notes (ce qu'il fait) et pour afficher le résultat dans PANEL1 sur ma forme (ce qui ne marche pas). une personne aimable peut me mettre sur la bonne voie? Merci

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;
Était-ce utile?

La solution

Toutes vérification d'erreur omis, mais cela devrait vous aider à démarrer:

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;

Ce que vous devez certainement faire est d'énumérer les fenêtres du nouveau processus, au lieu d'utiliser simplement une poignée de fenêtre FindWindow () retours.

Autres conseils

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

Ce sera une question délicate, si elle est encore possible.

J'ai vu des approches qui fonctionnent pour les applications basées sur des textes -. Ils capturent généralement la sortie standard du processus comme il arrive et le mettre dans un contrôle de texte

Mais qu'est-ce que vous parlez est une application graphique à part entière (Bloc-notes, malgré un travail sur le texte, les pixels d'affichage, pas des codes de caractères).

Alors, à moins que le Bloc-notes fournit une interface où vous pouvez:

  • demander des caractères arbitraires dans la mémoire tampon; et
  • envoyer des frappes arbitraires au programme, Je dirais que vous êtes à plat de chance.

Certainement une bidouille, mais une option est de surveiller en permanence les fenêtres Bloc-notes et vous assurer qu'il est toujours superposé sur vos formulaires espace client. C'est assez horrible car vous devez arrêter le déplacement, le redimensionnement, réduisant au minimum et ainsi de suite, et maintenir son ordre z être juste au-dessus de vos applications. Je ne voudrais pas ces exigences sur mon pire ennemi.

Avez-vous pensé à utiliser un contrôle de l'éditeur construit spécifiquement pour Delphi (ou un éditeur ActiveX que vous pouvez intégrer)? Cela pourrait être une meilleure approche.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top