2

I want to send every item from my listbox to a notepad,but my logic is kinda beating me.

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

In my logic this should send every item from the listbox to a notepad every item on a different line.But that doesn't happen every time,sometimes it just sends the only the last item from the listbox as many items there are in the listbox. Am I missing something?

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
John Pietrar
  • 513
  • 7
  • 19

5 Answers5

3

An another option you can find the Edit control of notepad using FindWindowEx and send a WM_SETTEXT message to it using SendMessage. This way you don't need to bring the notepad window to front.

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!");
    }
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • This solution is more elegant than using sendkeys to send the string or paste the string. It also works if the notepad application is minimized. Let me know if you have any question about the answer :) – Reza Aghaei Oct 14 '16 at 15:10
  • I am asking you to help because I know you can give proper explanations step by step, not only answer it and maybe I can close this `winhandle` topic once and for all. – John Pietrar Oct 26 '16 at 10:14
  • The idea which comes to my mind at the moment is: You can use `EnumChildWindows` in a timer `Tick` event and check if the title of a child window is `Page Setup` (may be and its class name is `#32770 (Dialog)`) then do the job that you want. – Reza Aghaei Oct 26 '16 at 17:11
  • I have even more questions now lol ... could you post an answer there if I ask nicely please ,so I can understand better ? – John Pietrar Oct 26 '16 at 19:45
  • I posted the answer for you. – Reza Aghaei Oct 27 '16 at 12:57
1

I have a sample test, it works if you change SendKeys.Send to 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}");
    }

Because the key applied later than update Clipboard and loop, so that issue happend.

zquanghoangz
  • 663
  • 5
  • 11
1

You can do it with InputSimulator, Package Manage Console: Install-Package 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);

                    }
                }
            }
Justin CI
  • 2,693
  • 1
  • 16
  • 34
1

Better than using System.Threading.Thread.Sleep(); use await Task.Delay(); https://stackoverflow.com/a/20084603/6886308

Community
  • 1
  • 1
Rossalinda
  • 33
  • 7
0

From @GillBates suggestion I used System.Threading.Thread.Sleep(); and it seem to work great now.

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

            }
}
John Pietrar
  • 513
  • 7
  • 19