Окно теряет ручку при стыковке / расстыковке - PullRequest
0 голосов
/ 19 апреля 2020

Я использую PageControl в своей основной форме, чтобы служить в качестве сайта для док-станции для других форм.

Одна из этих форм, fPanelSonar, имеет панель, которая служит контейнером для стороннего приложения, которое я загружаю следующим образом:

var
  i : Integer;
  ExecutePingViewer : string;
  sePingViewer,seOVREC: TShellExecuteInfo;
begin
  Timer1.Enabled := False;
  fPanelSonar.hdlPing360 := FindWindow(nil, PChar('Ping Viewer - v2.0.4'));
  if fPanelSonar.hdlPing360 = 0 then
  begin
    ExecutePingViewer:='C:\Program Files (x86)\Oceanvault\pingviewer_release\deploy\pingviewer.exe';
    FillChar(sePingViewer, SizeOf(sePingViewer), 0) ;
    sePingViewer.cbSize := SizeOf(TShellExecuteInfo) ;
    with sePingViewer do
    begin
      fMask := SEE_MASK_NOCLOSEPROCESS;
      Wnd := 0;
      lpFile := PChar(ExecutePingViewer) ;
      nShow := SW_HIDE;
    end;
    if ShellExecuteEx(@sePingViewer) then
    begin
      fPanelSonar.hdlPing360 := FindWindow(nil, PChar('Ping Viewer - v2.0.4'));
      Windows.SetParent(hdlPing360, pSonar.Handle);
      ShowWindow(hdlPing360, SW_SHOWMAXIMIZED);
    end
    else ShowMessage('Error loading Ping360!') ;
  end;

Это работает хорошо, и мое стороннее приложение загружается, как я хочу.

Проблема заключается в том, что когда я помещаю fPanelSonar в PageControl, стороннее приложение исчезает, даже если его процесс "pingviewer.exe" все еще выполняется.

Так как я сохранил hwnd fPanelSonar.hdlPing360, я снова смогу установить его обратно в родительский, но он появляется, хотя этот дескриптор недопустим, потому что он не ' т работа. (Даже если я отсоединяю его).

Более того, я не могу найти какой-либо другой дескриптор, когда подключаюсь к док-станции:

FindWindowEx(fPanelSonar.pSonar.Handle,0,nil, PChar('Ping Viewer - v2.0.4'));

Я все еще могу найти идентификатор процесса с помощью этой функции Я нашел форум, поэтому я знаю, что его не убили. (Я также вижу это в диспетчере задач окна)

function GetPIDbyProcessName(processName:String):integer;
var
  GotProcess: Boolean;
  tempHandle: tHandle;
  procE: tProcessEntry32;
begin
  tempHandle:=CreateToolHelp32SnapShot(TH32CS_SNAPALL, 0);
  procE.dwSize:=SizeOf(procE);
  GotProcess:=Process32First(tempHandle, procE);
  {$B-}
    if GotProcess and (procE.szExeFile <> processName) then
      repeat GotProcess := Process32Next(tempHandle, procE);
      until (not GotProcess) or (procE.szExeFile = processName);
  {$B+}

  if GotProcess then
    result := procE.th32ProcessID
  else
    result := 0; // process not found in running process list

  CloseHandle(tempHandle);
end;

Я попытался найти hwd с идентификатором процесса, но это не сработало.

Обратите внимание, что если я подключу fPanelSonar до того, как назначить родительский pingviewer.exe, он работает.

В настоящее время я могу использовать события dock / undock, чтобы убить процесс pingviewer и загрузить новый, но это ужасно грязно ...

Так что я немного запутался, почему это происходит и как это правильно решить.

Ура, E.

...