none
How do I use WM_GETTEXT in VB.net to Pass text from 1 Progrm to another open Program RRS feed

  • Question

  • I want to make a program that can pass the value of text box from 1 program to another text box of an open program in vb.. 

    I search in the internet and found this code. 

    Imports System.Runtime.InteropServices Public Class Form2 Private Const WM_SETTEXT = &HC Private Declare Function SendMessageSTRING Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Int32, _ ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As String) As Int32 Private Declare Function FindWindow Lib "user32.dll" Alias _ "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Int32 Private Declare Function FindWindowEx Lib "user32.dll" Alias _ "FindWindowExA" (ByVal hWnd1 As Int32, ByVal hWnd2 As Int32, ByVal lpsz1 As String, _ ByVal lpsz2 As String) As Int32 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'Using Spy++ I got the structure of the program that will receive the data TEXT/TITLE = 'ProgramName'

    Dim Hwnd As IntPtr = FindWindow(" ProgramName", Nothing)

    ' Using SPy++ I got the structure of the text box from the program that will receive the data. CLASS ='WindowForms10.EDIT etc.... Dim Handle As IntPtr = FindWindowEx(Hwnd, IntPtr.Zero, "WindowsForms10.EDIT.app.0.141b42a_r15_ad1", Nothing)

    SendMessageSTRING(Handle, WM_SETTEXT, TextBox1.TextLength, TextBox1.Text) End Sub End Class

    But when I execute my code and click the button it didn't send the data to another program.

    Please help  me. 
    thanks in advanced.

    Friday, June 15, 2018 11:48 AM

