Cómo pagar a otra aplicación y hacer que aparezca en una forma delphi
-
18-09-2019 - |
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;
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.