Jump to content

COM Treeview


eltorro
 Share

Recommended Posts

It appears that some of the properties can be set but I cannot get a node added.

Has anyone figured this out yet??

comctrltest.au3

#include <GuiConstants.au3>;Inclusion file for the GUI interface controls
;0-tvwFirst, 1-tvwLast, 2-tvwNext, 3-tvwPrevious,or 4-tvwChild
Global Const $TVW_FIRST =0
Global Const $TVW_LAST  =1
Global Const $TVW_NEXT  =2
Global Const $TVW_PREVIOUS  =3
Global Const $TVW_CHILD =4

$Form1 = GUICreate("Tree Notify Test", 359, 315, 192, 125)

$objTree= ObjCreate("MSComctlLib.Treectrl")
$oMyError = ObjEvent("AutoIt.Error","_COMerr")
$treex = GUICtrlCreateObj($objTree,8,8,190,120)

$objTree.Style = 6  ;The text, plus or minus symbols, and lines are displayed.
$objTree.BorderStyle = 1;bordered
$objTree.Enabled =True
ConsoleWrite("Hwnd="&$objTree.hwnd)
;TreeView1.Nodes.Add Relative, Relationship, Key, Text, Image, SelectedImage
$objTree.Nodes.Add(,$TVW_FIRST,"Root","This is Root")
$objTree.Nodes.Add ("Root",$TVW_CHILD, "child1_root", "Child1 of Root")
$objTree.Nodes.Add( "Root",$TVW_CHILD, "child2_root", "Child2 of Root")
$objTree.Nodes.Add ("child1_root",$TVW_CHILD, "child1_child1", "Child1 of Child1")
$objTree.Nodes("child1_child1").EnsureVisible

GUISetState(@SW_SHOW)

While 1
    $msg= GUIGetMsg()
    Select 
        Case $msg = $GUI_EVENT_CLOSE
            $treex =""
            $objTree = ""
            GUIDelete()
            Exit
         Case Else
         sleep(100)
     EndSelect   
WEnd
Exit
Func _COMerr() 
  $HexNumber=hex($oMyError.number,8)
  Msgbox(0,"AutoItCOM Test","We intercepted a COM Error !"     & @CRLF  & @CRLF & _
             "err.description is: " & @TAB & $oMyError.description  & @CRLF & _
             "err.windescription:"   & @TAB & $oMyError.windescription & @CRLF & _
             "err.number is: "       & @TAB & $HexNumber              & @CRLF & _
             "err.lastdllerror is: "   & @TAB & $oMyError.lastdllerror   & @CRLF & _
             "err.scriptline is: "   & @TAB & $oMyError.scriptline   & @CRLF & _
             "err.source is: "       & @TAB & $oMyError.source       & @CRLF & _
             "err.helpfile is: "       & @TAB & $oMyError.helpfile     & @CRLF & _
             "err.helpcontext is: " & @TAB & $oMyError.helpcontext _
            )
  SetError(1); to check for after this function returns

Endfunc ;;==>
Link to comment
Share on other sites

It appears that some of the properties can be set but I cannot get a node added.

Has anyone figured this out yet??

comctrltest.au3

#include <GuiConstants.au3>;Inclusion file for the GUI interface controls
;0-tvwFirst, 1-tvwLast, 2-tvwNext, 3-tvwPrevious,or 4-tvwChild
Global Const $TVW_FIRST =0
Global Const $TVW_LAST  =1
Global Const $TVW_NEXT  =2
Global Const $TVW_PREVIOUS  =3
Global Const $TVW_CHILD =4

$Form1 = GUICreate("Tree Notify Test", 359, 315, 192, 125)

$objTree= ObjCreate("MSComctlLib.Treectrl")
$oMyError = ObjEvent("AutoIt.Error","_COMerr")
$treex = GUICtrlCreateObj($objTree,8,8,190,120)

