Pregunta

En Delphi que he usado durante años ShellExecute para poner en marcha (y opcionalmente esperar a que otras aplicaciones). Ahora, sin embargo, tengo que tener una de estas aplicaciones aparecen en una de mis formas de aplicaciones Delphi. He intentado por debajo del código como una prueba simple para abrir el bloc de notas (que lo hace) y para mostrar el resultado dentro de PANEL1 en mi formulario (que se duerma). ¿Puede alguna persona amable me puso en el camino correcto? Gracias

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;
¿Fue útil?

Solución

comprobación omite todo error, pero esto debe empezar:

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;

Lo que definitivamente debe hacer es enumerar las ventanas del nuevo proceso, en lugar de simplemente utilizar cualquier identificador de ventana que FindWindow () devoluciones.

Otros consejos

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

Eso será un asunto difícil, si es aún posible.

He visto enfoques que funcionarán para aplicaciones basadas en texto -. Por lo general capturan la salida estándar del proceso, ya que sucede y lo puso en un control de texto

Pero lo que estamos hablando es una aplicación gráfica de pleno derecho (Bloc de notas, a pesar de trabajar en el texto, la pantalla píxeles, no los códigos de caracteres).

Así que, a menos que el Bloc de notas proporciona una interfaz donde se puede:

  • solicitar caracteres arbitrarios en la memoria intermedia; y
  • enviar pulsaciones de teclas arbitrarias al programa, Yo diría que eres plana de suerte.

Sin duda una chapuza, pero una opción es para controlar continuamente las ventanas Bloc de notas y asegurarse de que siempre se superpone sobre su área de cliente formas. Eso es bastante horrible ya que hay que detenerlo mover, redimensionar, minimizar y así sucesivamente, y a mantener su orden z para ser justo por encima de sus aplicaciones. No desearía esos requisitos ni a mi peor enemigo.

¿Ha pensado en el uso de un control de editor construido específicamente para Delphi (o un editor de ActiveX que se puede incrustar)? Eso podría ser un mejor enfoque.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top