다른 앱에 껍질을 벗기고 델파이 형태로 나타나는 방법
-
18-09-2019 - |
문제
델파이에서는 수년간 ShellexeCute를 사용하여 다른 응용 프로그램을 시작하고 선택적으로 기다렸습니다. 그러나 이제 이러한 응용 프로그램 중 하나가 Delphi 앱 양식 중 하나에 나타나야합니다. 아래 코드를 간단한 테스트로 시도하여 메모장을 열고 내 양식의 패널 1 내에 결과를 표시하려고했습니다 (그렇지 않음). 어떤 친절한 사람이 나를 올바른 길로 데려 갈 수 있습니까? 감사
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);
가능하다면 까다로운 일이 될 것입니다.
텍스트 기반 애플리케이션에서 작동하는 접근 방식을 보았습니다. 일반적으로 프로세스의 표준 출력을 캡처하여 텍스트 제어에 넣습니다.
그러나 당신이 말하는 것은 완전히 신생 그래픽 응용 프로그램입니다 (메모장, 텍스트 작업에도 불구하고 문자 코드가 아닌 디스플레이 픽셀).
따라서 Notepad가 할 수있는 인터페이스를 제공하지 않는 한 :
- 버퍼에 임의의 문자를 요청합니다. 그리고
- 임의의 키 스트로크를 프로그램에 보내면 운이 좋지 않다고 말합니다.
확실히 kludge이지만, 한 가지 옵션은 메모장 창을 지속적으로 모니터링하고 항상 양식 클라이언트 영역에 겹쳐 지도록하는 것입니다. 이동, 크기 조정, 최소화 등을 막아야하기 때문에 꽤 끔찍합니다. 그리고 Z-Order를 응용 프로그램 바로 위에 있도록 유지하십시오. 나는 최악의 적에 대한 요구 사항을 원하지 않을 것입니다.
Delphi (또는 포함 할 수있는 ActiveX 편집기)를 위해 특별히 구축 된 편집기 컨트롤을 사용한다고 생각 했습니까? 그것은 더 나은 접근법 일 수 있습니다.