; --------------------------------------------------------------------- ; 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 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(1) AddGadgetItem(1, 0, "Item0") AddGadgetItem(1, 0, "Item0") 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 need to check, if it's really the TreeGadget that sent the Message If *lp\hwndFrom = GadgetID(1) ; 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 of the Check for right Gadget EndIf ; The If contition for #WM_NOTIFY EndIf ; now, we return the 'return' value: ProcedureReturn result ; that's it, for the callback procedure. EndProcedure