将表单窗口附加到C#中的另一个窗口

我想将一个表单附加到另一个窗口(另一个进程)。 我尝试通过使用来做到这一点

[DllImport("user32.dll", SetLastError = true)] private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); setParentWindow(myWindowHwnd, newParentHwnd); 

这样做我的forms变得紧密,但也是看不见的 。 问题“附加窗口..”解决了WPF窗口的这个问题,基本上是通过使用

 HwndSourceParameters parameters = new HwndSourceParameters(); ... HwndSource src = new HwndSource(parameters); 

我试图将其转移到我的表单,但我无法这样做(例如如何处理src.RootVisual = (Visual)window.Content; – > Complete source )。

另一条评论说,我需要修改windows风格:

出于兼容性原因,SetParent不会修改其父级正在更改的窗口的WS_CHILD或WS_POPUP窗口样式。 因此,如果hWndNewParent为NULL,则还应清除WS_CHILD位并在调用SetParent后设置WS_POPUP样式。 相反,如果hWndNewParent不为NULL且窗口以前是桌面的子项,则应在调用SetParent之前清除WS_POPUP样式并设置WS_CHILD样式。

在这里我错过了相应的API,我可以直接从C#中完成它还是让我再次使用另一个DllImport

好或坏 – 不同进程之间的SetParent()win32 API建议不要在不同的进程中附加窗口,但至少我想尝试。

题:

我需要做什么才能看到表单窗口? 如果使用WS_Child的方法是正确的,我该如何设置它? 或者WPF方法是可行的,但我如何将其应用于Windows窗体?

– 调查结果(后来补充) –

使用winAPI修改另一个应用程序的Windows样式显示如何从C#/ PInvoke修改样式

在这里找到所有的窗口样式 ,底部是C#语法。

– 与Alan讨论的调查结果 –

我确实在Win XP上运行我的程序进行交叉检查(参见下面的Alan的回答和评论)。 至少我现在看到的东西。 由于我已经添加了Alan的例子中的坐标,当我移动到左上角附近的另一个窗口时,我的窗口现在在记事本中闪耀。 您仍然可以在记事本中看到键入的文本作为叠加层。 在Win 7(32)下,我什么也看不见。

  1. 现在我需要弄清楚这是否可以以稳定的方式编写,也出现在Win 7上。
  2. 不过,我仍然无法点击表格上的任何按钮,也需要解决。

WinXP WinForm附加到记事本

这是一个有效的例子。 托管应用程序是一个简单的WinForms应用程序,其中包含一个空白表单(此处未包含),而“访客应用程序”有一个主要表单(下面包含的代码)和一些控件,包括一个测试按钮,用于在更改访客后显示消息表格的父母。

OP问题中常见的警告也适用于此。

 public partial class GuestForm: Form { [DllImport("user32.dll")] public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll")] public static extern int GetWindowLong(IntPtr hWnd, int nIndex); [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); public static int GWL_STYLE = -16; public static int WS_CHILD = 0x40000000; public GuestForm() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { MessageBox.Show("done"); } private void button2_Click(object sender, EventArgs e) { Process hostProcess = Process.GetProcessesByName("HostFormApp").FirstOrDefault(); if (hostProcess != null) { Hide(); FormBorderStyle = FormBorderStyle.None; SetBounds(0, 0, 0, 0, BoundsSpecified.Location); IntPtr hostHandle = hostProcess.MainWindowHandle; IntPtr guestHandle = this.Handle; SetWindowLong(guestHandle, GWL_STYLE, GetWindowLong(guestHandle, GWL_STYLE) | WS_CHILD); SetParent(guestHandle, hostHandle); Show(); } } } 

@Horst Walter嘿,伙计,我不确定你是否解决了这个问题,但我刚刚找到了解决方案。

对我来说,问题是你想要的另一种forms的主要forms的透明度。

只是禁用透明度,它应该工作。