$objTree.Style = 6 ;The text, plus or minus symbols, and lines are displayed.
$objTree.BorderStyle = 1;bordered
$objTree.Enabled =True
ConsoleWrite("Hwnd="&$objTree.hwnd)
;TreeView1.Nodes.Add Relative, Relationship, Key, Text, Image, SelectedImage
$objTree.Nodes.Add(,$TVW_FIRST,"Root","This is Root")
$objTree.Nodes.Add ("Root",$TVW_CHILD, "child1_root", "Child1 of Root")
$objTree.Nodes.Add( "Root",$TVW_CHILD, "child2_root", "Child2 of Root")
$objTree.Nodes.Add ("child1_root",$TVW_CHILD, "child1_child1", "Child1 of Child1")
$objTree.Nodes("child1_child1").EnsureVisible

GUISetState(@SW_SHOW)

While 1
    $msg= GUIGetMsg()
    Select 
        Case $msg = $GUI_EVENT_CLOSE
            $treex =""
            $objTree = ""
            GUIDelete()
            Exit
         Case Else
         sleep(100)
     EndSelect   
WEnd
Exit
Func _COMerr() 
  $HexNumber=hex($oMyError.number,8)
  Msgbox(0,"AutoItCOM Test","We intercepted a COM Error !"     & @CRLF  & @CRLF & _
             "err.description is: " & @TAB & $oMyError.description  & @CRLF & _
             "err.windescription:"   & @TAB & $oMyError.windescription & @CRLF & _
             "err.number is: "       & @TAB & $HexNumber              & @CRLF & _
             "err.lastdllerror is: "   & @TAB & $oMyError.lastdllerror   & @CRLF & _
             "err.scriptline is: "   & @TAB & $oMyError.scriptline   & @CRLF & _
             "err.source is: "       & @TAB & $oMyError.source       & @CRLF & _
             "err.helpfile is: "       & @TAB & $oMyError.helpfile     & @CRLF & _
             "err.helpcontext is: " & @TAB & $oMyError.helpcontext _
            )
  SetError(1); to check for after this function returns

Endfunc;;==>
you don't have to reinvent the wheel, look in the index of your help file for the _GUICtrlTreeView* functions
Link to comment
Share on other sites

There is a specific reason for wanting to use the treeview as an ActiveX component instead of a built. Mainly it is to see if it is possible to trap the expand and contract events. If you click on an indent, it does not fire a Guimsg. If you select a node, and then click the indent, it is possible to get the expand state of the node. However, if you select a node and click and indent on another node, no event fires.

Hacked together example:

#include <GUIConstants.au3>

Global $treeview
Global $Event_Code
Global $Event_wParam

Global Const $WM_NOTIFY = 0x004E
Global Const $DebugIt = 1
Global Const $TV_FIRST = 0x1100
Global Const $TVIS_EXPANDED = 0x20
Global Const $TVIS_EXPANDEDONCE = 0x40
Global Const $TVM_GETITEMSTATE = ($TV_FIRST + 39)
Global Const $TVN_FIRST = -400
Global Const $TVN_LAST = -499
Global Const $TVN_SELCHANGINGA  = ($TVN_FIRST - 1)
Global Const $TVN_SELCHANGINGW  = ($TVN_FIRST - 50)
Global Const $TVN_SELCHANGEDA   = ($TVN_FIRST - 2)
Global Const $TVN_SELCHANGEDW   = ($TVN_FIRST - 51)
Global Const $TVN_GETDISPINFOA  = ($TVN_FIRST - 3)
Global Const $TVN_GETDISPINFOW  = ($TVN_FIRST - 52)
Global Const $TVN_SETDISPINFOA  = ($TVN_FIRST - 4)
Global Const $TVN_SETDISPINFOW  = ($TVN_FIRST - 53)
Global Const $TVN_ITEMEXPANDINGA    = ($TVN_FIRST - 5)
Global Const $TVN_ITEMEXPANDINGW    = ($TVN_FIRST - 54)
Global Const $TVN_ITEMEXPANDEDA = ($TVN_FIRST - 6)
Global Const $TVN_ITEMEXPANDEDW = ($TVN_FIRST - 55)
Global Const $TVN_BEGINDRAGA    = ($TVN_FIRST - 7)
Global Const $TVN_BEGINDRAGW    = ($TVN_FIRST - 56)
Global Const $TVN_BEGINRDRAGA   = ($TVN_FIRST - 8)
Global Const $TVN_BEGINRDRAGW   = ($TVN_FIRST - 57)
Global Const $TVN_DELETEITEMA   = ($TVN_FIRST - 9)
Global Const $TVN_DELETEITEMW = ($TVN_FIRST - 58)
Global Const $TVN_BEGINLABELEDITA   = ($TVN_FIRST - 10)
Global Const $TVN_BEGINLABELEDITW   = ($TVN_FIRST - 59)
Global Const $TVN_ENDLABELEDITA = ($TVN_FIRST - 11)
Global Const $TVN_ENDLABELEDITW = ($TVN_FIRST - 60)
Global Const $TVN_KEYDOWN   = ($TVN_FIRST - 12)

