2017-08-27 72 views
1

我想要做的很简单:使我的WinForm在另一个顶部,但不是最顶层。我喜欢,当我点击一个窗口时,我的winform将会在其上,但是当我点击其他的东西时,比如浏览器,我的表单就不会在它之上。是否可以将表单保留在另一个表单上,而不是TopMost?

像TopMost WinForm一样,但仅限于特定的进程。 (林制作了游戏的叠加,所以我需要它只能在游戏中最顶层)

图片,以帮助(一切的红色边框内是我的表单):enter image description here

然后我什么时候更改为另一个窗口(在这种情况下,资源管理器)我希望我的表单处于后台,就像传奇客户端enter image description here

+0

可以肯定的是:我希望我的WinForms应用程序能够与另一个进程(League of Legends)“停靠”,以创建一个自定义界面。这样,当我最小化或游戏窗口在后台时,我的表单将在游戏之上,但不是TopMost。 –

回答

3

拥有的表单总是显示在其所有者窗体的顶部。为了使由所有者拥有一种形式,你可以所有者窗体的引用赋予国有形式的Onwer属性,例如:

var f = new Form(); 
f.Owner = this; 
f.Show(); 

设置另一个进程的窗口作为所有者

要做到这一点,你应该先找到其他进程的窗口的句柄,然后使用SetWindowLong API功能,您可以将其设置为您的窗体的所有者,例如:

//using System.Runtime.InteropServices; 
//using System.Diagnostics; 

[DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)] 
public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong); 
private void button1_Click(object sender, EventArgs e) 
{ 
    var notepad = Process.GetProcessesByName("notepad").FirstOrDefault(); 
    if(notepad!=null) 
    { 
     var owner = notepad.MainWindowHandle; 
     var owned = this.Handle; 
     var i = SetWindowLong(owned, -8 /*GWL_HWNDPARENT*/, owner); 
    } 
} 

在上面的例子中,哟你的形式将永远在记事本窗口的顶部。

+0

这应该与2种形式,但它不是我的情况。 我的程序是一个表单,我希望它被附加到不是WinForm的程序。 –

+0

被告知,你在这里离开安全代码,这是在.NET中执行任何事情的自然方式。使用不安全的代码是很有可能的,但是你会遇到前.NET世界的所有麻烦以及在跨越重要.NET边界的工作中增加的问题。如果这是一个核心功能,那么最好使用更原生的(本地C++)或任何技巧将不安全的代码分离出主应用程序(https://social.msdn.microsoft.com/Forums/) vstudio/EN-US/644c2f9c-F06A-496A-b497-6420a7919fdb/64位应用程序,调用32位的DLL?论坛= csharpgeneral)。 – Christopher

+0

@Christopher这是设置'Owner'属性内部工作的方式。看看它的[源代码](https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Form.cs,6c3819871d1e9085,references)。 –

0

如果它是一个形式,你可以打开它与下面的代码多种形式对话:

var modalForm = new Form(); 
    modalForm .ShowDialog(); 

ShowDialogue()将始终打开窗体作为从中创建它顶形态。但是一个问题是,除非关闭模态对话框,否则无法对父窗体执行任何操作。

+0

ShowDialog,阻止后面的窗口。此外OP还在寻找可用于其他进程的窗口的解决方案。 –

+0

是的,你是对的。我也提到过。 – Tanjeer

相关问题