加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 将窗口嵌入另一个进程

发布时间:2020-12-15 10:06:55 所属栏目:大数据 来源:网络整理
导读:我在StackOverflow上看过一些帖子,但没有一个对我有用.这是我用来在我的表单上显示标准计算器窗口的代码: procedure TForm1.Button1Click(Sender: TObject);var Tmp: Cardinal; R: TRect;begin CalcWindow := FindWindow(nil,'Calculator'); if (CalcWindow
我在StackOverflow上看过一些帖子,但没有一个对我有用.这是我用来在我的表单上显示标准计算器窗口的代码:
procedure TForm1.Button1Click(Sender: TObject);
var
  Tmp: Cardinal;
  R: TRect;
begin
  CalcWindow := FindWindow(nil,'Calculator');
  if (CalcWindow <> 0) then
  begin
    GetWindowThreadProcessID(CalcWindow,CalcProcessID);

    Tmp := GetWindowLong(CalcWindow,GWL_STYLE);
    Tmp := (Tmp and not WS_POPUP) or WS_CHILD;
    SetWindowLong(CalcWindow,GWL_STYLE,Tmp);
    GetWindowRect(CalcWindow,R);

    SetForegroundWindow(CalcWindow);
    Windows.SetParent(CalcWindow,Panel1.Handle);
    SetWindowPos(CalcWindow,HWND_TOPMOST,SWP_NOSIZE or SWP_FRAMECHANGED);

    AttachThreadInput(GetCurrentThreadID(),CalcWindow,True);
  end;
end;

它确实在我的窗体上显示窗口,但玻璃边框有时丢失(特别是当我移动窗体时),很难将焦点恢复到嵌入窗口(我需要多次单击).

可能是什么导致了这个?另外,您是否看到使用此方法可能遇到的任何潜在问题?

感谢您的时间.

解决方法

试试这个代码.我从一个较旧的源代码中获取了它.您将失去玻璃框架,但主菜单是可见的,我没有注意到将焦点设置回嵌入式应用程序时出现任何问题.您应该可以使用SetForegroundWindow()API函数执行此操作.每当您移动容器表单时,嵌入式应用程序都会失去焦点,因此您需要再次调用SetForegroundWindow来恢复焦点:
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,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,GetWindowLong(Container.Handle,GWL_STYLE) or WS_CLIPCHILDREN);
  /// Make the running app to fill all the client area of the container
  SetWindowPos(WindowHandle,Container.ClientWidth,Container.ClientHeight,SWP_NOZORDER);

  SetForegroundWindow(WindowHandle);
end;

你可以这样称呼它:

ShowAppEmbedded(FindWindow(nil,'Calculator'),Panel1);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读