Jump to content

Listview / WM_Notify


Vision
 Share

Recommended Posts

Hi all,

i trying to work with listviews,

found here many sample scripts but i cant get it on work corectly

my script

querys a sqlite db and fills the data in a listview, everything right but if i try interact with the listview /WM_Notify i cant read the text (getitemtext)

maybe some can help me?

here a sample:

this operation doesnot work:

MsgBox(0,"Double Clicked",_GUICtrlListView_GetItemText($ListView, _GUICtrlListView_GetSelectedIndices($ListView)))

it gives back a empty msgbox, if i deleate the the _getItemtext var he shows the id of the row i clicked (that works right)

#include <GuiConstants.au3>;Inclusion file for the GUI interface controls
#include <GuiListView.au3>
#include <SQLite.au3>
#include <SQLite.dll.au3>


Global $ListView
Global Const $WM_NOTIFY = 0x004E
Global Const $DebugIt = 1

;ListView Events
Global Const $NM_FIRST = 0
Global Const $NM_LAST = (-99)
Global Const $NM_OUTOFMEMORY = ($NM_FIRST - 1)
Global Const $NM_CLICK = ($NM_FIRST - 2)
Global Const $NM_DBLCLK = ($NM_FIRST - 3)
;~ Global Const $NM_RETURN = ($NM_FIRST - 4)
;~ Global Const $NM_RCLICK = ($NM_FIRST - 5)
;~ Global Const $NM_RDBLCLK = ($NM_FIRST - 6)
;~ Global Const $NM_SETFOCUS = ($NM_FIRST - 7)
;~ Global Const $NM_KILLFOCUS = ($NM_FIRST - 8)
;~ Global Const $NM_CUSTOMDRAW = ($NM_FIRST - 12)
;~ Global Const $NM_HOVER = ($NM_FIRST - 13)
;~ Global Const $NM_NCHITTEST = ($NM_FIRST - 14)
;~ Global Const $NM_KEYDOWN = ($NM_FIRST - 15)
;~ Global Const $NM_RELEASEDCAPTURE = ($NM_FIRST - 16)
;~ Global Const $NM_SETCURSOR = ($NM_FIRST - 17)
;~ Global Const $NM_CHAR = ($NM_FIRST - 18)
;~ Global Const $NM_TOOLTIPSCREATED = ($NM_FIRST - 19)
#endregion End Global variables

Opt("WinTitleMatchMode", 2)

$main_GUI = GUICreate("GuiRegisterMsg Test", 225, 400, 300, 10)

$ListView = GUICtrlCreateListView("Entry Name|Category", 5, 75, 195, 280, BitOR($LVS_SORTASCENDING, $LVS_SINGLESEL))
_GUICtrlListView_SetColumnWidth ($ListView, 0, 100)
_GUICtrlListView_SetColumnWidth ($ListView, 1, 100)
GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
GUICtrlCreateListViewItem("Name 1|Category 1", $ListView)
GUICtrlCreateListViewItem("Name 2|Category 2", $ListView)
GUISetState()




;Register WM_NOTIFY  events
GUIRegisterMsg($WM_NOTIFY, "WM_Notify_Events")

While 1
   $msg = GUIGetMsg()
   Switch $msg
   ;-----------------------------------------------------------------------------------------
   ;This case statement exits and updates code if needed
      Case $GUI_EVENT_CLOSE
         Exit
      ;-----------------------------------------------------------------------------------------
      ;put all the misc. stuff here
        Case Else
        ;;;
   EndSwitch
WEnd

; WM_NOTIFY event handler
Func WM_Notify_Events($hWndGUI, $MsgID, $wParam, $lParam)
    #forceref $hWndGUI, $MsgID, $wParam
    Local $tagNMHDR, $event, $hwndFrom, $code
    $tagNMHDR = DllStructCreate("int;int;int", $lParam);NMHDR (hwndFrom, idFrom, code)
    If @error Then Return
    $event = DllStructGetData($tagNMHDR, 3)
    Select
    Case $wParam = $ListView
        Select
            Case $event = $NM_CLICK
               ConsoleWrite("SingleClick" & @LF)
           Case $event = $NM_DBLCLK

                MsgBox(0,"Double Clicked",_GUICtrlListView_GetItemText($ListView, _GUICtrlListView_GetSelectedIndices($ListView)))
            EndSelect
    EndSelect
    $tagNMHDR = 0
    $event = 0
    $lParam = 0
