Iczer Posted June 28, 2015 Posted June 28, 2015 I have troubles with moving script to 64bit - functions "_GUICtrlTreeView_GetImageIndex()" and "_GUICtrlTreeView_GetText()" stop working without any errorstreeView control belong some x86 application - and x86 script work with it .What i can do about it? Is it bug in UDF?#AutoIt3Wrapper_UseX64=Y #include <GuiTreeView.au3> Func SubFunction_GetState($hWnd) Local $TVShandle, $TVSSelHandle, $TVSCount, $TVSParentHandle, $TVSS, $i, $TVSItemHandle, $TVSItemIcon AutoItSetOption("WinTitleMatchMode", 2) WinWaitActive($hWnd) $TVShandle = ControlGetHandle($hWnd, "", "[NAME:_treeView]") $TVSSelHandle = _GUICtrlTreeView_GetSelection($TVShandle) ConsoleWrite(@crlf&"$TVSSelHandle = "&$TVSSelHandle&@crlf&"@Error = "&@error&@crlf) $TVSCount = _GUICtrlTreeView_GetSiblingCount($TVShandle, $TVSSelHandle) ConsoleWrite(@crlf&"$TVSCount = "&$TVSCount&@crlf&"@Error = "&@error&@crlf) $TVSParentHandle = _GUICtrlTreeView_GetParentHandle($TVShandle) ConsoleWrite(@crlf&"$TVSParentHandle = "&$TVSParentHandle&@crlf&"@Error = "&@error&@crlf) Local $TVSS[1] = [0] For $i = 0 To $TVSCount-1 $TVSItemHandle = _GUICtrlTreeView_GetItemByIndex($TVShandle, $TVSParentHandle, $i) ConsoleWrite(@crlf&"$TVSItemHandle = "&$TVSItemHandle&@crlf&"@Error = "&@error&@crlf) $TVSItemIcon = _GUICtrlTreeView_GetImageIndex($TVShandle, $TVSItemHandle) ConsoleWrite("$TVSItemIcon = "&$TVSItemIcon&@crlf&"@Error = "&@error&@crlf) ConsoleWrite("_GUICtrlTreeView_GetText = "&_GUICtrlTreeView_GetText($TVShandle, $TVSItemHandle)&@crlf&"@Error = "&@error&@crlf) If $TVSItemIcon = 7 Then ReDim $TVSS[UBound($TVSS)+1] $TVSS[0] += 1 $TVSS[$TVSS[0]] = $TVSItemHandle ConsoleWrite("_GUICtrlTreeView_GetText = !!!"&@crlf) EndIf Next EndFuncx86 script output:$TVSSelHandle = 0x066F3FD0 @Error = 0 $TVSCount = 40 @Error = 0 $TVSParentHandle = 0x003CBFB8 @Error = 0 $TVSItemHandle = 0x066F3930 @Error = 0 $TVSItemIcon = 5 @Error = 0 _GUICtrlTreeView_GetText = Item01 @Error = 0x64 script output:$TVSSelHandle = 0x00000000066F3FD0 @Error = 0 $TVSCount = 40 @Error = 0 $TVSParentHandle = 0x00000000003CBFB8 @Error = 0 $TVSItemHandle = 0x00000000066F3930 @Error = 0 $TVSItemIcon = 0 @Error = 0 _GUICtrlTreeView_GetText = @Error = 0
Iczer Posted June 28, 2015 Author Posted June 28, 2015 (edited) tried to search bug tracker for something similar - found #1816 and #2694If change in $tagLVITEM "ptr Text" to "uint Text" (i.e. make it 32bit) _GUICtrlListView_GetItemText solve the problem (but not solves the bug). but it didn't help...Also bug #1479 seems relevant Edited June 28, 2015 by Iczer addition
LarsJ Posted June 29, 2015 Posted June 29, 2015 (edited) This is not a bug. You must use a 32 bit AutoIt script to automate a 32 bit application. And you must use a 64 bit AutoIt script to automate a 64 bit application.If you look at _GUICtrlTreeView_GetText it uses a TVITEMEX structure. On 64 bit this is a 80 byte structure. On 32 bit this is a 60 byte structure.If your AutoIt script is running 64 bit a 80 byte structure is created. The communication between your script and the application takes place when the _SendMessage command (succeeding "If $fUnicode Then") is executed. $pMemory is a pointer to the structure. But the application running 32 bit expects a 60 byte structure. This means that the _SendMessage command fails and returns False (0).Perhaps one can say that it is a mistake not to check the return value of the _SendMessage command and set @error in case of an error.expandcollapse popupFunc _GUICtrlTreeView_GetText($hWnd, $hItem = 0) If Not IsHWnd($hItem) Then $hItem = _GUICtrlTreeView_GetItemHandle($hWnd, $hItem) If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) If $hItem = 0x00000000 Then Return SetError(1, 1, "") Local $tTVITEM = DllStructCreate($tagTVITEMEX) Local $tText Local $fUnicode = _GUICtrlTreeView_GetUnicodeFormat($hWnd) If $fUnicode Then $tText = DllStructCreate("wchar Buffer[4096]"); create a text 'area' for receiving the text Else $tText = DllStructCreate("char Buffer[4096]"); create a text 'area' for receiving the text EndIf DllStructSetData($tTVITEM, "Mask", $TVIF_TEXT) DllStructSetData($tTVITEM, "hItem", $hItem) DllStructSetData($tTVITEM, "TextMax", 4096) If _WinAPI_InProcess($hWnd, $__ghTVLastWnd) Then DllStructSetData($tTVITEM, "Text", DllStructGetPtr($tText)) _SendMessage($hWnd, $TVM_GETITEMW, 0, $tTVITEM, 0, "wparam", "struct*") Else Local $iItem = DllStructGetSize($tTVITEM) Local $tMemMap Local $pMemory = _MemInit($hWnd, $iItem + 4096, $tMemMap) Local $pText = $pMemory + $iItem DllStructSetData($tTVITEM, "Text", $pText) _MemWrite($tMemMap, $tTVITEM, $pMemory, $iItem) If $fUnicode Then _SendMessage($hWnd, $TVM_GETITEMW, 0, $pMemory, 0, "wparam", "ptr") Else _SendMessage($hWnd, $TVM_GETITEMA, 0, $pMemory, 0, "wparam", "ptr") EndIf _MemRead($tMemMap, $pText, $tText, 4096) _MemFree($tMemMap) EndIf Return DllStructGetData($tText, "Buffer") EndFunc ;==>_GUICtrlTreeView_GetText Edited June 29, 2015 by LarsJ Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions
Iczer Posted June 29, 2015 Author Posted June 29, 2015 hmm... so, if i change this structure to be 60 byte in both x64 and x86 cases, it should work in Autoit64 for control over x86 applications?
LarsJ Posted June 30, 2015 Posted June 30, 2015 How will you do it? On x64 a pointer is 8 byte. On x86 it's 4 byte. How will you store an 8 byte pointer in a 4 byte structure field? This is not just a problem for pointers. This is also a problem for the following data types: hwnd, handle, int_ptr, long_ptr, lresult, lparam, uint_ptr, ulong_ptr, dword_ptr, wparam and struct. You have to add a lot of additional code to handle this. All the additional code will make your script run slow.When you have implemented all that code, your script will not work if the target application is running 64 bit. The 64 bit application still expects a 80 byte structure.Have you considered how many functions you need to change in that way? You have to change _GUICtrlTreeView_GetImageIndex, too. How many more functions in the GuiTreeView UDF do you have to change? How many more functions in the other GUI UDFs do you have to change? How many functions in the WinApi and other UDFs do you have to change?Believe me. It's a bad idea. Instead of messing around with the code in the standard UDFs, it's a much better idea to make sure that your own scripts can run as both 32 and 64 bit programs. And they probably can this by default. If you need to automate a 32 bit target application, run the script as a 32 bit program. If the target application is running 64 bit, run the script as a 64 bit program. Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions
Iczer Posted June 30, 2015 Author Posted June 30, 2015 problem is - i need to automate a 32 bit target application, but my script in peak memory consumption hitting upper limit for x86 and crush - it seems (?) it about 1400...1500 Mb. I wanted to counter that and get some speed by moving to 64 bit. If i have to divide script to 32 and 64bit parts... can i instead call functions from autoit_x86.dll from 64bit script?
LarsJ Posted July 1, 2015 Posted July 1, 2015 Why does your script use so much memory? There seems to be something wrong. Does the target application also use that much memory? To try to solve the problems by porting your script to 64 bit will just make things worse. You should focus on why your script uses so many resources. Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions
Iczer Posted July 2, 2015 Author Posted July 2, 2015 It's big input files and then fileread uses up to 6x times of filesize and then up to 8...10x times uses regexp, and in the end sqlite give finishing blow to script...64bit do not have this limit. all i need is 2-3Gb of memory. any way i cannot reduce memory consumption of filesize and regexp...i'm working on sqlite for now
LarsJ Posted July 2, 2015 Posted July 2, 2015 If you run this version of _GUICtrlTreeView_GetText on a 64 bit system, you can get the text of a treeview item in a 32 bit application.expandcollapse popupFunc _GUICtrlTreeView_GetText32($hWnd, $hItem = 0) If Not IsHWnd($hItem) Then $hItem = _GUICtrlTreeView_GetItemHandle($hWnd, $hItem) If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) If $hItem = 0x00000000 Then Return SetError(1, 1, "") ; All 8 byte data types for a 64 bit system changed to 4 byte uint's for a 32 bit system Local $tagTVITEMEX32 = "struct; uint Mask;struct; uint hItem;uint State;uint StateMask;uint Text;int TextMax;int Image;int SelectedImage;int Children;uint Param; endstruct;" & _ "int Integral;uint uStateEx;uint hwnd;int iExpandedImage;int iReserved; endstruct" Local $tTVITEM = DllStructCreate($tagTVITEMEX32) Local $tText Local $fUnicode = _GUICtrlTreeView_GetUnicodeFormat($hWnd) If $fUnicode Then $tText = DllStructCreate("wchar Buffer[4096]"); create a text 'area' for receiving the text Else $tText = DllStructCreate("char Buffer[4096]"); create a text 'area' for receiving the text EndIf DllStructSetData($tTVITEM, "Mask", $TVIF_TEXT) DllStructSetData($tTVITEM, "hItem", BitShift( $hItem, -32 )) ; 8 byte value --> 4 byte value DllStructSetData($tTVITEM, "TextMax", 4096) If _WinAPI_InProcess($hWnd, $__ghTVLastWnd) Then DllStructSetData($tTVITEM, "Text", DllStructGetPtr($tText)) _SendMessage($hWnd, $TVM_GETITEMW, 0, $tTVITEM, 0, "wparam", "struct*") Else Local $iItem = DllStructGetSize($tTVITEM) Local $tMemMap Local $pMemory = _MemInit($hWnd, $iItem + 4096, $tMemMap) Local $pText = $pMemory + $iItem DllStructSetData($tTVITEM, "Text", BitShift( $pText, -32 )) ; 8 byte value --> 4 byte value _MemWrite($tMemMap, $tTVITEM, $pMemory, $iItem) If $fUnicode Then _SendMessage($hWnd, $TVM_GETITEMW, 0, BitShift( $pMemory, -32 ), 0, "wparam", "ptr") ; 8 byte value --> 4 byte value Else _SendMessage($hWnd, $TVM_GETITEMA, 0, $pMemory, 0, "wparam", "ptr") EndIf _MemRead($tMemMap, $pText, $tText, 4096) _MemFree($tMemMap) EndIf Return DllStructGetData($tText, "Buffer") EndFunc Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now