The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: newAsm on March 28, 2008, 01:17:09 PM

Title: Locating treeview level
Post by: newAsm on March 28, 2008, 01:17:09 PM
Hi,

I have a treeview and has 3 levels: Root, Child, grandchild. The user can double clicked at any level. I am only interested in the child level,

+-  Root
       +-- Child           <<<<--- I am interested at this level
              +---- grandchild


I can detect the mouse click but I cannot determine which level. I allow only 1 Root level, many child and grandchild levels. hParent handle contains the Root handle. hItem contains the child handle if the user clicked on a child level.

I used

               INVOKE   SendMessage, hTvwGroup, TVM_GETNEXTITEM, TVGN_PARENT, addr tvi
                mov   eax,tvi.hItem
                .if eax != hParent
                     ... do something
                .endif

How is the best way to determine at which level (branch) did the user clicked on. I also tried using

               imask - TVIF_CHILDREN and then checking if tvi.cChdilren is zero does not work as well.

Pls, some advise would be appreciated. Thanks..newAsm




Title: Re: Locating treeview level
Post by: Grincheux on March 28, 2008, 07:02:23 PM
When adding an item into your treeview you can set a value in lParam member of TVITEM structure.

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;

If it is the root you set 0 and add one for children

+-- Root (0)
|
+------------------> Child 1
+------------------> Child 2
                     +----------------> Sub item 1 (value = 0201h)
                     +----------------> Sub Item 2 (value = 0202h)
+------------------> Child 3

It is an idea...
Title: Re: Locating treeview level
Post by: Tedd on March 28, 2008, 07:36:35 PM
Grincheux's suggestion is probably the best (I was going to say it :bdg) as long as you're not otherwise using lParam.

The only other alternative I can think of is to repeatedly get the parent, until you eventually reach the root, counting the number of parents on the way.
Title: Re: Locating treeview level
Post by: newAsm on March 28, 2008, 11:53:34 PM
Wow great, thanks Grincheux & tedd. I have never thought of that because I thought there must be some API capable of doing that it. Now I know using an index, you have help me solved the problem.

Thanks a lot..newAsm
Title: Re: Locating treeview level
Post by: newAsm on March 29, 2008, 12:13:51 AM
Hi Grincheux  & Tedd,

I tried setting the lParam with a value (1 - one), and then I used GETITEM (API) to get the item data.

In setting up the TV_INSERTSTRUCT

                     mov     eax, hParent      ; get the root parent handle
                     mov     tvis.hParent, eax
                     mov     tvis.hInsertAfter, TVI_LAST
                     mov     eax, offset sNewGroup
                     mov     tvis.item.pszText, eax
                     mov      tvis.item.lParam,1      ;
                     INVOKE  SendMessage, hTvwGroup, TVM_INSERTITEM, 0, addr tvis

when a double clicked occurred

    .elseif uMsg == WM_NOTIFY
         .if wParam == IDC_TVW_Group
            mov     eax, lParam
            mov     ebx, (NM_TREEVIEW ptr [eax]).hdr.code
            mov     ecx, (NM_TREEVIEW ptr [eax]).itemNew.hItem
            mov     edx, (NM_TREEVIEW ptr [eax]).itemNew.state

             .if ebx == TVN_SELCHANGED
                 test   (NM_TREEVIEW ptr [eax]).action, TVIS_FOCUSED
                jz      Ret0
                  mov      tvi.hItem, ecx
                  mov      tvi.imask, TVIF_TEXT
                  lea      eax, sItem
                  mov      tvi.pszText, eax
                  mov      tvi.cchTextMax, 32

               INVOKE   SendMessage, hTvwGroup, TVM_GETITEM, NULL, addr tvi
            mov      eax,tvi.lParam
            
            .if eax == 1
               invoke   MessageBox,hWnd,offset sItem,ADDR AppName,MB_OK
            .endif
         .endif
         .endif

I used a messagebox to indicate that the right level has been detected. No message occurred. Is TVM_GETITEM sufficient to get the selected item data? I have included the source. Lines 164 - 172 is where insertion of the "Child" occurred. Lines 254 - 282 is where the treeview selection check takes place. Appreciate your feedback.




[attachment deleted by admin]
Title: Re: Locating treeview level
Post by: Grincheux on March 29, 2008, 06:58:43 AM
When you insert the data into your treeview you must set the TVItem.imask member to TVIF_PARAM like this :