All replies

  • You have put a space at beginning of " ProgramName"

    And are you sure that "ProgramName" is the right Class name of the window ?


    • Edited by Castorix31 Friday, June 15, 2018 12:08 PM
    Friday, June 15, 2018 12:06 PM
  • this is the real Class name of the window. i got it using spy++ 

    Dim Hwnd As IntPtr = FindWindow("WindowsForms10.Window.8.app.0.141b42a_r15_ad1", Nothing)

    I also try to use both  Window name and Text/Title name but didn't work.

    Dim Hwnd As IntPtr = FindWindow("Capture", "0004039C")

    still dosn't work please advice @Castorix31



    • Edited by BONITOS Friday, June 15, 2018 12:32 PM
    Friday, June 15, 2018 12:28 PM
  • Hi

    Maybe NamedPipes could do the job. EXAMPLE


    Regards Les, Livingston, Scotland

    Friday, June 15, 2018 12:33 PM
  • With the right Class name and/or Title (text), it should work.

    For example, with the hierarchy below, it works for me :

    with  the Class name :

    Dim Hwnd As IntPtr = FindWindow("WindowsForms10.Window.8.app.0.141b42a_r9_ad1", Nothing)
    Dim Handle As IntPtr = FindWindowEx(Hwnd, IntPtr.Zero, "WindowsForms10.EDIT.app.0.141b42a_r9_ad1", Nothing)
    

    or the title :

    Dim Hwnd As IntPtr = FindWindow(Nothing, "Form1")
    Dim Handle As IntPtr = FindWindowEx(Hwnd, IntPtr.Zero, "WindowsForms10.EDIT.app.0.141b42a_r9_ad1", Nothing)

    Friday, June 15, 2018 1:05 PM
  • I try code below but still not work for me, anyone please advice.

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    
    Dim Hwnd As Integer = Win32.FindWindow("WindowsForms10.Window.8.app.0.141b42a_r15_ad1", "Capture") 
    Dim CHwnd As Integer = Win32.FindWindowEx(Hwnd, Nothing, "WindowsForms10.EDIT.app.0.141b42a_r15_ad1", Nothing) 
     
            If (Not Hwnd = 0 And Not CHwnd = 0) Then 
                Win32.SetForegroundWindow(CHwnd) 
                Win32.SendMessage(CHwnd, Win32.WM_SETTEXT, TextBox1.TextLength, TextBox1.Text) 
                Else 
                MessageBox.Show("Handler not found,check the title") 
     
            End If 
        End Sub

    I got Hwnd parameter as below:

    ClassName (I add image but I am not yet allowed to attached image)


    Caption/Title:

    (I add image but I am not yet allowed to attached image)

    parameter of CHwnd: 

    below is the class i used, it is  the structure of my textbox which will receive the data that will be pass.

    (I add image but I am not yet allowed to attached image)

    I think everything is correct but when i click the button it calls the else statements. 

    but if i target notepad it is working well:

    Dim Hwnd As Integer = Win32.FindWindow(Nothing, "Untitled - Notepad") 
            Dim CHwnd As Integer = Win32.FindWindowEx(Hwnd, Nothing, "Edit", Nothing)

    is my sendMessage has problem ? or  what ?

    btw here is the structure of my Class Win32:

    Public Class Win32 
    #Region "Methods and functions declaration" 
        Public Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Int32 
        Public Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hwnd As Int32) As Int32 
        Public Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWnd1 As Int32, ByVal hWnd2 As Int32, ByVal lpsz1 As String, ByVal lpsz2 As String) As Int32 
        Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As Int32) As Int32 
        Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As String) As Int32 
     
    #Region "Messages" 
        Public Const WM_SETTEXT As Int32 = &HC 
    #End Region 
     
    #End Region 
    End Class


    Saturday, June 16, 2018 6:44 AM
  • but if i target notepad it is working well:

    Dim Hwnd As Integer = Win32.FindWindow(Nothing, "Untitled - Notepad") 
    Dim CHwnd As Integer = Win32.FindWindowEx(Hwnd, Nothing, "Edit", Nothing)

    When it doesn't work with the other values for class/title, Hwnd and CHwnd are = 0 ?  or just CHwnd ?
    Saturday, June 16, 2018 8:27 AM
  • I knew now my problem , I must use EnumChildWindows Function , because the textbox that I am targeting is at the long list under the Parent Handler. anyone here a good example using EnumChildWindows function?

    Saturday, June 16, 2018 8:56 AM
  • I knew now my problem , I must use EnumChildWindows Function , because the textbox that I am targeting is at the long list under the Parent Handler. anyone here a good example using EnumChildWindows function?

    A test sample with Notepad :

    Dim callback As EnumCallBack = New EnumCallBack(AddressOf EnumWindowsProc)
    Dim hWndNotepad As IntPtr = FindWindow("Notepad", Nothing)
    If (hWndNotepad <> IntPtr.Zero) Then
        EnumChildWindows(hWndNotepad, callback, IntPtr.Zero)
    End If

    with declarations :

    <DllImport("User32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    Public Shared Function EnumChildWindows(ByVal hWndParent As IntPtr, ByVal lpEnumFunc As EnumCallBack, ByRef lParam As Integer) As Boolean
    End Function
    
    Public Delegate Function EnumCallBack(ByVal hwnd As IntPtr, ByRef lParam As IntPtr) As Boolean
    
    Public Shared Function EnumWindowsProc(ByVal hWnd As Integer, ByRef lParam As IntPtr) As Boolean
        Dim sWindowClass As StringBuilder = New StringBuilder(128)
        GetClassName(hWnd, sWindowClass, 128)
        Dim nLenght As Integer = SendMessage(hWnd, WM_GETTEXTLENGTH, 0, IntPtr.Zero)
        Dim sText As String = ""
        If (nLenght > 0) Then
            Dim sWindowText As StringBuilder = New StringBuilder(nLenght + 1)
            SendMessage(hWnd, WM_GETTEXT, sWindowText.Capacity, sWindowText)
            sText = sWindowText.ToString()
        End If
        Console.WriteLine("Window : {0:X} - Class : {1} - Text : {2}", hWnd.ToString("x"), sWindowClass.ToString(), sText)
        Return True
    End Function
    
    Public Const WM_GETTEXT As Integer = &HD
    Public Const WM_GETTEXTLENGTH As Integer = &HE
    
    <DllImport("User32.dll", EntryPoint:="SendMessageA", SetLastError:=True)>
    Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
    End Function
    
    <DllImport("User32.dll", EntryPoint:="SendMessageA", SetLastError:=True)>
    Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As StringBuilder) As Integer
    End Function  
    
    <DllImport("User32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>                                                                
    Public Shared Function GetClassName(ByVal hWnd As IntPtr, ByVal lpClassName As StringBuilder, ByVal nMaxCount As Integer) As Integer
    End Function 

    • Marked as answer by BONITOS Monday, June 18, 2018 4:32 AM
    • Unmarked as answer by BONITOS Monday, June 18, 2018 9:40 AM
    Saturday, June 16, 2018 9:27 AM
  • hi Sir,

    thank you very much for the answer,

    another thing is , is it possible to pass the data of text box from one application  to another application text box where the cursor is active or wherever the cursor is ? 

    Monday, June 18, 2018 4:32 AM
  • hi Sir ,

    I haven't try to use EnumChildWindow because i am a newbie i don't understand fully your code.

    please help me with my code below .

    I tried to use FindWindowEx multiple times, but couldn't get the handler for the 2nd child can you adviced.

    please read my comment.

            'parameter className and Title of Parent control 
            Dim Hwnd As Integer = Win32.FindWindow(Nothing, "Form1") 
            'you declare new variable , what value should i put to it ? the classname of last child that i want to target ???? or the first child ?  
            ' Dim ChildWindowTypeName = "WindowsForms10.EDIT.app.0.af25cb_r31_ad1" 
            '3rd parameter is the class name of the 1st child  
            Dim CHwnd As Integer = Win32.FindWindowEx(Hwnd, Nothing, "WindowsForms10.Window.8.app.0.af25cb_r31_ad1", Nothing) 
            '3rd parameter is the class name of the 2nd child 
            CHwnd = Win32.FindWindowEx(Hwnd, Nothing, "WindowsForms10.BUTTON.app.0.af25cb_r31_ad1", Nothing)

    Monday, June 18, 2018 9:40 AM
  • With FindWindowEx, you must follow the hierarchy of windows shown by Spy++ (if there aren't multiple windows with same class or text...)

    If you test EnumChildWindows, you will see it works

    The code is simple : I just get the class and the text in the callback function for testing, but you can check other properties of child windows.

    You can also test with other windows with more children like the Taskbar ("Shell_TrayWnd") and it will enumerate all the children (and children of children...)



    • Edited by Castorix31 Monday, June 18, 2018 11:59 AM
    Monday, June 18, 2018 11:54 AM
  • Experimenting with FindWindow, FindWindowEx and EnumChildWindows is fine for educational purposes.

    But what you are doing in this thread is not always practical in the real world.

    First, it depends on using Spy++ to obtain prior knowledge of the window class names used by a Winforms Textbox control.

    Also, if you create two different Winform applications and examine the class names used for Textbox controls in each of them you will see that they are not the same.  Each application creates and registers its own class name.

    And while there are window class names (other than those documented by Microsoft or other software authors) that are well-known and consistently used across versions of windows and certain applications there are no guarantees that this will always be the case in all circumstances.  So in those cases reliance on observed window class names is reliance on an implementation detail that is subject to change.

    Generally, when programs are designed to communicate with one another they use documented methods to cooperate.  There are various methods described at Interprocess Communications.

    Also, keep in mind that changing the content or state of a control in one program from a different application such as what this thread is doing could have unexpected results in a real world scenario.  The target program may not be aware that the content of one of its controls has been changed,

    Jut some things to think about while you continue your experiments. :)

    Monday, June 18, 2018 12:22 PM
  • hi Sir RLWA32,

    Thanks for explanation, you are correct I think i cannot use this in the real world because the structure of program changes always. Sir is it possible to pass data from the textbox of 1 application to the control (text box,grid view etc) of another application where the cursor or the tab index is located ? instead of the structure of the control I will find the cursor on the other program. 

    thanks in advance Sir. 

    Tuesday, June 19, 2018 8:03 AM
  • You are talking about changing the content of an arbitrary control in another application's window.  So if you are just targeting a child window that has the keyboard focus you don't really know what kind of window you are attempting to manipulate.  Is it a textbox? Is it a button?  Is it a listbox? And so forth.  So does it make sense to do this?

    Tuesday, June 19, 2018 10:46 AM