Нижепреведенный код работает, но не очень корректно.
Нельзя правой клавишей мыши выделять пункты TreeView.
То есть, приходится сначала нажать левой клавишей на интересующий пункт TreeView, а уже потом применить к нему контекстное меню. Иначе контекстное меню будет применяться к последнему выделенному пунктуTreeView.
Как можно решить эту проблему?
Нельзя правой клавишей мыши выделять пункты TreeView.
То есть, приходится сначала нажать левой клавишей на интересующий пункт TreeView, а уже потом применить к нему контекстное меню. Иначе контекстное меню будет применяться к последнему выделенному пунктуTreeView.
Как можно решить эту проблему?
Код:
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiTreeView.au3>
$iStyle = BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS)
$hForm1 = GUICreate("Form1", 400, 436, 123, 130)
$hTreeView = _GUICtrlTreeView_Create($hForm1, 8, 8, 225, 420, $iStyle, $WS_EX_CLIENTEDGE)
$hItem1 = _GUICtrlTreeView_Add($hTreeView, 0, 'Parent')
_GUICtrlTreeView_AddFirst($hTreeView, 0, 'Parent First')
_GUICtrlTreeView_AddChild($hTreeView, $hItem1, 'str1')
_GUICtrlTreeView_AddChild($hTreeView, $hItem1, 'str2')
_GUICtrlTreeView_Expand($hTreeView, $hItem1) ; Развернуть пункт
; ---- Контекстное Меню для TreeView
$DummyMenu = GUICtrlCreateDummy()
$ContextMenu = GUICtrlCreateContextMenu($DummyMenu)
$ContextMenu1 = GUICtrlCreateMenuItem("Строка1", $ContextMenu)
;$ContextMenu2 = GUICtrlCreateMenuItem("Строка2", $ContextMenu)
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
Exit
Case $ContextMenu1
$hItem=_GUICtrlTreeView_GetSelection($hTreeView)
$ItemText=_GUICtrlTreeView_GetText($hTreeView,$hItem)
MsgBox(64,'',$ItemText)
EndSwitch
WEnd
; Show a menu in a given GUI window which belongs to a given GUI ctrl
Func ShowMenu($hWnd, $nContextID, $nContextControlID, $iMouse=0)
Local $hMenu = GUICtrlGetHandle($nContextID)
Local $iCtrlPos = ControlGetPos($hWnd, "", $nContextControlID)
Local $X = $iCtrlPos[0]
Local $Y = $iCtrlPos[1] + $iCtrlPos[3]
ClientToScreen($hWnd, $X, $Y)
If $iMouse Then
$X = MouseGetPos(0)
$Y = MouseGetPos(1)
EndIf
DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $X, "int", $Y, "hwnd", $hWnd, "ptr", 0)
EndFunc
; Convert the client (GUI) coordinates to screen (desktop) coordinates
Func ClientToScreen($hWnd, ByRef $x, ByRef $y)
Local $stPoint = DllStructCreate("int;int")
DllStructSetData($stPoint, 1, $x)
DllStructSetData($stPoint, 2, $y)
DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint))
$x = DllStructGetData($stPoint, 1)
$y = DllStructGetData($stPoint, 2)
; release Struct not really needed as it is a local
$stPoint = 0
EndFunc
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg, $iwParam
Local $hWndFrom, $iCode, $tNMHDR, $hWndTreeView, $hWndListView, $tInfo
; Контекстное меню Для TreeView
$hWndTreeView = $hTreeView
If Not IsHWnd($hTreeView) Then $hWndTreeView = GUICtrlGetHandle($hTreeView)
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iCode = DllStructGetData($tNMHDR, "Code")
Switch $hWndFrom
Case $hWndTreeView
Switch $iCode
Case $NM_RCLICK ; Контекстное меню
$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
$iIndex = DllStructGetData($tInfo, "Index")
If $iIndex <> -1 Then
$iLast_LV_Index = $iIndex
ShowMenu($hWnd, $ContextMenu, $hTreeView, 1)
EndIf
Case $NM_CLICK
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc