Page 1 of 2

Tutorial: How to make TreeGadgets editable...

Posted: Tue Dec 17, 2002 11:20 pm
by BackupUser
Code updated For 5.20+

Restored from previous forum. Originally posted by freak.

Hi again,

As you can see, i'm doing a lot of Stuff with TreeGadgets ATM. I just want to share the Stuff i'm finding out, so here's a tutorial on how you can allow the User to edit the Items of a TreeGadget (like Windows-Explorer does.)

This will also be on the RecourceSite soon.

Hope it helps somebody...

Code: Select all

; ---------------------------------------------------------------------
; How to make TreeGadget Items Editable by the User
; by Timo Harter
; ---------------------------------------------------------------------
;
; By implementing this in your Program, the User can edit the Items
; of a TreeGadget by first right-clicking, and then left-clicking on it.
; (just like in Windows-Explorer)
;
; This is just a skeleton, how it is done, but it should be easy to
; understand, and implement in your own Programs.
; ---------------------------------------------------------------------


; This Constant will be needed:

#TVS_EDITLABELS = 8  ; The Window Style for Label Editing

; There's also a not defined Structure, we will need.

;     Structure NMTVDISPINFO
;       hdr.NMHDR
;       item.TV_ITEM
;     EndStructure

; We'll need one Global Variable for this, to store the Windows-Handle to the Gadget:

Global hWndTV

; We'll also need a Callback procedure for that. (If you never used one, don't be afraid,
; it's not that hard.). I'll just declare it here, the Procedure will be further down.

Declare Callback(Window, Message, wParam, lParam)

; First, we'll just create a Window, and a a TreeGadget.

