Sign in to follow this  
Followers 0
sandin

how can treeview detect enter button?

14 posts in this topic

#1 ·  Posted (edited)

I'm building a script with treeview, and I'm using WM_NOTIFY to detect any operation regarding treeview, though I can't find how to make it detect ENTER key, I tried this:

Case $TVN_KEYDOWN ; A key has been pressed
                    $tInfo = DllStructCreate($tagNMTVKEYDOWN, $lParam)
                    ConsoleWrite(DllStructGetData($tInfo, "VKey") & @CRLF)oÝ÷ Ù©Ý"­iÊyú+z÷«ÊG²²Úèç±qêmÔÄFG²N«{lj[(jz-êé®åzh"Ç­j|¨~l¢µé­ e
ÚåN·V'°Ø­Mìm²Ö­{^â+!·*b!jÒ0j{Hq©÷ö۽譲)ÜxCS¬]z×µ¦åzØb²+,¶¶§çºÇ¶¸vØ^±©Â+a+-¾'°jwb~+^+"çb¶ËZµê'qâ!קµêíébè¬mè§Æ¯yÖ¬ì-ʧ^nëpØeËoìq©÷öØbµéíz¶§uÊ'r[zw°·*hl@ÈOöÞÅ©©æuçZºÚ"µÍÚ[ÛYH   ÑÝZPÛÛÝ[Ñ^]LÉÝÂÚ[ÛYH ÑÝZUYUY]Ë]LÉÝÂÚ[ÛYH ÕÚ[ÝÜÐÛÛÝ[Ë]LÉÝÂÜ
    ][ÝÑÕRPÛÜÙSÛTÐÉ][ÝË
BÌÍÚTÝ[HH]Ô    ÌÍÕ×ÑQUPSË    ÌÍÕ×ÒTÐUÓË  ÌÍÕ×ÒTÓSTË   ÌÍÕ×ÓSTÐUÓÕ ÌÍÕ×ÑTÐPQQÑÔ    ÌÍÕ×ÔÒÕÔÑSSÐVTÊBÌÍÑÕRHHÕRPÜX]J ][ÝÕYUY]É][ÝË
Ì
BÌÍÝY]Y]ÈHÑÕRPÝYUY]×ÐÜX]J ÌÍÑÕRKÎM   ÌÍÚTÝ[K ÌÍÕÔ×ÑVÐÓQSQÑJBÕRTÙ]Ý]J
BÕRTYÚÝÙÊ  ÌÍÕÓWÓÕQK ][Ý×ÕÓWÓÕQI][ÝÊBÑÕRPÝYUY]×ÐYÚ[]J  ÌÍÝY]Y]ÊBÜ ÌÍÞHHÈ[ÛJLJBIÌÍÚ][HHÑÕRPÝYUY]×ÐY
    ÌÍÝY]Y]ËÝ[ÑÜX]
    ][ÝÓ]È][I][ÝË  ÌÍÞ
JBQÜ   ÌÍÞHHHÈ[ÛJLJBBWÑÕRPÝYUY]×ÐYÚ[
    ÌÍÝY]Y]Ë    ÌÍÚ][[ÑÜX]
    ][ÝÓ]ÈÚ[    ][ÝË  ÌÍÞJJBS^^ÑÕRPÝYUY]×Ñ[]J ÌÍÝY]Y]ÊBÂ[[ÕRQÙ]ÙÊ
HH  ÌÍÑÕRWÑUSÐÓÔÑB[ÈÕÓWÓÕQJ   ÌÍÚÛÕRK    ÌÍÓÙÒQ ÌÍÝÔ[K  ÌÍÛ[JBHÙÜÙY   ÌÍÚÛÕRK    ÌÍÓÙÒQ ÌÍÝÔ[BSØØ[    ÌÍÝR ÌÍÙ][    ÌÍÚÛÛK ÌÍØÛÙK ÌÍÚWÚY]Ë   ÌÍÙÑYÜË   ÌÍÛÝ[   ÌÍÚYÛK  ÌÍÚWÚYÛSØØ[  ÌÍÝUÓÓT    ÌÍÝUÕUSBIÌÍÝRHÝXÝÜX]J ÌÍÝYÓR  ÌÍÛ[JBIÌÍÚÛÛHHÝXÝÙ]]J    ÌÍÝR ][ÝÚÛÛI][ÝÊBIÌÍÚYÛHHÝXÝÙ]]J    ÌÍÝR ][ÝÒQÛI][ÝÊBIÌÍØÛÙHHÝXÝÙ]]J    ÌÍÝR ][ÝÐÛÙI][ÝÊBTÝÚ]Ú  ÌÍÚÛÛBBXØÙH  ÌÍÝY]Y]ÂBBTÝÚ]Ú  ÌÍØÛÙBBBBPØÙH    ÌÍÕÒÑVQÕÓÈHÙ^HÈY[ÜÙYBBBBIÌÍÝ[ÈHÝXÝÜX]J   ÌÍÝYÓUÑVQÕÓ  ÌÍÛ[JBBBBBPÛÛÛÛUÜ]JÝXÝÙ]]J   ÌÍÝ[Ë   ][ÝÕÙ^I][ÝÊH   [ÈÔBBBBBSØØ[    ÌÍØÝ[ÜÙ[[ÛHÑÕRPÝYUY]×ÑÙ]Ù[[Û   ÌÍÝY]Y]ÊBBBBBZYÝXÝÙ]]J   ÌÍÝ[Ë   ][ÝÕÙ^I][ÝÊHH  ][ÝÎMÎ
M
I][ÝÈ[ÑÕRPÝYUY]×ÑY]^
    ÌÍÝY]Y]Ë    ÌÍØÝ[ÜÙ[[ÛHÑÙ^H
Y]
BBBQ[ÝÚ]ÚQ[ÝÚ]ÚT] ÌÍÑÕRWÔSQTÑÂ[[ÈÏOIÝ×ÕÓWÓÕQ

P.S. Since it's not detecting ENTER, it's not detecting ESC either (to cancel editing treeview's item)

Edited by sandin

Share this post


Link to post
Share on other sites



Tnx! that did the trick =) however, I still have this issue remaining, how to save edited item once I changed it's txt? It's working fine with listview, but it isn't with treeview, it just won't conclude editing on ENTER and cancel on ESC like it does with listview, why is that? Is it a bug or am I missing something (style $TVS_EDITLABELS is included in the creation of the treeview)?

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

sandin

Hotkeys rules :)

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiTreeView.au3>

Opt("GUICloseOnESC", 0)

HotKeySet("{F2}", "_TextEdit")
HotKeySet("{Enter}", "_TextSet")
HotKeySet("{Esc}", "_EditClose")

Global $iEditFlag = 0

$hGUI = GUICreate("Test GUI", 300, 200)

GUICtrlCreateLabel("F2 - Edit text, Enter - Set text", 10, 10, 140, 16)

$hTreeView = _GUICtrlTreeView_Create($hGUI, 10, 40, 280, 140, _
BitOR($TVS_EDITLABELS, $TVS_INFOTIP, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_HASBUTTONS), $WS_EX_CLIENTEDGE)

For $i = 1 To 5
    $hItem = _GUICtrlTreeView_Add($hTreeView, $i, "Item" & $i)
    For $j = 1 To 5
        _GUICtrlTreeView_AddChild($hTreeView, $hItem, "SubItem" & $j)
    Next
Next

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

GUISetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $tNMHDR, $HwndFrom, $iCode
    
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $HwndFrom = DllStructGetData($tNMHDR, "HwndFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    
    Switch $HwndFrom
        Case $hTreeView
            Switch $iCode
                Case $TVN_ENDLABELEDIT, $TVN_ENDLABELEDITW
                    If $iEditFlag Then
                        $iEditFlag = 0
                        Local $tInfo = DllStructCreate($tagNMTVDISPINFO, $lParam)
                        Local $sBuffer = DllStructCreate("wchar Text[" & DllStructGetData($tInfo, "TextMax") & "]")
                        If Not _GUICtrlTreeView_GetUnicodeFormat($HwndFrom) Then $sBuffer = StringTrimLeft($sBuffer, 1)
                        DllStructSetData($sBuffer, "Text", DllStructGetData($tInfo, "Text"))
                        If StringLen(DllStructGetData($sBuffer, "Text")) Then Return 1
                    EndIf
            EndSwitch
    EndSwitch
    
    Return $GUI_RUNDEFMSG
EndFunc

Func _TextEdit()
    Local $hItem = _GUICtrlTreeView_GetSelection($hTreeView)
    If $hItem Then _GUICtrlTreeView_EditText($hTreeView, $hItem)
EndFunc

Func _TextSet()
    $iEditFlag = 1
    _GUICtrlTreeView_EndEdit($hTreeView)
EndFunc

Func _EditClose()
    $iEditFlag = 0
    _GUICtrlTreeView_EndEdit($hTreeView)
EndFunc
Edited by rasim

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

that really works, but having hotkeys is not very good option for any script, especially ENTER and ESC ones, cause, then it blocks sending ENTER and ESC to any other windows application.

I tried to do it over subclass method as u suggested previous, but soon as a treeview item get input status, nothing of the script can be detected (if it's not a hotkey)

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiTreeView.au3>
#Include <WinAPI.au3>
#include <Constants.au3>
#Include <Misc.au3>

Opt("GUICloseOnESC", 0)

Global Const $VK_RETURN = 0x0D ;Enter key
Global Const $VK_ESC = 0x1B ;Esc key
Global Const $VK_F2 = 0x71 ;F2 key
;~ HotKeySet("{F2}", "_TextEdit")
;~ HotKeySet("{Enter}", "_TextSet")
;~ HotKeySet("{Esc}", "_EditClose")

Global $iEditFlag = 0

$hGUI = GUICreate("Test GUI", 300, 200)

GUICtrlCreateLabel("F2 - Edit text, Enter - Set text", 10, 10, 140, 16)

$hTreeView = _GUICtrlTreeView_Create($hGUI, 10, 40, 280, 140, _
BitOR($TVS_EDITLABELS, $TVS_INFOTIP, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_HASBUTTONS), $WS_EX_CLIENTEDGE)

For $i = 1 To 5
    $hItem = _GUICtrlTreeView_Add($hTreeView, $i, "Item" & $i)
    For $j = 1 To 5
        _GUICtrlTreeView_AddChild($hTreeView, $hItem, "SubItem" & $j)
    Next
Next

GUISetState()

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
$wProcHandle = DllCallbackRegister("_WindowProc", "int", "hwnd;uint;wparam;lparam")
$wProcOld = _WinAPI_SetWindowLong($hTreeView, $GWL_WNDPROC, DllCallbackGetPtr($wProcHandle))

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            _WinAPI_SetWindowLong($hTreeView, $GWL_WNDPROC, $wProcOld)
            DllCallbackFree($wProcHandle)
            Exit
    EndSwitch
WEnd

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $tNMHDR, $HwndFrom, $iCode
   
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $HwndFrom = DllStructGetData($tNMHDR, "HwndFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
   
    Switch $HwndFrom
        Case $hTreeView
            Switch $iCode
                Case $TVN_ENDLABELEDIT, $TVN_ENDLABELEDITW
                    If $iEditFlag Then
                        $iEditFlag = 0
                        Local $tInfo = DllStructCreate($tagNMTVDISPINFO, $lParam)
                        Local $sBuffer = DllStructCreate("wchar Text[" & DllStructGetData($tInfo, "TextMax") & "]")
                        If Not _GUICtrlTreeView_GetUnicodeFormat($HwndFrom) Then $sBuffer = StringTrimLeft($sBuffer, 1)
                        DllStructSetData($sBuffer, "Text", DllStructGetData($tInfo, "Text"))
                        If StringLen(DllStructGetData($sBuffer, "Text")) Then Return 1
                    EndIf
;~              Case $TVN_BEGINLABELEDIT, $TVN_BEGINLABELEDITW
                    
            EndSwitch
    EndSwitch
   
    Return $GUI_RUNDEFMSG
EndFunc


Func _WindowProc($hWnd, $Msg, $wParam, $lParam)
    Switch $hWnd
        Case $hTreeView
            Switch $Msg
                Case $WM_GETDLGCODE
                    Switch $wParam
                        Case $VK_RETURN
                            _TextSet()
                        case $VK_ESC
                            _EditClose()
                        case $VK_F2
                            _TextEdit()
                    EndSwitch
            EndSwitch
    EndSwitch
   
    Return _WinAPI_CallWindowProc($wProcOld, $hWnd, $Msg, $wParam, $lParam)
EndFunc

Func _TextEdit()
    Local $hItem = _GUICtrlTreeView_GetSelection($hTreeView)
    If $hItem Then _GUICtrlTreeView_EditText($hTreeView, $hItem)
EndFunc

Func _TextSet()
    $iEditFlag = 1
    _GUICtrlTreeView_EndEdit($hTreeView)
EndFunc

Func _EditClose()
    $iEditFlag = 0
    _GUICtrlTreeView_EndEdit($hTreeView)
EndFunc
Edited by sandin

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

I've done it, tnx for help rasim

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiTreeView.au3>
#include <Constants.au3>

Opt("GUICloseOnESC", 0)

Global $iEditFlag = 0

$hGUI = GUICreate("Test GUI", 300, 200)

GUICtrlCreateLabel("F2 - Edit text, Enter - Set text", 10, 10, 140, 16)

$hTreeView = _GUICtrlTreeView_Create($hGUI, 10, 40, 280, 140, _
BitOR($TVS_EDITLABELS, $TVS_INFOTIP, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_HASBUTTONS), $WS_EX_CLIENTEDGE)

For $i = 1 To 5
    $hItem = _GUICtrlTreeView_Add($hTreeView, $i, "Item" & $i)
    For $j = 1 To 5
        _GUICtrlTreeView_AddChild($hTreeView, $hItem, "SubItem" & $j)
    Next
Next

GUISetState()

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $tNMHDR, $HwndFrom, $iCode
   
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $HwndFrom = DllStructGetData($tNMHDR, "HwndFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
   
    Switch $HwndFrom
        Case $hTreeView
            Switch $iCode
                Case $TVN_ENDLABELEDIT, $TVN_ENDLABELEDITW
                    If $iEditFlag Then
                        $iEditFlag = 0
                        Local $tInfo = DllStructCreate($tagNMTVDISPINFO, $lParam)
                        Local $sBuffer = DllStructCreate("wchar Text[" & DllStructGetData($tInfo, "TextMax") & "]")
                        If Not _GUICtrlTreeView_GetUnicodeFormat($HwndFrom) Then $sBuffer = StringTrimLeft($sBuffer, 1)
                        DllStructSetData($sBuffer, "Text", DllStructGetData($tInfo, "Text"))
                        If StringLen(DllStructGetData($sBuffer, "Text")) Then Return 1
                    EndIf
                    HotKeySet("{Enter}")
                    HotKeySet("{Esc}")
                Case $TVN_BEGINLABELEDIT, $TVN_BEGINLABELEDITW
                    HotKeySet("{Enter}", "_TextSet")
                    HotKeySet("{Esc}", "_EditClose")
                Case $NM_SETFOCUS
                    HotKeySet("{F2}", "_TextEdit")
                Case $NM_KILLFOCUS
                    HotKeySet("{F2}")
            EndSwitch
    EndSwitch
   
    Return $GUI_RUNDEFMSG
EndFunc

Func _TextEdit()
    Local $hItem = _GUICtrlTreeView_GetSelection($hTreeView)
    If $hItem Then _GUICtrlTreeView_EditText($hTreeView, $hItem)
EndFunc

Func _TextSet()
    $iEditFlag = 1
    _GUICtrlTreeView_EndEdit($hTreeView)
EndFunc

Func _EditClose()
    $iEditFlag = 0
    _GUICtrlTreeView_EndEdit($hTreeView)
EndFunc
Edited by sandin

Share this post


Link to post
Share on other sites

sandin

Q How to set hotkey only if my GUI is active?

A Example:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>

$hGUI = GUICreate("Test", 300, 200)

GUIRegisterMsg($WM_ACTIVATE, "WM_ACTIVATE")

GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func WM_ACTIVATE($hWnd, $Msg, $wParam, $lParam)
    Local $wActive = BitAND($wParam, 0x0000FFFF)
    
    If $wActive Then
        HotKeySet("{Enter}", "_MyFunc")
    Else
        HotKeySet("{Enter}")
    EndIf
    
    Return $GUI_RUNDEFMSG
EndFunc

Func _MyFunc()
    ConsoleWrite("_MyFunc" & @LF)
EndFunc

:)

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Here is the best way to detect Enter and Esc:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Opt("GUICloseOnESC", 0)
$Form1 = GUICreate("Form1", 633, 447, -1, -1)
$Label1 = GUICtrlCreateLabel("Label1", 96, 80, 200, 17)
GUISetState(@SW_SHOW)
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd

Func WM_COMMAND($hWndGUI, $iMsg, $iwParam, $ilParam)
    Switch BitAND($iwParam, 0x0000FFFF)
        Case 1;enter
            GUICtrlSetData($Label1, "Enter pressed " & Random(0,999,1))
        Case 2;esc
            GUICtrlSetData($Label1, "Esc pressed " & Random(0,999,1))
    EndSwitch
EndFunc
Edited by n3nE

[quote name='dbzfanatic' post='609696' date='Nov 26 2008, 08:46 AM']This is a help forum not a "write this for me" forum.[/quote](Sorry for bad English) :)

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Okay then, but you can use GUISetAccelerators...

That is like Hotkey, but only for your GUI (you know that) :)

Edited by n3nE

[quote name='dbzfanatic' post='609696' date='Nov 26 2008, 08:46 AM']This is a help forum not a "write this for me" forum.[/quote](Sorry for bad English) :)

Share this post


Link to post
Share on other sites

Okay then, but you can use GUISetAccelerators...

That is like Hotkey, but only for your GUI (you know that) :)

Did u tried this? Accelerators are replacing hotkeys for controls, and in my case, I don't have any. At ENTER key, editing of treeview item needs to be closed, and saved, but Accelerators can be related only to a control (which is not my case) (see post #6)

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

You are wrong, you can use GUISetAccelerators without any controls... if you use wm_command, 1 = Enter / 2 = Esc, and instead control variable, you can set 1 (enter)... Here is little example:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Opt("GUICloseOnESC", 0)
$Form1 = GUICreate("Form1", 633, 447, -1, -1)
$Label1 = GUICtrlCreateLabel("Label1", 96, 80, 200, 17)
GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
Dim $AccelKeys[2][2]=[["{ENTER}", 1], ["{ESC}", 2]]
GUISetAccelerators($AccelKeys, $Form1)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd

Func WM_COMMAND($hWndGUI, $iMsg, $iwParam, $ilParam)
    Switch BitAND($iwParam, 0x0000FFFF)
        Case 1;enter
            GUICtrlSetData($Label1, "Enter pressed " & Random(0,999,1))
        Case 2;esc
            GUICtrlSetData($Label1, "Esc pressed " & Random(0,999,1))
        Case $Label1
            MsgBox(0,"","Clicked label...")
    EndSwitch
EndFunc

Are you understand now? :)