Global Const $TVN_GETINFOTIPA   = ($TVN_FIRST - 13)
Global Const $TVN_GETINFOTIPW   = ($TVN_FIRST - 14)
Global Const $TVN_SINGLEEXPAND  = ($TVN_FIRST - 15)

$Form1 = GUICreate("Tree Notify Test", 359, 315, 192, 125)
$treeview = GUICtrlCreateTreeView(8, 8, 209, 250)
$generalitem = GUICtrlCreateTreeViewItem("General", $treeview)
$displayitem = GUICtrlCreateTreeViewItem("Display", $treeview)
$aboutitem = GUICtrlCreateTreeViewItem("About", $generalitem)
$compitem = GUICtrlCreateTreeViewItem("Computer", $generalitem)
$anotheritem = GUICtrlCreateTreeViewItem("DVD+-RW", $compitem)
$useritem = GUICtrlCreateTreeViewItem("User", $generalitem)
$resitem = GUICtrlCreateTreeViewItem("Resolution", $displayitem)
$otheritem = GUICtrlCreateTreeViewItem("Other", $displayitem)

$Button1 = GUICtrlCreateButton("Get State", 232, 240, 83, 41)


$Label1 = GUICtrlCreateLabel("", 0, 296, 355, 17, $SS_SUNKEN)
$Label2 = GUICtrlCreateLabel("", 0, 276, 355, 17, $SS_SUNKEN)

;Register WM_NOTIFY  events
;GUIRegisterMsg ($WM_NOTIFY, "WM_Notify_Events")

GUISetState(@SW_SHOW)
While 1
    $msg = GUIGetMsg()
    $tree_event = GUICtrlRead($treeview)
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
        Case $msg = $treeview Or $msg = $generalitem Or $msg = $displayitem Or $msg = $tree_event
            $ctrldata = GUICtrlRead($tree_event, 1)
            GUICtrlSetData($Label1, "TREEVIEW " & $tree_event & " State= " & $ctrldata[0])
            $tree_event = 0
            
        Case $tree_event
            GUICtrlSetData($Label1, "TREEEVENT " & $tree_event & "Expanded =" & _IsExpanded($treeview, GUICtrlRead($treeview), $TVIS_EXPANDED))
            $tree_event = 0
            Sleep(10)
        Case $msg = $Button1
            GUICtrlSetData($Label1, "Expanded =" & _IsExpanded($treeview, GUICtrlRead($treeview), $TVIS_EXPANDED))
        Case $Event_Code <> 0
            If $DebugIt Then GUICtrlSetData($Label2, "Control hwnd=" & $Event_wParam & " Code=" & $Event_Code)
            $Event_Code = 0
        Case Else
            If $msg <> 0 And $msg <> - 11 Then
                GUICtrlSetData($Label2, "msg =" & $msg & "Tree =" & $tree_event)
            EndIf
            Sleep(100)
            $Event_Code = 0
    EndSelect
