.NET 跨历程设置父子窗口SetParent

打印 上一主题 下一主题

主题 907|帖子 907|积分 2721

跨历程设置父子窗口除了owner方案 C# 跨历程 设置窗口owner - 唐宋元明清2188 - 博客园,还有Win32-SetParent SetParent 函数 (winuser.h) - Win32 apps | Microsoft Learn
SetParent可以实现将子窗口嵌入另一个窗口中
  1. 1     [DllImport("user32.dll", SetLastError = true)]
  2. 2     static extern int SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
复制代码
hWndChild是子窗口,hWndNewParent是新父窗口句柄,返回参数为子窗口的上一次父窗口句柄
我们建个demo试试,
可以使用syp++-查找窗口句柄。这里为了效率高,直接显示窗口句柄方便获取:
  1. 1     CurrentHandleTextBox.Text = new WindowInteropHelper(this).Handle.ToString("X");
复制代码
根据其它窗口句柄和当前窗口句柄,设置SetParent
  1. 1     private void AddChildWindow_OnClick(object sender, RoutedEventArgs e)
  2. 2     {
  3. 3         var inputInt32 = Convert.ToInt32(InputTextBox.Text, 16);
  4. 4         IntPtr inputPtr = (IntPtr)inputInt32;
  5. 5         var currentInPtr = new WindowInteropHelper(this).Handle;
  6. 6
  7. 7         var result = SetParent(inputPtr, currentInPtr);
  8. 8         MessageBox.Show($"SetParent Result:{result}");
  9. 9     }
复制代码
显示效果如下:

设置成功时,结果:

65552是上一个父窗口句柄,这是哪个窗口呢?
我们把65552换成16进制,通过syp++,能看到是这是桌面窗口

上面Demo详见 kybs00/SetParentDemo
SetParent函数非常强大,适合那些必要设置子窗口只在父窗口地区内显示,好比分屏软件,可以把父窗口完全当作一个显示器来使用。
根据小伙伴反馈,应用设置了uiAccess后,在此历程打开其它软件,其它软件内部调用SetParent实现相关功能时会失败。
  1. 时间: 2025-01-08 18:03:44,034
  2. 线程ID: [1]
  3. 错误描述: 寄宿的 HWND 必须是指定父级的子窗口。
  4. 异常: System.InvalidOperationException: 寄宿的 HWND 必须是指定父级的子窗口。
  5.    在 System.Windows.Interop.HwndHost.BuildWindow(HandleRef hwndParent)
  6.    在 System.Windows.Interop.HwndHost.BuildOrReparentWindow()
  7.    在 System.Windows.Interop.HwndHost.OnSourceChanged(Object sender, SourceChangedEventArgs e)
  8.    在 System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
  9.    在 System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
  10.    在 System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
  11.    在 System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
  12.    在 System.Windows.PresentationSource.UpdateSourceOfElement(DependencyObject doTarget, DependencyObject doAncestor, DependencyObject doOldParent)
  13.    在 System.Windows.PresentationSource.OnVisualAncestorChanged(DependencyObject uie, AncestorChangedEventArgs e)
  14.    在 System.Windows.UIElement.OnVisualAncestorChanged(Object sender, AncestorChangedEventArgs e)
  15.    在 System.Windows.Media.Visual.ProcessAncestorChangedNotificationRecursive(DependencyObject e, AncestorChangedEventArgs args)
  16.    在 System.Windows.Media.Visual.ProcessAncestorChangedNotificationRecursive(DependencyObject e, AncestorChangedEventArgs args)
  17.    在 System.Windows.Media.Visual.ProcessAncestorChangedNotificationRecursive(DependencyObject e, AncestorChangedEventArgs args)
  18.    在 System.Windows.Media.Visual.AddVisualChild(Visual child)
  19.    在 System.Windows.FrameworkElement.set_TemplateChild(UIElement value)
  20.    在 System.Windows.Controls.ContentPresenter.UseContentTemplate.BuildVisualTree(FrameworkElement container)
  21.    在 System.Windows.StyleHelper.ApplyTemplateContent(UncommonField`1 dataField, DependencyObject container, FrameworkElementFactory templateRoot, Int32 lastChildIndex, HybridDictionary childIndexFromChildID, FrameworkTemplate frameworkTemplate)
  22.    在 System.Windows.FrameworkTemplate.ApplyTemplateContent(UncommonField`1 templateDataField, FrameworkElement container)
  23.    在 System.Windows.FrameworkElement.ApplyTemplate()
  24.    在 System.Windows.FrameworkElement.MeasureCore(Size availableSize)
  25.    在 System.Windows.UIElement.Measure(Size availableSize)
  26.    在 System.Windows.Controls.Border.MeasureOverride(Size constraint)
  27.    在 System.Windows.FrameworkElement.MeasureCore(Size availableSize)
  28.    在 System.Windows.UIElement.Measure(Size availableSize)
  29.    在 System.Windows.Controls.Control.MeasureOverride(Size constraint)
  30.    在 System.Windows.FrameworkElement.MeasureCore(Size availableSize)
  31.    在 System.Windows.UIElement.Measure(Size availableSize)
  32.    在 System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV)
  33.    在 System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV, Boolean& hasDesiredSizeUChanged)
  34.    在 System.Windows.Controls.Grid.MeasureOverride(Size constraint)
  35.    在 System.Windows.FrameworkElement.MeasureCore(Size availableSize)
  36.    在 System.Windows.UIElement.Measure(Size availableSize)
  37.    在 System.Windows.ContextLayoutManager.UpdateLayout()
  38.    在 MagicWindowSplit.SplitService.<SplitWindow>d__25.MoveNext()
  39. --- 引发异常的上一位置中堆栈跟踪的末尾 ---
  40.    在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
  41.    在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
  42.    在 MagicWindowSplit.SplitService.<SelectControlSplit>d__16.MoveNext()
  43. --- 引发异常的上一位置中堆栈跟踪的末尾 ---
  44.    在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
  45.    在 System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
  46.    在 System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
