TimRude Posted October 16, 2022 Share Posted October 16, 2022 The code below displays the beginnings of a GUI with a ListView populated with 14 boxes (pseudo thumbnails), and the user can click and select only one icon at a time. However, I don't see an easy way to identify (from the GUIGetMsg function) when an item in my ListView has been clicked. All of the click messages just return the handle of the GUI, nowhere does it return the handle of the ListView control. What vital piece of the puzzle am I missing so that I can know when the user has clicked (anywhere) on the ListView? Since I limit the user to only selecting a single ListView item at a time, I can easily figure out which ListView item is selected if any (by using _GUICtrlListView_GetSelectedIndices) once I know the ListView has been clicked. I suppose I can maybe look at the mouse X & Y position returned in the array by the GUIGetMsg(1) call and then keep careful track of how the ListView is positioned and sized to see if the click fell inside that area, but is that really how this is normally done? Surely there has to be a better way of signaling a click on a ListView, isn't there? expandcollapse popup#include <GUIConstantsEx.au3> #include <GuiImageList.au3> #include <GuiListView.au3> #include <MsgBoxConstants.au3> #include <WindowsConstants.au3> #include <Array.au3> ; Create GUI with a ListView control Global $hGUI = GUICreate("ListView", 700, 500, -1, -1, $WS_OVERLAPPEDWINDOW) Global $hListView = _GUICtrlListView_Create($hGUI, "", 2, 2, 630, 420, BitOR($LVS_ICON, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS)) GUISetState(@SW_SHOW, $hGUI) ; Create and load ImageList control with psuedo thumbnails Global $SizeX = 160 ; width of each thumbnail Global $SizeY = 100 ; height of each thumbnail Global $hImgLst = _GUIImageList_Create($SizeX, $SizeY) Local $BoxColor = 0xFF0000 For $i = 0 To 13 ; create 14 pseudo thumbnails (boxes of varying colors) _GUIImageList_Add($hImgLst, _GUICtrlListView_CreateSolidBitMap($hListView, $BoxColor - ($i * 0x139d76), $SizeX, $SizeY)) Next _GUICtrlListView_SetImageList($hListView, $hImgLst, 0) ; Add the thumbnail images as items to the ListView For $i = 0 To 13 _GUICtrlListView_AddItem($hListView, "Item " & $i, $i) Next ; Process GUI messages, looping until the user exits Do Local $Msg = "" Local $aMsg = GUIGetMsg(1) Local $MsgNum = $aMsg[0] Switch $MsgNum Case 0 $Msg = "" ; $GUI_EVENT_NONE Case -3 $Msg = "$GUI_EVENT_CLOSE" Case -4 $Msg = "$GUI_EVENT_MINIMIZE" Case -5 $Msg = "$GUI_EVENT_RESTORE" Case -6 $Msg = "$GUI_EVENT_MAXIMIZE" Case -7 $Msg = "$GUI_EVENT_PRIMARYDOWN" Case -8 $Msg = "$GUI_EVENT_PRIMARYUP" Case -9 $Msg = "$GUI_EVENT_SECONDARYDOWN" Case -10 $Msg = "$GUI_EVENT_SECONDARYUP" Case -11 $Msg = "" ; $GUI_EVENT_MOUSEMOVE Case -12 $Msg = "$GUI_EVENT_RESIZED" Case -13 $Msg = "$GUI_EVENT_DROPPED" Case Else $Msg = $MsgNum EndSwitch If $Msg <> "" Then ConsoleWrite($Msg & " [" & _ArrayToString($aMsg) & "]" & @CRLF) Until $MsgNum = $GUI_EVENT_CLOSE GUIDelete() Exit Link to comment Share on other sites More sharing options...
Solution Dan_555 Posted October 16, 2022 Solution Share Posted October 16, 2022 I had a code which needed a doubleclick on the LW to work. Here is a modified code to use the single click: expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <GuiListView.au3> Local $test[5][2] = [['.au3', 'AutoIt'], ['.ahk', 'Auto Hotkey'], ['.txt', 'text'],['.sdlbas', 'Sdl Basic'], ['.html', 'Webpage']] $Form1 = GUICreate("Create New File", 210, 307, -1,-1, $WS_CAPTION , $WS_EX_TOOLWINDOW) $List = GUICtrlCreateListView("", 5,5, 200, 200) _GUICtrlListView_InsertColumn($List, 0, "Extension", 80) _GUICtrlListView_InsertColumn($List, 1, "Name", 130) _GUICtrlListView_AddArray($List, $test) $Button1 = GUICtrlCreateButton("Ok", 16, 214, 45, 26) $Button2 = GUICtrlCreateButton("Cancel", 140, 214, 45, 26) $cDummy = GUICtrlCreateDummy() GUISetState(@SW_SHOW) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE, $Button2 Exit Case $Button1, $cDummy local $tmptxt=StringSplit(_GUICtrlListView_GetItemTextString($List), "|")[1] if StringLen($tmptxt)>0 then MsgBox(0, "test", $tmptxt) EndIf EndSwitch WEnd ;================================================================================ Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView $hWndListView = $List If Not IsHWnd($List) Then $hWndListView = GUICtrlGetHandle($List) $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hWndListView Switch $iCode Case $NM_CLICK GUICtrlSendToDummy($cDummy) EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc TimRude and pixelsearch 1 1 Some of my script sourcecode Link to comment Share on other sites More sharing options...
TimRude Posted October 16, 2022 Author Share Posted October 16, 2022 @Dan_555 Thanks! That WM_NOTIFY routine tossing the click back to a dummy control was the missing piece. I've extracted the necessary bits and integrated them into my code and it's working fine now. Much appreciated! Link to comment Share on other sites More sharing options...
c.haslam Posted November 7 Share Posted November 7 (edited) How can I detect when the user clicks: In the ListView control, but not on an item? Outside the Listview control but in the window? The user may have clicked on another control or outside all controls. Edited November 7 by c.haslam Spoiler CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard Link to comment Share on other sites More sharing options...
Nine Posted November 7 Share Posted November 7 What have you tried ? Show the script that is not working. What is the purpose to check all those clicks ? “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
c.haslam Posted November 8 Share Posted November 8 When user enters stuff in e.g. Date, Time and Message then clicks on Set the data appears in a Listview item. If the user clicks on a ListView item and presses Edit (which disables Set), the data of that item appears in the Date, Time and Message controls. minutes advance warning is also available. e.g. if he enters 10 in that control, rather than 0, for the Send Comments item, the Date and Time changes to 20:38 and the Message changes to 20:48 My script has been working for years, but there is/are subtle bugs, so the time has come for a rewrite. Spoiler CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard Link to comment Share on other sites More sharing options...
Dan_555 Posted November 8 Share Posted November 8 (edited) To detect if the listbox or an item is clicked there is a simple change from my previous script needed: If StringLen($tmptxt) > 0 Then If $tmptxt = "0" Then MsgBox(0, "test", "Listview clicked but not on an item") Else MsgBox(0, "test", $tmptxt) EndIf EndIf Quote Outside the Listview control but in the window? The user may have clicked on another control or outside all controls. The command GUIGetCursorInfo() can give you the needed information. Edited November 8 by Dan_555 Some of my script sourcecode Link to comment Share on other sites More sharing options...
c.haslam Posted November 8 Share Posted November 8 Thanks. How about adding a checkbox to the window? How can one catch a user clicking on it? Spoiler CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard Link to comment Share on other sites More sharing options...
Dan_555 Posted November 8 Share Posted November 8 (edited) his is my TO GO snippet for the checkboxes. Func _IsChecked($idControlID) ;Return BitAND(GUICtrlRead($idControlID), $GUI_CHECKED) = $GUI_CHECKED ;Returns true or false (oneliner) ;The lines below convert true and false to numbers - 1 and 0 local $x=BitAND(GUICtrlRead($idControlID), $GUI_CHECKED) = $GUI_CHECKED If $x = True Then Return 1 Return 0 EndFunc ;==>_IsChecked Func _CheckUncheck($id, $nr) If $nr = 0 Then GUICtrlSetState($id, $GUI_UNCHECKED) Else GUICtrlSetState($id, $GUI_CHECKED) EndIf EndFunc ;==>_CheckUncheck You can see how the checkboxes are catched in the Help file. Basically they function just like normal buttons just their display is different. Edited November 8 by Dan_555 Some of my script sourcecode Link to comment Share on other sites More sharing options...
c.haslam Posted November 8 Share Posted November 8 (edited) Is there a way of populating a listview without using a printable character to delineate columns? (Perhaps I should write subitems rather than columns.) The examples appear to use the | character, but what if a cell can contain any keyboard character? Edited November 9 by c.haslam Spoiler CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard Link to comment Share on other sites More sharing options...
Dan_555 Posted November 9 Share Posted November 9 (edited) Not sure what you mean ... if you look at the help page for the GUICtrlCreateListView you may notice that it has (just before the example script) a related link section. If you read it carefully, you may notice a link saying : GUIDataSeparatorChar (Option) ... which is, what, i think, you are asking for. BTW: My script is populating the Listview using an array ... Then there is a way to add things to the Listview by using the _GUICtrlListView_AddItem() and _GUICtrlListView_AddSubItem() Edited November 9 by Dan_555 Some of my script sourcecode Link to comment Share on other sites More sharing options...
c.haslam Posted November 9 Share Posted November 9 Thanks. Looking at the example for _GUICtrlListView_AddSubItem() I see this: if you think of a Listview as a table, with 1-based rows and 1-based columns, an Item is column 1 and a SubItem is any other column. To add column n one has to _GUICtrlListView_InsertColumn for columns 1 to n-1 first. Spoiler CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard 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