Jump to content

Change the caption of a window!!!

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
12 replies to this topic

#1
sakishrist

sakishrist

    Programmer

  • Members
  • PipPipPipPip
  • 109 posts
Here is what I've done:

I've declared the [c]SendMessage[/c] function.
I've found the handle of the window I want.
And I called the function
SendMessage(hWnd, &HC, 0&, "Test")
*&HC is the WM_SETTEXT message

And now I have this error: [c]Conversion from string "Test" to type 'Integer' is not valid.[/c]

What am I doing wrong?

#2
sakishrist

sakishrist

    Programmer

  • Members
  • PipPipPipPip
  • 109 posts
OK ... sorry for this post but it was really foolish! the declaration was made with the lparam as integer so the code failed! Now it works fine with the captions of the windows but what do I need to do to make it change the contents of a textbox like the one in notepad?

#3
excavator

excavator

    Newbie

  • Members
  • PipPip
  • 16 posts
i was wondering, what if u use DefWindowProc function and change the hWnd parameter into textbox's hWnd.

#4
sakishrist

sakishrist

    Programmer

  • Members
  • PipPipPipPip
  • 109 posts
Problem is I use the enumWindows to find all the windows but this doesn't find just the textbox of the notepad. Why could that be?

#5
excavator

excavator

    Newbie

  • Members
  • PipPip
  • 16 posts
man, thats quite tricky. enumWindows only enumerate top windows only. i think after u run enumWindows you should do enumChildWindows then do enumProps for each child window until you find the textbox and then do getProp or setProp for the textbox. this is just my opinion, i can't guarantee that it will work.

please let me know if there any progress, i'm learning from this post too. :)

#6
sakishrist

sakishrist

    Programmer

  • Members
  • PipPipPipPip
  • 109 posts
So if I'm right enumProps is not for finding windows but for finding properties? in the MSDN there is not really much information about it but I found this. Is this what it really does? I also found its definition here and I'll try to get this working. I will post here once I have progress or problems! :)

#7
excavator

excavator

    Newbie

  • Members
  • PipPip
  • 16 posts
yes, enumProps is for finding (enumerating) properties. those links u posted have the necessary sample code. i believe u can pull this off. :)

#8
sakishrist

sakishrist

    Programmer

  • Members
  • PipPipPipPip
  • 109 posts
Oh ... Please help me with the enumProps function! Here is what I've done but I cant get it working. I tried to find something from the web but there is not really much about it! I did the callback function as described in a vb6 sample but I had no luck converting it successfully.
Public Class Form1

    Private Declare Function EnumProps Lib "user32" Alias "EnumPropsA" (ByVal hwnd As Long, ByVal lpEnumFunc As Long) As Long
    Delegate Function EnumPropCallback(ByVal hWnd As Long, ByVal lpszString As Long, ByVal hData As Long) As Long
    Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As String) As Long
    Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As Object, ByVal lpString2 As Object) As Long

    Public Function PropEnumProc(ByVal hwnd As Long, ByVal lpszString As Long, ByVal hData As Long) As Long
        Dim sPropName As String
        sPropName = lstrlen(lpszString)
        lstrcpy(sPropName, lpszString)
        MsgBox(sPropName & " = " & hData)
        PropEnumProc = 1 ' continue enumeration
    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       
        Call EnumProps(Me.Handle, [COLOR="Red"]New EnumPropCallback(AddressOf PropEnumProc)[/COLOR])
    End Sub

End Class
*In red I've marked the error I get which is: Value of type 'WindowsApplication1.Form1.EnumPropCallback()' cannot be converted to 'Long'.
It may be something really easy again but I cant find it or the error is somewhere else in my code!


Thanks for your help!

#9
excavator

excavator

    Newbie

  • Members
  • PipPip
  • 16 posts

Public Class Form1

    

    Private Declare Function EnumProps Lib "user32" Alias "EnumPropsA" (ByVal hwnd As IntPtr, ByVal lpEnumFunc As EnumPropCallback) As Integer

    Delegate Function EnumPropCallback(ByVal hWnd As IntPtr, ByVal lpszString As IntPtr, ByVal hData As IntPtr) As Boolean

    Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As String) As Integer

    Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As String) As Integer


    Private Function PropEnumProc(ByVal hwnd As IntPtr, ByVal lpszString As String, ByVal hData As IntPtr) As Boolean

        Dim sPropName As String = ""


        sPropName = lpszString

        lstrcpy(sPropName, lpszString)

        MsgBox(sPropName & " = " & hData.ToString)

        'PropEnumProc = True  ' continue enumeration


        Return True

    End Function


    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Call EnumProps(Me.Handle, AddressOf Me.PropEnumProc)

    End Sub

End Class


i think u still need to use EnumChildWindows to find the textbox's handle.

#10
excavator

excavator

    Newbie

  • Members
  • PipPip
  • 16 posts
i've found the textbox's handle.
maybe we can ignore setprop/getprop and use SendMessage with WM_SETTEXT instead.


