Hello, I’m trying to update a label and press a button in an external (Xojo) App I created. This is for Windows. I was able to get the window handle with some help from a post resolved by Arnaud N. Below is that code. What I want to do is within that app I want to find the label that has a text of “USER NAME” and change it to say “GEORGE”, and I want to click the button with the caption of “REFRESHNAME”. Below my window handle code is some code I used in .NET to do this but I cannot figure it out in Xojo. Any help would be great, thanks.
—Xojo Find Window handle
Soft Declare Function FindWindowW Lib "user32.dll" (lpClassName As integer,lpWindowName As integer) as integer
Soft Declare Function GetWindow Lib "user32" (hWnd As integer,wCmd As integer) As integer
Soft Declare Function GetWindowTextW Lib "user32" (hWnd As integer,lpString As ptr,cch As integer) As integer
Dim ret As Integer
Dim mb as new MemoryBlock(255)
ret=FindWindowW(0,0)
While ret>0
if GetWindowTextW(ret,mb,mb.size)>0 then
lstCurrentScan.AddRow(mb.WString(0))
lstWindowHandle.AddRow(ret.tostring)
if mb.WString(0)="TWINS" then
exit
end if
end if
ret=GetWindow(ret,2)
Wend
—.NET code
Public 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
Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As IntPtr
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 Const WM_SETTEXT = &HC
Public Const BM_CLICK = &HF5
Dim s as string = "GEORGE
Dim Handle As IntPtr = FindWindowEx(Hwnd, IntPtr.Zero, Nothing, "USER NAME")
Dim hWndButton As IntPtr = FindWindowEx(Hwnd, IntPtr.Zero, Nothing, "REFRESHNAME")
SendMessageSTRING(Handle, WM_SETTEXT, IntPtr.Zero, s)
SendMessage(hWndButton, BM_CLICK, 0&, 0&)
Declare Function SendMessageW Lib "User32" (HWND As Integer, Msg As Integer, WParam As Ptr, LParam As WString) As Integer
Declare Function FindWindowExW Lib "User32" (Parent As Integer, ChildAfter As Integer, Classname As WString, WindowName As WString) As Integer
Const WM_SETTEXT = &hC
Const BM_CLICK = &hF5
Dim Handle As Integer = FindWindowExW(Hwnd, 0, Nil, "USER NAME")
Dim hWndButton As Integer = FindWindowExW(Hwnd, 0, Nil, "REFRESHNAME")
Call SendMessageW(Handle, WM_SETTEXT, Nil, "GEORGE")
Call SendMessageW(hWndButton, BM_CLICK, Nil, Nil)
Andrew,
After looking into this more I realized that the button click (BM_CLICK) does not work/do anything. I was able to send the message to the label and change the label name but I am unable to click the button on sendmessage. Is the const wrong or something? Thanks for any help you can provide.
Hah, I was literally just trying that, found a reference to it on another site where somebody suggested it because they said sometimes one works and the other doesn’t. It worked! Thanks for the quick reply!
The documentation says it might fail if the button is on an inactive dialog box.It goes on to suggest using SetActiveWindow, but it’s documentation makes it sound like it should only be used within the app that owns the window; maybe send a WM_ACTIVATE message (to the window, not the button) instead?
I seem to remember from my time working with the Win32 API using these functions that the WM messages were more reliable than BK_CLICK because many controls simply didn’t respond to BK_CLICK the same way, or at all, as they do with WM_LBUTTONDOWN and WM_LBUTTONUP, but I could be remembering that wrong. It’s been nearly 15 years since I had to do this regularly.
@anon20074439 would probably have some insight as the resident Win32 API guru.
Thanks. It seems like there’s some inconsistencies with it. I’ve a got a simple app that I created for testing that finds the button and clicks it. I have the same exact button type and name in a different app and it doesn’t click it. The one that doesn’t work is the same window type and title as the sample app. I’m also seeing that after having the button work 3 or 4 times it quits working. Definitely seems like an Active Window thing like you mentioned. Below is my code. I have 2 buttons, one with the caption “USER NAME” which I use to update the user name. (Tried using a label but it seems that does not update correctly in Xojo Windows (saw a post about it). My other button is captioned “REFRESHNAME” and is the one that needs to be clicked. It works for the sample app but not my other app that I need it to.
Soft Declare Sub ShowWindow Lib “User32” (wnd As Integer, nCmdShow As Integer)
Soft Declare Function SetForegroundWindow Lib “User32” (hWnd As Integer) As Integer
Declare Function SendMessageW Lib “User32” (HWND As Integer, Msg As Integer, WParam As Ptr, LParam As WString) As Integer
Declare Function FindWindowExW Lib “User32” (Parent As Integer, ChildAfter As Integer, Classname As WString, WindowName As WString) As Integer
Const WM_SETTEXT = &hC
Const BM_CLICK = &hF5
Const WM_LBUTTONDOWN = &H201
Const WM_LBUTTONUP = &H202