2012-01-16 45 views
6

我使用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中看到的东西),而形式将会失去重点。

+0

它是确定启动窗口处于最小化状态? – NoviceProgrammer 2012-01-16 14:14:16

+0

是的,没关系,但它仍然不起作用。我会在我的问题中更新 – nawfal 2012-01-16 14:14:57

+0

你试过这个吗? http://stackoverflow.com/questions/2121911/starting-a-process-without-stealing-focus-c – NoviceProgrammer 2012-01-16 14:17:37

回答

9

我尝试了几乎所有的互联网(所以肯定:) :))。充其量,我可以在所有其他形式之上获得我的表格,但没有关注(通过@Hans Passant的方法)。通过大量的代码遍历,我不知何故会觉得这很简单。所以我总是用SetForegroundWindow()与其他代码块。从来没有想过只有SetForegroundWindow()会做到这一点。

这工作。有时这个方法产生一个重点放在父窗体上(在我希望的窗体是它的父窗体的一个模态子窗体的情况下);在这种情况下,只需添加this.Focus()到最后一行..

即使这样的工作:通过here

2

我有同样的问题,我最终清盘通过编程调用ALT标签:

[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); 
} 

//编辑:您应该使用process.MainWindowHandle代替ofcourse

+0

谢谢。明天会让你知道..这绝对是不同的想法,但我担心这个解决方法有时会产生问题。你有没有遇到这种方法的问题? – nawfal 2012-01-16 16:27:13

+0

这是行不通的。 – nawfal 2012-01-18 06:41:35

1

Windows禁止推搡他们的应用程序窗口进入用户的脸部,你看到了这个工作。 AllowSetForegroundWindow()的MSDN文档中记录了应用程序可能窃取焦点的确切规则。

此限制的后门是AttachThreadInput()函数。此代码运行良好,我没有找到拥有前台窗口的线程的线程ID的快捷方式。记事本足够好,可能不适用于其他应用程序。请小心Raymond Chen做的不是赞同这种黑客。

private void button1_Click(object sender, EventArgs e) { 
     var prc = Process.Start("notepad.exe"); 
     prc.WaitForInputIdle(); 
     int tid = GetCurrentThreadId(); 
     int tidTo = prc.Threads[0].Id; 
     if (!AttachThreadInput(tid, tidTo, true)) throw new Win32Exception(); 
     this.BringToFront(); 
     AttachThreadInput(tid, tidTo, false); 
    } 

    [DllImport("user32.dll", SetLastError = true)] 
    private static extern bool AttachThreadInput(int tid, int tidTo, bool attach); 
    [DllImport("kernel32.dll")] 
    private static extern int GetCurrentThreadId(); 
+0

谢谢。但我怀疑,如果BringToFront真的在这里工作。这不仅仅是使控制在另一个控制之上可见的一种措施吗?这不是吗?激活是一个更好的选择吗? – nawfal 2012-01-16 16:33:49

+0

谁是雷蒙德?批准这个? :o – nawfal 2012-01-16 16:34:22

+0

Form.BringToFront()调用SetForegroundWindow(),通过试图编码很容易看到。 Raymond Chen是微软程序员,拥有一个受欢迎的博客。帖子也在这里回答,我不想让他失望。 http://blogs.msdn.com/b/oldnewthing/ – 2012-01-16 16:36:52

-1

提供

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

解决方法试试这个:

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(); 
    } 
} 
+0

这是如何回答这个问题的? – nawfal 2013-02-19 09:52:27

相关问题