WEnd
Exit
Func WM_Notify_Events($hWndGUI, $MsgID, $wParam, $lParam)
    #forceref $hWndGUI, $MsgID
    Local $tagNMHDR, $event
    $tagNMHDR = DllStructCreate("int;int;int", $lParam);NMHDR (hwndFrom, idFrom, code)
    If @error Then Return
    $event = DllStructGetData($tagNMHDR, 3)
    Switch $wParam
        Case $treeview
            Return
        Case Else
;~           $Event_Code = $event
;~           $Event_wParam = $wParam
            If $DebugIt Then GUICtrlSetData($Label1, "Control hwnd=" & $wParam & " Code=" & $event)
    EndSwitch
    $tagNMHDR = 0
EndFunc  ;==>WM_Notify_Events



Func _IsExpanded($h_tree, $h_item, $state)
    $ret = $state and (BitAND($state, GUICtrlSendMsg($h_tree, $TVM_GETITEMSTATE, GUICtrlGetHandle($h_item), $state)))
    Return $ret
EndFunc  ;==>_IsExpanded

It possible to trap the events using $WM_NOTIFY

If you want to see something really funky, uncomment the line on or about line 61 that reads ;GUIRegisterMsg ($WM_NOTIFY, "WM_Notify_Events")

Link to comment
Share on other sites

That's because in this case the WM_Notify_Event is incorrect

lParam

Pointer to an NMHDR structure that contains the notification

code and additional information.

For some notification messages, this parameter points to a

larger structure that has the NMHDR structure as its first member.

NMTreeView

NMHDR hdr;

UINT action;

TVITEM itemOld;

TVITEM itemNew;

POINT ptDrag;

hdr

NMHDR structure that contains information about this notification message. action Notification-specific action flag. itemOld TVITEM structure that contains information about the old item state.

This member is zero for notification messages that do not use it.

itemNew TVITEM structure that contains information about the new item state.

This member is zero for notification messages that do not use it.

ptDrag POINT structure that contains the client coordinates of the mouse

at the time the event occurred that caused the notification message to be sent.

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

Here's what I have for the structs, but not sure how to implement them with the header.

;====== structs needed for funcs
;~ typedef struct tagTVITEM {
;~   UINT mask;
;~   HTREEITEM hItem;
;~   UINT state;
;~   UINT stateMask;
;~   LPTSTR pszText;
;~   int cchTextMax;
;~   int iImage;
;~   int iSelectedImage;
;~   int cChildren;
;~   LPARAM lParam;
;~ } TVITEM, *LPTVITEM;
    $TVITEM_Old = DllStructCreate("uint;int;uint;uint;ptr;int;int;int;int;int")
    $TVITEM_new = DllStructCreate("uint;int;uint;uint;ptr;int;int;int;int;int")
    
   ;This is needed for the the one following
;~ typedef struct tagPOINT {
;~   LONG x;
;~   LONG y;
;~ } POINT, *PPOINT;
    $POINT_struct = DllStructCreate("int,int")
    
;~ typedef struct tagNMTREEVIEW {
;~   NMHDR hdr;
;~   UINT action;
;~   TVITEM itemOld;
;~   TVITEM itemNew;
;~   POINT ptDrag;
;~ } NMTREEVIEW, *LPNMTREEVIEW
    $NMTREEVIEW = DllStructCreate("ptr;uint;ptr;ptr;ptr")
    
;~ typedef struct tagNMTVDISPINFO {
;~   NMHDR hdr;
;~   TVITEM item;
;~ } NMTVDISPINFO, *LPNMTVDISPINFO;
    $NMTVDISPINFO = DllStructCreate("ptr;ptr")
    
;~ typedef struct tagNMTVGETINFOTIP {
;~   NMHDR hdr;
;~   LPTSTR pszText; $INFOTIP_BUFFER = 1024
;~   int cchTextMax;
;~   HTREEITEM hItem;
;~   LPARAM lParam;
;~ } NMTVGETINFOTIP, *LPNMTVGETINFOTIP;
    $INTOTIP_BUFFER = DllStructCreate("char[1024]")
    $NMTVGETINFOTIP = DllStructCreate("ptr;ptr;int;hwnd;int")
    
