Mattaceten
Mattaceten

Reputation: 159

Copying text to a notepad instance in C#

I know this question has already been answered. Here is my problem. I have a Windows Form with a button and a textbox. The user enters info into the textbox, and when the user clicks the button, an instance of notepad is launched and the text of the textbox is then loaded into the notepad.

Here is my code (which I got from a question on this site)

  [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
        [DllImport("User32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);

        private void btnCopyToNotepad_Click(object sender, EventArgs e)
        {
            StartNotepad();

            Process[] notepads = Process.GetProcessesByName("notepad");
            if (notepads.Length == 0) return;
            if (notepads[0] != null)
            {
                Clipboard.SetText(textBox1.Text);
                SendMessage(FindWindowEx(notepads[0].MainWindowHandle, new IntPtr(0), "Edit", null), 0x000C, 0, textBox1.Text);
            }
        }
        private static void StartNotepad() 
        {
            Process.Start("notepad.exe");
        }

When I run this code, stepping through debug, it runs fine, and the logic does what its intended to do (copy text to the instance of notepad). When I run it in release, nothing is copied to the instance of notepad. Any ideas why this is happening? No i'm not running multiple instances of notepad..

Upvotes: 1

Views: 3431

Answers (3)

PatMunits
PatMunits

Reputation: 41

Everton Santos' version can paste contents into a wrong instance of Notepad. This happens whenever user has other Notepad windows open. Pasting into a wrong Notepad instance overwrites all prior contents of that window. Undo doesn't work and leads to loss of user's own data.

Here's a version that holds pointer to the correct Notepad instance:

[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);

private void btnCopyToNotepad_Click(object sender, EventArgs e)
{
    var notepad = Process.Start("notepad.exe");
    notepad.WaitForInputIdle();
    Clipboard.SetText(textBox1.Text);
    SendMessage(FindWindowEx(notepad.MainWindowHandle, new IntPtr(0), "Edit", null), 0x000C, 0, textBox1.Text);
}

Upvotes: 3

Brian
Brian

Reputation: 249

Something re-usable maybe? BTW, this opens a new instance of notepad each time.

using System.Diagnostics;
using System.Runtime.InteropServices;

static class Notepad
{
    #region Imports
    [DllImport("user32.dll")]
    public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

    [DllImport("User32.dll")]
    private static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);

    //this is a constant indicating the window that we want to send a text message
    const int WM_SETTEXT = 0X000C;
    #endregion


    public static void SendText(string text)
    {
        Process notepad = Process.Start(@"notepad.exe");
        System.Threading.Thread.Sleep(50);
        IntPtr notepadTextbox = FindWindowEx(notepad.MainWindowHandle, IntPtr.Zero, "Edit", null);
        SendMessage(notepadTextbox, WM_SETTEXT, 0, text);
    }
}

Upvotes: 0

Everton Santos
Everton Santos

Reputation: 162

You need wait until the process is started, then send the text:

    [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
    public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
    [DllImport("User32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);

    private void btnCopyToNotepad_Click(object sender, EventArgs e)
    {
        StartNotepad();

        Process[] notepads = null;
        while (notepads == null || notepads.Length == 0)
        {
            notepads = Process.GetProcessesByName("notepad");   
            Thread.Sleep(500);
        }

        if (notepads.Length == 0) return;
        if (notepads[0] != null)
        {
            Clipboard.SetText(textBox1.Text);
            SendMessage(FindWindowEx(notepads[0].MainWindowHandle, new IntPtr(0), "Edit", null), 0x000C, 0, textBox1.Text);
        }
    }
    private static void StartNotepad() 
    {
        Process.Start("notepad.exe");
    }

Upvotes: 2

Related Questions