C# Windows窗体:根据外部窗口启用的焦点设置窗体可见性

C# Windows窗体:根据外部窗口启用的焦点设置窗体可见性,c#,winforms,forms,C#,Winforms,Forms,我想创建一个Windows窗体应用程序,该应用程序在运行时仅在启用/聚焦另一个外部窗口notepad.exe后可见。任何提示,我都不知道从哪里开始 如果我的表单正在运行,我希望它在记事本启用时弹出,在记事本失去焦点时消失。您可以尝试查看针对C的Windows自动化API。使用这些API,您应该能够查看所有打开的窗口并找到记事本。我还没有看过API的一系列内容,但最好的基本场景是,对于您可以处理的窗口,会有一个activate/lostfocus事件。最糟糕的情况是,您可以每隔100毫秒左右进行一

我想创建一个Windows窗体应用程序,该应用程序在运行时仅在启用/聚焦另一个外部窗口notepad.exe后可见。任何提示,我都不知道从哪里开始


如果我的表单正在运行,我希望它在记事本启用时弹出,在记事本失去焦点时消失。

您可以尝试查看针对C的Windows自动化API。使用这些API,您应该能够查看所有打开的窗口并找到记事本。我还没有看过API的一系列内容,但最好的基本场景是,对于您可以处理的窗口,会有一个activate/lostfocus事件。最糟糕的情况是,您可以每隔100毫秒左右进行一次轮询,查看记事本窗口是否有焦点。

您只需使用API调用和计时器即可完成此操作。将此行添加到表单的using语句:

using System.Runtime.InteropServices;
接下来,将这些声明添加到表单中:

[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, 
    string lpWindowName); 

[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
最后,在窗体上放置一个计时器,并将其Enabled属性设置为true。在其勾号事件中,输入以下代码:

IntPtr hWndNotepad = FindWindow(null, "Whatever.txt - Notepad");
IntPtr hWndForegroundWindow = GetForegroundWindow();
if (this.Handle != hWndForegroundWindow)
{
    this.Visible = (hWndNotepad == hWndForegroundWindow);
}
我还没有测试过这段代码,但它应该可以工作。代码正在寻找要在记事本中打开的特定文件;不同的文件会导致标题栏中出现不同的文本,因此此代码不起作用。我认为,如果您将FindWindow调用更改为FindWindownotepad,null它将与Notepad的任何打开实例一起工作,它可能是Notepad.exe-不确定

更新:如果您希望在任何记事本实例打开时表单可见,您可以将此代码放入计时器的勾号事件中:

IntPtr hWndForegroundWindow = GetForegroundWindow();
bool NotepadIsForeground = false;
Process[] procs = Process.GetProcessesByName("notepad");
foreach (Process proc in procs)
{
    if (proc.MainWindowHandle == hWndForegroundWindow)
    {
        NotepadIsForeground = true;
        break;
    }
}
if (this.Handle != hWndForegroundWindow)
{
    this.Visible = NotepadIsForeground;
}
在您的使用指令中需要:

using System.Diagnostics;

也没有测试,但我今天做得很好,为什么要麻烦呢?

这很有效!这是我想去的方向。谢谢,还有一个问题吗?如果我点击我的表单,它会持续闪烁,而不是在它和记事本之间交替聚焦。“我该怎么修理它呢?”锡安:哎呀,我告诉过你我没有测试过它。所发生的事情是,当你点击你的表单时,它就变成了前台窗口,所以下一次计时器关闭时,你的表单又让自己不可见了。我修正了代码示例。@zion:好的,我刚刚意识到,从你的问题措辞来看,你只希望当记事本是焦点窗口时,你的表单可见,所以当你点击表单时,你会希望表单不可见,因为记事本不再有焦点。我认为最简单的修复方法是在窗体的激活事件中禁用计时器,然后在窗体的停用事件中重新启用计时器。这听起来对你来说是正确的吗?是的,逻辑听起来是正确的,我很欣赏你的回答和代码。