2016-02-19 26 views
1

如果找到所需的窗口句柄(即"DesiredWindow"当前正在计算机上运行),我无法找出正确提升事件的方法而只有只有在窗口句柄可以找到的情况下才会引发事件

目前,我的应用程序将SetForegroundWindow并发送一个按键到正确的窗口,只要该应用程序正在运行;我的问题是:如果所需的窗口不可用(即目标应用程序未运行),它仍然会在发生事件时将按键发送到任何活动窗口,即使我已指定窗口句柄想要将其发送到,并且该窗口句柄在系统上不存在。

我想知道的是:如果特定的lpWindowName存在,是否可以告诉我的应用程序只发送按键,并且如果指定的窗口名称找不到,什么也不做?

伪代码:

public partial class form1: Form 
{ 
    [DllImport("User32.dll")] 
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 
    [DllImport("User32.dll")] 
    static extern int SetForegroundWindow(IntPtr hWnd); 
    static IntPtr DesiredWindow = FindWindow(null, "(Desired Window Name)"); 

    public form1() 
    { 
     InitializeComponent(); 
    } 

    //... 

       private void MyEvent() 
      { 
       if (DesiredWindow cannot be found) 
       { 
       return; //Do not send KeyPress 
       } 

       SetForegroundWindow(DesiredWindow); 
       Thread.Sleep(50); 
       Keyboard.KeyPress(Keys.(WhateverKey)); 
      } 
} 

我已经试过:

  private void MyEvent() 
      {      
       if (!DesiredWindow) 
       { 
        MessageBox.Show("DesiredWindow not found"); 
        return; 
       }     
       SetForegroundWindow(DesiredWindow); 
       Thread.Sleep(50); 
       Keyboard.KeyPress(Keys.WhateverKey); 
      } 

但我得到的错误Operator '!' cannot be applied to operand of type 'IntPtr'

我也试过:

  private void MyEvent() 
      {      
       if (DesiredWindow == IntPtr.Zero) 
       { 
        MessageBox.Show("DesiredWindow not found"); 
        return; 
       }     
       SetForegroundWindow(DesiredWindow); 
       Thread.Sleep(50); 
       Keyboard.KeyPress(Keys.WhateverKey); 
      } 

但是,当我使用这种方法时似乎没有发生。

我已将MessageBox.Show("DesiredWindow not found");添加到if声明中,让我知道它是否正常工作,但即使所需窗口可用,也会弹出消息框。

我已经试过另一种方法是:

  private void MyEvent() 
      {      
       if (DesiredWindow > 0) 
       {     
       SetForegroundWindow(DesiredWindow); 
       Thread.Sleep(50); 
       Keyboard.KeyPress(Keys.WhateverKey); 
       } 
      } 

但我得到的错误Operator '>' cannot be applied to operand of type 'IntPtr' or 'Int'

我不知道检查,看看是否存在DesiredWindow的正确途径。

+0

'else if(msg.Equals(“Message”))'这是什么..?你错过了一些代码..? – MethodMan

+0

对不起,这正是触发我的事件的原因。这是一个TCP客户端/服务器应用程序,服务器根据从客户端收到的消息发送不同的击键。我想我会离开这部分,以避免混淆 – Patrick

+0

@MethodMan我编辑的问题,以避免混淆事件引发,并添加更多的细节,我的尝试。 – Patrick

回答

1

不知道如果你引用了正确的库,我已经试过你的代码,他们工作没有任何问题。请看下面的工作代码:

using System; 
using System.Runtime.InteropServices; 
using System.Threading; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     [DllImport("User32.dll")] 
     private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 

     [DllImport("User32.dll")] 
     private static extern int SetForegroundWindow(IntPtr hWnd); 

     private const string DesiredWindowTitle = "(Desired Window Name)"; 

     // do not invoke the method to find the window when the form was constructing 
     // private static IntPtr DesiredWindow = FindWindow(null, DesiredWindowTitle); 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      // find the window at run time 
      IntPtr DesiredWindow = FindWindow(null, DesiredWindowTitle); 

      if (DesiredWindow == IntPtr.Zero) 
      { 
       return; //Do not send KeyPress 
      } 

      SetForegroundWindow(DesiredWindow); 
      Thread.Sleep(50); 
      Keyboard.KeyPress(Keys.(WhateverKey)); 
     } 
    } 
} 
+0

谢谢,这工作完美。请注意:当事件发生时,我需要找到窗口,而不是在表单构建时找到窗口的原因是什么?仅供将来参考,因为在我看来(我非常适合初学者),它看起来像一个更简洁的方法,代码少,但显然是不正确的。 – Patrick

+0

不知道为什么,猜测当时窗体正在构建时,底层操作系统正试图为新窗体分配一个新的窗口句柄。同时,当你的事件发生时,以前发现的窗口句柄可能不再存在,因此句柄可能无效。 –

+0

嗯没关系。我只问,因为我有大约100个几乎完全相同的事件,所以最终成为很多简单的代码行......我会看看是否可以找到另一种方法来整理它;如果没有,我想是时候让我的复制/粘贴...感谢您的帮助 – Patrick

相关问题