Moderators Melba23 Posted October 6, 2018 Moderators Share Posted October 6, 2018 (edited) Hi all, Please ignore this post - the problem was elsewhere - see my later post in this thread. It appears that the rather large struct I have been using within the WM_NOTIFY handler of my ChooseFileFolder UDF (and which took so long to design with the help of guinness) does not function correctly when the #AutoIt3Wrapper_UseX64=y directive is used within the script on x64 systems. I have only just got an x64 system to play with and so was previously unable to determine the cause of a couple of complaints about the UDF - everything works fine without the directive and on x32 systems. Here is the struct itself and the various data elements taken from it: ; Create NMTREEVIEW structure Local $tStruct = DllStructCreate("struct;hwnd hWndFrom;uint_ptr IDFrom;INT Code;endstruct;" & _ "uint Action;struct;uint OldMask;handle OldhItem;uint OldState;uint OldStateMask;" & _ "ptr OldText;int OldTextMax;int OldImage;int OldSelectedImage;int OldChildren;lparam OldParam;endstruct;" & _ "struct;uint NewMask;handle NewhItem;uint NewState;uint NewStateMask;" & _ "ptr NewText;int NewTextMax;int NewImage;int NewSelectedImage;int NewChildren;lparam NewParam;endstruct;" & _ "struct;long PointX;long PointY;endstruct", $lParam) Local $hWndFrom = DllStructGetData($tStruct, "hWndFrom") Local $hItem = DllStructGetData($tStruct, "NewhItem") Local $iCode = DllStructGetData($tStruct, "Code") In particular the NewhItem element is not returning the correct value - usually returning either the handle of the top element of the TreeView or 0. I would be most grateful if someone could point me towards how to get the !#$£*? thing working when the Autoit3Wrapper directive is set. M23 Edited October 13, 2018 by Melba23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
Deye Posted October 6, 2018 Share Posted October 6, 2018 I can confirm something isn't looking right I just did a switch from #AutoIt3Wrapper_UseX64=n to y and everything worked then switched back from "y" to "n" and got jinxed with the same thing as mentioned here And cannot get it to work either ways switching, maybe something gets mistakenly saved into Scite's Settings or something alike .. I'm not going to debug this matter as i'm doing other stuff I'm sure its resolvable, for anyone wanting to try this out : try running some examples of ChooseFileFolder UDF maybe you will be lucky to reproduce this Deye Link to comment Share on other sites More sharing options...
Deye Posted October 6, 2018 Share Posted October 6, 2018 To all, I take my above post back: ,.. when i was testing and suggesting this I had something else in place which made the expanding part break exactly as described :surprise: another one is that the user is probably not using the correct syntax for X64 or for x32 #AutoIt3Wrapper_OutFile_X64=My.exe #AutoIt3Wrapper_UseX64=y all works here for me. not sure about whats happening on 32bit machines .. eye Link to comment Share on other sites More sharing options...
Danyfirex Posted October 7, 2018 Share Posted October 7, 2018 Hello What a beautiful question, Initially I thought it was a data alignment problem. But after many tests I have the problem. The problem is IsHWnd. It would seem that this is not the problem but it is. Probably we have all been using this function without being aware of its internal structure. Or perhaps we are very used to using it for any data of handle type. That's where the problem lies. We says IsHWnd (SomeHandle) but we do not worry about the true data type, in this case the handle returned by NMTREEVIEW-> NewhItem will not match. You also need to check inside _GUICtrlTreeView_GetItemHandle It sometimes make all work as we would expect due to same issue with IsHWnd. So You structure is correctly. Here is an Example where you can check the IsHwnd is not working as we expect. expandcollapse popup#AutoIt3Wrapper_UseX64=y #include <GUIConstantsEx.au3> #include <GuiTreeView.au3> #include <MsgBoxConstants.au3> #include <WindowsConstants.au3> Example() Func Example() Local $idItem, $idTreeView Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES) GUICreate("TreeView Get First Item", 400, 300) $idTreeView = GUICtrlCreateTreeView(2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE) GUISetState(@SW_SHOW) _GUICtrlTreeView_BeginUpdate($idTreeview) For $x = 1 To 10 $idItem = GUICtrlCreateTreeViewItem(StringFormat("[%02d] New Item", $x), $idTreeView) Next _GUICtrlTreeView_EndUpdate($idTreeview) Local $hItem = _GUICtrlTreeView_GetFirstItem($idTreeview) Local $sText = "" Local $hItem7=0 ;sometimes show correct values sometimes no. same IsHWnd issue. For $i = 0 To _GUICtrlTreeView_GetCount($idTreeview) - 1 $sText = _GUICtrlTreeView_GetText(($idTreeview), $hItem) ConsoleWrite($sText & @TAB & @TAB & @TAB & $hItem & @CRLF) $hItem = _GUICtrlTreeView_GetNext(($idTreeview), $hItem) If $i=5 Then $hItem7=$hItem Next Local $tStruct = DllStructCreate("handle item") DllStructSetData($tStruct, 1, $hItem7) Local $hItem = DllStructGetData($tStruct, 1) If Not IsHWnd($hItem) Then MsgBox(0, "I'm not a Window Handle :(", "TreeView Item Handle: " & $hItem & @CRLF & "IsHWnd(" & $hItem & ")=" & IsHWnd($hItem) & @CRLF & _ "Value 7: " & _GUICtrlTreeView_GetText($idTreeview, $hItem) & @CRLF & @CRLF & _ "The Value must be wrong sometimes. " & @CRLF & @CRLF & "Make sure to run many times to get the issue." & @CRLF) Else MsgBox(0, "this will not be shown", $hItem & @CRLF & "Value: " & _GUICtrlTreeView_GetText($idTreeview, $hItem)) EndIf ; Loop until the user exits. Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() EndFunc ;==>Example Here is a example removing IsWnd verification of _GUICtrlTreeView_GetText2 that makes work all right. expandcollapse popup#AutoIt3Wrapper_UseX64=y #include <GUIConstantsEx.au3> #include <GuiImageList.au3> #include <GuiTreeView.au3> #include <MsgBoxConstants.au3> #include <WindowsConstants.au3> Global $g_hImage, $g_hStateImage Example() Func Example() Local $ahItem[10], $aidChildItem[30], $iYItem = 0, $iRand, $idTreeView Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES) GUICreate("TreeView Get Text", 400, 300) $idTreeView = GUICtrlCreateTreeView(2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE) GUISetState(@SW_SHOW) _GUICtrlTreeView_BeginUpdate($idTreeView) For $x = 0 To 9 $ahItem[$x] = _GUICtrlTreeView_Add($idTreeView, 0, StringFormat("[%02d] New Item", $x), 4, 5) Next _GUICtrlTreeView_EndUpdate($idTreeView) _GUICtrlTreeView_SelectItem($idTreeView, $ahItem[0]) _GUICtrlTreeView_SetStateImageIndex($idTreeView, $ahItem[0], 2) Local $iRand = 7 MsgBox($MB_SYSTEMMODAL, "It Fails sometimes", StringFormat("Text for Item %d: \n %-40s", $iRand, _GUICtrlTreeView_GetText($idTreeView, $ahItem[$iRand]))) MsgBox($MB_SYSTEMMODAL, "This Always Fine", StringFormat("Text for Item %d: \n %-40s", $iRand, _GUICtrlTreeView_GetText2($idTreeView, $ahItem[$iRand]))) ; Loop until the user exits. Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() EndFunc ;==>Example Func _GUICtrlTreeView_GetText2($hWnd, $hItem = 0) ;~ If Not IsHWnd($hItem) Then $hItem = _GUICtrlTreeView_GetItemHandle($hWnd, $hItem) ;remove this to make work all correctly If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) If $hItem = 0x00000000 Then Return SetError(1, 1, "") Local $tTVITEM = DllStructCreate($tagTVITEMEX) Local $tText Local $bUnicode = _GUICtrlTreeView_GetUnicodeFormat($hWnd) If $bUnicode 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, $__g_hTVLastWnd) 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 $bUnicode 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 Saludos Danp2 and FrancescoDiMuro 2 Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
Deye Posted October 7, 2018 Share Posted October 7, 2018 I didn't test but I think it is all coming from __GUICtrlTreeView_AddItem($hWnd If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) should go in before starting off this point Local $hItem, $hItemID = 0 If $hRelative <> 0x00000000 Then Switch $iMethod Case $TVNA_ADD, $TVNA_ADDFIRST $hItem = _GUICtrlTreeView_GetParentHandle($hWnd, $hRelative) might as well be the struct to blame (none specific ..) for needing to have in all the functions these validations .. Deye Link to comment Share on other sites More sharing options...
Deye Posted October 7, 2018 Share Posted October 7, 2018 another thing maybe a better approach will be to try and incorporate and depend more on: https://docs.microsoft.com/en-us/windows/desktop/Controls/tvn-getdispinfo with TVIF_DI_SETITEM and LPSTR_TEXTCALLBACK that will surely take care of many things and make all the treeview functions lighter Deye Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted October 13, 2018 Author Moderators Share Posted October 13, 2018 Hi, After a LOT of detective work I have got to the bottom of the problem - in fact there were 2 points of failure (that I have discovered so far!): - 1. I was using GUICtrlSendToDummy to pass the handle of the element to expand from the message handler to the code which did all the work - it appears this is limited to 32 bits and so the 64bit handle was not correctly passed. Simple to workaround - use a Global variable to hold the handle instead. - 2. The second is more difficult to fix. It seems _GUICtrlTreeView_DisplayRectEx does not like x64 handles either, but as yet I have not found a solution as it requires the handle of the item . Thanks to the responders above - I will keep the thread updated with any new information. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
Danyfirex Posted October 13, 2018 Share Posted October 13, 2018 I was checking deeply. and I've noticed that _GUICtrlTreeView_GetItemHandle has an issue exactly in GUICtrlGetHandle because sometimes it returns a value where it should not return a value. (Just fail in x64 compiled version) But all this could be avoided with my first answer because it's related to the way of using IsHWnd. anyway the solution should be rewrite _GUICtrlTreeView_GetItemHandle. About _GUICtrlTreeView_DisplayRectEx You just need to write a handle to the Rect structure. of course it need to be inside of _GUICtrlTreeView_DisplayRectEx You can't write the x64 handle to the Rect structure due it use long types so you get your x64 value casted. But you can overwrite first two members this way. Local $tHandle=DllStructCreate("handle hItem",DllStructGetPtr($tRECT)) DllStructSetData($tHandle, "hItem", $hItem) PD: Sorry for not using sintaxis highlighter my slow connection is unable to load the feature. Saludos Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
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