Sign in to follow this  
Followers 0
Vision

Listview / WM_Notify

6 posts in this topic

#1 ·  Posted (edited)

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

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

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

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

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 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

ChrisL,

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

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


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
Sign in to follow this  
Followers 0