OpenWindow(0, 0, 0, 200, 400, "TreeGadget Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;     CreateGadgetList(WindowI())

; Store the Handle in the Global value:

hWndTV = TreeGadget(1, 5, 5, 190, 390)

; Now, here we run into our first Problem: There's no Flag for enabling Label Editing.
; so we'll have to to it ourselves.
; We can change that using the API Functions GetWindowLong_() and SetWindowLong_()
; What we do, is change a Style of the Window (That's the Stuff you specify with the Flags)

; First, get the existing Styles:

Styles = GetWindowLong_(hWndTV, #GWL_STYLE)

; Then Add Label Editing to these Styles:

Styles = Styles | #TVS_EDITLABELS

; Now Set the new Styles for the Gadget:

SetWindowLong_(hWndTV, #GWL_STYLE, Styles)

; Now Label Editing is allowed in this TreeGadget

; We'll now add some Items

AddGadgetItem(1, -1, "Item0",0,0)
AddGadgetItem(1, -1, "Item0",0,0)
;     OpenTreeGadgetNode()
AddGadgetItem(1, -1, "Item0",0,1)
AddGadgetItem(1, -1, "Item0",0,1)
;     CloseTreeGadgetNode()

; Now we'll need to set the Callback Procedure (for more Inofrmation see 'SetWindowCallback()'
; in the Help Files in the 'Window' Library.

SetWindowCallback(@Callback())

; That was all that was to be done in the Main prog, now your Main Loop can follow, that
; will handle all normal PureBasic Events.
; In this case, we handle no other Events, so this Loop only waits for the Close
; Button to be Pressed, and then Ends the Program.

While WaitWindowEvent() <> #PB_Event_CloseWindow: Wend
End

; This is the End of the Main Code.
; ------------------------------------------------------------------------------------

; Now following is the Callback Procedure. Here we handle the Editing.
; The Events are Send as Messages, where a Message is just a Constantt
; like the Event-Constants, wParam and lParam are just the parameters for
; these Events. You see, the Callback-thingy is not that hard.
; the only thing is to always use the skeleton you can find in the Help files
; (at 'SetWindowCallback()') as otherwise, your Program will crash.


Procedure Callback(Window, Message, wParam, lParam)
  result = #PB_ProcessPureBasicEvents
  
  ; The Messages we need are sent as a WM_NOTIFY Message. THis means, the Message will
  ; in our case always be #WM_NOTIFY, and the selection of the real Message will be made
  ; later.
  
  ; So we only need to find this Message:
  
  If Message = #WM_NOTIFY
    
    ; lParam contains the Pointer to a Structure with the actual Message:
    
    *lp.NMHDR = lParam
    
    ; now we see, what Message it was: (the code Member of the Structure contains the Message.)
    ; We'll need only 2 Messages:
    
    Select *lp\code
        
        ; fist is #TVN_BEGINLABELEDIT, this one is sent, if the user want's to edit an Item.
        
      Case #TVN_BEGINLABELEDIT
        
        ; here you can check, if you want to allow the user to edit this Item, or not.
        ; use GetGadgetState() to check, which Item in the TreeGadget is being edited.
        ; If you want to allow it, just do nothing, if not, you have to set
        ; 'result' to #TRUE.
        ; So if you want to always allow it, just write nothing here.
        
        ; In our case, we forbit editing Item 1: (which is actually the second in the Tree)
        ; but you can also do any other thing to find you, if you want to allo editing, this
        ; depends, on, what the Program will be for.
        
        If GetGadgetState(1) = 1
          result = #True
        EndIf
        
        ; ------------------------------------------
        
      Case #TVN_ENDLABELEDIT
        
        ; here you can check, if you want to accept the edited Text. For this, we'll
        ; need to get the new Text.
        
        ; lParam contains the Pointer to a Stucture with the Information
        ; As we allready know, lParam also pointed to the Structure from the
        ; #WM_NOTIFY Message. That's why this new Structure also contains the
        ; Structure NMHDR, which was from #WM_NOTIFY.
        
        *pvdi.NMTVDISPINFO = lParam
        
        ; The 'pszText' of the TV_ITEM Structure inside this Structure is a Pointer
        ; to the new entered Text. If this Pointer is #NULL, the Editing was
        ; chanceled by the User, and nothing will be changed. So we can ignore
        ; this Message in this case.
        ; Note: The Text can still be "", if the user deleted everything, but in this
        ; case, the Pointer will still not be #NULL.
        
        ; Check, that the 'pszText' Member is not #NULL
        
        If *pvdi\item\pszText <> #Null
          
          ; now, we get the entered Text:
          
          Text.s = PeekS(*pvdi\item\pszText)
          
          ; now you can decide, if you want to accept this Text, or not. If you want
          ; to find out the Item Number, use GetGadgetState().
          
          ; If you want to accept the Text, set 'result' to #True, if not, set it to
          ; #False.
          
          ; In our case, we don't want the user to enter an empty String.
          
          If Text = ""
            result = #False
          Else
            result = #True
          EndIf
          
        EndIf
        
        ; ------------------------------------------
        
        ; Well, that was all, you need, to make a TreeGadget editable, no a very big deal :wink:
        ; We now just close all started Contitions
        
        ; the selection of the Message   
        
    EndSelect
    
    ; The If contition for #WM_NOTIFY
    
  EndIf
  
  ; now, we return the 'return' value:
  
  ProcedureReturn result
  
  ; that's it, for the callback procedure.
  
EndProcedure

; ---------------------------------------------------------------------

That's it...

Timo

Posted: Tue Dec 17, 2002 11:32 pm
by BackupUser
Restored from previous forum. Originally posted by Kale.

very clever! nice example Timo :)

--Kale

New to PureBasic and falling in Love! :)

Posted: Wed Dec 18, 2002 8:42 am
by BackupUser
Restored from previous forum. Originally posted by fred.

Nice example ! The same code should be applied to ListIconGadget()... About your global hTVhwnd variable, you can use GadgetID(#Gadget) instead, so it makes your code a bit more friendly. It's also advised to make a check in the callback to see if it's the right gadget. Thanks for such snippet !

Fred - AlphaSND

Posted: Wed Dec 18, 2002 8:49 am
by BackupUser
Restored from previous forum. Originally posted by Fangbeast.
Originally posted by freak

Hi again,

As you can see, i'm doing a lot of Stuff with TreeGadgets ATM. I just want to share the Stuff i'm finding out, so here's a tutorial on how you can allow the User to edit the Items of a TreeGadget (like Windows-Explorer does.)

This will also be on the RecourceSite soon.

Hope it helps somebody...

That's it...

Timo
Timo, you are a genius. Do you remember months ago where you did other stuff to insert into tree, delete from tree, make tree item visible, get name of tree item, set text of tree item, expand/collapse tree node, expand whole tree, sort node and sort whole tree??

I want to see your stuff as native PB commands, they are a great help to us tree fellers (Irish joke) :):)

Fang

Fangles woz ear orright den?

Posted: Wed Dec 18, 2002 3:45 pm
by BackupUser
Restored from previous forum. Originally posted by freak.

> The same code should be applied to ListIconGadget()...

This is not hard, it is just the same, only the Constants and Structures are different. I've modified the code for ListIconGadgets
below, and commented all changes.

> About your global hTVhwnd variable, you can use GadgetID(#Gadget)
> instead, so it makes your code a bit more friendly. It's also
> advised to make a check in the callback to see if it's
> the right gadget.

Yes, i've also done that in my example below.


> Timo, you are a genius.

No, I wouldn't say that. This is just a result, of reading the API stuff, and watching my code crash a thousand times, till it works :)

I just want to share, what I've found out, that's all.

Timo

Code: Select all

; here comes the ListIconGadget code...
; -------------------------------------------------------------------

#List = 1 ; just to make the Code more readable.

; This Structure is a little different that the one for TreeGadget
; (it is LV_ITEM instead of TV_ITEM, and the Name is different :)  )

Structure NMLVDISPINFO
  hdr.NMHDR
  item.LV_ITEM
EndStructure

Declare Callback(Window.l, Message.l, wParam.l, lParam.l)

OpenWindow(0, 0, 0, 200, 400, #PB_Window_SystemMenu | #PB_Window_Screencentered, "ListIconGadget Example")
CreateGadgetList(WindowID())

ListIconGadget(#List, 5, 5, 190, 390, "Edit Items:", 150)

; change the Styles: here, we add #LVS_EDITLABELS

Styles.l = GetWindowLong_(GadgetID(#List), #GWL_STYLE)
Styles = Styles | #LVS_EDITLABELS
SetWindowLong_(GadgetID(#List), #GWL_STYLE, Styles)

AddGadgetItem(1, 0, "Item0")
AddGadgetItem(1, 0, "Item0")
AddGadgetItem(1, 0, "Item0")
AddGadgetItem(1, 0, "Item0")

SetWindowCallback(@Callback())


While WaitWindowEvent()  #PB_EventCloseWindow: Wend
End

; ------------------------------------------------------------------------------------

Procedure Callback(Window.l, Message.l, wParam.l, lParam.l)
  result = #PB_ProcessPureBasicEvents 
    
  If Message = #WM_NOTIFY
      
      *lp.NMHDR = lParam
      
      ; check, if it was really this Gadget, who sent the Message:
      ; this can also be done for TreeGadgets (i forgot that)
      
      If *lp\hwndFrom = GadgetID(#List)
      
        ; get real Message:
        
        Select *lp\code
        
          Case #LVN_BEGINLABELEDIT
                     
             ; this is just the same as for TreeGadget, only the Message Constant is different.
             ; return #True, to forbit editing, #False to allow it.
           
             If GetGadgetState(1) = 1
               result = #True
             EndIf
           
             ; ------------------------------------------
           
         Case #LVN_ENDLABELEDIT
       
             ; This is also the same, just the Structure Name and the Constant has changed.
           
             *pvdi.NMLVDISPINFO = lParam
           
             ; Even the Members of the Structure are the same:         
           
             If *pvdi\item\pszText  #NULL
             
               Text.s = PeekS(*pvdi\item\pszText)
             
             ; If you want to accept the Text, set 'result' to #True, if not, set it to
             ; #False.
             
             
               If Text = ""
                 result = #False
               Else
                 result = #True
               EndIf
            
             EndIf
           
           ; ------------------------------------------
          
       
        EndSelect
      
      EndIf
  
  EndIf
  
  ProcedureReturn result
  
EndProcedure


Posted: Wed Dec 18, 2002 10:03 pm
by BackupUser
Restored from previous forum. Originally posted by Fangbeast.
Originally posted by freak

> The same code should be applied to ListIconGadget()...
Timo, how can this be expanded so that other collumns in the same row would be editable? This would make it very 'spreadsheet' like in its' behaviour. Useful stuff.

Fangles woz ear orright den?

Posted: Wed Dec 18, 2002 10:36 pm
by BackupUser
Restored from previous forum. Originally posted by freak.

I don't know, if this is possible. You can't even select annother column, if you
don't include the FullrowSelect Flag.

AFAIK, you can only edit the left column. The code i have posted contains all
stuff that was mentioned in the Platform SDK. There was no additional Information on
what you ask for.

Sorry, but if there is some Way, i don't know it :cry:

Timo

Posted: Thu Dec 19, 2002 8:37 am
by BackupUser
Restored from previous forum. Originally posted by fred.

I tends to confirm freak tough, as I never saw a such stuff. BTW, you know than the editable stuff is only a StringGadget with thin border which is drawn over the treeview ? So it should be possible to do it manually for other columns, get getting the line, the columns with/height and display the gadget :). A bit tricky but it should work...

Fred - AlphaSND

Is still right with 3.91 version of PureBasic

Posted: Fri Aug 27, 2004 2:54 pm
by ROUMANET
Hi,

I would to know if there is no other since 2002 to edit a ListIconGadget ?

Thanks
David

Posted: Fri Dec 02, 2005 4:17 pm
by josku_x
Can someone please upload the PB file of this snippet? I cannot execute the code because PureBasic doesn't understand the code because of the line formatting:


Code: Select all

; ---------------------------------------------------------------------; How to make TreeGadget Items Editable by the User; by Timo Harter; ---------------------------------------------------------------------;; By implementing this in your Program, the User can edit the Items; of a TreeGadget by first right-clicking, and then left-clicking on it.; (just like in Windows-Explorer) ;; This is just a skeleton, how it is done, but it should be easy to ; understand, and implement in your own Programs.; ---------------------------------------------------------------------; This Constant will be needed:#TVS_EDITLABELS = 8  ; The Window Style for Label Editing; There's also a not defined Structure, we will need.Structure NMTVDISPINFO  hdr.NMHDR  item.TV_ITEMEndStructure; We'll need one Global Variable for this, to store the Windows-Handle to the Gadget:Global hWndTV.l; We'll also need a Callback procedure for that. (If you never used one, don't be afraid, ; it's not that hard.). I'll just declare it here, the Procedure will be further down.Declare Callback(Window.l, Message.l, wParam.l, lParam.l); First, we'll just create a Window, and a a TreeGadget.OpenWindow(0, 0, 0, 200, 400, #PB_Window_SystemMenu | #PB_Window_Screencentered, "TreeGadget Example")CreateGadgetList(WindowID()); Store the Handle in the Global value:hWndTV = TreeGadget(1, 5, 5, 190, 390); Now, here we run into our first Problem: There's no Flag for enabling Label Editing.; so we'll have to to it ourselves.; We can change that using the API Functions GetWindowLong_() and SetWindowLong_(); What we do, is change a Style of the Window (That's the Stuff you specify with the Flags); First, get the existing Styles:Styles.l = GetWindowLong_(hWndTV, #GWL_STYLE); Then Add Label Editing to these Styles:Styles = Styles | #TVS_EDITLABELS; Now Set the new Styles for the Gadget:SetWindowLong_(hWndTV, #GWL_STYLE, Styles); Now Label Editing is allowed in this TreeGadget; We'll now add some ItemsAddGadgetItem(1, 0, "Item0")AddGadgetItem(1, 0, "Item0")OpenTreeGadgetNode()  AddGadgetItem(1, 0, "Item0")  AddGadgetItem(1, 0, "Item0")CloseTreeGadgetNode(); Now we'll need to set the Callback Procedure (for more Inofrmation see 'SetWindowCallback()'; in the Help Files in the 'Window' Library.SetWindowCallback(@Callback()); That was all that was to be done in the Main prog, now your Main Loop can follow, that; will handle all normal PureBasic Events.; In this case, we handle no other Events, so this Loop only waits for the Close; Button to be Pressed, and then Ends the Program.While WaitWindowEvent() <> #PB_EventCloseWindow: WendEnd; This is the End of the Main Code.; ------------------------------------------------------------------------------------; Now following is the Callback Procedure. Here we handle the Editing.; The Events are Send as Messages, where a Message is just a Constantt; like the Event-Constants, wParam and lParam are just the parameters for; these Events. You see, the Callback-thingy is not that hard.; the only thing is to always use the skeleton you can find in the Help files; (at 'SetWindowCallback()') as otherwise, your Program will crash.Procedure Callback(Window.l, Message.l, wParam.l, lParam.l)  result = #PB_ProcessPureBasicEvents     ; The Messages we need are sent as a WM_NOTIFY Message. THis means, the Message will  ; in our case always be #WM_NOTIFY, and the selection of the real Message will be made  ; later.    ; So we only need to find this Message:    If Message = #WM_NOTIFY             ; lParam contains the Pointer to a Structure with the actual Message:             *lp.NMHDR = lParam            ; now we see, what Message it was: (the code Member of the Structure contains the Message.)      ; We'll need only 2 Messages:            Select *lp\code              ; fist is #TVN_BEGINLABELEDIT, this one is sent, if the user want's to edit an Item.                Case #TVN_BEGINLABELEDIT                      ; here you can check, if you want to allow the user to edit this Item, or not.           ; use GetGadgetState() to check, which Item in the TreeGadget is being edited.           ; If you want to allow it, just do nothing, if not, you have to set           ; 'result' to #TRUE.           ; So if you want to always allow it, just write nothing here.                      ; In our case, we forbit editing Item 1: (which is actually the second in the Tree)           ; but you can also do any other thing to find you, if you want to allo editing, this           ; depends, on, what the Program will be for.                      If GetGadgetState(1) = 1             result = #True           EndIf                      ; ------------------------------------------                  Case #TVN_ENDLABELEDIT                  ; here you can check, if you want to accept the edited Text. For this, we'll           ; need to get the new Text.                      ; lParam contains the Pointer to a Stucture with the Information           ; As we allready know, lParam also pointed to the Structure from the           ; #WM_NOTIFY Message. That's why this new Structure also contains the           ; Structure NMHDR, which was from #WM_NOTIFY.                      *pvdi.NMTVDISPINFO = lParam                      ; The 'pszText' of the TV_ITEM Structure inside this Structure is a Pointer           ; to the new entered Text. If this Pointer is #NULL, the Editing was           ; chanceled by the User, and nothing will be changed. So we can ignore           ; this Message in this case.           ; Note: The Text can still be "", if the user deleted everything, but in this           ; case, the Pointer will still not be #NULL.                      ; Check, that the 'pszText' Member is not #NULL                      If *pvdi\item\pszText <> #NULL                        ; now, we get the entered Text:                          Text.s = PeekS(*pvdi\item\pszText)                          ; now you can decide, if you want to accept this Text, or not. If you want             ; to find out the Item Number, use GetGadgetState().                          ; If you want to accept the Text, set 'result' to #True, if not, set it to             ; #False.                          ; In our case, we don't want the user to enter an empty String.                          If Text = ""               result = #False             Else               result = #True             EndIf                     EndIf                      ; ------------------------------------------                     ; Well, that was all, you need, to make a TreeGadget editable, no a very big deal            ; We now just close all started Contitions            ; the selection of the Message                 EndSelect        ; The If contition for #WM_NOTIFY    EndIf    ; now, we return the 'return' value:    ProcedureReturn result; that's it, for the callback procedure.  EndProcedure; ---------------------------------------------------------------------
Just what compiler understands that??

Posted: Fri Dec 02, 2005 4:55 pm
by Berikco
No need to post in red

just past the code first in wordpad....and copy/paste again to pb editor
Its the old forum that causes this
this is the result after wordpadding the code

Code: Select all

; ---------------------------------------------------------------------
; How to make TreeGadget Items Editable by the User
; by Timo Harter
; ---------------------------------------------------------------------
;
; By implementing this in your Program, the User can edit the Items
; of a TreeGadget by first right-clicking, and then left-clicking on it.
; (just like in Windows-Explorer) 
;
; This is just a skeleton, how it is done, but it should be easy to 
; understand, and implement in your own Programs.
; ---------------------------------------------------------------------


; This Constant will be needed:

#TVS_EDITLABELS = 8  ; The Window Style for Label Editing

; There's also a not defined Structure, we will need.

Structure NMTVDISPINFO
  hdr.NMHDR
  item.TV_ITEM
EndStructure

; We'll need one Global Variable for this, to store the Windows-Handle to the Gadget:

Global hWndTV.l

; We'll also need a Callback procedure for that. (If you never used one, don't be afraid, 
; it's not that hard.). I'll just declare it here, the Procedure will be further down.

Declare Callback(Window.l, Message.l, wParam.l, lParam.l)

; First, we'll just create a Window, and a a TreeGadget.

OpenWindow(0, 0, 0, 200, 400, #PB_Window_SystemMenu | #PB_Window_Screencentered, "TreeGadget Example")
CreateGadgetList(WindowID())

; Store the Handle in the Global value:

hWndTV = TreeGadget(1, 5, 5, 190, 390)

; Now, here we run into our first Problem: There's no Flag for enabling Label Editing.
; so we'll have to to it ourselves.
; We can change that using the API Functions GetWindowLong_() and SetWindowLong_()
; What we do, is change a Style of the Window (That's the Stuff you specify with the Flags)

; First, get the existing Styles:

Styles.l = GetWindowLong_(hWndTV, #GWL_STYLE)

; Then Add Label Editing to these Styles:

Styles = Styles | #TVS_EDITLABELS

; Now Set the new Styles for the Gadget:

SetWindowLong_(hWndTV, #GWL_STYLE, Styles)

; Now Label Editing is allowed in this TreeGadget

; We'll now add some Items

AddGadgetItem(1, 0, "Item0")
AddGadgetItem(1, 0, "Item0")
OpenTreeGadgetNode()
  AddGadgetItem(1, 0, "Item0")
  AddGadgetItem(1, 0, "Item0")
CloseTreeGadgetNode()

; Now we'll need to set the Callback Procedure (for more Inofrmation see 'SetWindowCallback()'
; in the Help Files in the 'Window' Library.

SetWindowCallback(@Callback())

; That was all that was to be done in the Main prog, now your Main Loop can follow, that
; will handle all normal PureBasic Events.
; In this case, we handle no other Events, so this Loop only waits for the Close
; Button to be Pressed, and then Ends the Program.

While WaitWindowEvent() <> #PB_EventCloseWindow: Wend
End

; This is the End of the Main Code.
; ------------------------------------------------------------------------------------

; Now following is the Callback Procedure. Here we handle the Editing.
; The Events are Send as Messages, where a Message is just a Constantt
; like the Event-Constants, wParam and lParam are just the parameters for
; these Events. You see, the Callback-thingy is not that hard.
; the only thing is to always use the skeleton you can find in the Help files
; (at 'SetWindowCallback()') as otherwise, your Program will crash.


Procedure Callback(Window.l, Message.l, wParam.l, lParam.l)
  result = #PB_ProcessPureBasicEvents 
  
  ; The Messages we need are sent as a WM_NOTIFY Message. THis means, the Message will
  ; in our case always be #WM_NOTIFY, and the selection of the real Message will be made
  ; later.
  
  ; So we only need to find this Message:
  
  If Message = #WM_NOTIFY 
      
      ; lParam contains the Pointer to a Structure with the actual Message: 
      
      *lp.NMHDR = lParam
      
      ; now we see, what Message it was: (the code Member of the Structure contains the Message.)
      ; We'll need only 2 Messages:
      
      Select *lp\code
      
        ; fist is #TVN_BEGINLABELEDIT, this one is sent, if the user want's to edit an Item.
        
        Case #TVN_BEGINLABELEDIT
           
           ; here you can check, if you want to allow the user to edit this Item, or not.
           ; use GetGadgetState() to check, which Item in the TreeGadget is being edited.
           ; If you want to allow it, just do nothing, if not, you have to set
           ; 'result' to #TRUE.
           ; So if you want to always allow it, just write nothing here.
           
           ; In our case, we forbit editing Item 1: (which is actually the second in the Tree)
           ; but you can also do any other thing to find you, if you want to allo editing, this
           ; depends, on, what the Program will be for.
           
           If GetGadgetState(1) = 1
             result = #True
           EndIf
           
           ; ------------------------------------------
           
       Case #TVN_ENDLABELEDIT
       
           ; here you can check, if you want to accept the edited Text. For this, we'll
           ; need to get the new Text.
           
           ; lParam contains the Pointer to a Stucture with the Information
           ; As we allready know, lParam also pointed to the Structure from the
           ; #WM_NOTIFY Message. That's why this new Structure also contains the
           ; Structure NMHDR, which was from #WM_NOTIFY.
           
           *pvdi.NMTVDISPINFO = lParam
           
           ; The 'pszText' of the TV_ITEM Structure inside this Structure is a Pointer
           ; to the new entered Text. If this Pointer is #NULL, the Editing was
           ; chanceled by the User, and nothing will be changed. So we can ignore
           ; this Message in this case.
           ; Note: The Text can still be "", if the user deleted everything, but in this
           ; case, the Pointer will still not be #NULL.
           
           ; Check, that the 'pszText' Member is not #NULL
           
           If *pvdi\item\pszText <> #NULL
           
             ; now, we get the entered Text:
             
             Text.s = PeekS(*pvdi\item\pszText)
             
             ; now you can decide, if you want to accept this Text, or not. If you want
             ; to find out the Item Number, use GetGadgetState().
             
             ; If you want to accept the Text, set 'result' to #True, if not, set it to
             ; #False.
             
             ; In our case, we don't want the user to enter an empty String.
             
             If Text = ""
               result = #False
             Else
               result = #True
             EndIf
          
           EndIf
           
           ; ------------------------------------------
          
           ; Well, that was all, you need, to make a TreeGadget editable, no a very big deal Wink
           ; We now just close all started Contitions
      
      ; the selection of the Message    
       
      EndSelect
      
  ; The If contition for #WM_NOTIFY
  
  EndIf
  
  ; now, we return the 'return' value:
  
  ProcedureReturn result

; that's it, for the callback procedure.
  
EndProcedure

; ---------------------------------------------------------------------

Posted: Fri Dec 02, 2005 11:37 pm
by josku_x
Sorry, I wrote in red as I was mad why PB didn't understand it... But I tried to first copy the code to Wordpad and then to PB, but it doesn't work... Atleast it works for you :?

Thanks!

Posted: Sat Dec 03, 2005 1:30 am
by Dare2
@Bericko: Such restraint. ;)

@josku_x: Well you have it now. (Um. I assume you copy-pasted from Bericko's post?) :)

Posted: Sat Dec 03, 2005 2:37 pm
by josku_x
Yes, I copied the code from Bericko's post..

But I don't realize how the code works-.. :cry:

also it tells me that the structure is already declared: NMTVDISPINFO

Posted: Sat Dec 03, 2005 3:56 pm
by gnozal
josku_x wrote:But I don't realize how the code works-..
The #TVS_EDITLABELS style makes it possible for the user to edit the labels of the TreeViewGadget items.
From MSDN :
The user can directly edit the labels of items in a tree-view control that has the TVS_EDITLABELS style. The user begins editing by clicking the label of the item that has the focus. An application begins editing by using the TVM_EDITLABEL message. The tree-view control notifies the parent window when editing begins and when it is canceled or completed. When editing is completed, the parent window is responsible for updating the item's label, if appropriate.

When label editing begins, a tree-view control sends its parent window a TVN_BEGINLABELEDIT notification message. By processing this notification, an application can allow editing of some labels and prevent editing of others. Returning zero allows editing, and returning nonzero prevents it.

When label editing is canceled or completed, a tree-view control sends its parent window a TVN_ENDLABELEDIT notification message. The lParam parameter is the address of an NMTVDISPINFO structure. The item parameter is a TVITEM structure that identifies the item and includes the edited text. The parent window is responsible for updating the item's label if it wishes to keep the new label. The pszText member of TVITEM is zero if editing is canceled.

During label editing, typically in response to the TVN_BEGINLABELEDIT notification message, you can retrieve the handle to the edit control used for label editing by using the TVM_GETEDITCONTROL message. You can send the edit control an EM_SETLIMITTEXT message to limit the amount of text a user can enter or subclass the edit control to intercept and discard invalid characters. Note, however, that the edit control is displayed only after TVN_BEGINLABELEDIT is sent.
josku_x wrote:also it tells me that the structure is already declared: NMTVDISPINFO
It is already declared in PB 3.94.
Try this (fixed) code :

Code: Select all

; This Constant will be needed: 

#TVS_EDITLABELS = 8  ; The Window Style for Label Editing 

; There's also a not defined Structure, we will need. 

; Already declared
; Structure NMTVDISPINFO 
  ; hdr.NMHDR 
  ; item.TV_ITEM 
; EndStructure 

; We'll need one Global Variable for this, to store the Windows-Handle to the Gadget: 

Global hWndTV.l 

; We'll also need a Callback procedure for that. (If you never used one, don't be afraid, 
; it's not that hard.). I'll just declare it here, the Procedure will be further down. 

Declare Callback(Window.l, message.l, wParam.l, lParam.l) 

; First, we'll just create a Window, and a a TreeGadget. 

OpenWindow(0, 0, 0, 200, 400, #PB_Window_SystemMenu | #PB_Window_Screencentered, "TreeGadget Example") 
CreateGadgetList(WindowID()) 

; Store the Handle in the Global value: 

hWndTV = TreeGadget(1, 5, 5, 190, 390) 

; Now, here we run into our first Problem: There's no Flag for enabling Label Editing. 
; so we'll have to to it ourselves. 
; We can change that using the API Functions GetWindowLong_() and SetWindowLong_() 
; What we do, is change a Style of the Window (That's the Stuff you specify with the Flags) 

; First, get the existing Styles: 

Styles.l = GetWindowLong_(hWndTV, #GWL_STYLE) 

; Then Add Label Editing to these Styles: 

Styles = Styles | #TVS_EDITLABELS 

; Now Set the new Styles for the Gadget: 

SetWindowLong_(hWndTV, #GWL_STYLE, Styles) 

; Now Label Editing is allowed in this TreeGadget 

; We'll now add some Items 

AddGadgetItem(1, -1, "Item0") 
AddGadgetItem(1, -1, "Item1") 
OpenTreeGadgetNode(1) 
AddGadgetItem(1, -1, "Item2") 
AddGadgetItem(1, -1, "Item3") 
CloseTreeGadgetNode(1) 

; Now we'll need to set the Callback Procedure (for more Inofrmation see 'SetWindowCallback()' 
; in the Help Files in the 'Window' Library. 

SetWindowCallback(@Callback()) 

; That was all that was to be done in the Main prog, now your Main Loop can follow, that 
; will handle all normal PureBasic Events. 
; In this case, we handle no other Events, so this Loop only waits for the Close 
; Button to be Pressed, and then Ends the Program. 

While WaitWindowEvent() <> #PB_EventCloseWindow: Wend 
End 

; This is the End of the Main Code. 
; ------------------------------------------------------------------------------------ 

; Now following is the Callback Procedure. Here we handle the Editing. 
; The Events are Send as Messages, where a Message is just a Constantt 
; like the Event-Constants, wParam and lParam are just the parameters for 
; these Events. You see, the Callback-thingy is not that hard. 
; the only thing is to always use the skeleton you can find in the Help files 
; (at 'SetWindowCallback()') as otherwise, your Program will crash. 


Procedure Callback(Window.l, message.l, wParam.l, lParam.l) 
  result = #PB_ProcessPureBasicEvents 
  
  ; The Messages we need are sent as a WM_NOTIFY Message. THis means, the Message will 
  ; in our case always be #WM_NOTIFY, and the selection of the real Message will be made 
  ; later. 
  
  ; So we only need to find this Message: 
  
  If message = #WM_NOTIFY 
    
    ; lParam contains the Pointer to a Structure with the actual Message: 
    
    *lp.NMHDR = lParam 
    
    ; now we see, what Message it was: (the code Member of the Structure contains the Message.) 
    ; We'll need only 2 Messages: 
    
    Select *lp\code 
      
      ; fist is #TVN_BEGINLABELEDIT, this one is sent, if the user want's to edit an Item. 
      
      Case #TVN_BEGINLABELEDIT 
        
        ; here you can check, if you want to allow the user to edit this Item, or not. 
        ; use GetGadgetState() to check, which Item in the TreeGadget is being edited. 
        ; If you want to allow it, just do nothing, if not, you have to set 
        ; 'result' to #TRUE. 
        ; So if you want to always allow it, just write nothing here. 
        
        ; In our case, we forbit editing Item 1: (which is actually the second in the Tree) 
        ; but you can also do any other thing to find you, if you want to allo editing, this 
        ; depends, on, what the Program will be for. 
        
        If GetGadgetState(1) = 1 
          result = #TRUE 
        EndIf 
        
        ; ------------------------------------------ 
        
      Case #TVN_ENDLABELEDIT 
        
        ; here you can check, if you want to accept the edited Text. For this, we'll 
        ; need to get the new Text. 
        
        ; lParam contains the Pointer to a Stucture with the Information 
        ; As we allready know, lParam also pointed to the Structure from the 
        ; #WM_NOTIFY Message. That's why this new Structure also contains the 
        ; Structure NMHDR, which was from #WM_NOTIFY. 
        
        *pvdi.NMTVDISPINFO = lParam 
        
        ; The 'pszText' of the TV_ITEM Structure inside this Structure is a Pointer 
        ; to the new entered Text. If this Pointer is #NULL, the Editing was 
        ; chanceled by the User, and nothing will be changed. So we can ignore 
        ; this Message in this case. 
        ; Note: The Text can still be "", if the user deleted everything, but in this 
        ; case, the Pointer will still not be #NULL. 
        
        ; Check, that the 'pszText' Member is not #NULL 
        
        If *pvdi\item\pszText <> #NULL 
          
          ; now, we get the entered Text: 
          
          Text.s = PeekS(*pvdi\item\pszText) 
          
          ; now you can decide, if you want to accept this Text, or not. If you want 
          ; to find out the Item Number, use GetGadgetState(). 
          
          ; If you want to accept the Text, set 'result' to #True, if not, set it to 
          ; #False. 
          
          ; In our case, we don't want the user to enter an empty String. 
          
          If Text = "" 
            result = #FALSE 
          Else 
            result = #TRUE 
          EndIf 
          
        EndIf 
        
        ; ------------------------------------------ 
        
        ; Well, that was all, you need, to make a TreeGadget editable, no a very big deal Wink 
        ; We now just close all started Contitions 
        
        ; the selection of the Message    
        
    EndSelect 
    
    ; The If contition for #WM_NOTIFY 
    
  EndIf 
  
  ; now, we return the 'return' value: 
  
  ProcedureReturn result 
  
  ; that's it, for the callback procedure. 
  
EndProcedure