如何打开进程(记事本)后将焦点重新设置为表单?

问题描述 投票:9回答:5

我使用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中看到该内容),并且窗体将失去焦点。

c# winforms process focus windows-shell
5个回答
11
投票

我几乎尝试了Internet上的所有内容(对此很确定:))。充其量我可以将我的表单放在所有其他表单之上,但是没有重点(通过@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提供的解决方案


2
投票

我有同样的问题,我最终还是以编程方式调用alt-tab:]

[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);

private void alttab()
{
     uint WM_SYSCOMMAND = 0x0112;
     int SC_PREVWINDOW = 0xF050;            

     PostMessage(Process.GetCurrentProcess().MainWindowHandle, WM_SYSCOMMAND, SC_PREVWINDOW, 0);
}

1
投票

Windows阻止应用程序将其窗口推向用户的脸部,您正在看到它在起作用。 MSDN文档中的AllowSetForegroundWindow()中记录了应用程序可能会抢占焦点的确切规则。


0
投票
如果您要启动一个过程并集中到表单,然后以最小化状态启动该过程,如下所示:

Dim psi As New ProcessStartInfo("notepad") psi.WindowStyle = ProcessWindowStyle.Minimized Process.Start(psi)


-1
投票
尝试一下:

public partial class MainForm : Form { private ShowForm showForm; public MainForm() { InitializeComponent(); } private void showButton_Click(object sender, EventArgs e) { this.showForm = new ShowForm(); this.showForm.FormClosed += showForm_FormClosed; this.showForm.Show(this); } private void showForm_FormClosed(object sender, FormClosedEventArgs e) { this.Focus(); } }

© www.soinside.com 2019 - 2024. All rights reserved.