ripdad Posted June 25, 2011 Posted June 25, 2011 This is a simplified example of something I've been experimenting with. Perhaps it has been done before. I'm sure this could be done better. Benefits: - Set a specific "menu group" to a specific listview item control. - Menus won't activate, unless a control is assigned a menu group. Side Benefits: -> No menu on listview description bar. -> No menu on listview item group labels. -> No menu on white space Now, what I'd like to be able to do is make a "menu group" a "module" and then attach that module to a listview item control. This way, I only have to get each menu group once. (stored as a control?) I tried it with a dummy control. I couldn't make it work. Any ideas would be appreciated. expandcollapse popupOpt('MustDeclareVars', 1) Opt('GUIOnEventMode', 1) ; Local $gui = GUICreate('Example - SetMenu2LvItemCtrl', 410, 310, -1, -1) Local $Lv = GUICtrlCreateListView('List of Items', 5, 5, 400, 300) GUICtrlSendMsg($Lv, 0x101E, 0, 396) GUISetOnEvent(-3, '_AllExit') ; _Set_Menus() GUISetState(@SW_SHOW, $gui) ; While 1 Sleep(1000) WEnd ; Func _AllExit() GUIDelete($gui) Exit EndFunc ; Func _Set_Menus() ; ======================================================== Local $hLvi = GUICtrlCreateListViewItem('Label One', $Lv); set group label (no menu assigned) GUICtrlSetBkColor($hLvi, 0xC0C0C0); set color for label GUICtrlSetState($hLvi, 128);$GUI_DISABLE = 128 For $i = 1 To 5 $hLvi = GUICtrlCreateListViewItem('ITEM ' & $i, $Lv) Menu1_SetMenu2LvItemCtrl($hLvi); assign menu to this listview item control Next ; ======================================================== $hLvi = GUICtrlCreateListViewItem('Label Two', $Lv) GUICtrlSetBkColor($hLvi, 0xC0C0C0) For $i = 1 To 5 $hLvi = GUICtrlCreateListViewItem('ITEM ' & $i, $Lv) Menu2_SetMenu2LvItemCtrl($hLvi) Next ; ======================================================== $hLvi = GUICtrlCreateListViewItem('Label Three', $Lv) GUICtrlSetBkColor($hLvi, 0xC0C0C0) For $i = 1 To 5 $hLvi = GUICtrlCreateListViewItem('ITEM ' & $i, $Lv) Menu3_SetMenu2LvItemCtrl($hLvi) Next EndFunc ; Func Menu1_SetMenu2LvItemCtrl($LvI) Local $h = GUICtrlCreateContextMenu($LvI) Local $a = GUICtrlCreateMenuItem('Menu1 - Menu Item1', $h) Local $b = GUICtrlCreateMenuItem('Menu1 - Menu Item2', $h) GUICtrlCreateMenuItem('', $h) Local $c = GUICtrlCreateMenuItem('Menu1 - Menu Item3', $h) Local $d = GUICtrlCreateMenuItem('Menu1 - Menu Item4', $h) GUICtrlCreateMenuItem('', $h) Local $e = GUICtrlCreateMenuItem('Menu1 - Menu Item5', $h) Local $f = GUICtrlCreateMenuItem('Menu1 - Menu Item6', $h) GUICtrlCreateMenuItem('', $h) Local $g = GUICtrlCreateMenuItem('Menu1 - Menu Item7', $h) GUICtrlSetOnEvent($a, '_Function1') GUICtrlSetOnEvent($b, '_Function2') GUICtrlSetOnEvent($c, '_Function3') GUICtrlSetOnEvent($d, '_Function4') GUICtrlSetOnEvent($e, '_Function5') GUICtrlSetOnEvent($f, '_Function6') GUICtrlSetOnEvent($g, '_Function7') EndFunc ; Func Menu2_SetMenu2LvItemCtrl($LvI) Local $h = GUICtrlCreateContextMenu($LvI) Local $a = GUICtrlCreateMenuItem('Menu2 - Menu Item1', $h) Local $b = GUICtrlCreateMenuItem('Menu2 - Menu Item2', $h) GUICtrlSetOnEvent($a, '_Function1') GUICtrlSetOnEvent($b, '_Function8') EndFunc ; Func Menu3_SetMenu2LvItemCtrl($LvI) Local $h = GUICtrlCreateContextMenu($LvI) Local $a = GUICtrlCreateMenuItem('Menu3 - Menu Item1', $h) Local $b = GUICtrlCreateMenuItem('Menu3 - Menu Item2', $h) GUICtrlCreateMenuItem('', $h) Local $c = GUICtrlCreateMenuItem('Menu3 - Menu Item3', $h) Local $d = GUICtrlCreateMenuItem('Menu3 - Menu Item4', $h) GUICtrlSetOnEvent($a, '_Function2') GUICtrlSetOnEvent($b, '_Function4') GUICtrlSetOnEvent($c, '_Function9') GUICtrlSetOnEvent($d, '_Function3') EndFunc ; Func _Function1() MsgBox(0,'','_Function1()') EndFunc ; Func _Function2() MsgBox(0,'','_Function2()') EndFunc ; Func _Function3() MsgBox(0,'','_Function3()') EndFunc ; Func _Function4() MsgBox(0,'','_Function4()') EndFunc ; Func _Function5() MsgBox(0,'','_Function5()') EndFunc ; Func _Function6() MsgBox(0,'','_Function6()') EndFunc ; Func _Function7() MsgBox(0,'','_Function7()') EndFunc ; Func _Function8() MsgBox(0,'','_Function8()') EndFunc ; Func _Function9() MsgBox(0,'','_Function9()') EndFunc ; "The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward
rover Posted June 25, 2011 Posted June 25, 2011 This is a simplified example of something I've been experimenting with. Perhaps it has been done before. I'm sure this could be done better. Benefits: - Set a specific "menu group" to a specific listview item control. - Menus won't activate, unless a control is assigned a menu group. Side Benefits: -> No menu on listview description bar. -> No menu on listview item group labels. -> No menu on white space Now, what I'd like to be able to do is make a "menu group" a "module" and then attach that module to a listview item control. This way, I only have to get each menu group once. (stored as a control?) I tried it with a dummy control. I couldn't make it work. Any ideas would be appreciated. you should use the listview groups feature and set group membership for each item native listview items have their pseudo control ID stored in the items param find the index of the item you want to set a menu to and get the control ID for the items menu with _GUICtrlListView_GetItemParam() (listview items are not controls, they only have an index and if set, a command ID that can be used to track items in a sorted listview) this example shows how you could use the groups feature instead of an item as a group label and sets a listview item to a menu of choice by getting the native listview item pseudo control ID you cannot use this with UDF created items, either stick with GUICtrlCreateListViewItem() or _GUICtrlListView_AddItem), _GUICtrlListView_AddSubItem() and _GUICtrlListView_InsertItem() but never both at the same time. expandcollapse popup#Include <GuiListView.au3> Opt('MustDeclareVars', 1) Opt('GUIOnEventMode', 1) ; Local $gui = GUICreate('Example - SetMenu2LvItemCtrl', 410, 460, -1, -1) Local $Lv = GUICtrlCreateListView('List of Items', 5, 5, 400, 450) GUICtrlSendMsg($Lv, 0x101E, 0, 396) _GUICtrlListView_EnableGroupView($Lv) GUISetOnEvent(-3, '_AllExit') ; _Set_Menus() GUISetState(@SW_SHOW, $gui) ;set last item in Group 4 to X menu Local $hLvi = GUICtrlCreateListViewItem('ITEM X', $Lv) _GUICtrlListView_SetItemGroupID($Lv, _GUICtrlListView_GetItemCount($Lv)-1, 4) ;set index of item to group 4 membership MenuX_SetMenu2LvItemCtrl(_GUICtrlListView_GetItemParam($Lv, _GUICtrlListView_GetItemCount($Lv)-1)) ;get ID of item and set menu While 1 Sleep(1000) WEnd ; Func _AllExit() GUIDelete($gui) Exit EndFunc ; Func _Set_Menus() ; ======================================================== Local $hLvi ;Local $hLvi = GUICtrlCreateListViewItem('Label One', $Lv); set group label (no menu assigned) ;GUICtrlSetBkColor($hLvi, 0xC0C0C0); set color for label ;GUICtrlSetState($hLvi, 128);$GUI_DISABLE = 128 _GUICtrlListView_InsertGroup($Lv, 0, 1, "Group 1") For $i = 1 To 5 $hLvi = GUICtrlCreateListViewItem('ITEM ' & $i, $Lv) _GUICtrlListView_SetItemGroupID($Lv, _GUICtrlListView_GetItemCount($Lv)-1, 1) Menu1_SetMenu2LvItemCtrl($hLvi); assign menu to this listview item control Next ; ======================================================== ;$hLvi = GUICtrlCreateListViewItem('Label Two', $Lv) ;GUICtrlSetBkColor($hLvi, 0xC0C0C0) _GUICtrlListView_InsertGroup($Lv, _GUICtrlListView_GetItemCount($Lv)-1, 2, "Group 2") For $i = 1 To 5 $hLvi = GUICtrlCreateListViewItem('ITEM ' & $i, $Lv) _GUICtrlListView_SetItemGroupID($Lv, _GUICtrlListView_GetItemCount($Lv)-1, 2) Menu2_SetMenu2LvItemCtrl($hLvi) Next ; ======================================================== ;$hLvi = GUICtrlCreateListViewItem('Label Three', $Lv) ;GUICtrlSetBkColor($hLvi, 0xC0C0C0) _GUICtrlListView_InsertGroup($Lv, _GUICtrlListView_GetItemCount($Lv)-1, 3, "Group 3") For $i = 1 To 5 $hLvi = GUICtrlCreateListViewItem('ITEM ' & $i, $Lv) _GUICtrlListView_SetItemGroupID($Lv, _GUICtrlListView_GetItemCount($Lv)-1, 3) Menu3_SetMenu2LvItemCtrl($hLvi) Next ;Create Group 4 "x" _GUICtrlListView_InsertGroup($Lv, _GUICtrlListView_GetItemCount($Lv)-1, 4, "Group X") EndFunc ; Func Menu1_SetMenu2LvItemCtrl($LvI) Local $h = GUICtrlCreateContextMenu($LvI) Local $a = GUICtrlCreateMenuItem('Menu1 - Menu Item1', $h) Local $b = GUICtrlCreateMenuItem('Menu1 - Menu Item2', $h) GUICtrlCreateMenuItem('', $h) Local $c = GUICtrlCreateMenuItem('Menu1 - Menu Item3', $h) Local $d = GUICtrlCreateMenuItem('Menu1 - Menu Item4', $h) GUICtrlCreateMenuItem('', $h) Local $e = GUICtrlCreateMenuItem('Menu1 - Menu Item5', $h) Local $f = GUICtrlCreateMenuItem('Menu1 - Menu Item6', $h) GUICtrlCreateMenuItem('', $h) Local $g = GUICtrlCreateMenuItem('Menu1 - Menu Item7', $h) GUICtrlSetOnEvent($a, '_Function1') GUICtrlSetOnEvent($b, '_Function2') GUICtrlSetOnEvent($c, '_Function3') GUICtrlSetOnEvent($d, '_Function4') GUICtrlSetOnEvent($e, '_Function5') GUICtrlSetOnEvent($f, '_Function6') GUICtrlSetOnEvent($g, '_Function7') EndFunc ; Func Menu2_SetMenu2LvItemCtrl($LvI) Local $h = GUICtrlCreateContextMenu($LvI) Local $a = GUICtrlCreateMenuItem('Menu2 - Menu Item1', $h) Local $b = GUICtrlCreateMenuItem('Menu2 - Menu Item2', $h) GUICtrlSetOnEvent($a, '_Function1') GUICtrlSetOnEvent($b, '_Function8') EndFunc ; Func Menu3_SetMenu2LvItemCtrl($LvI) Local $h = GUICtrlCreateContextMenu($LvI) Local $a = GUICtrlCreateMenuItem('Menu3 - Menu Item1', $h) Local $b = GUICtrlCreateMenuItem('Menu3 - Menu Item2', $h) GUICtrlCreateMenuItem('', $h) Local $c = GUICtrlCreateMenuItem('Menu3 - Menu Item3', $h) Local $d = GUICtrlCreateMenuItem('Menu3 - Menu Item4', $h) GUICtrlSetOnEvent($a, '_Function2') GUICtrlSetOnEvent($b, '_Function4') GUICtrlSetOnEvent($c, '_Function9') GUICtrlSetOnEvent($d, '_Function3') EndFunc Func MenuX_SetMenu2LvItemCtrl($LvI) Local $h = GUICtrlCreateContextMenu($LvI) Local $a = GUICtrlCreateMenuItem('MenuX - Menu Item1', $h) GUICtrlSetOnEvent($a, '_FunctionX') EndFunc ; Func _Function1() MsgBox(0,'','_Function1()') EndFunc ; Func _Function2() MsgBox(0,'','_Function2()') EndFunc ; Func _Function3() MsgBox(0,'','_Function3()') EndFunc ; Func _Function4() MsgBox(0,'','_Function4()') EndFunc ; Func _Function5() MsgBox(0,'','_Function5()') EndFunc ; Func _Function6() MsgBox(0,'','_Function6()') EndFunc ; Func _Function7() MsgBox(0,'','_Function7()') EndFunc ; Func _Function8() MsgBox(0,'','_Function8()') EndFunc ; Func _Function9() MsgBox(0,'','_Function9()') EndFunc ; Func _FunctionX() MsgBox(0,'','_FunctionX()') EndFunc I see fascists...
rover Posted June 25, 2011 Posted June 25, 2011 (edited) OK I misunderstood you initially, I think this is what you want. A variation on the example for GUICtrlCreateContextMenu(), but using Groups Edit: some additional error checking and example of a group without a menu added expandcollapse popup#include <GuiListView.au3> #include <WindowsConstants.au3> #include <GuiConstantsEx.au3> #include <GuiMenu.au3> Opt('MustDeclareVars', 1) Opt('GUIOnEventMode', 1) ; Local $gui = GUICreate('Example - SetMenu2LvItemCtrl', 410, 400, -1, -1) Local $Lv = GUICtrlCreateListView('List of Items', 5, 5, 400, 390) GUICtrlSendMsg($Lv, 0x101E, 0, 396) _GUICtrlListView_EnableGroupView($Lv) GUISetOnEvent(-3, '_AllExit') ; ;create as many context menus set to a dummy control placeholder as you need Local $aMenu[4] ;array for storing group menu handles Local $cMenu1 = GUICtrlCreateDummy() Local $cMenu2 = GUICtrlCreateDummy() $aMenu[1] = Menu1_SetMenu2LvItemCtrl($cMenu1) $aMenu[2] = Menu2_SetMenu2LvItemCtrl($cMenu2) $aMenu[3] = 0 $aMenu[0] = 2 _Set_Items();create listview items and set each item to group 1 or 2 membership GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY") GUISetState(@SW_SHOW, $gui) While 1 Sleep(1000) WEnd ; Func _AllExit() GUIDelete($gui) Exit EndFunc ;==>_AllExit ; Func _Set_Items() ; ======================================================== Local $hLvi _GUICtrlListView_InsertGroup($Lv, 0, 1, "Group 1") For $i = 1 To 5 $hLvi = GUICtrlCreateListViewItem('ITEM ' & $i, $Lv) _GUICtrlListView_SetItemGroupID($Lv, _GUICtrlListView_GetItemCount($Lv) - 1, 1) Next ; ======================================================== _GUICtrlListView_InsertGroup($Lv, _GUICtrlListView_GetItemCount($Lv) - 1, 2, "Group 2") For $i = 1 To 5 $hLvi = GUICtrlCreateListViewItem('ITEM ' & $i, $Lv) _GUICtrlListView_SetItemGroupID($Lv, _GUICtrlListView_GetItemCount($Lv) - 1, 2) Next ; ======================================================== _GUICtrlListView_InsertGroup($Lv, _GUICtrlListView_GetItemCount($Lv) - 1, 3, "Group 3") For $i = 1 To 5 $hLvi = GUICtrlCreateListViewItem('ITEM ' & $i, $Lv) _GUICtrlListView_SetItemGroupID($Lv, _GUICtrlListView_GetItemCount($Lv) - 1, 3) Next ; ======================================================== EndFunc ;==>_Set_Items ; Func _WM_NOTIFY($hWnd, $Msg, $wParam, $lParam) #forceref $hWnd, $Msg, $wParam Local $tNMHDR, $hWndFrom, $iCode $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iCode = DllStructGetData($tNMHDR, "Code") Local $IDFrom = DllStructGetData($tNMHDR, "IDFrom") Switch $IDFrom Case $Lv Switch $iCode Case $NM_RCLICK ; determine if right click on an item Local $tInfox = DllStructCreate($tagNMITEMACTIVATE, $lParam) If @error Then Return $GUI_RUNDEFMSG Local $Item = DllStructGetData($tInfox, "Index") If @error Or $Item = -1 Then Return $GUI_RUNDEFMSG Local $tTest = DllStructCreate($tagLVHITTESTINFO) Local $x = DllStructGetData($tInfox, "X") ; X Local $y = DllStructGetData($tInfox, "Y") ; Y DllStructSetData($tTest, "X", $x) DllStructSetData($tTest, "Y", $y) Local $iRet = GUICtrlSendMsg($IDFrom, $LVM_HITTEST, 0, DllStructGetPtr($tTest)) If @error Or $iRet = -1 Then Return $GUI_RUNDEFMSG ; -1 = not on lv item, otherwise returns index Switch DllStructGetData($tTest, "Flags") Case $LVHT_ONITEMICON, $LVHT_ONITEMLABEL, $LVHT_ONITEM ;hit was on item icon or 1st row or subitem ;get the items group membership ID Local $iGroupID = _GUICtrlListView_GetItemGroupID($IDFrom, $Item) If @error Or $iGroupID < 0 Then Return $GUI_RUNDEFMSG ;pop the menu for the group membership ID If $iGroupID > UBound($aMenu)-1 Then Return $GUI_RUNDEFMSG If $aMenu[$iGroupID] <> 0 And _GUICtrlMenu_IsMenu($aMenu[$iGroupID]) = 1 Then Local $tpoint = DllStructCreate("int X;int Y") DllStructSetData($tpoint, "X", $x) DllStructSetData($tpoint, "Y", $y) ;convert hittest coordinates to screen coordinates for context menu _WinAPI_ClientToScreen($hWndFrom, $tpoint) ;$iSubItem = DllStructGetData($tInfox, "SubItem") _GUICtrlMenu_TrackPopupMenu($aMenu[$iGroupID], $hWnd, DllStructGetData($tpoint, "X"), DllStructGetData($tpoint, "Y"), 1, 1, 1) EndIf EndSwitch EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_WM_NOTIFY Func Menu1_SetMenu2LvItemCtrl($LvI) Local $h = GUICtrlCreateContextMenu($LvI) Local $a = GUICtrlCreateMenuItem('Menu1 - Menu Item1', $h) Local $b = GUICtrlCreateMenuItem('Menu1 - Menu Item2', $h) GUICtrlCreateMenuItem('', $h) Local $c = GUICtrlCreateMenuItem('Menu1 - Menu Item3', $h) Local $d = GUICtrlCreateMenuItem('Menu1 - Menu Item4', $h) GUICtrlCreateMenuItem('', $h) Local $e = GUICtrlCreateMenuItem('Menu1 - Menu Item5', $h) Local $f = GUICtrlCreateMenuItem('Menu1 - Menu Item6', $h) GUICtrlCreateMenuItem('', $h) Local $g = GUICtrlCreateMenuItem('Menu1 - Menu Item7', $h) GUICtrlSetOnEvent($a, '_Function1') GUICtrlSetOnEvent($b, '_Function2') GUICtrlSetOnEvent($c, '_Function3') GUICtrlSetOnEvent($d, '_Function4') GUICtrlSetOnEvent($e, '_Function5') GUICtrlSetOnEvent($f, '_Function6') GUICtrlSetOnEvent($g, '_Function7') Return GUICtrlGetHandle($h) EndFunc ;==>Menu1_SetMenu2LvItemCtrl ; Func Menu2_SetMenu2LvItemCtrl($LvI) Local $h = GUICtrlCreateContextMenu($LvI) Local $a = GUICtrlCreateMenuItem('Menu2 - Menu Item1', $h) Local $b = GUICtrlCreateMenuItem('Menu2 - Menu Item2', $h) GUICtrlSetOnEvent($a, '_Function1') GUICtrlSetOnEvent($b, '_Function8') Return GUICtrlGetHandle($h) EndFunc ;==>Menu2_SetMenu2LvItemCtrl ; ; Func _Function1() MsgBox(0, '', '_Function1()') EndFunc ;==>_Function1 ; Func _Function2() MsgBox(0, '', '_Function2()') EndFunc ;==>_Function2 ; Func _Function3() MsgBox(0, '', '_Function3()') EndFunc ;==>_Function3 ; Func _Function4() MsgBox(0, '', '_Function4()') EndFunc ;==>_Function4 ; Func _Function5() MsgBox(0, '', '_Function5()') EndFunc ;==>_Function5 ; Func _Function6() MsgBox(0, '', '_Function6()') EndFunc ;==>_Function6 ; Func _Function7() MsgBox(0, '', '_Function7()') EndFunc ;==>_Function7 ; Func _Function8() MsgBox(0, '', '_Function8()') EndFunc ;==>_Function8 Edited June 25, 2011 by rover I see fascists...
ripdad Posted June 25, 2011 Author Posted June 25, 2011 rover, Thanks for your time and examples. That will give me plenty to work with. "The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward
rover Posted June 26, 2011 Posted June 26, 2011 ripdad One more thing I would like to add if you or anyone else is interested. The code I use for my listview contextmenus differs slightly from what I posted. I use a WM_CONTEXTMENU handler for _GUICtrlMenu_TrackPopupMenu() This way the NM_RCLICK notification returns immediately, and the WM_CONTEXTMENU handler, has the blocking function TrackPopupMenu(). WM_CONTEXTMENU also has the screen coordinates, eliminating the need for _WinAPI_ClientToScreen(). This revised and more efficient version splits the menu between WM_CONTEXTMENU and WM_NOTIFY, and has the advantage of getting the selected lv item and the client coordinates for the hittest from the WM_NOTIFY NMITEMACTIVATE struct, and the screen coordinates for _GUICtrlMenu_TrackPopupMenu() from WM_CONTEXTMENU lParam. This can also be done entirely in the WM_CONTEXTMENU handler, but it requires extra dllcalls (SendMessage() for getting the selected lv item and _WinAPI_ScreenToClient() for the hittest coordinates. Addendum: I never put listview contextmenu Appkey/Shift-F10 support in my code, so I've worked it out for my own use and added it here. So, more code ends up in the WM_CONTEXTMENU handler after all... You can remove the WM_SYSCOMMAND handler and the WM_CONTEXTMENU keyboard navigation code if you don't require Appkey/Shift-F10 support or care about possible use of shift-f10 on a listview item. *** (see notes in code) -remove the code in section below "If $lParam = -1 Then" ;Menu Appkey or Shift-F10 expandcollapse popup#include <GuiListView.au3> #include <WindowsConstants.au3> #include <GuiConstantsEx.au3> #include <GuiMenu.au3> Opt('MustDeclareVars', 1) Opt('GUIOnEventMode', 1) Local $iGroupID = -1, $fSysMenu = True, $hLv Local $gui = GUICreate('Example - SetMenu2LvItemCtrl', 410, 450, -1, -1) Local $Lv = GUICtrlCreateListView('List of Items', 5, 5, 400, 390) $hLv = GUICtrlGetHandle($Lv) GUICtrlSendMsg($Lv, 0x101E, 0, 396) _GUICtrlListView_EnableGroupView($Lv) GUISetOnEvent(-3, '_AllExit') ; ;create as many context menus set to a dummy control placeholder as you need Local $aMenu[4] ;array for storing group menu handles Local $cMenu1 = GUICtrlCreateDummy() Local $cMenu2 = GUICtrlCreateDummy() $aMenu[1] = Menu1_SetMenu2LvItemCtrl($cMenu1) $aMenu[2] = Menu2_SetMenu2LvItemCtrl($cMenu2) $aMenu[3] = 0 $aMenu[0] = 2 _Set_Items();create listview items and set each item to group 1 or 2 membership GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY") GUIRegisterMsg($WM_CONTEXTMENU, "_WM_CONTEXTMENU") GUIRegisterMsg($WM_SYSCOMMAND, "_WM_SYSCOMMAND") GUISetState(@SW_SHOW, $gui) GUICtrlCreateButton("", 5, 410, 80, 25) ;*** ;button added to allow changing focus with tab to demonstrate fix for annoying windows feature. ;the system menu will capture the keyboard focus from the listview ;when shift-f10 is used on an item without a contextmenu. ;when scrolling through the listview items with the arrow keys and using shift-f10 ;instead of the menu appkey to pop up the selected items contextmenu, the system menu will be activated if ;the item does not have a contextmenu, this is standard windows behaviour. ;when the arrow key is next moved after using shift-f10 on an item without a contextmenu, ;the system menu will pop up and capture the keyboard. ;this behaviour can be changed by setting a flag when an item does not have a contextmenu ;and in WM_SYSCOMMAND check for the $SC_KEYMENU command, reset the flag and return zero. While 1 Sleep(1000) WEnd ; Func _AllExit() GUIDelete($gui) Exit EndFunc ;==>_AllExit ; Func _Set_Items() ; ======================================================== Local $hLvi _GUICtrlListView_InsertGroup($Lv, 0, 1, "Group 1") For $i = 1 To 5 $hLvi = GUICtrlCreateListViewItem('ITEM ' & $i, $Lv) _GUICtrlListView_SetItemGroupID($Lv, _GUICtrlListView_GetItemCount($Lv) - 1, 1) Next ; ======================================================== _GUICtrlListView_InsertGroup($Lv, _GUICtrlListView_GetItemCount($Lv) - 1, 2, "Group 2") For $i = 1 To 5 $hLvi = GUICtrlCreateListViewItem('ITEM ' & $i, $Lv) _GUICtrlListView_SetItemGroupID($Lv, _GUICtrlListView_GetItemCount($Lv) - 1, 2) Next ; ======================================================== _GUICtrlListView_InsertGroup($Lv, _GUICtrlListView_GetItemCount($Lv) - 1, 3, "Group 3") For $i = 1 To 5 $hLvi = GUICtrlCreateListViewItem('ITEM ' & $i, $Lv) _GUICtrlListView_SetItemGroupID($Lv, _GUICtrlListView_GetItemCount($Lv) - 1, 3) Next ; ======================================================== EndFunc ;==>_Set_Items ; Func _WM_NOTIFY($hWnd, $Msg, $wParam, $lParam) #forceref $hWnd, $Msg, $wParam Local $tNMHDR, $hWndFrom, $iCode $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iCode = DllStructGetData($tNMHDR, "Code") Local $IDFrom = DllStructGetData($tNMHDR, "IDFrom") Switch $IDFrom Case $Lv Switch $iCode Case $NM_RCLICK ; determine if right click on an item $iGroupID = -1 ;reset global ID Local $tInfox = DllStructCreate($tagNMITEMACTIVATE, $lParam) If @error Then Return $GUI_RUNDEFMSG Local $Item = DllStructGetData($tInfox, "Index") If @error Or $Item = -1 Then Return $GUI_RUNDEFMSG Local $tTest = DllStructCreate($tagLVHITTESTINFO) DllStructSetData($tTest, "X", DllStructGetData($tInfox, "X")) DllStructSetData($tTest, "Y", DllStructGetData($tInfox, "Y")) Local $iRet = GUICtrlSendMsg($IDFrom, $LVM_HITTEST, 0, DllStructGetPtr($tTest)) If @error Or $iRet = -1 Then Return $GUI_RUNDEFMSG ; -1 = not on lv item, otherwise returns index Switch DllStructGetData($tTest, "Flags") Case $LVHT_ONITEMICON, $LVHT_ONITEMLABEL, $LVHT_ONITEM ;hit was on item icon or 1st row or subitem ;get the items group membership ID ;(stripped down version of _GUICtrlListView_GetItemGroupID() - several dllcalls removed) Local $tItem = DllStructCreate($tagLVITEM) DllStructSetData($tItem, "Mask", $LVIF_GROUPID) DllStructSetData($tItem, "Item", $Item) Local $iRet = GUICtrlSendMsg($IDFrom, $LVM_GETITEMW, 0, DllStructGetPtr($tItem)) If @error Or $iRet <> 1 Then $iGroupID = -1 Else $iGroupID = DllStructGetData($tItem, "GroupID") If $iGroupID < 0 Then $iGroupID = -1 EndIf EndSwitch EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_WM_NOTIFY ;fix for system menu focus stealing from the listview with Shift-F10 ;on lv items without a contextmenu Func _WM_SYSCOMMAND($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam ;SC_KEYMENU = 0xF100 If $wParam = $SC_KEYMENU And $fSysMenu = False Then $fSysMenu = True Return 0 EndIf Return $GUI_RUNDEFMSG EndFunc ;==>_WM_CONTEXTMENU Func _WM_CONTEXTMENU($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam Switch $wParam Case $hLv ;bypass other contextmenus ;If $lParam = -1 Then Return $GUI_RUNDEFMSG ;option: ignore menu appkey/Shift-F10 Local $iX, $iY, $aSel, $aPos, $iIdx, $tpoint If $lParam = -1 Then ;Menu Appkey/Shift-F10 ;get last selected item (if one or more selected by keyboard)) $aSel = _GUICtrlListView_GetSelectedIndices($wParam, True) If @error Or UBound($aSel) <= 1 Then Return $GUI_RUNDEFMSG If $aSel[$aSel[0]] = -1 Then Return $GUI_RUNDEFMSG $iIdx = $aSel[$aSel[0]] ;get group ID Local $tItem = DllStructCreate($tagLVITEM) DllStructSetData($tItem, "Mask", $LVIF_GROUPID) DllStructSetData($tItem, "Item", $iIdx) Local $iRet = _SendMessage($wParam, $LVM_GETITEMW, 0, DllStructGetPtr($tItem), 0, "wparam", "ptr") If @error Or $iRet <> 1 Then $iGroupID = -1 Else $iGroupID = DllStructGetData($tItem, "GroupID") If $iGroupID < 0 Then $iGroupID = -1 EndIf If $iGroupID <> -1 Then $aPos = _GUICtrlListView_GetItemPosition($wParam, $iIdx) $tpoint = DllStructCreate("int X;int Y") DllStructSetData($tpoint, "X", $aPos[0]) DllStructSetData($tpoint, "Y", $aPos[1]) _WinAPI_ClientToScreen($wParam, $tPoint) $iX = DllStructGetData($tpoint, "X") $iY = DllStructGetData($tpoint, "Y") EndIf Else $iX = BitAND($lParam, 0x0000FFFF) $iY = BitShift($lParam, 16) EndIf If $iGroupID = -1 Or $iGroupID > (UBound($aMenu) - 1) Then Return $GUI_RUNDEFMSG ;failed hittests on listview If $iX >= 0 And $iY >= 0 Then ;pop the menu for the group membership ID If $aMenu[$iGroupID] <> 0 And _GUICtrlMenu_IsMenu($aMenu[$iGroupID]) = 1 Then _GUICtrlMenu_TrackPopupMenu($aMenu[$iGroupID], $hWnd, $iX, $iY, 1, 1, 1) $iGroupID = -1 Return True Else $fSysMenu = False EndIf EndIf EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_WM_CONTEXTMENU Func Menu1_SetMenu2LvItemCtrl($LvI) Local $h = GUICtrlCreateContextMenu($LvI) Local $a = GUICtrlCreateMenuItem('Menu1 - Menu Item1', $h) Local $b = GUICtrlCreateMenuItem('Menu1 - Menu Item2', $h) GUICtrlCreateMenuItem('', $h) Local $c = GUICtrlCreateMenuItem('Menu1 - Menu Item3', $h) Local $d = GUICtrlCreateMenuItem('Menu1 - Menu Item4', $h) GUICtrlCreateMenuItem('', $h) Local $e = GUICtrlCreateMenuItem('Menu1 - Menu Item5', $h) Local $f = GUICtrlCreateMenuItem('Menu1 - Menu Item6', $h) GUICtrlCreateMenuItem('', $h) Local $g = GUICtrlCreateMenuItem('Menu1 - Menu Item7', $h) GUICtrlSetOnEvent($a, '_Function1') GUICtrlSetOnEvent($b, '_Function2') GUICtrlSetOnEvent($c, '_Function3') GUICtrlSetOnEvent($d, '_Function4') GUICtrlSetOnEvent($e, '_Function5') GUICtrlSetOnEvent($f, '_Function6') GUICtrlSetOnEvent($g, '_Function7') Return GUICtrlGetHandle($h) EndFunc ;==>Menu1_SetMenu2LvItemCtrl ; Func Menu2_SetMenu2LvItemCtrl($LvI) Local $h = GUICtrlCreateContextMenu($LvI) Local $a = GUICtrlCreateMenuItem('Menu2 - Menu Item1', $h) Local $b = GUICtrlCreateMenuItem('Menu2 - Menu Item2', $h) GUICtrlSetOnEvent($a, '_Function1') GUICtrlSetOnEvent($b, '_Function8') Return GUICtrlGetHandle($h) EndFunc ;==>Menu2_SetMenu2LvItemCtrl ; ; Func _Function1() MsgBox(0, '', '_Function1()') EndFunc ;==>_Function1 ; Func _Function2() MsgBox(0, '', '_Function2()') EndFunc ;==>_Function2 ; Func _Function3() MsgBox(0, '', '_Function3()') EndFunc ;==>_Function3 ; Func _Function4() MsgBox(0, '', '_Function4()') EndFunc ;==>_Function4 ; Func _Function5() MsgBox(0, '', '_Function5()') EndFunc ;==>_Function5 ; Func _Function6() MsgBox(0, '', '_Function6()') EndFunc ;==>_Function6 ; Func _Function7() MsgBox(0, '', '_Function7()') EndFunc ;==>_Function7 ; Func _Function8() MsgBox(0, '', '_Function8()') EndFunc ;==>_Function8 I see fascists...
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