Page 1 of 3 123 LastLast
Results 1 to 10 of 28

Thread: Control_GetText and Control_SetText

  1. #1

    Control_GetText and Control_SetText

    Hi,
    I am trying to use ThinBasic to automate an existing win32 graphics application (xara).
    However, I seem unable to make it work. The Control_GetText and Control_SetText calls appear to have no effect.

    I can get the application handle easily using this code.
    hWnd = Win_FindByTitle("Xara...")
    I know the controlID using WinSpy
    controlID = 14377

    However, in ThinBasic I have not found a way to make the following have any effect:
    EditText= CONTROL_GetText(hwnd, controlID)
    s = CONTROL_SetText(hwnd, controlID, "10cm")
    There are no errors and nothing appears to happen.

    If I do this for a dialogue I create in Thinbasic it all seems to work ok. But for other apps nothing.
    I can make AutoIT and Autokey work perfectly but prefer to use ThinBasic due to its langauge structure and debugging capabilities.

    Can someone tell me the correct way to get and set text in the other applications edit boxes please.

  2. #2
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,781
    Rep Power
    10
    Ciao rjp74 and welcome to thinBasic community.

    CONTROL_GetText and CONTROL_SetText work using the window handle of the parent window containing the control plus the control id
    Win_FindByTitle instead just return the windows handle of the window whose title is ... something your search for.

    So you need the windows handle of the parent control (that is a dynamic internal handle that change at every window creation) plus the control ID (that is always the same)

    Finding the parent window is not that easy in some situations because complex user interfaces there can have hidden windows of windows not easily identifiable.

    Can you please post a picture of the are you area trying to get?
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

  3. #3

    Control_GetText and Control_SetText

    [QUOTE=Can you please post a picture of the are you area trying to get?[/QUOTE]
    Thank you for your comments. Here is a picture showing the main parts I am in interested in automating. The arrows show the main controls I am trying to access.
    The text boxes are only meaningful when the green highlighted panel is active. I have to add code that ensures this, or do it by hand for testing purposes.

    xara controls.png

    If I was doing this in AutoIT I would write the following code. This works perfectly.

    Const $zara = "[CLASS:XTPMainFrame]"
    Const $xX = 14377
    ; -- set "X" edit box to contain the text "1.00cm"
    ControlSetText($zara, "1.00cm", $xX)
    
    Setting the text is one thing - I also need to send an {Enter} to get xara to action the new value. This I can do through a second call. I only need do it after all the values have been entered.
    First I need to get some form of set text and get text working. I seem to be totallly stuck with this.

    Perhaps you have an example showing how to set or read the display text box for something simple such as the standard Windows Calculator? Given a working example I am sure I could discover how to make the same thing work for my xara script.
    many thanks

  4. #4
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,129
    Rep Power
    732
    Hi rjp74,

    maybe you could try a bit more low level approach:
    ' -- Add these functions to your code
    Function Custom_SetText( hWindow As DWord, idCtl As Long, sText As String )
    
      Dim szText As Asciiz * 1024
      szText = sText
         
      DWord hCtl = Win_GetDlgItem(hWindow, idCtl)
      
      SendMessage hCtl, %WM_SETTEXT, 0, VarPtr(szText)
    
    End Function
    
    Function Custom_SendEnterKey( hWindow As DWord, idCtl As Long )
    
      DWord hCtl = Win_GetDlgItem(hWindow, idCtl)
      
      Win_SetFocus( hCtl )
      SendKeys("{ENTER}")
      
    End Function
    
    You can use this code like:
    DWord hWnd = Win_FindByTitle("Xara...") 
    Long  controlID = 14377
    Custom_SetText(hWnd, controlID, "1.00cm")
    Custom_SendEnterKey(hWnd, controlID)
    

    Petr
    Last edited by Petr Schreiber; 28-08-2012 at 21:48.
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  5. #5
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,781
    Rep Power
    10
    Dear rjp74,

    I have bad news, sorry

    The main problem is that thinBasic UI module is not designed to automate controls in process different from current thinBasic process. AutoIt instead was initially designed to control windows in whatever process they are. For this reason AutoIt developer designed some specific commands (in this case ControlSetText) to be able to discover and manage child controls.

    In details, CONTROL SET TEXT uses Windows API called SetWindowText and this API is able to set text only in the controls created by the current process (that is in windows created by thinBasic scripts). To SET TEXT into controls not belonging into current process, Microsoft suggest to use SendMessage to send a %WM_SETTEXT message to the window you want to change text. The disadvantage of this process is that you need to know the exact window handle of the control you want to change the text content and this is dynamic.

    So, for the moment I have no solution for your request.
    I will study AutoIt ControlSetText function to see if I can add something similar to thinBasic.

    Ciao
    Eros
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

  6. #6

    ControlGetText and ControlSetTExt

    Hi,

    Thanks for informing me that for the moment there is no solution. I am relieved that it was not caused by my making some basic mistakes.

    I tried the code suggested by Petr Schreiber but it failed on this line of code:
    DWord hCtl = Win_GetDlgItem(hWindow, idCtl)
    It returns 0 instead of the expected value. Here is the trace and the Au3Info display for the specified control.

    Custom_SetText.png

    I did look up the web page for the source for AutoIT. It is here:
    https://github.com/AutoHotkey/AutoHo...ce/script2.cpp
    I am not a c++ or a windows deep internals programmer but it seems that the magic occurs in a routine called DetermineTargetWindow()

    many thanks for your help

  7. #7
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,781
    Rep Power
    10
    Thanks a lot for the AutoIt link.
    As I suspected, it is using SendMessage with %WM_SETTEXT message
    ResultType Line::ControlSetText(char *aControl, char *aNewText, char *aTitle, char *aText
    	, char *aExcludeTitle, char *aExcludeText)
    {
    	g_ErrorLevel->Assign(ERRORLEVEL_ERROR); // Set default ErrorLevel.
    	HWND target_window = DetermineTargetWindow(aTitle, aText, aExcludeTitle, aExcludeText);
    	if (!target_window)
    		return OK;
    	HWND control_window = ControlExist(target_window, aControl); // This can return target_window itself for cases such as ahk_id %ControlHWND%.
    	if (!control_window)
    		return OK;
    	// SendMessage must be used, not PostMessage(), at least for some (probably most) apps.
    	// Also: No need to call IsWindowHung() because SendMessageTimeout() should return
    	// immediately if the OS already "knows" the window is hung:
    	DWORD result;
    	SendMessageTimeout(control_window, WM_SETTEXT, (WPARAM)0, (LPARAM)aNewText
    		, SMTO_ABORTIFHUNG, 5000, &result);
    	DoControlDelay;
    	return g_ErrorLevel->Assign(ERRORLEVEL_NONE); // Indicate success.
    }
    
    I think the trick is inside ControlExist function. It should be able to enumerate though all child controls even if in between the main windows and the needed control there are hidden windows like in the case of XARA where the Edit control you want to change is inside other two parent windows.

    I will see what I can do. It is quite interesting having something similar.

    Ciao
    Eros
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

  8. #8
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,781
    Rep Power
    10
    I think I've found a piece of Power Basic code I can use as a starter.
    http://www.powerbasic.com/support/pb...umChildWindows

    The API to be used is EnumChildWindows
    Once I've the handle of the main Window (in this case Xara) I will use EnumChildWindows to enumerate all child windows (controls) of a certains class or having a certain Control ID.
    Once found I can use SendMessage ... %WM_SETTEXT to fill the requested control with required text

    Should be quite easy but I need some days to develop and test.

    I will let your know.
    Eros
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

  9. #9
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,781
    Rep Power
    10
    I've downloaded and installed Xara Designer 7 in order to test it.
    Than created a PB application to see if the idea I had is working or not and it seems all is working fine like in AutoIt.

    So ...I think by this evening I will replicate AutoIt function called ControlSetText
    Initially I will create a specific module to be tested in thinBasic scripts. If tests will be OK, I will include into UI module

    Stay tuned ...
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

  10. #10

    setting control text

    Hi, I made some progress. I needed to write a recursive control finder that returned the parent handle for that control. Then I could correctly use the send message function.
    The code doesnt do much - it simply writes "1.00cm" into the X text box of Xara.
    Next task is to find out how to simulate the pressing of the enter key to get the value accepted.....
    After that I will need mouse clicks, and control clicks. I can live without control_getText for now but I can see that other people would find this very helpful.

    ' Empty ThinBASIC CONSOLE file template
    Uses "UI"
    Uses "console"  
    Declare Function GetWindow Lib "user32.dll"  Alias "GetWindow" (ByVal hWnd As DWord, ByVal uCmd As Long) As Long   
    Declare Function GetDlgCtrlID Lib "user32.dll" Alias "GetDlgCtrlID" (ByVal hwndCtl As DWord) As Integer
    
      
    DWord hWnd = Win_FindByTitle("Xara...") 
    Long  cId_X = 14377
    DWord Parent = 0 
       
       Parent = FindHandle(hWnd, cId_X)  
       Console_WriteLine Str$(Parent)
       Custom_SetText(Parent, cId_X, "1.00cm")
       Console_WaitKey
    
    Function FindHandle(hWnd As DWord, myCtrlID As Long ) As DWord
      Long hChild = GetWindow(hWnd, %GW_CHILD) 
      While hChild       
         Long thisCtrlId = GetDlgCtrlID(hChild) 
         If thisCtrlId = myCtrlID Then Return  hChild    ' found it 
         Long FoundParent = FindHandle(hChild, myCtrlID) 
         If (FoundParent > 0) Then Return FoundParent     ' no need to search further
         hChild = GetWindow(hChild, %GW_HWNDNEXT) 
      Wend 
      Return 0      ' not found               
    End Function
    
    Function Custom_SetText( hWindow As DWord, idCtl As Long, sText As String)
       Dim szText As Asciiz * 1024
       szText = sText
       SendMessage hWindow, %WM_SETTEXT, 0, VarPtr(szText)
    End Function
    

Page 1 of 3 123 LastLast

Members who have read this thread: 0

There are no members to list at the moment.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •