Umbenennen im TreeGadget() mit PopupMenu()
Verfasst: 29.05.2005 20:06
Ich habe letztens diesen Code gefunden, der zeigt wie man ein TreeGadget() dazu bringt, dass man die Einträge umbenennen kann. Das ganze funktioniert auch super. Ich möchte aber noch ein PopupMenu einbauen, in dem dann ein 'Umbennen' Item ist (so wie z.B. im Windows Explorer). Ich weiß aber jetzt nicht, wie ich das TreeGadget() dazu bringe, dass er den aktuellen Eintrag zu dem Eingabefeld umwandelt, damit man den Eintrag dann editieren kann. Mir kam bis jetzt die Idee ein SendMessage_(hWnd_TreeGadget, #WM_LButtonDown, bla, bla) zu machen, um einen Mausklick zu 'simulieren', doch dazu müsste ich die Koordinaten des Items kennen. Oder gibts da vielleicht eine andere Message? Kann mir damit jemand helfen? Danke schonmal im vorraus!
Hier ist noch der Source:
Hier ist noch der Source:
Code: Alles auswählen
; ---------------------------------------------------------------------
; 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
; 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, -1, "Item0")
AddGadgetItem(1, -1, "Item0")
OpenTreeGadgetNode(1)
AddGadgetItem(1, -1, "Item0")
AddGadgetItem(1, -1, "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.
Repeat
Event=WaitWindowEvent()
Until Event=#PB_Event_CloseWindow
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
Debug 1
Debug wParam
; 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
Debug 2
; 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