EndFunc  ;==>WM_Notify_Events
Edited by Vision
Link to comment
Share on other sites

  • Moderators

Vision,

Certain of the UDF functions require the Handle and not the ControlID of the control. Try putting:

$hLV_Handle = GUICtrlGetHandle(-1)

immediately after the GUICtrlCreateListView line and use that variable in the _GUICtrlListView_ functions.

This code shows what I mean:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <GuiListView.au3>
#include <ListViewConstants.au3>

Global $fDblClk = False

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

$ListView = GUICtrlCreateListView("Entry Name|Category", 5, 75, 195, 280, BitOR($LVS_SORTASCENDING, $LVS_SINGLESEL))
$hLV_Handle = GUICtrlGetHandle(-1)
_GUICtrlListView_SetColumnWidth ($ListView, 0, 100)
_GUICtrlListView_SetColumnWidth ($ListView, 1, 100)
GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
GUICtrlCreateListViewItem("Name 1|Category 1", $ListView)
GUICtrlCreateListViewItem("Name 2|Category 2", $ListView)

GUISetState()

GUIRegisterMsg($WM_NOTIFY, "MY_WM_NOTIFY")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch

    If $fDblClk Then
        $fDblClk = False
        MsgBox(0,"Double Clicked",_GUICtrlListView_GetItemText($hLV_Handle, _GUICtrlListView_GetSelectedIndices($hLV_Handle)))
    EndIf
WEnd

; React to double clicks on  ListView
Func MY_WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)

    #forceref $hWnd, $iMsg, $wParam
    Local $tNMHDR = DllStructCreate("int;int;int", $lParam)
    If @error Then Return
    If DllStructGetData($tNMHDR, 1) = $hLV_Handle Then
        If DllStructGetData($tNMHDR, 3) = $NM_DBLCLK Then $fDblClk = True
    EndIf
    $tNMHDR = 0
    Return $GUI_RUNDEFMSG

EndFunc   ;==>MY_WM_NOTIFY

I hope this helps. :)

M23

Edit: I forgot to mention that you should NOT put things like MsgBox in the registered function. From the Help file for GUIRegisterMsg:

Warning: blocking of running user functions which executes window messages with commands such as "Msgbox()" can lead to unexpected behavior, the return to the system should be as fast as possible !!!

That is why I use a flag in my example. ;)

Edited by Melba23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png 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 columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

It's a conversion problem with this UDF. _GUICtrlListView_GetSelectedIndices returns a string or an array of selected indices. _GUICtrlListView_GetItemText need a numbers as zero based index.

So change your line to

MsgBox(0,"Double Clicked",_GUICtrlListView_GetItemText($ListView, number(_GUICtrlListView_GetSelectedIndices($ListView))))
and it should work fine.

If you select more than one row your script will crash.

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

thanks guys!!

this now works, i got the next problem ^.^

maybe you can help again:

if want to start a func after the double click with a gui, the gui freezes

see _editsqlquery() Func and added where the doubleclick was

#include <GuiConstants.au3>;Inclusion file for the GUI interface controls
#include <GuiListView.au3>
#include <SQLite.au3>
#include <SQLite.dll.au3>


Global $ListView
Global Const $WM_NOTIFY = 0x004E
Global Const $DebugIt = 1

;ListView Events
Global Const $NM_FIRST = 0
Global Const $NM_LAST = (-99)
Global Const $NM_OUTOFMEMORY = ($NM_FIRST - 1)
Global Const $NM_CLICK = ($NM_FIRST - 2)
Global Const $NM_DBLCLK = ($NM_FIRST - 3)
;~ Global Const $NM_RETURN = ($NM_FIRST - 4)
;~ Global Const $NM_RCLICK = ($NM_FIRST - 5)
;~ Global Const $NM_RDBLCLK = ($NM_FIRST - 6)
;~ Global Const $NM_SETFOCUS = ($NM_FIRST - 7)
;~ Global Const $NM_KILLFOCUS = ($NM_FIRST - 8)
;~ Global Const $NM_CUSTOMDRAW = ($NM_FIRST - 12)
;~ Global Const $NM_HOVER = ($NM_FIRST - 13)
;~ Global Const $NM_NCHITTEST = ($NM_FIRST - 14)
;~ Global Const $NM_KEYDOWN = ($NM_FIRST - 15)
;~ Global Const $NM_RELEASEDCAPTURE = ($NM_FIRST - 16)
;~ Global Const $NM_SETCURSOR = ($NM_FIRST - 17)
;~ Global Const $NM_CHAR = ($NM_FIRST - 18)
;~ Global Const $NM_TOOLTIPSCREATED = ($NM_FIRST - 19)
#endregion End Global variables