Edited by n3nE

[quote name='dbzfanatic' post='609696' date='Nov 26 2008, 08:46 AM']This is a help forum not a "write this for me" forum.[/quote](Sorry for bad English) :)

Share this post


Link to post
Share on other sites

You are wrong, you can use GUISetAccelerators without any controls... if you use wm_command, 1 = Enter / 2 = Esc, and instead control variable, you can set 1 (enter)... Here is little example:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Opt("GUICloseOnESC", 0)
$Form1 = GUICreate("Form1", 633, 447, -1, -1)
$Label1 = GUICtrlCreateLabel("Label1", 96, 80, 200, 17)
GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
Dim $AccelKeys[2][2]=[["{ENTER}", 1], ["{ESC}", 2]]
GUISetAccelerators($AccelKeys, $Form1)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd

Func WM_COMMAND($hWndGUI, $iMsg, $iwParam, $ilParam)
    Switch BitAND($iwParam, 0x0000FFFF)
        Case 1;enter
            GUICtrlSetData($Label1, "Enter pressed " & Random(0,999,1))
        Case 2;esc
            GUICtrlSetData($Label1, "Esc pressed " & Random(0,999,1))
        Case $Label1
            MsgBox(0,"","Clicked label...")
    EndSwitch
EndFunc

Are you understand now? :)

I allready told you, WM_COMMAND is not detectable when treeview item is in edit state. #9

Share this post


Link to post
Share on other sites

Yes it can, but it sends notification for every typed letter when Editing TreeView Item... but it can be fixed... But if you said it's WM_COMMAND not detectable, then Ok, you made it by your own :)


[quote name='dbzfanatic' post='609696' date='Nov 26 2008, 08:46 AM']This is a help forum not a "write this for me" forum.[/quote](Sorry for bad English) :)

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