Jump to content

_GUICtrlListView_ClickItem issue ?


Recommended Posts

Hi everybody :)
In the script below, this is what happens when you click the Button :
1) If the horizontal scrollbar was on the left side, then all is good.
2) If the horizontal scrollbar was moved to the middle (or to the right) then the GUI disappears in the background after you clicked the button.

#include <GuiListView.au3>
#include <GuiConstantsEx.au3>

$hGUI = GUICreate("Test", 500, 400)

$idListView = GUICtrlCreateListView("Col0|Col1|Col2|Col3|Col4|Col5|Col6|Col7|Col8|Col9", 10, 10, 480, 300)
For $i = 0 To 9
    _GUICtrlListView_SetColumnWidth($idListView, $i, 200)
Next
$idItem = GUICtrlCreateListViewItem("0|1|2|3|4|5|6|7|8|9", $idListview)

$idButton = GUICtrlCreateButton("Click me", 200, 340, 85, 25)

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop

        Case $idButton ; click when scrollbar is on left, then with scrollbar on right
            _GUICtrlListView_ClickItem($idListView, 0)
    EndSwitch
WEnd

GUIDelete($hGui)

Is it a known behavior of _GUICtrlListView_ClickItem ?
Thanks

Link to post
Share on other sites

Interesting behaviour.  It appears the way the function works is by finding the rectangle area of the indexed item, then clicking in the center of it.  You can see that when you drag the slider to the right as you described, the rectangle area is outside of the window area--if you change the mouse move parameter to true you can see exactly where it is clicking.  Behind the scenes, the MouseMove parameter always moves the mouse there to click, then moves it back if the parameter is False.

As a workaround, I would suggest using ControlFocus & _GUICtrlListView_SetItemSelected; you might also have to use EnsureVisible. 

If you absolutely have to click it then you might have to get a little creative and get the item rectangle coordinates, but instead of clicking the X position, just click the Y position and reference the control X position.

 

Link to post
Share on other sites

Thanks @spudw2k for the confirmation, It's hard to believe it never happened to anyone else during all these years.
I faced this issue in this post 3 days ago. As the problem appeared after having added a ghost column 0 at the left of the LV in a complicated script, then it wasn't easy to know what was the exact cause.

Before presenting the simple script above, I did this to debug :

Script "2u", search "a" (for example), context menu "Show all rows" => F3 to start the search

Modify function _GUICtrlListView_ClickItem() in a COPY of GuiListView.au3
Insert a ConsoleWrite between each of its lines :

Func _GUICtrlListView_ClickItem($hWnd, $iIndex, $sButton = "left", $bMove = False, $iClicks = 1, $iSpeed = 1)
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)

    ConsoleWrite("1  " & WinActive("[ACTIVE]") & @crlf)
    _GUICtrlListView_EnsureVisible($hWnd, $iIndex, False)
    ConsoleWrite("2  " & WinActive("[ACTIVE]") & @crlf)
    Local $tRECT = _GUICtrlListView_GetItemRectEx($hWnd, $iIndex, $LVIR_LABEL)
    ConsoleWrite("3  " & WinActive("[ACTIVE]") & @crlf)
    Local $tPoint = _WinAPI_PointFromRect($tRECT, True)
etc...

Launch script "2u"

Horizontal Scrollbar on the left, Console display :

1  0x02070622
2  0x02070622
3  0x02070622
4  0x02070622
5  0x02070622
6  0x02070622
7  0x02070622
8  0x02070622
9  0x02070622
10 0x02070622
11 0x02070622
12 0x02070622
13 0x02070622
14 0x02070622
15 0x02070622
16 0x02070622

Horizontal Scrollbar on the right, Console display :

1  0x02070622
2  0x02070622
3  0x02070622
4  0x02070622
5  0x02070622
6  0x02070622
7  0x02070622
8  0x02070622
9  0x02070622
10 0x02070622
11 0x02070622
12 0x006F04FC => change of handle, GUI is no more the active window
13 0x006F04FC
14 0x006F04FC
15 0x006F04FC
16 0x006F04FC

So issue happens between step 11 and 12 when F3 is pressed and Horizontal Scrollbar is on the right (GUI is no more the active window)
In the function _GUICtrlListView_ClickItem(), the line between step 11 and 12 is :

MouseClick($sButton, $iX, $iY, $iClicks, $iSpeed)

I added just after it :

ConsoleWrite("$sButton = " & $sButton & "   $iX = " & $iX & "   $iY = " & $iY & "   $iClicks = " & $iClicks & "   $iSpeed = " & $iSpeed & @crlf)

Example of result when ok (Horizontal Scrollbar on the left)

$sButton = left   $iX = 202   $iY = 130   $iClicks = 1   $iSpeed = 1

1214044726_1-goodclick-scrollbaronleft.png.db0aacd66e96717c3b527bb9425221df.png

