Search code examples
c#.netwinformswinapipinvoke

Using WM_SETTEXT to set Notepad text is not affecting Text_Changed event in the Notepad instance


I've almost completed a project that will basically, take the contents of a .txt file, open a new notepad instance using 'Process.Start("notepad")' and then set the text using the "WM_SETTEXT" constant. I have this working beautifully so I don't need any assistance with setting the text. However, I have one small issue I noticed during testing. After the text is set in the notepad instance, if you close the notepad window, it does NOT ask if you wish to save the changes. This led me to believe that "WM_SETTEXT" does NOT fire the "Text_Changed" event in the notepad instance.

After some thinking, I realized that it could also mean that notepad only asks to save changes if a user types something manually. So perhaps rather than checking for "Text_Changed" it may be checking for a "Mouse_Down" event?? Whichever one it may be, I would like some input from someone with a little more knowledge as to the 'internal' workings of notepad and how it checks if there were 'changes' to the text that need to be saved.

Here is part of my SetText function:

        if (FileIO.Index != null && FileIO.Index.Count > 0)
        {
            MessageBox.Show("Recovering " + FileIO.Index.Count + " files...");
            foreach (string guid in FileIO.Index)
            {
                if (!string.IsNullOrWhiteSpace(guid))
                {
                    string contents = "";
                    if (!FileIO.Recover(guid, out contents))
                        MessageBox.Show("Couldn't recover '" + guid + "'");
                    else
                    {
                        Process p = Process.Start("notepad");
                        Thread.Sleep(200);
                        SetText(GetNotepadEditBox(p.MainWindowHandle), contents);
                    }
                }
            }
            MessageBox.Show("Recovered all files successfully!", "Done recovering files!", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

Methods:

private static IntPtr GetNotepadEditBox(IntPtr hParentWindow)
{
    return Win32.FindWindowEx(hParentWindow, IntPtr.Zero, "Edit", null);
}

private void SetText(IntPtr hEditBox, string text)
{
    IntPtr len = new IntPtr(text.Length);
    StringBuilder sb = new StringBuilder(text);

    Win32.SendMessage(hEditBox, Win32.WM_SETTEXT, len, sb);

    sb = null;
    len = IntPtr.Zero;
}

Solution

  • The edit control keeps the properties text and modified as distinct entities, allowing applications to build their own modification management around them. Sending a WM_SETTEXT message does not automatically set the modified flag. To set this flag you have to explicitly send an EM_SETMODIFY message to the edit control.