复制代码
uiAccess历程启动软件,会默认添加管理员权限。为了简化后续形貌,我们称“uiAccess权限历程启动其它软件”,有uiAccess影响。
下面我们启动俩个雷同demo.exe,使用俩个不同历程的窗口,来验证SetParent情况
1.俩个均有uiAccess影响的窗口 -  正常
2.有uiAccess影响的窗口A、非uiAccess影响窗口B,在A内设置A为B的子窗口 - 正常
3.有uiAccess影响的窗口A、非uiAccess影响窗口B,在B内设置A为B的子窗口 - 错误,返回值0
原因是管理员权限题目,非管理员权限无法设置管理员权限窗口为其子窗口,仅用管理员权限验证也是一样的结果。
4. 有uiAccess影响的窗口A、非uiAccess影响窗口B,在A内设置B为A的子窗口 - 正常
5. 有uiAccess影响的窗口A、非uiAccess影响窗口B,在B内设置B为A的子窗口 - 错误
原因是管理员权限题目,非管理员权限无法设置管理员权限窗口为其父窗口,仅用管理员权限验证也是一样的结果。
所以设置SetParent失败与uiAccess影响无关,仅仅是管理员权限不敷。而上面小伙伴反馈的分屏软件调用SetParent非常是其它业务题目,毅仔有相关先容 System.InvalidOperationException:“寄宿的 HWND 必须是指定父级的子窗口。” - walterlv  SetParent其它题目可以参考:SetParent 函数修改父窗口的误区-CSDN博客使用 SetParent 制作父子窗口的时候,如何设置子窗口的窗口样式以避免抢走父窗口的核心 - walterlv使用 SetParent 跨历程设置父子窗口时的一些题目(小心卡死) - walterlv出处:http://www.cnblogs.com/kybs0/让学习成为习惯,假设明天就有重大机遇等着你,你准备好了么本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文毗连,否则保留追究法律责任的权利。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

自由的羽毛

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表