Example of result when bad behavior (Horizontal Scrollbar on the right) and the GUI disappears (I restored it from the tray in the pic below) :

$sButton = left   $iX = 106   $iY = 160   $iClicks = 1   $iSpeed = 1

892895263_2-badclick-scrollbaronright.png.5ca52b9fd494436ea7ab5d2661f1d9f2.png

So I moved the horizontal scrollbar 78 pixels on the right and the function clicks on 96 pixels (202-106) on the left, outside GUI (coords to be reconfirmed)

55 minutes ago, spudw2k said:

f you absolutely have to click it then you might have to get a little creative

Count on me for that :D

Now I have to add a little post in the other thread, linking to this one, so LarsJ won't investigate in case he reads it.
Thanks for your confirmation & advices.

Link to post
Share on other sites

Hello, I fixed like this:

#include <GuiListView.au3>
#include <GuiConstantsEx.au3>

$hGUI = GUICreate("Test", 500, 400)

$idListView = GUICtrlCreateListView("Col0|Col1|Col2|Col3|Col4|Col5|Col6|Col7|Col8|Col9", 10, 10, 480, 300)
For $i = 1 To 9
    _GUICtrlListView_SetColumnWidth($idListView, $i, 200)
Next
$idItem1 = GUICtrlCreateListViewItem("0|1|2|3|4|5|6|7|8|9", $idListView)
$idItem2 = GUICtrlCreateListViewItem("0|1|2|3|4|5|6|7|8|9", $idListView)

$idButton = GUICtrlCreateButton("Click me", 200, 340, 85, 25)

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop

        Case $idButton ; click when scrollbar is on left, then with scrollbar on right
            _GUICtrlListView_ClickItemMod($idListView, 0)
    EndSwitch
WEnd

GUIDelete($hGUI)


Func _GUICtrlListView_ClickItemMod($hWnd, $iIndex, $sButton = "left", $bMove = False, $iClicks = 1, $iSpeed = 1)
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)

    _GUICtrlListView_EnsureVisible($hWnd, $iIndex, False)
    Local $tRECT = _GUICtrlListView_GetItemRectEx($hWnd, $iIndex, $LVIR_LABEL)
    Local $tPoint = _WinAPI_PointFromRect($tRECT, True)
    Local $iXPlus = DllStructGetData($tRECT, "Left") < 0 ? DllStructGetData($tRECT, "Left") * -1 : 0
    $tPoint = _WinAPI_ClientToScreen($hWnd, $tPoint)
    Local $iX, $iY
    _WinAPI_GetXYFromPoint($tPoint, $iX, $iY)
    Local $iMode = Opt("MouseCoordMode", 1)
    If Not $bMove Then
        Local $aPos = MouseGetPos()
        _WinAPI_ShowCursor(False)
        MouseClick($sButton, $iX + $iXPlus, $iY, $iClicks, $iSpeed)
        MouseMove($aPos[0], $aPos[1], 0)
        _WinAPI_ShowCursor(True)
    Else
        MouseClick($sButton, $iX + $iXPlus, $iY, $iClicks, $iSpeed)
    EndIf
    Opt("MouseCoordMode", $iMode)
EndFunc   ;==>_GUICtrlListView_ClickItemMod

 

Saludos

Link to post
Share on other sites
Posted (edited)

Hello @Danyfirex

Thanks for your input.
But In my case (column 0 hidden), _GUICtrlListView_ClickItemMod() isn't quite enough to have the row selected when the horizontal scrollbar has been moved to the right (even just a bit).

After adding 2 ConsoleWrite to _GUICtrlListView_ClickItemMod() , here are the results :

Local $tRECT = ...
ConsoleWrite('DllStructGetData($tRECT, "Left") = ' & DllStructGetData($tRECT, "Left") & @crlf)

MouseClick(...)
ConsoleWrite("$iX = " & $iX & "   $iXPlus = " & $iXPlus & "   $iX + $iXPlus = " & $iX + $iXPlus & "   $iY = " & $iY & @crlf)

We launch the script (the one in your post) and drag column 0 divider to the left, so column 0 is now hidden, then :

1) With horizontal scrollbar completely to the left, we click the button and the row becomes selected :

130797251_3-hidecol0-scrollbaronleft(selection).png.93bcc909f80b2f4d9eb34c38b5f5ce82.png

DllStructGetData($tRECT, "Left") = 4
$iX = 277   $iXPlus = 0   $iX + $iXPlus = 277   $iY = 222

2) Deselect the row, then with horizontal scrollbar dragged just a little bit to the right, button clicked, row is not selected  :

259620648_4-hidecol0-scrollbarnotonleft(noselection).png.73aebd2905fe536fee95cbdd4f0283ed.png

DllStructGetData($tRECT, "Left") = -16
$iX = 257   $iXPlus = 16   $iX + $iXPlus = 273   $iY = 222

