日期:2014-05-18  浏览次数:21273 次

C#中WindowsForms 调用 FindWindow,SetForegroundWindow,奇怪的问题
思路是这样的,C#中WindowsForms 单击个按钮 调用WINAPI,
并把程序切换到了个另外个 文本程序 "新建 文本文档 (6).txt - 记事本" 中,
然后输入个字符"a"(其实是模拟CTRL+V,“a”好说明白些)
···········································
可是,只能执行1次,第2次的时候能切换到“记事本”,却不能模拟按键了
···········································
  [DllImport("user32.dll ")]
  public static extern IntPtr FindWindow(string 类名, string 程序标题);

  [DllImport( "user32.dll ")]  
  private static extern bool SetForegroundWindow(IntPtr hWnd); 


private void button3_Click(object sender, EventArgs e)
  {
  IntPtr hwnd = FindWindow(null, "新建 文本文档 (6).txt - 记事本"); //放回句柄
  if (hwnd.ToInt32 () != 0)
  {
  SetForegroundWindow(hwnd);
  //SendKeys.Send("^{V}");
  SendKeys.Send(Keys.A.ToString()); /////只有第一次输出成功,第2次按钮就没的用了
  }
  else { MessageBox.Show("记事本没有运行 "); }
   
  }

------解决方案--------------------
手动启动notepad没有问题,可以一直输入.
你的notepad是程序调用的吗?
试试
Process myProcess = new Process();
myProcess.StartInfo.FileName = File_Path;
myProcess.Start();
myProcess.WaitForInputIdle();
SendKeys...
System.Threading.Thread.Sleep(1000);
------解决方案--------------------
帮顶~
------解决方案--------------------
不要使用
SendKeys.Send(Keys.A.ToString()); /////只有第一次输出成功,第2次按钮就没的用了 
这个东西对本进程还好 对其他进程并不好用.

使用

[DllImport("user32.dll", EntryPoint = "keybd_event")]
public static extern void Keybd_Event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);

效果好点
------解决方案--------------------
添加一个应用程序配置文件,启用新的SendKeys类实现,就可以解决问题了。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="SendKeys" value="SendInput"/>
</appSettings>
</configuration>

其实你看看MSDN中SendKeys类的说明就会知道了:

SendKeys 类易出现计时问题,某些开发人员必须解决这些问题。更新的实现仍易出现计时问题,但它略快,可能需要对解决方法进行更改。SendKeys 类尝试先使用以前的实现,如果失败,则使用新实现。因此,在不同的操作系统上,SendKeys 类的行为可能不同。此外,如果 SendKeys 类使用新实现,则将消息发送到另一进程时,SendWait 方法不会等待处理这些消息。 

如果无论操作系统如何应用程序都依赖一致的行为,则通过在 app.config 文件中添加下列应用程序设置,可以强制 SendKeys 类使用新实现。

<appSettings>

<add key="SendKeys" value="SendInput"/>

</appSettings>


------解决方案--------------------
如果是想实现CTRL+V粘贴功能的话,你可以直接发送WM_PASTE粘贴消息
C# code
[DllImport("user32.dll ")] 
      public static extern IntPtr  FindWindow(string 类名, string 程序标题); 

    [DllImport( "user32.dll ")]  
      private  static  extern  bool  SetForegroundWindow(IntPtr hWnd); 


private void button3_Click(object sender, EventArgs e) 
        { 
            IntPtr hwnd = FindWindow(null, "新建 文本文档 (6).txt - 记事本"); //放回句柄 
              int WM_PASTE = // 具体的消息号你可以网上查下
              if (hwnd.ToInt32 () != 0) 
            { 
            SetForegroundWindow(hwnd);