프로세스를 생성하고 프로세스의 폼을 내 애플리케이션의 특정 영역(패널 등)에 넣도록 하는 코드입니다.
1, 아래 그림과 같이 메모장(notepad.exe)을 실행해 Panel에 넣어봤습니다.
2, 프로세스의 폼(메모장)의 테두리를 없앴습니다.
3, 창 크기가 변경될때 프로세스의 폼 크기를 변경하도록 했습니다.(비동기)
uses
Winapi.ShellAPI;
// 메모장 실행 / Embed 시키기
procedure TForm1.Button1Click(Sender: TObject);
var
ExecuteFile : string;
SEInfo: TShellExecuteInfo;
RetryCount: Integer;
begin
ExecuteFile:='c:\Windows\notepad.exe';
FillChar(SEInfo, SizeOf(SEInfo), 0) ;
SEInfo.cbSize := SizeOf(TShellExecuteInfo) ;
with SEInfo do
begin
fMask := SEE_MASK_NOCLOSEPROCESS;
Wnd := Panel1.Handle;
lpFile := PChar(ExecuteFile) ;
nShow := SW_HIDE;
end;
if ShellExecuteEx(@SEInfo) then
begin
// 실행 후 바로 찾을 수 없어 윈도우 핸들 찾기 재시도
RetryCount := 0;
repeat
FAppWnd := FindWindow(PChar('notepad'), PChar('제목 없음 - 메모장'));
Sleep(100);
Inc(RetryCount);
until (FAppWnd <> 0) or (RetryCount > 10);
// 부모설정, 테두리제거, 최대화
if FAppWnd <> 0 then
begin
WinAPI.Windows.SetParent(FAppWnd, SEInfo.Wnd);
SetWindowLong(FAppWnd, GWL_STYLE,
GetWindowLong(Handle, GWL_STYLE) // 기존 스타일에서
and not WS_BORDER // 크기조정 테두리 - 제거
and not WS_THICKFRAME // 두꺼운 프레임 - 제거
and not WS_DLGFRAME // 이중 테두리 - 제거
);
ShowWindow(FAppWnd, SW_SHOWMAXIMIZED);
end;
end;
end;
// 메모장 닫기(프로세스 종료)
procedure TForm1.Button2Click(Sender: TObject);
begin
if FAppWnd <> 0 then
begin
PostMessage(FAppWnd, WM_Close, 0, 0);
FAppWnd := 0;
end;
end;
// 메모장 크기 조절
procedure TForm1.Panel1Resize(Sender: TObject);
begin
if IsWindow(FAppWnd) then
SetWindowPos(FAppWnd, 0, 0, 0, Panel1.Width, Panel1.Height, SWP_ASYNCWINDOWPOS);
end;참고링크
- http://stackoverflow.com/questions/2154560/embed-an-application-exe-file-into-another-exe-file-mozembed-like
- http://www.duncom.co.kr/asp/Function/SetWindowPos.htm
- http://www.duncom.co.kr/asp/Function/SetWindowLong.htm
- http://stackoverflow.com/questions/2398746/removing-window-border
EmbedFormSource.zip