Opt("WinTitleMatchMode", 2)

$main_GUI = GUICreate("GuiRegisterMsg Test", 225, 400, 300, 10)

$ListView = GUICtrlCreateListView("Entry Name|Category", 5, 75, 195, 280, BitOR($LVS_SORTASCENDING, $LVS_SINGLESEL))
_GUICtrlListView_SetColumnWidth ($ListView, 0, 100)
_GUICtrlListView_SetColumnWidth ($ListView, 1, 100)
GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
GUICtrlCreateListViewItem("Name 1|Category 1", $ListView)
GUICtrlCreateListViewItem("Name 2|Category 2", $ListView)
GUISetState()




;Register WM_NOTIFY  events
GUIRegisterMsg($WM_NOTIFY, "WM_Notify_Events")

While 1
   $msg = GUIGetMsg()
   Switch $msg
   ;-----------------------------------------------------------------------------------------
   ;This case statement exits and updates code if needed
      Case $GUI_EVENT_CLOSE
         Exit
      ;-----------------------------------------------------------------------------------------
      ;put all the misc. stuff here
        Case Else
        ;;;
   EndSwitch
WEnd

; WM_NOTIFY event handler
Func WM_Notify_Events($hWndGUI, $MsgID, $wParam, $lParam)
    #forceref $hWndGUI, $MsgID, $wParam
    Local $tagNMHDR, $event, $hwndFrom, $code
    $tagNMHDR = DllStructCreate("int;int;int", $lParam);NMHDR (hwndFrom, idFrom, code)
    If @error Then Return
    $event = DllStructGetData($tagNMHDR, 3)
    Select
    Case $wParam = $ListView
        Select
 ;           Case $event = $NM_CLICK
 ;              ConsoleWrite("SingleClick" & @LF)
           Case $event = $NM_DBLCLK
                  _editsqlquery()
;                MsgBox(0,"Double Clicked",_GUICtrlListView_GetItemText($ListView, _GUICtrlListView_GetSelectedIndices($ListView)))


            EndSelect
    EndSelect
    $tagNMHDR = 0
    $event = 0
    $lParam = 0
EndFunc  ;==>WM_Notify_Events


Func _editsqlquery()

$child_gui = GUICreate("test", 300, 300, -1, -1, -1, -1, $gui)
GUISetState(@SW_SHOW)

While 1
        $msg2 = GUIGetMsg(1)

        Select
            Case $msg2[0] = $GUI_EVENT_CLOSE
             GUIDelete($child_gui)

             GUISetState(@SW_SHOW, $gui)
            ExitLoop
    EndSelect
Wend

Endfunc
Link to comment
Share on other sites

Melba23 posted a "Warning" above but you either didn't read it or didn't understand it.

In your WM_Notify_Events function you can not call another function that then doesn't return for some time, it is a blocking function it has a loop that can't exit without user interaction.

WM_Notify_Events has to return to the main part of the program as soon as possible.

What I have done is set a Global variable with WM_Notify_Events and then in the main loop checked to see the value of the Global variable.

If $editsqlquery = 1 then I launch a new GUI from the Main loop not the WM_Notify_Events function.

#include <GuiConstants.au3>;Inclusion file for the GUI interface controls
#include <GuiListView.au3>
#include <SQLite.au3>
#include <SQLite.dll.au3>


Global $ListView
Global Const $WM_NOTIFY = 0x004E
Global Const $DebugIt = 1

