Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 1020305
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 16, 20262026-05-16T11:08:53+00:00 2026-05-16T11:08:53+00:00

I have a method set that uses pinvoke to call WM_GETTEXT on another program’s

  • 0

I have a method set that uses pinvoke to call WM_GETTEXT on another program’s textbox – and it works fairly well, but frequently I just get back total junk text appended to the end of it. (The ORIGINAL text is always intact.)

This is random, I cannot reproduce it on demand, but it is frequent enough to be stopship.

Here is the text to get the information.

System.Text.StringBuilder strBuffer = new System.Text.StringBuilder();

int nLen = 0;

bool nUpdated = false;

try
{
    this.isOpen = false;

    if (ptrHandle == null)
        return;

    if (ptrHandle == IntPtr.Zero)
        return;

    nLen =
        Converter.SendMessage(ptrHandle, Converter.WM_GETTEXTLENGTH, 0, 0);

    if (nLen <= 0)
        return;

    if (nPreviousLen != nLen)
        nUpdated = true;

    if (nUpdated)
    {
        System.Diagnostics.Debug.WriteLine("nLen:\t{0}", nLen);

        strBuffer = new System.Text.StringBuilder(null, nLen + 1);

        System.Diagnostics.Debug.WriteLine("strBuffer:\t{0}", strBuffer.ToString());

        int sLen = Converter.SendMessageByString(ptrHandle, Converter.WM_GETTEXT, nLen
            , strBuffer);

        System.Diagnostics.Debug.WriteLine("sLen:\t{0}", sLen);

        System.Diagnostics.Debug.WriteLine("\n\nstrBuffern\n\n{0}", strBuffer.ToString());

        strBuffer = new System.Text.StringBuilder(strBuffer.ToString().Left(sLen));

        System.Diagnostics.Debug.WriteLine("\n\nsLenBuffer\n\n{0}", strBuffer.ToString());

source = new Special.IO.TextReader( 
                    new System.IO.MemoryStream(  System.Text.Encoding.Default.GetBytes(strBuffer.ToString() ) ), nUpdated );
        }
    }
}


    /// <summary>
    /// Sends the specified message to a window or windows. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message.
    /// <br />
    /// To send a message and return immediately, use the SendMessageCallback or SendNotifyMessage function. To post a message to a thread's message queue and return immediately, use the PostMessage or PostThreadMessage function.
    /// </summary>
    /// <param name="hWnd">
    /// Handle to the window whose window procedure will receive the message. 
    /// If this parameter is HWND_BROADCAST, the message is sent to all top-level windows in the system, including disabled or invisible unowned windows, overlapped windows, and pop-up windows; but the message is not sent to child windows.
    /// </param>
    /// <param name="Msg">
    /// [in] Specifies the message to be sent.
    /// </param>
    /// <param name="wParam">
    /// [in] Specifies additional message-specific information.
    /// </param>
    /// <param name="lParam">
    /// [in] Specifies additional message-specific information.
    /// </param>
    /// <returns>
    /// The return value specifies the result of the message processing; it depends on the message sent.
    /// </returns>
    [DllImport("user32.dll", EntryPoint = "SendMessageA", CharSet = CharSet.Ansi, SetLastError = false)]
    internal static extern int SendMessageByString(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);

    /// <summary>
    /// Sends the specified message to a window or windows. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message.
    /// <br />
    /// To send a message and return immediately, use the SendMessageCallback or SendNotifyMessage function. To post a message to a thread's message queue and return immediately, use the PostMessage or PostThreadMessage function.
    /// </summary>
    /// <param name="hWnd">
    /// Handle to the window whose window procedure will receive the message. 
    /// If this parameter is HWND_BROADCAST, the message is sent to all top-level windows in the system, including disabled or invisible unowned windows, overlapped windows, and pop-up windows; but the message is not sent to child windows.
    /// </param>
    /// <param name="Msg">
    /// [in] Specifies the message to be sent.
    /// </param>
    /// <param name="wParam">
    /// [in] Specifies additional message-specific information.
    /// </param>
    /// <param name="lParam">
    /// [in] Specifies additional message-specific information.
    /// </param>
    /// <returns>
    /// The return value specifies the result of the message processing; it depends on the message sent.
    /// </returns>
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    internal static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-16T11:08:54+00:00Added an answer on May 16, 2026 at 11:08 am

    There seems to be some-thing weird going on with this, it looks like the control you are targeting, when using P/Invoke via WM_GETTEXT is returning the junk… I suggest the following, instead of returning the whole buffer, return back the current line which would make things a bit snappier…

    try{
        int nLineCount = Converter.SendMessage(ptrHandle, Converter.EM_GETLINECOUNT, 0, 0);
        int nIndex = Converter.SendMessage(ptrHandle, Converter.EM_LINEINDEX, nLineCount, 0);
        int nLineLen = Converter.SendMessage(ptrHandle, Converter.EM_LINELENGTH, nIndex, 0);
        //
        strBuffer = new System.Text.StringBuilder(nLineLen);
        strBuffer.Append(Convert.ToChar(nLineLen));
        strBuffer.Length = nLineLen;
        int nCharCnt = Converter.SendMessage(ptrHandle, Converter.EM_GETLINE, new IntPtr(nLineCount),     strBuffer).ToInt32();
        nLen = nCharCnt;
        if (nLen <= 0) return;
        if (nPreviousLen != nLen) nUpdated = true;
    }finally{
        source = new TextReader(strBuffer.ToString(), nUpdated, isOpen ? true : false);
        this.isOpen = true;
        nPreviousLen = nLen;
    }
    

    In that way, we obtain:

    • the line count in the control – nLineCount
    • Obtain the character index that is the start of the line nLineCount – nIndex
    • Finally, obtain the line length using the nIndex – nLineLen

    Using nLineLen, then we can set up the StringBuilder buffer, the tricky part in using EM_GETLINE is, the zero’th position of the buffer MUST contain the length in char’s – hence the usage of strBuffer.Append(Convert.ToChar(nLineLen)), and the stringbuilder’s Length property specified.

    Here are the constants required for the above P/Invoke

    • const int EM_GETLINECOUNT = 0xBA;
    • const int EM_LINEINDEX = 0xBB;
    • const int EM_LINELENGTH = 0xC1;
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.