我想将表单附加到另一个窗口(另一个进程)。我尝试使用
来做到这一点[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
setParentWindow(myWindowHwnd, newParentHwnd);
这样做我的表单会附加,但也不可见。问题"Attach window .."基本上通过使用
解决了WPF窗口的这个问题HwndSourceParameters parameters = new HwndSourceParameters();
...
HwndSource src = new HwndSource(parameters);
我已尝试将此格式转移到我的表单中,但我无法将其转移(例如如何处理src.RootVisual = (Visual)window.Content;
? - > Complete source)。
Another comment说,我需要修改windows样式:
出于兼容性原因,SetParent不会修改其父级正在更改的窗口的WS_CHILD或WS_POPUP窗口样式。因此,如果hWndNewParent为NULL,则还应清除WS_CHILD位并在调用SetParent后设置WS_POPUP样式。相反,如果hWndNewParent不是NULL并且窗口以前是桌面的子窗口,则应该在调用SetParent之前清除WS_POPUP样式并设置WS_CHILD样式。
我在这里错过了相应的API,我可以直接从C#中执行此操作,还是让我再次使用其他DllImport
?
Good or evil - SetParent() win32 API between different processes建议不要在不同的进程中附加窗口,但至少我想尝试。
问题:
要让表单窗口可见,我需要做什么?如果WS_Child
的方法是正确的,我该如何设置它?或者是WPF approach的方法,但我如何将其应用于Windows窗体?
- 调查结果(后来添加) -
Modify the windows style of another application using winAPI显示了如何从C#/ PInvoke
修改样式在此处查找所有windows styles,在底部找到C#语法。
- 与Alan讨论的结果 -
我确实在Win XP上运行我的程序进行交叉检查(参见下面的Alan的回答和评论)。至少我现在看到的东西。由于我已经添加了Alan的例子中的坐标,当我在靠近左上角的另一个窗口移动时,我的窗口现在在记事本中闪耀。您仍然可以在记事本中看到键入的文本作为叠加层。在Win 7(32)下,我什么也看不见。
答案 0 :(得分:14)
这是一个工作示例。托管应用程序是一个简单的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();
}
}
}
答案 1 :(得分:3)
对我来说,问题是你想要在另一种形式中使用的主要形式的透明度。
只需禁用透明度即可。