Warpi Posted May 13, 2007 Posted May 13, 2007 Hi all! I spent the whole day on searching and reading about how can I send a mouse double click SysListView32 Control, with a selected item, but cannot find anything. Someone on this forum asked about the same problem a long time ago, but finally ... well I didn't read a solution in that thread. I read a lot about windows msgs, may be I have to learn more about that because I am not familiar with them. What I have is a window that opens a SysListView32 control. Using the ControlListView commands I can, for instance, read and select the items on the list. The way to trigger an action from this control is to double click in one of its items. MouseClick is not good for this because the items change from time to time and same for the control position. Even more, the windows has scrollbars, so the item I need may be is not on sight. More or less the same for ControlClick, as it need some coords, if not it will click in the center of the control, hence, selecting a wrong item. So, once I have selected the right item, how can I trigger a double click for the SysListView32 control, cannot I just "Send({DOUBLE_CLICK})" to it? Thanks in advance.
PsaltyDS Posted May 13, 2007 Posted May 13, 2007 Get the control ID or ClassNameNN of the control with AutoItInfo tool and use it with ControlClick(): ControlClick("Your Window", "Some window text", "SysListView321", "Left", 2) Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Warpi Posted May 14, 2007 Author Posted May 14, 2007 Get the control ID or ClassNameNN of the control with AutoItInfo tool and use it with ControlClick():That was what I first thought, and I started coding with that in mind ... but it does not work as I expected ControlClick() without coords just click in the center position of the control, so it select the item under its click which is 99.999% of the time the one I do not want Giving the right coordinates to it is a pain, as they are not fixed An option is to check in which row is the item I want to select, to calculate the coords and to use ControlClick crossing your fingers. A problem with this approach is that the control has scroll bars, so I have to be able to move them too
PaulIA Posted May 14, 2007 Posted May 14, 2007 (edited) That was what I first thought, and I started coding with that in mind ... but it does not work as I expected ControlClick() without coords just click in the center position of the control, so it select the item under its click which is 99.999% of the time the one I do not want Giving the right coordinates to it is a pain, as they are not fixed An option is to check in which row is the item I want to select, to calculate the coords and to use ControlClick crossing your fingers. A problem with this approach is that the control has scroll bars, so I have to be able to move them too Welcome to the forum. ControlClick is virtually useless on a ListView control and I'm not sure why it was even offered as a solution. You have to get the bounding rectangle of the item you want to click on and the only reliable way to do that is through the ListView API.Auto3Lib has full support for the ListView control, including the ability to right/left/double click, etc. You can also right click an item in a ListView and control any popup menus. Plenty of examples and an AutoIt style help file are included. Check my signature for the download and feel free to PM me if you have any problems. Edited May 14, 2007 by PaulIA Auto3Lib: A library of over 1200 functions for AutoIt
Warpi Posted May 14, 2007 Author Posted May 14, 2007 Welcome to the forum.Thanks Auto3Lib has full support for the ListView control, including the ability to right/left/double click, etc.Thank you very much for pointing me to your lib, Paul, it seems you have done a very good job, I will PM you if I cannot find a solution on myself.
PsaltyDS Posted May 14, 2007 Posted May 14, 2007 ControlClick is virtually useless on a ListView control and I'm not sure why it was even offered as a solution. You have to get the bounding rectangle of the item you want to click on and the only reliable way to do that is through the ListView API.Although I put "SysListView321" in my example, I was actually thinking of the control ID of the ListViewItem, not the parent ListView. Does that still present the same problem using ControlClick() with the control ID of the ListViewItem? Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
PaulIA Posted May 14, 2007 Posted May 14, 2007 (edited) Although I put "SysListView321" in my example, I was actually thinking of the control ID of the ListViewItem, not the parent ListView. Does that still present the same problem using ControlClick() with the control ID of the ListViewItem? AutoIt does a lot of things to native Windows controls to make them easier for people to use. Assigning control IDs to ListView items is one of them. In the world outside of AutoIt, ListView items do not have control IDs and you reference them by their zero based index in the control. To click on an item, you have to make sure that it is visible, get the bounding rectangle of the item and then click within that rectangle. The _ListView_ClickItem UDF in Auto3Lib does all that for you. Edited May 14, 2007 by PaulIA Auto3Lib: A library of over 1200 functions for AutoIt
PsaltyDS Posted May 14, 2007 Posted May 14, 2007 I see, said the blind man... Thanks for the clarification. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
eltorro Posted May 14, 2007 Posted May 14, 2007 (edited) Here's something to try:expandcollapse popupFunc ListClick($hListView, $iItem = 0) Local $x, $y, $pos = _GuiCtrlListViewGetSubItemRect($hListView,$iItem) if IsArray($pos) Then Local $mPos = MouseGetPos() Local $wPos = _WinGetClientPos("","") Local $cPos = ControlGetPos("","",$hListView) $x = $wPos[0]+$cpos[0]+$pos[0]+10 ;this will check a check box $y = $wPos[1]+$cpos[1]+$pos[1]+7 MouseClick("primary",$x,$y,1,0) MouseMove($mPos[0],$mPos[1],0) EndIf EndFunc ;get the client pos relative to the desktop. Func _WinGetClientPos($sTitle="",$sText= "") Local $aPos[2] Local $wPos = WinGetPos($sTitle,$sText) Local $wSize = WinGetClientSize($sTitle,$sText) $aPos[0] = $wPos[0]+($wPos[2]-$wSize[0]) $aPos[1] = $wPos[1]+($wPos[3]-$wSize[1]) Return $aPos EndFunc ;=============================================================================== ; Function Name: _GUICtrlListViewGetSubItemRect ; Description: Get the bounding rect of a listview item ; Parameter(s): $h_listview - IN - ; $row - IN - ; $col - IN - ; Requirement(s): ; Return Value(s): an array with x ,y (relative to control), w,h or 0 on failure ; User CallTip: ; Author(s): ; Note(s): ;=============================================================================== Func _GUICtrlListViewGetSubItemRect($hlistview, $row, $col=0) Local $h_listview = 0 If Not IsHWnd($hlistview) then $h_ListView = HWnd($hListView) If @error then Return SetError(1,0,0) Else $h_listview = $hListView EndIf Local $rectangle, $rv,$aRect[4] $rectangle = DllStructCreate("int;int;int;int") ;left, top, right, bottom DllStructSetData($rectangle, 1, $LVIR_BOUNDS) DllStructSetData($rectangle, 2, $col) If IsHWnd($h_listview) Then Local $a_ret = DllCall("user32.dll", "int", "SendMessage", "hwnd", $h_listview, "int", $LVM_GETSUBITEMRECT, "int", $row, "ptr", DllStructGetPtr($rectangle)) $rv = $a_ret[0] Else $rv = GUICtrlSendMsg($h_listview, $LVM_GETSUBITEMRECT, $row, DllStructGetPtr($rectangle)) EndIf if $rv Then ReDim $aRect[4] $aRect[0] = DllStructGetData($rectangle, 1) $aRect[1] = DllStructGetData($rectangle, 2) $aRect[2] = DllStructGetData($rectangle, 3) $aRect[3] = DllStructGetData($rectangle, 4) - $aRect[1] $rectangle = 0 Sleep(10) Return $aRect EndIf Return 0 EndFunc ;==>_GUICtrlListViewGetSubItemRec ;===============================================================================Edit: removed a gui name. Edited May 14, 2007 by eltorro Regards, [indent]ElTorro[/indent][font="Book"] Decide, Commit, Achieve[/font]_ConfigIO.au3Language Translation --uses Google(tm) MsgBox Move XML wrapper UDF XML2TreeView Zip functionality Split your GUI Save Print ScreenZipPluginEdit In Place listviewSome of my scripts on Google code
Warpi Posted May 14, 2007 Author Posted May 14, 2007 Auto3Lib has full support for the ListView control, ...Just one word: impressive.It works, with just one function: _ListView_ClickItem()Many many thanks, Paul.BTW, eltoro, thanks for you code, however I prefer instead to use just a function call
eltorro Posted May 14, 2007 Posted May 14, 2007 That's ok. Essentially, it is one call though. ListClick($hListView, $iItem ) Regards, [indent]ElTorro[/indent][font="Book"] Decide, Commit, Achieve[/font]_ConfigIO.au3Language Translation --uses Google(tm) MsgBox Move XML wrapper UDF XML2TreeView Zip functionality Split your GUI Save Print ScreenZipPluginEdit In Place listviewSome of my scripts on Google code
RS200Z Posted November 26, 2007 Posted November 26, 2007 I have been using _ListView_ClickItem function from A3Lib for some time now. With the release of AutoIt v3.2.10.0, almost all functions of A3Lib (except String) are suppose to be included in AutoIt already. However, I couldn't find a similar function for this. Can some expert point me to the right direction?
PsaltyDS Posted November 26, 2007 Posted November 26, 2007 I have been using _ListView_ClickItem function from A3Lib for some time now. With the release of AutoIt v3.2.10.0, almost all functions of A3Lib (except String) are suppose to be included in AutoIt already. However, I couldn't find a similar function for this. Can some expert point me to the right direction?There are now functions in the _GuiCtrlListView_* section to select items (which is what happens when you click on them). Because a ListView can have multiple items selected, and the item wanted may not be visible (if the ListView is scrolled), I think the process is to select the item(s) with _GuiCtrlListView_SetItemSelected() instead. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
LOULOU Posted November 26, 2007 Posted November 26, 2007 There are now functions in the _GuiCtrlListView_* section to select items (which is what happens when you click on them). Because a ListView can have multiple items selected, and the item wanted may not be visible (if the ListView is scrolled), I think the process is to select the item(s) with _GuiCtrlListView_SetItemSelected() instead. It dosen't work with _GuiCtrlListView_SetItemSelected() , only the item is selected not like in library from Paul1AMay be ithis function has to be supported in udf but actually not .
PsaltyDS Posted November 26, 2007 Posted November 26, 2007 It dosen't work with _GuiCtrlListView_SetItemSelected() , only the item is selected not like in library from Paul1AMay be ithis function has to be supported in udf but actually not .I don't have time to set up a demo script to test with right now, my theory was that you would _GuiCtrlListView_SetItemSelected() any item(s) you want selected (which works for you, it appears) and then just ControlClick() the ListView itself (not trying to hit an item). Your scripts GuiGetMsg() loop or event function would be responsible to read the control for which item(s) selected (or the app you are automating).Even if I code a demo, it will be with an internal AuotIt GUI and may not show your situation in automating an external GUI from another app. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Fossil Rock Posted November 26, 2007 Posted November 26, 2007 (edited) Apparently I'm not the only one having to adjust to the new version (nothing wrong with it, just have to modify some code). Well I have this; _ListView_ClickItem($list, _ListView_FindInText($list, $results[$row][1]), "left", False, 2) which double clicks on an item when it finds it (all in one statement). So now I need to replace it with something in the new version. _GuiCtrlListView_SetItemSelected() will select it, the question is... is there a _GUICtrlListView_ClickItem or do I now have to send the clicks separately? I haven't found it in the help file yet, so if you already know - please share. Edited November 26, 2007 by Fossil Rock Agreement is not necessary - thinking for one's self is!
LOULOU Posted November 26, 2007 Posted November 26, 2007 Apparently I'm not the only one having to adjust to the new version (nothing wrong with it, just have to modify some code). Well I have this; _ListView_ClickItem($list, _ListView_FindInText($list, $results[$row][1]), "left", False, 2) which double clicks on an item when it finds it (all in one statement). So now I need to replace it with something in the new version. _GuiCtrlListView_SetItemSelected() will select it, the question is... is there a _GUICtrlListView_ClickItem or do I now have to send the clicks separately? I haven't found it in the help file yet, so if you already know - please share. ]_ListView_ClickItem was in the old version of paul1A lib but now can't be use and was not ported in UDF. Maybe if you are strong in programming you can port the function from the lib to an UDF? For my own i try but i fail to port.
PsaltyDS Posted November 26, 2007 Posted November 26, 2007 I'm not having any trouble selecting items, or reading the selections on command, but I can't figure out how to get any events to fire on the ListView. This is the demo being played with: expandcollapse popup#include <GuiConstantsEx.au3> #include <GuiListView.au3> Opt('MustDeclareVars', 1) Opt("GuiOnEventMode", 1) Global $hGUI, $hListView, $IdButton $hGUI = GUICreate("(Internal) ListView Set Item Selected", 400, 300) GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit") GUICtrlCreateLabel("UDF ListView:", 10, 10, 380, 20) $hListView = _GUICtrlListView_Create($hGUI, "", 10, 40, 380, 200, BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS)) GUICtrlSetOnEvent($hListView, "_ListViewEvent") _GUICtrlListView_AddColumn($hListView, "Items", 100) For $n = 0 To 19 _GUICtrlListView_AddItem($hListView, "Item " & $n) ; Select all even 6 thru 14 If ($n > 5) And ($n < 15) And (Mod($n, 2) = 0) Then _GUICtrlListView_SetItemSelected($hListView, $n) Next $IdButton = GUICtrlCreateButton("Read Data", 150, 260, 100, 30) GUICtrlSetOnEvent(-1, "_ButtonHit") GUISetState() While 1 Sleep(20) WEnd Func _ListViewEvent() ConsoleWrite("Debug: _ListViewEvent() triggered" & @LF) Local $sSelected = _GUICtrlListView_GetSelectedIndices($hListView, False) TrayTip("Selected", $sSelected, 5) EndFunc ;==>_ListViewEvent Func _ButtonHit() ConsoleWrite("Debug: _ButtonHit() triggered" & @LF) Local $sSelected = _GUICtrlListView_GetSelectedIndices($hListView, False) TrayTip("Selected", $sSelected, 5) EndFunc ;==>_ButtonHit Func _Quit() Exit EndFunc ;==>_Quit Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Fossil Rock Posted November 26, 2007 Posted November 26, 2007 ControlClick(_GuiCtrlListView_SetItemSelected($list, _GUICtrlListView_FindInText($list, $results[$row][1])), "", "left", 2) This is my replacement line that selects the correct item, but it doesn't double click it. I'm testing send("{ENTER}") for the click now, but it seems to send the enter before the line is selected. Gotta love those workarounds.... Agreement is not necessary - thinking for one's self is!
PsaltyDS Posted November 26, 2007 Posted November 26, 2007 ControlClick(_GuiCtrlListView_SetItemSelected($list, _GUICtrlListView_FindInText($list, $results[$row][1])), "", "left", 2) This is my replacement line that selects the correct item, but it doesn't double click it. I'm testing send("{ENTER}") for the click now, but it seems to send the enter before the line is selected. Gotta love those workarounds.... The _GuiCtrlListView_SetItemSelected() only returns True or False. How do you use that for WinTitle in your ControlClick()? Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
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