c# - 打开进程(记事本)后如何将焦点设置回表单?

标签 c# winforms process focus windows-shell

我使用 Process.Start() 从我的程序中打开一个记事本,但新打开的记事本覆盖了屏幕。但我确实希望我的应用程序保持其焦点。

我类似地(使用相同的 Process.Start)打开 MS Excel 和 Word,但要将注意力集中到我的表单上,我需要写的是:

this.Focus();

但是记事本有一个怪癖:我打开记事本(以及所有其他类似的进程)

Process process = new Process();
process.StartInfo.UseShellExecute = true;
process.EnableRaisingEvents = true;
process.StartInfo.FileName = @"abc.log";
process.Start();

现在记事本成为焦点。

我试过这些:

  1. this.Activate()this.Focus(),不用说了

  2. [DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]  
    public static extern IntPtr SetFocus(HandleRef hWnd);
    
    {
       IntPtr hWnd = myProcess.Handle;
       SetFocus(new HandleRef(null, hWnd));
    }
    
  3. [DllImport("User32")]
    private static extern int SetForegroundWindow(IntPtr hwnd);
    
    [DllImportAttribute("User32.DLL")]
    private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    private const int SW_SHOW = 5;
    private const int SW_MINIMIZE = 6;
    private const int SW_RESTORE = 9;
    
    {
        ShowWindow(Process.GetCurrentProcess().MainWindowHandle, SW_RESTORE);
        SetForegroundWindow(Process.GetCurrentProcess().MainWindowHandle);
    }
    
  4. 另一个更长的解决方案来自 here .

所有这些仍然将焦点放在记事本上。为什么仅将焦点放在一个窗口上如此困难,应用程序自己的窗口也是如此?

编辑:充其量我可以打开最小化的记事本,但在尝试了上述所有代码后它仍然不会将焦点放在表单上。记事本以最小化方式打开,但焦点仍会在记事本上(有时我们会在 windows xp 中看到)并且表单将失去焦点。

最佳答案

我几乎尝试了互联网上的所有内容(非常确定 :))。充其量我可以将我的表格置于所有其他表格之上,但没有焦点(通过@Hans Passant 的方法)。遍地都是沉重的代码块,我不知何故觉得这并不容易。所以我总是将 SetForegroundWindow() 与其他代码块一起使用。从来没有想过仅仅 SetForegroundWindow() 就可以做到这一点。

这有效。

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);

private void button1_Click(object sender, EventArgs e)
{ 
    Process process = new Process();
    process.StartInfo.FileName = @...\abc.log";
    process.Start();

    process.WaitForInputIdle(); //this is the key!!

    SetForegroundWindow(this.Handle);
}

有时这种方法会产生对父表单的关注(在我想要的表单是其父表单的模态子表单的情况下);在这种情况下,只需将 this.Focus() 添加到最后一行..

即使这样也行得通:

Microsoft.VisualBasic.Interaction.Shell(@"notepad.exe D:\abc.log", 
                                        Microsoft.VisualBasic.AppWinStyle.NormalNoFocus);

解决方案由here提供

关于c# - 打开进程(记事本)后如何将焦点设置回表单?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8881038/

相关文章:

.net - 检测整个窗口的箭头键-KeyDown

C# .NET 打印出格式化的 ArrayList

java - 在java中执行外部程序并传递命令

c# - 单击按钮后如何创建新的文本框?

c# - 关闭窗体 C# 时单击 "yes"双?

c# - 分离 int 和 char 并生成整数

c# - 缩放、旋转和裁剪图像

c# - C# winform 应用程序的数据模型

qt - QProcess::startDetached被UAC阻止(运行更新程序)

process - 主机上的容器进程