Birch
Members-
Posts
8 -
Joined
-
Last visited
Birch's Achievements
Seeker (1/7)
0
Reputation
-
Getting List Box selected item from another app
Birch replied to Birch's topic in AutoIt General Help and Support
Thanks for noticing this for me. It did look like a list box, so I went and made an ass of myself and umption. However, even correcting for this, it still seems to not be working in the same way. CODEOpt("WinWaitDelay",100)Opt("WinTitleMatchMode",4) Opt("WinDetectHiddenText",1) Opt("MouseCoordMode",0) #include <GuiConstantsEx.au3> #include <GuiListView.au3> WinWait("Add User Tables","A&vailable Tables:") If Not WinActive("Add User Tables","A&vailable Tables:") Then WinActivate("Add User Tables","A&vailable Tables:") WinWaitActive("Add User Tables","A&vailable Tables:") $hWndListBox = ControlGetHandle("Add User Tables", "", "WindowsForms10.SysListView32.app.0.33c0d9d2") MsgBox(0, "LBHwnd", $hWndListBox) $SelItem = _GUICtrlListView_GetItemTextString($hWndListBox, 1) MsgBox(0,"#SelItems", $SelItem) $SelItem = _GUICtrlListView_GetItemText($hWndListBox, 1) MsgBox(0,"#SelItems", $SelItem) This returns a null string for both _GUICtrlListView_GetItemTextString and _GUICtrlListView_GetItemTextString. Any other thoughts? -
After a long absence from using AutoIT to drive an application under test, I've returned to find that Paul Williams Auto3Lib has been subsumed into the UDF libraries. Yea! to this. However, I seem to be having some issues getting this to work like I was expecting it to. In particular, I'm trying to the get text of the selected item in a ListBox in an application I'm testing. I could probably do this handily enough using the "ControlCommand" function, but for a variety of reasons, I'd like to see if I can get this using the _GUICtrlListBox_ UDFs instead. The code I've got is this CODEOpt("WinWaitDelay",100) Opt("WinTitleMatchMode",4) Opt("WinDetectHiddenText",1) Opt("MouseCoordMode",0) #include <GuiConstantsEx.au3> #include <GuiListBox.au3> WinWait("Add User Tables","A&vailable Tables:") If Not WinActive("Add User Tables","A&vailable Tables:") Then WinActivate("Add User Tables","A&vailable Tables:") WinWaitActive("Add User Tables","A&vailable Tables:") $hWndListBox = ControlGetHandle("Add User Tables", "", "WindowsForms10.SysListView32.app.0.33c0d9d2") MsgBox(0, "LBHwnd", $hWndListBox) $LBItem = _GUICtrlListBox_GetText($hWndListBox, 1) MsgBox(0,"LBItem", $LBItem) ControlGetHandle is returning the correct handle for the list box. However, the _GUICtrlListBox_GetText call is only returning a null string. I am aware of the issues getting information from external applications (e.g., you need to allocate some memory in the external app that you've got a pointer to, then you need to get the info from that memory). However, I thought that Auto3Lib handled all that magic for you. Did that go away when then this got imported into the UDF? Or am I just making a particularly boneheaded mistake?
-
DLL calls that return pointers to an IDispatch interface
Birch replied to Birch's topic in AutoIt General Help and Support
Looking into this, it seems that it's the "idispatch_ptr" in the DllCall statement that causes things to break. Is there any way to get an undocumented, unsupported feature fixed? -
DLL calls that return pointers to an IDispatch interface
Birch replied to Birch's topic in AutoIt General Help and Support
Could you be more specific about which line was causing AutoIT to crash, and any information returned by AutoIT or the system as part of the crash? -
Paul, I just ran a test script to see whether I installed all these new versions correctly. The script ran, but AU3Check gave a lot of warnings like this: >Running AU3Check (1.54.7.0) from:C:\Program Files\AutoIt3\SciTE\.. C:\PROGRA~1\AutoIt3\Include\A3LWinAPI.au3(297,71) : WARNING: $GENERIC_EXECUTE: possibly used before declaration. if BitAND($iAccess, 1) <> 0 then $iDA = BitOR($iDA, $GENERIC_EXECUTE) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ When I went looking for the $GENERIC_EXECUTE constant in the files, I indeed could not find it. The question is - is the def for this missing or did I screw something up installing A3L? Thanks for the help! Charles
-
DLL calls that return pointers to an IDispatch interface
Birch replied to Birch's topic in AutoIt General Help and Support
Thanks! That got me quite a bit farther. At the risk of documenting things, here's what the DllCall code looks like: $result = DllCall("oleacc.dll", "long", "AccessibleObjectFromWindow", "hwnd", $hWnd, "long", $OBJID_WINDOW, "ptr", DllStructGetPtr($IID_IAccessible), "idispatch_ptr", "") $AccObjPtr = $result[4] Also, for anybody who drops by looking for MSAA stuff, none of that will work without a call to CoInitialize first, apparently, so the code ultimately winds up looking like this: Global Const $OBJID_WINDOW = 0x00000000 $IID_IAccessible = DllStructCreate("int;short;short;byte[8]") ;Define the GUID for the IAccessible interface. ;{618736E0-3C3D-11CF-810C-00AA00389B71} DllStructSetData($IID_IAccessible, 1,0x618736E0) DllStructSetData($IID_IAccessible, 2, 0x3C3D) DllStructSetData($IID_IAccessible, 3, 0x11CF) DllStructSetData($IID_IAccessible, 4, 0x81, 1) DllStructSetData($IID_IAccessible, 4, 0xC, 2) DllStructSetData($IID_IAccessible, 4, 0, 3) DllStructSetData($IID_IAccessible, 4, 0xAA, 4) DllStructSetData($IID_IAccessible, 4, 0, 5) DllStructSetData($IID_IAccessible, 4, 0x38, 6) DllStructSetData($IID_IAccessible, 4, 0x9B, 7) DllStructSetData($IID_IAccessible, 4, 0x71, 8) $hWnd = ControlGetHandle("Inbox - Microsoft Outlook","","NetUIHWND1") $COInitResult = DllCall("ole32.dll", "long", "CoInitialize", "ptr", "") $result = DllCall("oleacc.dll", "long", "AccessibleObjectFromWindow", "hwnd", $hWnd, "long", $OBJID_WINDOW, "ptr", DllStructGetPtr($IID_IAccessible), "idispatch_ptr", "") $AccObjPtr = $result[4] if True <> IsObj($AccObjPtr) then ;0x80070057 => invalid argument MsgBox(4096, "Sadness", "This is not an object: " & $AccObjPtr & "; Dll call returned " & Hex($result[0])) endif $oMyError = ObjEvent("AutoIt.Error","MyErrFunc"); Install a custom error handler $accCount = $AccObjPtr.accChildCount $accName = $AccObjPtr.accName() MsgBox(4096, "Maybe", "This works " & $accName & " Child count: " & $accCount) $COInitResult = DllCall("ole32.dll", "long", "CoUnInitialize") ; This is my custom error handler Func MyErrFunc() $HexNumber=hex($oMyError.number,8) Msgbox(0,"","We intercepted a COM Error !" & @CRLF & _ "Number is: " & $HexNumber & @CRLF & _ "Windescription is: " & $oMyError.windescription ) SetError(1); something to check for when this function returns Endfunc Now all I need to do is figure out why $accChild = $AccObjPtr.accChild(1) keeps returning 0x80020009 - "the parameter is incorrect" I'll raise that in a different thread, though -
Is it possible to turn pointers to IDispatch interfaces returned from a DLL call (particularly the MSAA AccessibleObjectFromWindow call) into Objects, at least as far as AutoIT is concerned? Or am I going to have to wrap this in a COM object so that I can instantiate this using ObjCreate? Or, am I just missing something that should be obvious? Here's the code I've got so far. Ignore the fact that I'm targeting Outlook for right now. That's just a stand-in for the app I'm eventually going to have to automate. Global Const $OBJID_WINDOW = 0x00000000 $IID_IDispatch = DllStructCreate("int;short;short;byte[8]") ; IID_IDispatch = {00020400-0000-0000-C000-000000000046} DllStructSetData($IID_IDispatch, 1,0x00020400) DllStructSetData($IID_IDispatch, 2, 0) DllStructSetData($IID_IDispatch, 3, 0) DllStructSetData($IID_IDispatch, 4, 192, 1); dec 192 = hex C0 DllStructSetData($IID_IDispatch, 4, 0, 2) DllStructSetData($IID_IDispatch, 4, 0, 3) DllStructSetData($IID_IDispatch, 4, 0, 4) DllStructSetData($IID_IDispatch, 4, 0, 5) DllStructSetData($IID_IDispatch, 4, 0, 6) DllStructSetData($IID_IDispatch, 4, 0, 7) DllStructSetData($IID_IDispatch, 4, 70, 8);dec 70 = hex 46 $hWnd = ControlGetHandle("Inbox - Microsoft Outlook","","NetUIHWND1") $AccObjPtr = DllStructCreate("ptr") $result = DllCall("oleacc.dll", "long", "AccessibleObjectFromWindow", "hwnd", $hWnd, "long", $OBJID_WINDOW, "ptr", DllStructGetPtr($IID_IDispatch), "ptr", DllStructGetPtr($AccObjPtr)) $AccObj=DllStructGetData($AccObjPtr,1) if IsObj($AccObj) then MsgBox(4096, "Success", "This is an object") else MsgBox(4096, "Sadness", "This is not an object: " & $AccObj & "; Dll call returned " & Hex($result[0])) endif ;The following does not work, $AccObj is not an obj ;$accName = $AccObj.accName ;MsgBox(4096, "Maybe", "Does this work? " & $accName) If this is something I'm going to have to wrap, does anybody know of an existant wrapping of this? I'd hate to go through all that if somebody else has already published a wrapper. Thanks in advance! CVC
-
He already has, sort of. I've already posted this in response to your question in a separate thread, but I wanted to cross-polinate in case some of the folks here wanted to know, too. To get stuff from context menus, try this: #include <A3LMenu.au3>;the source of much goodness. ;Can be found here: ;http://www.autoitscript.com/forum/index.php?showtopic=33677 Opt("WinTitleMatchMode", 4); Option required to be able to match window by classname ; Code to launch the context menu ; this can be arbitrarily complex, but don't forget that using ; ControlSend("<title", "", "<controlID>", "{APPSKEY}") can be just as effective $hWnd = WinGetHandle("classname=#32768"); Part one of the magic - this is the classname for popups. $hMenu = "0x" & Hex(_SendMessage($hWnd, $MF_GETHANDLE, 0, 0)); Part two of the magic ; where _SendMessage is found in Paul Campbell's Windows SDK ; library routines (A3LWinSDK.au3) $text = _Menu_GetMenuString($hMenu, 0, $MF_BYPOSITION) MsgBox(4096,"", "Menu item text: " & $text) Also, to give proper credit to everybody, I would like to point out that the second part of the magic was lifted from Paul Campbell's _PopupScan() function (also in A3LWinSDK.au3), though I would not have known to steal it without Christian ASTOR's comment and Kuc's reply in this thread: http://groups.google.com/group/microsoft.p...bf6f15e26a7d3a/ I would further like to point out that Mr. Campbell has some interesting code in A3LMenu.au3 that makes me wonder how difficult it will be to select items from submenus of context menus. However, since I don't have any applications right now that have that feature, I'll not worry about that until I get there. I would finally like to point out that Mr. Campbell has also done some very interesting things with ToolbarWindow32 in case that's a sticking point for you as well. To sum up . . . - use Paul Williams AU3 libraries - "classname=#32768" is the secret to getting the handle to the context menu window - (_SendMessage($hWnd, $MF_GETHANDLE, 0, 0)) is the secret to getting the handle to the context menu - hope this helps - thank you again, Mr. Campbell!