;~ typedef struct tagTVINSERTSTRUCT {
;~   HTREEITEM hParent;
;~   HTREEITEM hInsertAfter;
;~ #if (_WIN32_IE >= 0x0400)
;~   union
;~   {
;~       TVITEMEX itemex;
;~       TVITEM item;
;~   } DUMMYUNIONNAME;
;~ #else
;~   TVITEM item;
;~ #endif
;~ } TVINSERTSTRUCT, *LPTVINSERTSTRUCT;
    $TVINSERTSTRUCT = DllStructCreate("int;int;prt")
    
;~ typedef struct _RECT {
;~   LONG left;
;~   LONG top;
;~   LONG right;
;~   LONG bottom;
;~ } RECT, *PRECT;
    $RECT_stuct = DllStructCreate("int;int;int;int")
    
;~ typedef struct tagNMCUSTOMDRAWINFO {
;~   NMHDR hdr;
;~   DWORD dwDrawStage;
;~   HDC hdc;
;~   RECT rc;
;~   DWORD_PTR dwItemSpec;
;~   UINT uItemState;
;~   LPARAM lItemlParam;
;~ } NMCUSTOMDRAW, *LPNMCUSTOMDRAW;
    $NMCUSTOMDRAWINFO = DllStructCreate("ptr;int;int;ptr;ptr;uint;int")

Not sure that they are correct. Please have a look.

Link to comment
Share on other sites

I haven't tried it yet, but think it is possible with the treeview from with-in autoit

did the one for listview, first approach i took the difficult road, found out it was easier than

I 1st thought, here's an example in attachment.

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

I downloaded your attachment. I'll hopefully get a chance tommorrow today to get a good look at it. I really hope I (we, anybody) can get this to work. Not only would it solve my problem, but it would be an excellent addition to the Autoit community.

Link to comment
Share on other sites

I downloaded your attachment. I'll hopefully get a chance tommorrow today to get a good look at it. I really hope I (we, anybody) can get this to work. Not only would it solve my problem, but it would be an excellent addition to the Autoit community.

I'm close on the treeview nm events, just can't seem to get the pszText, i'm sure i'm doing something wrong on the struct, but i'm taking a break from it for now.

if you want to see where i got to on it, pm me and i'll send you the file.

Gary

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

There is a specific reason for wanting to use the treeview as an ActiveX component instead of a built. Mainly it is to see if it is possible to trap the expand and contract events. If you click on an indent, it does not fire a Guimsg. If you select a node, and then click the indent, it is possible to get the expand state of the node. However, if you select a node and click and indent on another node, no event fires.

maybe i'm over simplifying, but it would seem to me that an GUIMsg IS sent, even if it's not the one you're looking for. If you're clicking, the $GUI_EVENT_PRIMARYDOWN event is happening. That can be trapped, and can cue a check of the status of the treeview. Right?

Link to comment
Share on other sites

  • 2 months later...

Im on it actualy (posted another thread)

