[已解决]求解TreeView如何取得鼠标所在节点信息HotTrack形式
本帖最后由 dhlhmgc 于 2023-4-5 09:42 编辑目标想得到 TreeView 的鼠标移入、移出消息事件,求出当前鼠标下的节点信息!
就是HotTrack形式,在处理TREEVIEW控件又遇到问题 ,GUI消息事件:WM_NOTIFY
====================================
$tNMHdr = DllStructCreate("hwnd hWndFrom;int IDFrom;int Code;dword dwFlags"
已经知道:鼠标移入,移出的动态值就是在 dwFlags 里面,调试输出也有变化
但case的事件常量不知道用什么,求指教:
Switch $iIDFrom
Case $TreeView1
Switch $iCode
Case $NM_CLICK ;左键单击
============================================
鼠标移入\移出 试过:
;Case $BCN_HOTITEMCHANGE ; Win XP and Above
; If BitAND($dwFlags, 0x10) = 0x10 Then
; $sText = "$BCN_HOTITEMCHANGE - Entering:当鼠标进入 "
; WinSetTitle($fm1, "", "dw : " & $dwFlags)
; ElseIf BitAND($dwFlags, 0x20) = 0x20 Then
; $sText = "$BCN_HOTITEMCHANGE - Leaving: 当鼠标移出"
; WinSetTitle($fm1, "", "dw : " & $dwFlags)
; EndIf
貌似不起作用,这个是不是只对Button等控件起作用!?
TVN_开头的也看了一堆,但不确定移入、移出的CODE代码常量是哪个!?
求高人指点!
[已解决]
==============
非常感谢各位大神无私的指导,虽然对WM_NOTIFY、WM_COMMAND的消息机构还不是太熟悉,但目前的问题已基本得到解决!现次感谢!
==============
;---------------------------------------------------------------------------------------
; 功能: 对 TreeView项目的鼠标跟踪
; 语法:
;---------------------------------------------------------------------------------------
#include <WinAPI.au3>
#include <WinAPISys.au3>
#include <GuiTreeView.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <date.au3>
OnAutoItExitRegister('OnAutoItExit')
dim $hGUI = GUICreate('', 400, 300)
$iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES)
;$TreeView1 = GUICtrlCreateTreeView(5, 5, 390, 280, $iStyle, $WS_EX_CLIENTEDGE)
$TreeView1 = GUICtrlCreateTreeView(5, 5, 390, 280, -1, $WS_EX_CLIENTEDGE )
$hTreeView = GUICtrlGetHandle(-1)
GUICtrlSetFont(-1, 12, 400, 0, "宋体")
$TreeViewItem1 = GUICtrlCreateTreeViewItem('TreeViewItem1', $TreeView1)
GUICtrlCreateTreeViewItem('TreeViewItem1-1', $TreeViewItem1)
GUICtrlCreateTreeViewItem('TreeViewItem1-2', $TreeViewItem1)
GUICtrlCreateTreeViewItem('TreeViewItem1-3', $TreeViewItem1)
$TreeViewItem2 = GUICtrlCreateTreeViewItem('TreeViewItem2', $TreeView1)
GUICtrlCreateTreeViewItem('TreeViewItem2-1', $TreeViewItem2)
GUICtrlCreateTreeViewItem('TreeViewItem2-2', $TreeViewItem2)
GUICtrlCreateTreeViewItem('TreeViewItem2-3', $TreeViewItem2)
$TreeViewItem3 = GUICtrlCreateTreeViewItem('TreeViewItem3', $TreeView1)
GUICtrlCreateTreeViewItem('TreeViewItem3-1', $TreeViewItem3)
GUICtrlCreateTreeViewItem('TreeViewItem3-2', $TreeViewItem3)
GUICtrlCreateTreeViewItem('TreeViewItem3-3', $TreeViewItem3)
;~ GUICtrlSetState($TreeViewItem1, $GUI_EXPAND)
;~ GUICtrlSetState($TreeViewItem2, $GUI_EXPAND)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ;捕捉窗口控件交互时事件
GUISetState()
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case -3
Exit
EndSwitch
WEnd
Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
#forceref $hWnd, $Msg, $wParam
Local Const $BCN_HOTITEMCHANGE = -1249
Local $tNMBHOTITEM = DllStructCreate("hwnd hWndFrom;int IDFrom;int Code;dword dwFlags", $lParam)
Local $nNotifyCode = DllStructGetData($tNMBHOTITEM, "Code")
Local $nID = DllStructGetData($tNMBHOTITEM, "IDFrom")
Local $hCtrl = DllStructGetData($tNMBHOTITEM, "hWndFrom")
Local $dwFlags = DllStructGetData($tNMBHOTITEM, "dwFlags")
;Local $iMousePosX = BitAND($lParam, 0xFFFF) ;低位字,鼠标的 X 位置
;Local $iMousePosY = BitShift($lParam, 16) ;高位字,鼠标的 Y 位置
local $hForm = _WinAPI_GetParent( $hCtrl ) ;//检索指定子窗口的父窗口句柄.
Switch $nNotifyCode
Case $NM_CLICK
Case $NM_SETCURSOR
if $dwFlags Then
Local $tMPos= _WinAPI_GetMousePos(True, $hCtrl)
Local $tHit = _GUICtrlTreeView_HitTestEx($hCtrl, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2))
Local $hItem= DllStructGetData($tHit, "Item")
_GUICtrlTreeView_SelectItem ($TreeView1, $hItem, $TVGN_CARET) ;选中
$s = _GUICtrlTreeView_GetText ($TreeView1, $hItem)
$hItem = _GUICtrlTreeView_GetSelection($hCtrl)
if $hItem Then
$ss = " 热点:" & _GUICtrlTreeView_GetText ($TreeView1, $hItem)
else
$ss = ""
Endif
WinSetTitle($hForm, "", Random(10, 20, 1) & ' 鼠标:' & $s & $ss)
Return $GUI_RUNDEFMSG
Endif
EndSwitch
EndFunc
自己完善下吧,大致思路就是回调函数中修改
#include <WinAPISysWin.au3>
#include <GUIConstantsEx.au3>
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>
Global $g_hTreeView
Local $hGUI = GUICreate("TreeView Create (v" & @AutoItVersion & ")", 400, 300)
Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES)
$g_hTreeView = _GUICtrlTreeView_Create($hGUI, 2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE)
GUISetState(@SW_SHOW)
;~ GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
_GUICtrlTreeView_BeginUpdate($g_hTreeView)
Local $hItem
For $x = 0 To 5
$hItem = _GUICtrlTreeView_Add($g_hTreeView, 0, StringFormat("[%02d] New Item", $x))
For $y = 0 To 3
_GUICtrlTreeView_AddChild($g_hTreeView, $hItem, StringFormat("[%02d] New Child", $y))
Next
Next
_GUICtrlTreeView_EndUpdate($g_hTreeView)
$hProcNew = DllCallbackRegister("_MyWindowProc", "ptr", "hwnd;uint;long;ptr")
$g_hProcOld = _WinAPI_SetWindowLong($g_hTreeView, $GWL_WNDPROC, DllCallbackGetPtr($hProcNew))
; Loop until the user exits.
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
GUIDelete()
Func _MyWindowProc($hWnd, $iMsg, $wParam, $lParam)
Local $iCtrl = _WinAPI_GetDlgCtrlID($hWnd)
Local Const $TME_HOVER = 0x00000001
Local Const $TME_LEAVE = 0x00000002
Switch $iMsg
Case $WM_MOUSEHOVER ;鼠标悬停
Local Static $cur = 0
Local $hot = _TreeItemFromPoint($hWnd)
If $hot <> 0 Then
If $hot <> $cur Then
ConsoleWrite('移入' & $hot & @CRLF)
$cur = $hot
EndIf
EndIf
Case $WM_MOUSELEAVE ;鼠标离开
Case $WM_MOUSEMOVE ;鼠标移动
__TrackMouseEvent($hWnd, BitOR($TME_HOVER, $TME_LEAVE), 1) ;//MOUSELEAVE|MOUSEHOVER消息由此函数触发
Case $WM_LBUTTONUP ;弹起鼠标左键
Case $WM_LBUTTONDOWN ;按下鼠标左键
EndSwitch
Return _WinAPI_CallWindowProc($g_hProcOld, $hWnd, $iMsg, $wParam, $lParam)
EndFunc ;==>_MyWindowProc
Func __TrackMouseEvent($hWnd, $iFlags, $iTime = -1)
Local $tTME = DllStructCreate('dword;dword;hwnd;dword')
DllStructSetData($tTME, 1, DllStructGetSize($tTME))
DllStructSetData($tTME, 2, $iFlags)
DllStructSetData($tTME, 3, $hWnd)
DllStructSetData($tTME, 4, $iTime)
Local $aRet = DllCall('user32.dll', 'bool', 'TrackMouseEvent', 'struct*', $tTME)
If @error Then Return SetError(@error, @extended, 0)
Return $aRet
EndFunc ;==>__TrackMouseEvent
Func _TreeItemFromPoint($hWnd)
Local $tMPos = _WinAPI_GetMousePos(True, $hWnd)
Return _GUICtrlTreeView_HitTestItem($hWnd, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2))
EndFunc ;==>_TreeItemFromPoint
可用
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
If Not IsHWnd($TreeView) Then $hWndTreeView = GUICtrlGetHandle($TreeView)
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iCode = DllStructGetData($tNMHDR, "Code")
Switch $hWndFrom
Case $hWndTreeView
Switch $iCode
Case $NM_CLICK ; 鼠标左键单击
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY
页:
[1]