Как скопировать в другое приложение и отобразить его в форме delphi
В Delphi я использовал ShellExecute в течение многих лет, чтобы запускать (и, возможно, ждать) другие приложения. Теперь, хотя мне нужно, чтобы одно из этих приложений появилось в одной из форм приложения Delphi. Я пробовал код ниже как простой тест, чтобы открыть блокнот (что он делает) и отобразить результат в 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;
Ответы
Ответ 1
Вся ошибка проверки опущена, но это должно начать:
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().
Ответ 2
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);
Ответ 3
Это будет сложно, если это возможно.
Я видел подходы, которые будут работать для текстовых приложений - они обычно фиксируют стандартный вывод процесса, как это происходит, и помещают его в текстовый элемент управления.
Но то, о чем вы говорите, - это полноценное графическое приложение (Notepad, несмотря на работу с текстом, отображение пикселей, а не кодов символов).
Итак, если Notepad предоставляет интерфейс, где вы можете:
- запрашивать произвольные символы в буфере; и
- отправлять произвольные нажатия клавиш программе,
Я бы сказал, что вам не повезло.
Определенно kludge, но один из них - постоянно следить за окнами "Блокнот" и обеспечивать, чтобы он всегда накладывался поверх клиентской области форм. Это довольно ужасно, так как вы должны остановить его перемещение, изменение размера, минимизацию и т.д. И поддерживать его z-порядок как раз над вашими приложениями. Я бы не пожелал этих требований моему злейшему врагу.
Считаете ли вы, что используете редактор, созданный специально для Delphi (или редактор ActiveX, который вы можете вставлять)? Это может быть лучшим подходом.