Spiff59 Posted June 25, 2009 Share Posted June 25, 2009 (edited) I chopped up the ListView example script just to show what I'm after. I simply want the script to be aware of which ListView row is selected at all times. Searching, I found a few examples, but some seemed overly complex, some are outdated and don't run under 3.3.0.0. So, in the example below, a simple WM_NOTIFY function handles mouse clicks just fine. What's the cleanest way to also handle the highlighted row changing due to the up and down arrow keys? I'm guessing I'll be monitoring the listview for some focus event and processing the message with WM_COMMAND? Or ??? expandcollapse popup#include <GuiConstantsEx.au3> #include <GuiListView.au3> #include <WindowsConstants.au3> Global $listview, $Current_Row = -1 GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUICreate("", 220, 180) $listview = GUICtrlCreateListView("hdg1 |hdg2 |hdg3 ", 10, 10, 200, 120) $item0 = GUICtrlCreateListViewItem("item0|item0-1|item0-2", $listview) $item1 = GUICtrlCreateListViewItem("item1|item1-1|item1-2", $listview) $item2 = GUICtrlCreateListViewItem("item2|item2-1|item2-2", $listview) $item3 = GUICtrlCreateListViewItem("item3|item3-1|item3-2", $listview) $item4 = GUICtrlCreateListViewItem("item4|item4-1|item4-2", $listview) $listview = GUICtrlGetHandle($listview) GUICtrlCreateLabel("Row selected:", 40, 150, 80, 16) $Label_Row = GUICtrlCreateLabel("", 125, 150, 40, 16) GUISetState() While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE Exitloop EndSwitch If $Current_Row > -1 Then GUICtrlSetData($Label_Row,$Current_Row) $Current_Row = -1 EndIf WEnd Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) #forceref $hWnd, $iMsg, $iwParam $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $listview Switch $iCode Case -155 Beep(660,50) Case $NM_CLICK Beep(800,50) $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam) $aHit = _GUICtrlListView_SubItemHitTest($listview) If $aHit[0] > -1 Then $Current_Row = $aHit[0] EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc Edited June 25, 2009 by Spiff59 Link to comment Share on other sites More sharing options...
Spiff59 Posted June 25, 2009 Author Share Posted June 25, 2009 Nevermind! I found by using _GUICtrlListView_GetSelectionMark I can get the results I'm after with only a few lines of code. expandcollapse popup#include <GuiConstantsEx.au3> #include <GuiListView.au3> #include <WindowsConstants.au3> #include <array.au3> Global $listview, $Row_Changed GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUICreate("", 220, 180) $listview = GUICtrlCreateListView("hdg1 |hdg2 |hdg3 ", 10, 10, 200, 120) $item0 = GUICtrlCreateListViewItem("item0|item0-1|item0-2", $listview) $item1 = GUICtrlCreateListViewItem("item1|item1-1|item1-2", $listview) $item2 = GUICtrlCreateListViewItem("item2|item2-1|item2-2", $listview) $item3 = GUICtrlCreateListViewItem("item3|item3-1|item3-2", $listview) $item4 = GUICtrlCreateListViewItem("item4|item4-1|item4-2", $listview) $listview = GUICtrlGetHandle($listview) GUICtrlCreateLabel("Row selected:", 40, 150, 80, 16) $Label_Row = GUICtrlCreateLabel("", 125, 150, 40, 16) GUISetState() While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE Exitloop EndSwitch If $Row_Changed Then GUICtrlSetData($Label_Row,_GUICtrlListView_GetSelectionMark($listview)) $Row_Changed = 0 EndIf WEnd Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) #forceref $hWnd, $iMsg, $iwParam $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $listview Switch $iCode Case -155 $Row_Changed = 1 Case $NM_CLICK $Row_Changed = 1 EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc Link to comment Share on other sites More sharing options...
rover Posted June 29, 2009 Share Posted June 29, 2009 (edited) The listview notification for key events is LVN_KEYDOWN (see _GUICtrlListView_GetHotItem() example) you could optionally use GUICtrlCreateDummy instead of a global and filter out all key events from triggering except for arrow/pgup/pgdn/end/home Cheers expandcollapse popup#include <GuiConstantsEx.au3> #include <GuiListView.au3> #include <WindowsConstants.au3> ;Constants.au3 Global Const $VK_PRIOR = 0x21 Global Const $VK_NEXT = 0x22 Global Const $VK_END = 0x23 Global Const $VK_HOME = 0x24 Global Const $VK_LEFT = 0x25 Global Const $VK_UP = 0x26 Global Const $VK_RIGHT = 0x27 Global Const $VK_DOWN = 0x28 Global $hlistview GUICreate("", 220, 180) $clistview = GUICtrlCreateListView("hdg1 |hdg2 |hdg3 ", 10, 10, 200, 120) $item0 = GUICtrlCreateListViewItem("item0|item0-1|item0-2", $clistview) $item1 = GUICtrlCreateListViewItem("item1|item1-1|item1-2", $clistview) $item2 = GUICtrlCreateListViewItem("item2|item2-1|item2-2", $clistview) $item3 = GUICtrlCreateListViewItem("item3|item3-1|item3-2", $clistview) $item4 = GUICtrlCreateListViewItem("item4|item4-1|item4-2", $clistview) $hlistview = GUICtrlGetHandle($clistview) GUICtrlCreateLabel("Row selected:", 40, 150, 80, 16) $Label_Row = GUICtrlCreateLabel("", 125, 150, 40, 16) $cLVKeyDown = GUICtrlCreateDummy() GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUISetState() While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE Exitloop Case $cLVKeyDown GUICtrlSetData($Label_Row, GUICtrlSendMsg($clistview, $LVM_GETSELECTIONMARK, 0, 0)) ;GUICtrlSetData($Label_Row, _SendMessage($hlistview, $LVM_GETSELECTIONMARK)) EndSwitch WEnd Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) #forceref $hWnd, $iMsg, $iwParam Local $tNMHDR, $hWndFrom, $iIDFrom, $iCode $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hlistview Switch $iCode Case $NM_CLICK GUICtrlSendToDummy($cLVKeyDown) Case $LVN_KEYDOWN ;Virtual-Key Codes ;http://msdn.microsoft.com/en-us/library/ms645540(VS.85).aspx Switch BitAND(DllStructGetData(DllStructCreate($tagNMLVKEYDOWN, $ilParam), "VKey"), 0xFFFF);VKey LoWord is keycode ;up/dn/pgup/pgdn/home/end keys only ;Case $VK_UP, $VK_PRIOR, $VK_DOWN, $VK_NEXT, $VK_END, $VK_HOME Case $VK_PRIOR To $VK_DOWN GUICtrlSendToDummy($cLVKeyDown) EndSwitch EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc Edited June 29, 2009 by rover I see fascists... Link to comment Share on other sites More sharing options...
Spiff59 Posted June 29, 2009 Author Share Posted June 29, 2009 Oh, that's pretty slick! This is more in line with what I expected to use when I posted the first message in this thread. I'd never seen the dummy functions used before, they seem a great way to build and trigger custom events. I'll certaily be playing with (and using) this. Thanks. 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