; includes
#include "<GUIConstants.au3>"
; General window
Global Const $WM_NOTIFY = 0x004E
; Notifications codes from WM_NOTIFY
Global Const $TVN_FIRST            =-400
Global Const $TVN_LAST              =-499
Global Const $TVN_SELCHANGING        =($TVN_FIRST-1)
Global Const $TVN_SELCHANGED          =($TVN_FIRST-2)
Global Const $TVN_GETDISPINFO        =($TVN_FIRST-3)
Global Const $TVN_SETDISPINFO        =($TVN_FIRST-4)
Global Const $TVN_ITEMEXPANDING    =($TVN_FIRST-5)
Global Const $TVN_ITEMEXPANDED      =($TVN_FIRST-6)
Global Const $TVN_BEGINDRAG        =($TVN_FIRST-7)
Global Const $TVN_BEGINRDRAG          =($TVN_FIRST-8)
Global Const $TVN_DELETEITEM          =($TVN_FIRST-9)
Global Const $TVN_BEGINLABELEDIT      =($TVN_FIRST-10)
Global Const $TVN_ENDLABELEDIT      =($TVN_FIRST-11)
Global Const $TVN_KEYDOWN            =($TVN_FIRST-12)
Global Const $TVN_GETINFOTIPA        =($TVN_FIRST-13)
Global Const $TVN_GETINFOTIPW        =($TVN_FIRST-14)
Global Const $TVN_SINGLEEXPAND      =($TVN_FIRST-15)
Global Const $TVN_SELCHANGINGW      =($TVN_FIRST-50)
Global Const $TVN_SELCHANGEDW        =($TVN_FIRST-51)
Global Const $TVN_GETDISPINFOW      =($TVN_FIRST-52)
Global Const $TVN_SETDISPINFOW      =($TVN_FIRST-53)
Global Const $TVN_ITEMEXPANDINGW      =($TVN_FIRST-54)
Global Const $TVN_ITEMEXPANDEDW    =($TVN_FIRST-55)
Global Const $TVN_BEGINDRAGW          =($TVN_FIRST-56)
Global Const $TVN_BEGINRDRAGW        =($TVN_FIRST-57)
Global Const $TVN_DELETEITEMW        =($TVN_FIRST-58)
Global Const $TVN_BEGINLABELEDITW    =($TVN_FIRST-59)
Global Const $TVN_ENDLABELEDITW    =($TVN_FIRST-60)

; my GUI
$myGui=GUICreate("TVI click & DblClick ?",300,400,-1,-1)
$myTreeView=GUICtrlCreateTreeView(10,10,280,350)
; few parent items, Control IDs stored in array
Dim $MainItem[3]
$MainItem[0]=GUICtrlCreateTreeViewItem("Item1",$myTreeView)
$MainItem[1]=GUICtrlCreateTreeViewItem("Item2",$myTreeView)
$MainItem[2]=GUICtrlCreateTreeViewItem("Item3",$myTreeView)
; lots of subitems, Control IDs stored in array
$MaxSubItems=300
Dim $SubItems[$MaxSubItems]

For $i=0 to $MaxSubItems-1
    $r=Random(0,2,1); from 0 to 2 and return an Int
    $SubItems[$i]=GUICtrlCreateTreeViewItem("SubItem "&$i,$MainItem[$r])
Next
GUISetState(@SW_SHOW,$myGui)

; Register messages
GUIRegisterMsg($WM_NOTIFY, "WM_Notify_Events"); does crazy things on the treeview...

; Main event loop
While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
; Now i want to capture a click on a subitem...(unwanted method)
;For $i=0 to $MaxSubItems-1
;   If $msg=$SubItems[$i] Then ItemClicked($i)
;Next
Wend

Func ItemClicked($ItemNumber)
    MsgBox (0,"","SubItem "&$ItemNumber&" clicked !")
EndFunc

; WM_NOTIFY event handler
Func WM_Notify_Events($hWndGUI, $MsgID, $wParam, $lParam)
    #forceref $hWndGUI, $MsgID, $wParam
#cs
    Select
    Case $wParam = $myTreeView
        Local $tagNMHDR,$tagNMTREEVIEW, $event, $hwndFrom, $code,$ptr
        $tagNMTREEVIEW = DllStructCreate("ptr;uint;ptr;ptr;ptr",$lParam)
        $ptr=DllStructGetPtr ($tagNMTREEVIEW,1)
        $tagNMHDR = DllStructCreate("int;int;int", $ptr);NMHDR (hwndFrom, idFrom, code)
        If @error Then Return
        $event = DllStructGetData($tagNMHDR, 3)
        Select
            Case $event = $TVN_SELCHANGEDW
                ItemClicked("#")
            EndSelect
    EndSelect
   ;$tagNMHDR = 0
   ;$event = 0
   ;$lParam = 0
#ce
EndFunc

Even with the correct structs the treeview goes Funky mode,

worst thing is, even with an empty function the Funky mode still...

I guess the GUIRegisterMsg($WM_NOTIFY,func) is buged or maybe it receive to many WM_NOTIFYs in a given time, using Winspector shows many of them...

Looks like an old thread, maybe you found the solution ? :think:

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...