Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re^3: Enumerate a Win32 Treeview

by BrowserUk (Patriarch)
on Jul 25, 2005 at 22:17 UTC ( [id://477999]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Enumerate a Win32 Treeview
in thread Enumerate a Win32 Treeview

No, you cannot use the macros, but you should be able to use the Win32::GUI sendmsg() call to send TVM_GETNEXTITEM messages to iterate the contents of the treeview control.

I don't think that there is an Win32 API call for retrieving that information.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.

Replies are listed 'Best First'.
Re^4: Enumerate a Win32 Treeview
by slloyd (Hermit) on Jul 25, 2005 at 22:56 UTC
    ok, still cannot get it to return anything..
    ############### sub getListviewItems{ my $hwnd = shift || return "No treeview handle"; #if no result send a WM_GetText message to the window $WmSendMessage ||= new Win32::API("user32", "SendMessageA", [N, N, + N, P],'N') || return "SendMessageA Error"; my $TV_FIRST=4352; my $TVM_GETNEXTITEM=$TV_FIRST+10; my $text = " " x 2048; my $textLen = 2048; my @items=(); print "calling $hwnd with $TVM_GETNEXTITEM\n"; while(my $result = $WmSendMessage->Call($hwnd,$TVM_GETNEXTITEM, $t +extLen, $text)){ my $item=substr($text, 0, $result); print "getListviewItems: [$item]\n"; push(@items,$item); } return @items; }

      First, if you are using Win32::GUI, you shouldn't need to import SendMessage() yourself.

      Second, you cannot just make **it up as you go along :) The description of the TVM_GETNEXTITEM message from the page I linked is:

      lResult = SendMessage( // returns LRESULT in lResult (HWND) hWndControl, // handle to destination control (UINT) TVM_GETNEXTITEM, // message ID (WPARAM) wParam, // = (WPARAM) (UINT) flag; (LPARAM) lParam // = (LPARAM) (HTREEITEM) hitem; );

      The wparam argument should be one of the following flags, not the length of a buffer

      TVGN_CARET TVGN_CHILD TVGN_DROPHILITE TVGN_FIRSTVISIBLE TVGN_LASTVISIBLE TVGN_NEXT TVGN_NEXTVISIBLE TVGN_PARENT TVGN_PREVIOUS TVGN_PREVIOUSVISIBLE TVGN_ROOT

      And the lparam argument should be either null or the handle returned from a previous call, not a pointer to a buffer.

      The basic mechanism is,

      1. You pass TVGN_ROOT/null, to get a handle to the root item in the display.
      2. Then you pass TVGN_CHILD/roothandle (from above) to get the handle to the first child.
        1. Then you use TVGN_NEXT/firstChildHandle (from above) to iterate the first level children.
        2. And TGVN_CHILD/firstChildHandle to process the grandchildren...

      Obviously, you will need to loop/recurse at each level to optain all the siblings & children at each level. It's upto you to decide whether you depth first or breadth first.

      The return value from the SendMessage is the item handle to each node in the tree. As well as using this as an argument to get the next sibling or child in the tree, you also use it to send TVM_GETITEM messages to each of those items to retrive the TVMITEM(EX) structure that contains the data & state that is the node.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
        Thanks for the tutorial. Although I am fairly good at Perl, my windows API knowledge is just beginner level. I will try to take what you have suggested and get this to work.
        I am still having a difficult time getting this to work. Here is what I have so far. Can anyone help me out?
        ############### sub getListviewItems{ my $hwnd = shift || return "No treeview handle"; #if no result send a WM_GetText message to the window $WmSendMessage ||= new Win32::API("user32", "SendMessageA", [N, N, + N, P],'N') || return "SendMessageA Error"; my $TVGN_ROOT =0; my $TVGN_NEXT =1; my $TVGN_PREVIOUS =2; my $TVGN_PARENT =3; my $TVGN_CHILD =4; my $TVGN_FIRSTVISIBLE =5; my $TVGN_NEXTVISIBLE =6; my $TVGN_PREVIOUSVISIBLE =7; my $TVGN_DROPHILITE =8; my $TVGN_CARET =9; my $TVGN_LASTVISIBLE =10; my $TV_FIRST=4352; my $TVM_GETNEXTITEM=$TV_FIRST+10; # 1. You pass TVGN_ROOT/null, to get a handle to the root item in +the display. my $roothandle = $WmSendMessage->Call($hwnd,$TVM_GETNEXTITEM, $TVG +N_ROOT, 0); print "Root Handle: $roothandle\n"; # 2. Then you pass TVGN_CHILD/roothandle (from above) to get the h +andle to the first child. my $firstchildhwnd = $WmSendMessage->Call($hwnd,$TVM_GETNEXTITEM, +$TVGN_CHILD, $roothandle); print "firstchildhwnd: $firstchildhwnd\n"; # 3. # 1. Then you use TVGN_NEXT/firstChildHandle (from above) to +iterate the first level children. # 2. And TGVN_CHILD/firstChildHandle to process the grandchil +dren... while(my $tvwnd=$WmSendMessage->Call($hwnd,$TVM_GETNEXTITEM, $TVGN +_NEXT, $roothandle)){ my $text=getWindowText($tvwnd); print "Child Handle: $tvwnd, Text: $text\n"; } return 1; } ############### sub getWindowText{ my $hwnd = shift || return; $GetWindowText ||= new Win32::API("user32", "GetWindowText", ['N', + 'P', 'N'], 'N') || return; my $title = " " x 1024; my $titleLen = 1024; my $result = $GetWindowText->Call($hwnd, $title, $titleLen); if($result){return substr($title, 0, $result);} #if no result send a WM_GetText message to the window $WmSendMessage ||= new Win32::API("user32", "SendMessageA", [N, N, + N, P],'N') || return; my $WM_GETTEXT=13; my $text = " " x 2048; my $textLen = 2048; my $result = $WmSendMessage->Call($hwnd,$WM_GETTEXT, $textLen, $te +xt); if($result){return substr($text, 0, $result);} }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://477999]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (8)
As of 2024-03-29 08:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found