본문 바로가기

Delphi/C++Builder

[VCL] 다른 프로세스의 폼을 패널등에 넣기

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


1, 아래 그림과 같이 메모장(notepad.exe)을 실행해 Panel에 넣어봤습니다. 

2, 프로세스의 폼(메모장)의 테두리를 없앴습니다.

3, 창 크기가 변경될때 프로세스의 폼 크기를 변경하도록 했습니다.(비동기)


EmbedFormSource.zip


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;


참고링크