Delphi - 嵌入式应用程序滚动条不可见

4

根据“向另一个进程嵌入窗口”问题,我正在将只有TWebBrowser组件的应用程序嵌入到我的主应用程序中。即使我将其嵌入到TScrollBox组件中,当主应用程序调整大小时,滚动条也不会出现。我已经对此问题进行了一些研究,但没有成功。如何启用滚动框的滚动条?

LE:为了澄清问题:应用程序A是一个简单的表单,上面有一个TWebBrowser组件。应用程序B,即主应用程序,将应用程序A嵌入到放置在表单上且Align属性设置为alClient的TScrollBox中。将应用程序A嵌入到应用程序B中的代码:

procedure ShowAppEmbedded(WindowHandle: THandle; Container: TWinControl);
var
  WindowStyle : Integer;
  FAppThreadID: Cardinal;
begin
  /// Set running app window styles.
  WindowStyle := GetWindowLong(WindowHandle, GWL_STYLE);
  WindowStyle := WindowStyle
                 - WS_CAPTION
                 - WS_BORDER
                 - WS_OVERLAPPED
                 - WS_THICKFRAME;
  SetWindowLong(WindowHandle,GWL_STYLE,WindowStyle);

  /// Attach container app input thread to the running app input thread, so that
  ///  the running app receives user input.
  FAppThreadID := GetWindowThreadProcessId(WindowHandle, nil);
  AttachThreadInput(GetCurrentThreadId, FAppThreadID, True);

  /// Changing parent of the running app to our provided container control
  Windows.SetParent(WindowHandle,Container.Handle);
  SendMessage(Container.Handle, WM_UPDATEUISTATE, UIS_INITIALIZE, 0);
  UpdateWindow(WindowHandle);

  /// This prevents the parent control to redraw on the area of its child windows (the running app)
  SetWindowLong(Container.Handle, GWL_STYLE, GetWindowLong(Container.Handle,GWL_STYLE) or WS_CLIPCHILDREN);
  /// Make the running app to fill all the client area of the container
  SetWindowPos(WindowHandle,0,0,0,Container.ClientWidth,Container.ClientHeight,SWP_NOZORDER);

  SetForegroundWindow(WindowHandle);
end;

当调整主应用程序(B)的大小时,来自B的TScrollBox组件的滚动条不会显示,并且应用程序A保持在它从一开始设置的位置。

解决方案: 根据Kobik的评论,应用程序A嵌入到位于TScrollBox内对齐为alClient的TPanel中。在OnPanelResize事件中运行以下代码:

  if IsWindow(App_B_WindowHandle) then
    SetWindowPos(App_B_WindowHandle, 0, 0, 0, Panel1.Width, Panel1.Height, SWP_ASYNCWINDOWPOS);

1
这根本行不通。Windows 不适合执行这样的操作。当 Win32 被引入时,跨进程窗口父级停止合理化已经超过 20 年了。 - David Heffernan
@DavidHeffernan - 我认识David。解决方案是有效的,但我同意你的观点,这不应该这样做。 - RBA
很可能无法正常工作。肯定还有更多你尚未发现的问题。 - David Heffernan
举例来说,Google Chrome 会为每个标签页中的网页单独创建一个进程。@DavidHeffernan - kobik
它运行自己的合作IPC来实现这一点。 - David Heffernan
1个回答

1
将一个 VCL 容器(例如 TPanel)放置在 TScrollbox 中,并将客户端应用程序嵌入面板中。这样,TScrollbox 将能够正确处理面板。您不能简单地将嵌入的应用程序对齐到 Delphi 容器内。如果需要,您可能需要处理 TPanel.OnResize 来调整嵌入应用程序的新尺寸。

无论如何,正如您已经知道的那样,整个想法都是一场痛苦的世界。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接