2016-09-26 85 views
1

我想将每个项目从我的列表框发送到记事本,但我的逻辑有点击败我。使用进程将数据发送到记事本

private void send_Click(object sender, EventArgs e) 
{ 
    var notepad = Process.GetProcessesByName("Notepad").FirstOrDefault(p => p.MainWindowTitle == "Untitled - Notepad"); 

    if (notepad != null) 
    { 
     if (IsIconic(notepad.MainWindowHandle)) 
      ShowWindow(notepad.MainWindowHandle, 9); 

     SetForegroundWindow(notepad.MainWindowHandle); 
     string text = ""; 

     foreach (var item in listBox1.Items) 
     { 
      text = item.ToString(); 
      Clipboard.SetText(text); 
      SendKeys.Send("^V"); 
      SendKeys.Send("{ENTER}"); 
     } 
    } 
} 

在我的逻辑这应该每一个项目从列表框中每个项目在不同的line.But不发生每次发送到记事本,有时它只是从列表框中为发送唯一的最后一个项目列表框中有很多项目。我错过了什么吗?

+0

尽量放慢粘贴部分,可能是睡眠的效果,我觉得像你想粘贴太快。 –

+0

没有想到,真的很好的提示:) –

+0

而不是发送单个项目,只需使用'String.Join'在单个字符串中组合所有它们,例如'String.Join(“\ n”,listBox1。项目)' –

回答

1

的,你可以找到Edit控制使用FindWindowEx记事本和发送WM_SETTEXT消息时,它使用SendMessage另一种选择。这样你就不需要把记事本窗口放在前面。

using System.Diagnostics; 
using System.Runtime.InteropServices; 
[DllImport("user32.dll", SetLastError = true)] 
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, 
    string lpszClass, string lpszWindow); 
[DllImport("User32.dll")] 
static extern int SendMessage(IntPtr hWnd, int uMsg, IntPtr wParam, string lParam); 
const int WM_SETTEXT = 0x000C; 

private void button1_Click(object sender, EventArgs e) 
{ 
    //Find notepad by its name, or use the instance which you opened yourself 
    var notepad = Process.GetProcessesByName("notepad").FirstOrDefault(); 
    if(notepad!=null) 
    { 
     var edit = FindWindowEx(notepad.MainWindowHandle, IntPtr.Zero, "Edit", null); 
     SendMessage(edit, WM_SETTEXT, IntPtr.Zero, "This is a Text!"); 
    } 
} 
+0

这个解决方案比使用sendkeys发送字符串或粘贴字符串更优雅。如果记事本应用程序被最小化,它也可以工作。让我知道如果你有任何问题的答案:) –

+0

我要求你帮忙,因为我知道你可以一步一步给予适当的解释,不仅回答它,也许我可以一劳永逸地关闭这个'winhandle'主题。 –

+0

我现在想到的想法是:你可以在定时器Tick中使用'EnumChildWindows',并检查一个子窗口的标题是否为'页面设置'(可能是,它的类名是'## 32770(对话)')然后做你想要的工作。 –

0

从@GillBates的建议我用System.Threading.Thread.Sleep();它似乎现在工作得很好。

private void send_Click(object sender, EventArgs e) 
{ 
var notepad = Process.GetProcessesByName("Notepad").FirstOrDefault(p => p.MainWindowTitle == "Untitled - Notepad"); 

      if (notepad != null) 
      { 
       if (IsIconic(notepad.MainWindowHandle)) 
        ShowWindow(notepad.MainWindowHandle, 9); 

       SetForegroundWindow(notepad.MainWindowHandle); 
       string text = ""; 

       foreach (var item in listBox1.Items) 
       { 
        text = item.ToString(); 
        Clipboard.SetText(text); 
        SendKeys.Send("^V"); 
        SendKeys.Send("{ENTER}"); 
        System.Threading.Thread.Sleep(150); 
       } 

      } 
} 
1

我有一个样品的测试,如果你改变SendKeys.Send到SendKeys.SendWait

List<string> data = new List<string>() { "Test", "hope", "It", "works","Or" }; 
    foreach (var item in data) 
    { 
     Clipboard.Clear(); 
     Clipboard.SetText(item); 
     //SendKeys.Send("^V"); 
     //SendKeys.Send("{ENTER}"); 

     SendKeys.SendWait("^V"); 
     SendKeys.SendWait("{ENTER}"); 
    } 

因为后来应用了更新剪贴板和循环的关键,所以这个问题happend它的工作原理。

+0

不知道有关'SendKeys.SendWait'。感谢您与我分享:) –

+0

似乎这不起作用,像40次尝试后,我得到了该错误再次悲伤。 –

1

你可以用InputSimulator做到这一点,包管理控制台: 安装,包装InputSimulator

private void Button_Click_1(object sender, RoutedEventArgs e) 
      { 

       var notepad = Process.GetProcessesByName("Notepad").FirstOrDefault(p => p.MainWindowTitle == "Untitled - Notepad"); 
       if (notepad != null) 
       { 
        if (IsIconic(notepad.MainWindowHandle)) 
         ShowWindow(notepad.MainWindowHandle, 9); 

        var input = new InputSimulator(); 
        SetForegroundWindow(notepad.MainWindowHandle); 
        foreach (var item in listBox1.Items) 
        { 
         input.Keyboard.TextEntry(item.ToString()); 
         input.Keyboard.KeyPress(VirtualKeyCode.RETURN); 

        } 
       } 
      } 
+0

这究竟是什么?你能否详细解释一下? :)因为我从来没有听说过InputSimulator –

+0

它是一个用于将键发送给应用程序的包装器,它们已经在其中管理完成处理机制的代码。 –

+0

@JohnPietrar你可以参考这个https://inputsimulator.codeplex.com/ –