프로세스를 생성하고 프로세스의 폼을 내 애플리케이션의 특정 영역(패널 등)에 넣도록 하는 코드입니다.
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