Jump to content

_GUICtrlTab_GetItemText the target crashes on dissimilar architecture


Go to solution Solved by pixelsearch,

Recommended Posts

Posted

The problem I am facing is

I'm running the example 'C:\Program Files (x86)\AutoIt3\Examples\Helpfile\GUICtrlCreateTab.au3'  as the target application,
and with the main script I'm trying to read the tab names

the issue is that the main script runs on X64 and the target on X32

up to Local $hParentWnd = _WinAPI_GetParent($hCtrl)  everything goes well,

but if I try with  _GUICtrlTab_GetItemText($hCtrl, $x) , then the target crashes

I took a look in #include <GuiTab.au3>
and I realized that it has something to do with the SendMessage  and the architectural incompatibility

main script

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GuiTab.au3>

If Not WinExists("My GUI Tab") Then Exit

Local $hWnd = WinWait("My GUI Tab", "", 1)
ConsoleWrite("$hWnd=" & $hWnd & @CRLF)

Local $hCtrl = ControlGetHandle($hWnd, "", "SysTabControl321")
ConsoleWrite("$hCtrl=" & $hCtrl & @CRLF)

Local $hParentWnd = _WinAPI_GetParent($hCtrl)
ConsoleWrite("$hParentWnd=" & $hParentWnd & @CRLF)

; Show number of tabs
Local $iTabCnt = _GUICtrlTab_GetItemCount($hCtrl)
ConsoleWrite("Number of tabs: " & $iTabCnt & @CRLF & @CRLF)
Local $sItemText

; With this part the target crashes
;~ For $x = 0 To $iTabCnt - 1
;~  $sItemText = _GUICtrlTab_GetItemText($hCtrl, $x)
;~  ConsoleWrite($x & ") " & $sItemText & @CRLF)
;~ Next

the easy solution I thought of is to make a helper script like a bridge

But if there is a way to avoid this, I would like to know
Thanks a lot

 

I know that I know nothing

  • Solution
Posted


@ioa747 Hi

When you call _GUICtrlTab_GetItemText, then  _GUICtrlTab_GetItem is called

And _GuiCtrlTab_GetItem had issues as seen on Trac Ticket 3903 and in this post.
In the post, @Danyfirex worked on this x86-x64 issue and maybe he could give an advice here if he got time ?

Also I notice code in _GUICtrlTab_GetItem has been updated in new release 3.3.17.1 (beta) . Did you check your script with 3.3.17.1 , maybe it's solved with the new release ?

Fingers crossed & good luck :)

"I think you are searching a bug where there is no bug... don't listen to bad advice."

Posted (edited)

pixelsearch, analytical and comprehensive as always, thank you very much
The solution proposed by Danyfirex 🏆, in this particular post is completely functional

 

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GuiTab.au3>

;>> Target: C:\Program Files (x86)\AutoIt3\Examples\Helpfile\GUICtrlCreateTab.au3

If Not WinExists("My GUI Tab") Then Exit

Local $hWnd = WinWait("My GUI Tab", "", 1)
ConsoleWrite("$hWnd=" & $hWnd & @CRLF)

Local $hCtrl = ControlGetHandle($hWnd, "", "SysTabControl321")
ConsoleWrite("$hCtrl=" & $hCtrl & @CRLF)

Local $hParentWnd = _WinAPI_GetParent($hCtrl)
ConsoleWrite("$hParentWnd=" & $hParentWnd & @CRLF)

; Show number of tabs
Local $iTabCnt = _GUICtrlTab_GetItemCount($hCtrl)
ConsoleWrite("Number of tabs: " & $iTabCnt & @CRLF & @CRLF)
Local $sItemText, $aItem

; Now is working !!
For $x = 0 To $iTabCnt - 1
    $aItem = _GUICtrlTab_GetItemEx($hCtrl, $x)
    $sItemText = $aItem[1]
    ConsoleWrite("$sItemText=" & $sItemText & @CRLF)
Next


Func _GUICtrlTab_GetItemEx($hWnd, $iIndex)
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)

    Local $tagTCITEMEx = $tagTCITEM & ";ptr Filler" ; strange the Filler is erased by TCM_GETITEM : MS Bug!!!
    If Not _WinAPI_InProcess($hWnd, $__g_hGUICtrl_LastWnd) Then
        ;x86 read remote x64
        If (Not @AutoItX64) And (Not _WinAPI_IsWow64Process(DllCall("user32.dll", "dword", "GetWindowThreadProcessId", "hwnd", $hWnd, "dword*", 0)[2])) Then
            $tagTCITEMEx = StringReplace($tagTCITEMEx, "ptr", "INT64")
        EndIf

        ;x64 read remote x86
        If (@AutoItX64) And (_WinAPI_IsWow64Process(DllCall("user32.dll", "dword", "GetWindowThreadProcessId", "hwnd", $hWnd, "dword*", 0)[2])) Then
            $tagTCITEMEx = StringReplace($tagTCITEMEx, "ptr", "ULONG")
        EndIf
    EndIf

    Local $tItem = DllStructCreate($tagTCITEMEx)
    DllStructSetData($tItem, "Mask", $TCIF_ALLDATA)
    DllStructSetData($tItem, "StateMask", BitOR($TCIS_HIGHLIGHTED, $TCIS_BUTTONPRESSED))
    Local $tBuffer, $iMsg
    If _GUICtrlTab_GetUnicodeFormat($hWnd) Then
        $tBuffer = $__g_tTabBuffer
        $iMsg = $TCM_GETITEMW
    Else
        $tBuffer = $__g_tTabBufferANSI
        $iMsg = $TCM_GETITEMA
    EndIf
    Local $iRet = __GUICtrl_SendMsg($hWnd, $iMsg, $iIndex, $tItem, $tBuffer, True, 4, True)

    Local $aItem[4]
    $aItem[0] = DllStructGetData($tItem, "State")
    $aItem[1] = DllStructGetData($tBuffer, "Text")
    $aItem[2] = DllStructGetData($tItem, "Image")
    $aItem[3] = DllStructGetData($tItem, "Param")

    Return SetError($iRet = 0, 0, $aItem)
EndFunc   ;==>_GUICtrlTab_GetItem

This way, I avoid having to make a helper script like a bridge, I just add the function.
Mission accomplished. 

Thank you very much :)

 

Edited by ioa747

I know that I know nothing

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...