Maybe the rough solution would be to add sometimes 4 pixels to $iXPlus ?

Edit : here is a result that show a case where 273 should be "readjusted" to 277 :

DllStructGetData($tRECT, "Left") = 4
$iX = 277   $iXPlus = 0   $iX + $iXPlus = 277   $iY = 222
DllStructGetData($tRECT, "Left") = 0
$iX = 273   $iXPlus = 0   $iX + $iXPlus = 273   $iY = 222

 

Edited by pixelsearch
Link to post
Share on other sites

May be this ?

Func _GUICtrlListView_ClickItemMod($hWnd, $iIndex, $sButton = "left", $bMove = False, $iClicks = 1, $iSpeed = 1)
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)

    _GUICtrlListView_EnsureVisible($hWnd, $iIndex, False)
    Local $tRECT = _GUICtrlListView_GetItemRectEx($hWnd, $iIndex, $LVIR_LABEL)
    Local $tPoint = _WinAPI_PointFromRect($tRECT, True)
    $tPoint = _WinAPI_ClientToScreen($hWnd, $tPoint)
    Local $iX, $iY
    _WinAPI_GetXYFromPoint($tPoint, $iX, $iY)
    Local $tCtrl = _WinAPI_GetWindowInfo($hWnd)
    $iX = DllStructGetData($tCtrl, 'rClient', 1) + 4

    Local $iMode = Opt("MouseCoordMode", 1)
    If Not $bMove Then
        Local $aPos = MouseGetPos()
        _WinAPI_ShowCursor(False)
        MouseClick($sButton, $iX, $iY, $iClicks, $iSpeed)
        MouseMove($aPos[0], $aPos[1], 0)
        _WinAPI_ShowCursor(True)
    Else
        MouseClick($sButton, $iX, $iY, $iClicks, $iSpeed)
    EndIf
    Opt("MouseCoordMode", $iMode)
EndFunc   ;==>_GUICtrlListView_ClickItemMod

 

Link to post
Share on other sites

Is it win64 ?

Maybe it is similar issue which @LarsJ help me fix recently but with treeview... ?

Edited by mLipok

Signature beginning:
Please remember: "AutoIt".....  Wondering who uses AutoIt and what it can be used for ?
* GHAPI UDF - modest beginning - communication with GitHub REST API Forum Rules *
Include Dependency Tree (Tool for analyzing script relations)
ADO.au3 UDF     POP3.au3 UDF     XML.au3 UDF    How to use IE.au3  UDF with  AutoIt v3.3.14.x  for other useful stuff click the following button

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library *

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) *

PDF Related:How to get reference to PDF object embeded in IE *

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2021-03-17

Link to post
Share on other sites
Posted (edited)

@mLipok no it's not win64, but you know, LarsJ often got in his scripts this "4 pixels thing" when it comes to column 0, for example in one of his scripts :

If $iSubItem Then
    aRect = _GUICtrlListView_GetSubItemRect( $hListView, $iItem, $iSubItem ) ; Subitem rectangle
Else ; $iSubItem = 0, the listview item, first column
    ; This calculation of $aRect for the listview item is necessary to get
    ; things to work properly if $LVS_EX_HEADERDRAGDROP style is applied.
    $aRect = _GUICtrlListView_GetItemRect( $hListView, $iItem, 2 ) ; 2 - The bounding rectangle of the item text
    $aRect[0] -= 4
EndIf

And yes, I also got the $LVS_EX_HEADERDRAGDROP style :D

@Nine where do you find these incredible messages ?
I never heard of WINDOWINFO structure until now and it seems so useful, thanks for sharing !

So with your function, results look promising in all cases :

============
Col 0 hidden
============

Scrollbar placed at left :
$iX = 277
$iX = 279   $iY = 222

Scrollbar placed at Right :
$iX = -1047
$iX = 279   $iY = 222

=============
Col 0 visible
=============

Scrollbar placed at left :
$iX = 298
$iX = 279   $iY = 222

Scrollbar placed at right :
$iX = -1068
$iX = 279   $iY = 222

279 in all cases, what to ask for more ?
Especially the working 277 (in precedent post) seems "a bit too close" of LV border.

Guys, thank you so much. your 3 answers are really helpful. I would like to "mark as solution" the 3 of you but it seems impossible (I tried on 2 of you before I saw Nine post and didn't succeed) . Have a great evening :bye:

Edit: I wonder if a Trac ticket should be opened for this _GUICtrlListView_ClickItem() function

Edited by pixelsearch
Link to post
Share on other sites

Glad you like :)

10 minutes ago, pixelsearch said:

I wonder if a Trac ticket should be opened

Yep there is definitely a bug there. À tout seigneur, tout honneur :  I will let you write it.

Link to post
Share on other sites

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...