;ListView Events
Global Const $NM_FIRST = 0
Global Const $NM_LAST = (-99)
Global Const $NM_OUTOFMEMORY = ($NM_FIRST - 1)
Global Const $NM_CLICK = ($NM_FIRST - 2)
Global Const $NM_DBLCLK = ($NM_FIRST - 3)
;~ Global Const $NM_RETURN = ($NM_FIRST - 4)
;~ Global Const $NM_RCLICK = ($NM_FIRST - 5)
;~ Global Const $NM_RDBLCLK = ($NM_FIRST - 6)
;~ Global Const $NM_SETFOCUS = ($NM_FIRST - 7)
;~ Global Const $NM_KILLFOCUS = ($NM_FIRST - 8)
;~ Global Const $NM_CUSTOMDRAW = ($NM_FIRST - 12)
;~ Global Const $NM_HOVER = ($NM_FIRST - 13)
;~ Global Const $NM_NCHITTEST = ($NM_FIRST - 14)
;~ Global Const $NM_KEYDOWN = ($NM_FIRST - 15)
;~ Global Const $NM_RELEASEDCAPTURE = ($NM_FIRST - 16)
;~ Global Const $NM_SETCURSOR = ($NM_FIRST - 17)
;~ Global Const $NM_CHAR = ($NM_FIRST - 18)
;~ Global Const $NM_TOOLTIPSCREATED = ($NM_FIRST - 19)

Global $editsqlquery = 0
#endregion End Global variables

Opt("WinTitleMatchMode", 2)

$main_GUI = GUICreate("GuiRegisterMsg Test", 225, 400, 300, 10)

$ListView = GUICtrlCreateListView("Entry Name|Category", 5, 75, 195, 280, BitOR($LVS_SORTASCENDING, $LVS_SINGLESEL))
_GUICtrlListView_SetColumnWidth ($ListView, 0, 100)
_GUICtrlListView_SetColumnWidth ($ListView, 1, 100)
GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
GUICtrlCreateListViewItem("Name 1|Category 1", $ListView)
GUICtrlCreateListViewItem("Name 2|Category 2", $ListView)
GUISetState()




;Register WM_NOTIFY  events
GUIRegisterMsg($WM_NOTIFY, "WM_Notify_Events")

While 1
   $msg = GUIGetMsg()
   Switch $msg
   ;-----------------------------------------------------------------------------------------
   ;This case statement exits and updates code if needed
      Case $GUI_EVENT_CLOSE
         Exit
      ;-----------------------------------------------------------------------------------------
      ;put all the misc. stuff here
        Case Else
        If $editsqlquery = 1 then _editsqlquery()
   EndSwitch
WEnd

; WM_NOTIFY event handler
Func WM_Notify_Events($hWndGUI, $MsgID, $wParam, $lParam)
    #forceref $hWndGUI, $MsgID, $wParam
    Local $tagNMHDR, $event, $hwndFrom, $code
    $tagNMHDR = DllStructCreate("int;int;int", $lParam);NMHDR (hwndFrom, idFrom, code)
    If @error Then Return
    $event = DllStructGetData($tagNMHDR, 3)
    Select
    Case $wParam = $ListView
        Select
 ;           Case $event = $NM_CLICK
 ;              ConsoleWrite("SingleClick" & @LF)
           Case $event = $NM_DBLCLK
                  $editsqlquery = 1
                ;Setup GLOBAL variables rather than calling functions this part need to exit as fast as possible
            EndSelect
    EndSelect
    $tagNMHDR = 0
    $event = 0
    $lParam = 0
EndFunc  ;==>WM_Notify_Events


Func _editsqlquery()

 GUISetState(@SW_HIDE,$main_GUI)
$child_gui = GUICreate("test", 300, 300, -1, -1, -1, -1, $main_GUI)
GUISetState(@SW_SHOW)

While 1
        $msg2 = GUIGetMsg(1)

        Select
            Case $msg2[0] = $GUI_EVENT_CLOSE
             GUIDelete($child_gui)

             GUISetState(@SW_SHOW,$main_GUI)
            ExitLoop
            
    EndSelect
Wend
    $editsqlquery = 0
Endfunc
Link to comment
Share on other sites

  • Moderators

ChrisL,

Nice to see someone bothers to read to the end of the post! :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png 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 columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...