Ich würde gern Die Einträge in einem Listicongadget per Drag n Drop verschiebbar machen, und ausserdem solche dinge wie Markieren mit gedrückter Strg-oder Shift-Taste aktivieren, ist das möglich?
Vielen Dank
m0
Einträge im ListIconGadget per Drag and Drop Verschieben
CodeArchiv -> PB4
FF 
Code: Alles auswählen
; ------------------------------------------------------------------
;
; Drag & Drop example with ListIconGadget
; By Timo 'fr34k' Harter
;
; ------------------------------------------------------------------
;
; Hi, this is a rather basic example of how to do drag & drop with
; a ListIconGadget in PureBasic. It should give you a good start, of
; how to do such a thing in your own projects. This uses 2 Gadgets
; for the demonstration. It should not be hard to modify it to use
; more than that, or even to work with only one Gadget.
;
; Feel free, to copy & paste any of this code into your own, i don't
; care.
;
; ------------------------------------------------------------------
; Ok, let's start with what we need global, so it is always accessible
; from the callback procedure. 'IsDraging' is used to see, if a drag&drop
; operation is in progress, 'DragImageList' is used to store the displayed
; drag&drop image. The rest should be pretty clear.
Global IsDraging, DragImageList, SourceGadget, SourceItem, TargetGadget, TargetItem
Declare WindowCallback(Window, Message, wParam, lParam)
; Here, the GUI is created, nothing fancy about this one...
#ListIcon1 = 1
#ListIcon2 = 2
If OpenWindow(0, 0, 0, 600, 300, "ListIcon Drag&Drop", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
If CreateGadgetList(WindowID(0))
; callback is needed for the processing of the drag&drop messages
SetWindowCallback(@WindowCallback())
ListIconGadget(#ListIcon1, 5, 5, 290, 290, "Testing...", 250)
ListIconGadget(#ListIcon2, 305, 5, 290, 290, "Testing...", 250)
For i = 0 To 10
AddGadgetItem(#ListIcon1, -1, "Gadget1 - Item"+Str(i))
AddGadgetItem(#ListIcon2, -1, "Gadget2 - Item"+Str(i))
Next i
TargetGadget = -1
; all drag&drop handling is done in the callback procedure,
; so nothing is needed here.
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
EndIf
End
; If you are not familiar with the use of a WindowCallback procedure,
; you should read my basic explanation here:
; http://purebasic.myforums.net/viewtopic.php?p=39654#39654
Procedure WindowCallback(Window, Message, wParam, lParam)
Result = #PB_ProcessPureBasicEvents
; The first message we need is #LVN_BEGINDRAG. This is a so called
; Notification message. This means, that you don't get a message called
; #LVN_BEGINDRAG, but you get a #WM_NOTIFY message, with further information,
; that tells you, that it is #LVN_BEGINDRAG.
If Message = #WM_NOTIFY
; The lparam paramenter contains a pointer to a NMHDR structure. There is
; the information about the Message
*nmhdr.NMHDR = lParam
; The 'hwndfrom' member tells you, which Gadget actually sent the message
; This must be always checked to be sure, it is the right gadget.
; We allow only our 2 Gadgets:
If *nmhdr\hwndfrom = GadgetID(#ListIcon1) Or *nmhdr\hwndfrom = GadgetID(#ListIcon2)
; The 'code' member contains the real message, in our case #LVN_BEGINDRAG
If *nmhdr\code = #LVN_BEGINDRAG
; Let's find out, which of our Gadgets is the source, we will need this later.
; If you have more than 2 Gadgets with drag&drop, you have to add more checks
; here:
If *nmhdr\hwndfrom = GadgetID(#ListIcon1)
SourceGadget = #ListIcon1
Else ; must be #ListIcon2, as we have allready checked, that it is only one of the 2
SourceGadget = #ListIcon2
EndIf
; Ok, for the #LVN_BEGINDRAG notification message, lParam is a pointer to a
; NMLISTVIEW Structure. You might think that this can't be, as lParam allready
; pointed to a NMHDR structure, but this is correct, as NMLISTVIEW has a
; NMHDR structure inside, it only adds more members to it.
*nmv.NMLISTVIEW = lParam
; The 'iItem' member contains the index of the source item, which we will need
; later.
SourceItem = *nmv\iItem
; By sending a #LVM_CREATEDRAGIMAGE message to the gadget, we create an ImageList
; that contains just one image, the drag&drop image. We will need the Imagelist WinAPI
; commands to work with that one later. This message also expects a POINT structure
; as parameter that contains the hot-spot in the image. As we set this to (0|0), we
; don't even need to initialize this variable.
DragImageList = SendMessage_(GadgetID(SourceGadget), #LVM_CREATEDRAGIMAGE, SourceItem, @UpperLeft.POINT)
; It is important to check the result, as it would lock the mouse, if
; we continue without this one working.
If DragImageList
; This begins the drag&drop operation by displaying the image
If ImageList_BeginDrag_(DragImageList , 0, 0, 0)
; this command shows or hides the drag&drop image. Or course,
; we want to see it now :)
ImageList_DragShowNolock_(#True)
; this causes windows to send all mouse messages to our window,
; even if the mouse is outside of our window. This is neccesary,
; because we need to detect the mouseup event to abort the
; operation, even if the mouse is outside our window.
SetCapture_(GetParent_(GadgetID(SourceGadget)))
; hide the standart cursor
ShowCursor_(#False)
; When processing the other events, we need to know whether something
; is being draged or not.
IsDraging = #True
EndIf ; check for ImageList_BeginDrag_()
EndIf ; check for DragImageList
EndIf ; check for #LVN_BEGINDRAG
EndIf ; check for right gadget
; The next message we need is #WM_MOUSEMOVE, to update the mouse.
; But only if IsDraging is #TRUE.
ElseIf Message = #WM_MOUSEMOVE And IsDraging
; this moves the drag Image. It requires Screen coordinates.
ImageList_DragMove_(WindowMouseX(0)+WindowX(0), WindowMouseY(0)+WindowY(0))
; now we hide the image to avoid redraw problems.
ImageList_DragShowNolock_(#False)
; the next thing we do is hilighting the target item in the target gadget.
; for this, we need mouse coordinates relative to the client area of our
; window. WindowMouseX() and WindowMouseY() include the window borders, so
; we can't use them. When #EM_MOUSEMOVE is sent, the lParam parameter contains
; the x coordinate in the low-word and the y coordinate in the high-word, so we
; just use them here:
MouseX = lParam & $FFFF
MouseY = lParam >> 16
; first, we unhilight the previous target, if there was one:
If TargetGadget <> -1
; We send a #LNM_SETITEM message for that, but we only need to change the
; item state, so #LVIF_STATE is enough for the mask.
pitem.LV_ITEM
pitem\mask = #LVIF_STATE
pitem\iItem = TargetItem
; 'stateMask' determines, what will be changed, and 'state' sets the actual value,
; so here, we set the #LVIS_DROPHILITED state flag to 0.
pitem\state = 0
pitem\stateMask = #LVIS_DROPHILITED
SendMessage_(GadgetID(TargetGadget), #LVM_SETITEM, 0, @pitem)
; a redraw is neccesary here to avoid problems.
RedrawWindow_(GadgetID(TargetGadget), 0, 0, #RDW_UPDATENOW)
EndIf
; now we need to find out, which Gadget is currently the target one.
; with ChildWindowFromPoint_() we can get it's handle.
TargetGadgetID = ChildWindowFromPoint_(Window, MouseX, MouseY)
; find out the PB numeric ID for the Gadget
; again, for more Gadgets, more checks are needed.
If TargetGadgetID = GadgetID(#ListIcon1)
TargetGadget = #ListIcon1
ElseIf TargetGadgetID = GadgetID(#ListIcon2)
TargetGadget = #ListIcon2
Else
TargetGadget = -1
EndIf
If TargetGadget <> -1
; What we need next is the Item, that is currently under the mouse cursor.
; the #LVM_HITTEST message does that test for us.
; here, we need coordinates relative to the top/left corner of our target
; Gadget, so we substract the Gadget position from our window coordinates.
hittestinfo.LV_HITTESTINFO
hittestinfo\pt\x = MouseX - GadgetX(TargetGadget) - 24
hittestinfo\pt\y = MouseY - GadgetY(TargetGadget) - 24
; find the item, if none is under the cursor, we get -1, and the next
; SendMessage won't work, and nothing is hilighted.
TargetItem = SendMessage_(GadgetID(TargetGadget), #LVM_HITTEST, 0, @hittestinfo)
; same as before, this time we set the #LVIS_DROPHILITED flag to #LVIS_DROPHILITED.
pitem.LV_ITEM
pitem\mask = #LVIF_STATE
pitem\iItem = TargetItem
pitem\state = #LVIS_DROPHILITED
pitem\stateMask = #LVIS_DROPHILITED
SendMessage_(GadgetID(TargetGadget), #LVM_SETITEM, 0, @pitem)
RedrawWindow_(GadgetID(TargetGadget), 0, 0, #RDW_UPDATENOW) ; again a redraw
EndIf
; now we can show the drag image again:
ImageList_DragShowNolock_(#True)
; that's all to do while moving the mouse. Of course, there can be more checks added,
; and for example, a different cursor displayed, if you don't want the source to
; be draged to the current target and so on, but i think this is enough for a basic
; example.
; next is the end of the drag&drop operation... when the user releases the mouse.
ElseIf Message = #WM_LBUTTONUP And IsDraging
; first, we release all we did, to unlock the mouse.
; mouse messages will be sent to other windows again
ReleaseCapture_()
; and drag&drop (remove the image)
ImageList_EndDrag_()
; free the image list
ImageList_Destroy_(DragImageList)
; show cursor again
ShowCursor_(#True)
; no draging in progress now.
IsDraging = #False
; next, we unhilight the last target item, just like before:
If TargetGadget <> -1
pitem.LV_ITEM
pitem\mask = #LVIF_STATE
pitem\iItem = TargetItem
pitem\state = 0
pitem\stateMask = #LVIS_DROPHILITED
SendMessage_(GadgetID(TargetGAdget), #LVM_SETITEM, 0, @pitem)
RedrawWindow_(GadgetID(TargetGadget), 0, 0, #RDW_UPDATENOW)
EndIf
; there is no need to check, which is the target, because this was allready
; done on the last mouse move.
; just check, if the mouse is over one of our target gadgets:
If TargetGadget <> -1
; at this point, every thing is complete, and we know, that the
; drag&drop was successfull, from one gadget to another.
; We can now take the action on this operation.
; Note: TargetItem might be -1, if the item was draged into the
; empty area of the target gadget. The TargetItem doesn't have to
; be a valid item.
; for the example, we just remove the source, and add the target.
ItemText$ = GetGadgetItemText(SourceGadget, SourceItem, 0)
RemoveGadgetItem(SourceGadget, SourceItem)
AddGadgetItem(TargetGadget, TargetItem, ItemText$)
EndIf ; check TargetGadget
EndIf ; check Message
ProcedureReturn Result
EndProcedure
; ------------------------------------------------------------------
;
; That's all for this example. If you have more questions, feel free
; to post them at http://purebasic.myforums.net/, or send me a mail
; at freak@betriebsdirektor.de
;
; ------------------------------------------------------------------

Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Hey das klappt ja schonmal prima!!
Geht das auch irgendwie mit multiselection? wohl kaum gell? naja im endefekt egal das reicht vorerst nur muss ich noch rausfinden wie ich statt der 2. selection nen strich drawen könnte, der anzeigt wo es eingefügt wird, so is das bissl verwirrend weil man nicht weis ob oberhalb/unterhalb die selection geschoben wird
danke euch!
mfg
m0
Geht das auch irgendwie mit multiselection? wohl kaum gell? naja im endefekt egal das reicht vorerst nur muss ich noch rausfinden wie ich statt der 2. selection nen strich drawen könnte, der anzeigt wo es eingefügt wird, so is das bissl verwirrend weil man nicht weis ob oberhalb/unterhalb die selection geschoben wird
danke euch!
mfg
m0