【问题标题】:Delphi - embedded application scrollbars not visibleDelphi - 嵌入式应用程序滚动条不可见
【发布时间】:2016-02-11 04:14:21
【问题描述】:

基于Embedding window into another process 问题,我在我的主应用程序中嵌入了一个在主窗体上只有一个 TWebBrowser 组件的应用程序。即使我将它嵌入到 TScrollBox 组件中,当主应用程序调整大小时,滚动条也不会出现。我已经对这个问题进行了一些研究,但没有成功。如何启用滚动框的滚动条?

LE:澄清问题:应用程序 A 是一个简单的表单,上面有一个 TWebBrowser 组件。应用程序 B,主应用程序,将应用程序 A 嵌入到放置在表单上的 TScrollBox 上,并将 Align 设置为 alClient。将 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 嵌入到应用程序 B 中的 TPanel 内,该 TPanel 与 TScrollBox 内的 alClient 对齐。在 OnPanelResize 事件上运行以下代码:

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

【问题讨论】:

  • 这行不通。 Windows 不是为此类操作而设计的。 20 多年前,当引入 Win32 时,跨进程窗口育儿不再合理。
  • @DavidHeffernan - 我认识大卫。解决方案有效,但我同意你的观点,不应该这样做。
  • 它不太可能正常工作。肯定还有更多你还没有找到的问题。
  • @DavidHeffernan,例如 Google Chrome 在不同的进程中托管每个标签页。
  • 它运行自己的合作 IPC 来做到这一点。

标签: delphi delphi-xe2


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-29
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 2011-02-10
    相关资源
    最近更新 更多