Public Class Form1

    

    Private Declare Function EnumProps Lib "user32" Alias "EnumPropsA" (ByVal hwnd As IntPtr, ByVal lpEnumFunc As EnumPropCallback) As Integer

    Delegate Function EnumPropCallback(ByVal hWnd As IntPtr, ByVal lpszString As IntPtr, ByVal hData As IntPtr) As Boolean

    Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As String) As Integer

    Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As String) As Integer



    Private Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As IntPtr, ByVal lpEnumFunc As EnumChildProcCallback, ByVal lParam As IntPtr) As Boolean

    Delegate Function EnumChildProcCallback(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean


    Private Function EnumChildProc(ByVal hWnd As IntPtr, ByVal lparam As IntPtr) As Boolean

        MsgBox(hWnd.ToString)

        Return True

    End Function

    Private Function PropEnumProc(ByVal hwnd As IntPtr, ByVal lpszString As String, ByVal hData As IntPtr) As Boolean

        Dim sPropName As String = ""


        sPropName = lpszString

        lstrcpy(sPropName, lpszString)

        MsgBox(sPropName & " = " & hData.ToString)

        'PropEnumProc = True  ' continue enumeration


        Return True

    End Function


    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Call EnumProps(Me.Handle, AddressOf Me.PropEnumProc)

        Call EnumChildWindows(Me.Handle, AddressOf Me.EnumChildProc, 0)


    End Sub


    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        TextBox1.Text = TextBox1.Handle.ToString

        TextBox2.Text = TextBox2.Handle.ToString


    End Sub

End Class



#11
sakishrist

sakishrist

    Programmer

  • Members
  • PipPipPipPip
  • 109 posts
I did nearly nothing this time! I could not understand how do the functions work (enumprops and get/setprops). Could someone explain them to me? I tried to find some code samples about them but there ware non of them on the web. I also tried just to use WM_SETTEXT but it didn't work for editable areas like the one in notepad, just for titles. I've uploaded one of my projects just for anyone who want to try it (this project doesn't use the enumprops or get/setprops but it uses all the other functions like enumwindows and sendmessage).
Thanks for your help!

Attached Files



#12
sakishrist

sakishrist

    Programmer

  • Members
  • PipPipPipPip
  • 109 posts
OK, I have to say you ware right, I was using GetWindowText to get the text and I wasn't using the WM_SETTEXT properly so I did not have the result I wanted. Now that I use WM_GETTEXT and WM_SETTEXT It works perfect! Here Is the code I found:
Imports System.Text


Module Module1


    Sub Main()

        Dim notepadHandle As IntPtr


        notepadHandle = Win32.FindWindow(Nothing, "Untitled - Notepad")


        If notepadHandle <> IntPtr.Zero Then

            Win32.EnumChildWindows(notepadHandle, AddressOf EnumCallback, 0)

        Else

            Console.WriteLine("No notepad instances found.")

        End If

    End Sub


    Function EnumCallback(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean

        Console.WriteLine("Got: |{0}|", Win32.GetEditText(hWnd))

        Win32.SetEditText(hWnd, "This text was set programmatically.")


        ' By returning false I tell the program to stop enumerating.  This means I'm only working

        ' with the first child window of the notepad window, which I'm hoping will be the edit

        ' control.

        Return False

    End Function


    Private Class Win32


        Private Const WM_GETTEXTLENGTH As Integer = &HE

        Private Const WM_GETTEXT As Integer = &HD

        Private Const WM_SETTEXT As Integer = &HC


        Friend Declare Auto Function FindWindow Lib "user32.dll" (ByVal className As String, _

                                                             ByVal title As String) As IntPtr


        ' The three overloads of SendMessage exist for the following reasons:

        ' 1) WM_GETTEXT needs a StringBuilder for its lParam

        ' 2) WM_SETTEXT needs a normal string for its lParam

        ' 3) WM_GETTEXTLENGTH uses 0 for both lParam and wParam

        Friend Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, _

                                                              ByVal msgId As Integer, _

                                                              ByVal wParam As Integer, _

                                                              ByVal text As StringBuilder) _

                                                                As Integer


        Friend Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, _

                                                      ByVal msgId As Integer, _

                                                      ByVal wParam As Integer, _

                                                      ByVal text As String) _

                                                        As Boolean


        Friend Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, _

                                                      ByVal msgId As Integer, _

                                                      ByVal wParam As Integer, _

                                                      ByVal lParam As Integer) _

                                                        As Integer


        Friend Declare Auto Function EnumChildWindows Lib "user32.dll" (ByVal hWndParent As IntPtr, _

                                                                   ByVal callback As EnumChildProc, _

                                                                   ByVal lParam As Integer) As Boolean


        Friend Delegate Function EnumChildProc(ByVal hWnd As IntPtr, _

                                               ByVal lParam As Integer) As Boolean


        Friend Shared Function GetEditText(ByVal hWnd As IntPtr) As String

            ' We have to know the length before getting the text; the length is one less than

            ' the number of characters we should ask for due to C's terminating null

            Dim textLength As Integer = SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0)

            Dim controlText As New StringBuilder


            If textLength > 0 Then

                Dim charsCopied As Integer

                charsCopied = SendMessage(hWnd, WM_GETTEXT, textLength + 1, controlText)

            End If


            Return controlText.ToString()

        End Function


        Friend Shared Function SetEditText(ByVal hWnd As IntPtr, ByVal text As String) As Boolean

            Return SendMessage(hWnd, WM_SETTEXT, 0, text)

        End Function

    End Class


End Module
Thanks for your help!