;   ================================================================================

      lea   eax,_szTmp

      mov   _TVis.hInsertAfter,TVI_SORT
      mov   _TVis.itemex.pszText,eax
      mov   _TVis.itemex.imask,TVIF_DI_SETITEM or TVIF_PARAM or TVIF_TEXT or TVIF_IMAGE or TVIF_SELECTEDIMAGE
      mov   eax,_hComputer
      mov   _TVis.itemex.state,0
      mov   _TVis.itemex.iIntegral,0
      mov   _TVis.hParent,eax
      mov   _TVis.itemex.cChildren,1
      mov   _TVis.itemex.lParam,1234h

      INVOKE   SendMessage,hTreeView,TVM_INSERTITEM,0,ADDR _TVis

;   ================================================================================

After you catch the WM_NOTIFY like this :


;   ================================================================================

Folders_WmNotify   PROC   USES EBX EDI ESI,__hWnd:HWND,__lpNmHdr:Ptr NMHDR
         LOCAL   _Tvi:TVITEM
         LOCAL   _szTmp[MAX_PATH]:Byte

         mov   ebx,__lpNmHdr

         cmp   (NMHDR Ptr [ebx]).code,TVN_SELCHANGED
         jne   @Exit

@SelChanged :

         mov   eax,(NMTREEVIEW Ptr [ebx]).itemNew.hItem
         mov   _Tvi.hItem,eax
         mov   _Tvi._mask,TVIF_PARAM or TVIF_TEXT
         lea   eax,_szTmp
         mov   _Tvi.pszText,eax
         mov   _Tvi.cchTextMax,SIZEOF _szTmp
         mov   _Tvi.lParam,NULL

         INVOKE   SendMessage,hTreeView,TVM_GETITEM,0,ADDR _Tvi

         test   eax,eax
         jz   @Exit

            mov   eax,_Tvi.lParam

            cmp   eax,lpPosteDeTravail
            je   @_PosteDeTravail

               push   eax                     ; TV_FOLDER
               push   _Tvi.hItem                  ; hItem
               lea   eax,_szTmp
               push   eax                     ; Texte de l'item
               push   OFFSET @Exit
               jmp   SearchIntoThisDirectory

@_PosteDeTravail :

               jmp   @Exit

@Exit :

         mov   eax,TRUE

         ret
Folders_WmNotify   ENDP

;   ================================================================================

This function is called through the window's proc like this :

;   ================================================================================

LeftExplorerProc   PROC   USES EBX EDI ESI,__hWnd:HWND,__uMsg:UINT,__wParam:WPARAM,__lParam:LPARAM

         mov   eax,__uMsg

@WmNotify :

         cmp   eax,WM_NOTIFY
         jne   @WmSize

            push   __lParam               ; LPNMHDR
            push   __hWnd
            push   OFFSET @End
            jmp   Folders_WmNotify

@WmSize :

            cmp   eax,WM_SIZE
            jne   @WmCreate

               movzx   edx,Word Ptr __lParam + 2
               movzx   eax,Word Ptr __lParam

               push   TRUE
               push   edx
               push   eax
               push   0
               push   0
               push   hTreeView
               push   OFFSET @End
               jmp   MoveWindow

@WmCreate :

            cmp   eax,WM_CREATE
            jne   @WmClose

               mov   esi,__hWnd
               call   CreateTreeView
               call   Folders_WmCreate

               mov   eax,TRUE
               jmp   @Exit

@WmClose :

            cmp   eax,WM_CLOSE
            jne   @Default

               call   Folders_WmClose

               mov   eax,TRUE
               jmp   @Exit

@Default :


            push   __lParam
            push   __wParam
            push   __uMsg
            push   __hWnd
            push   OFFSET @Exit
            jmp   DefWindowProc      

@End :

            xor eax,eax

@Exit :

            ret
LeftExplorerProc      ENDP

;   ================================================================================

Is ii easier now ?




[attachment deleted by admin]
Title: Re: Locating treeview level
Post by: newAsm on March 30, 2008, 12:16:21 AM
Hi Grincheux,

Thanks a LOT! I am humbled about the details I have yet come to gripe with. It definitely has helped me with the example. i will study it. THANKS! Very helpful hint and hopefully remember.

..newAsm
Title: Re: Locating treeview level
Post by: newAsm on March 30, 2008, 01:24:08 AM
Hi Grincheux,

Working now. I will upload the program when done. Thanks for your help...newAsm