Im Codearchive hab ich mir folgenden Code angeschaut:
Drag & Drop example with ListIconGadget
; By Timo 'fr34k' Harter
Tutorial.
Auch einige der anderen Drag'n'Drop Codes.
Ebenso das Datei-Drag'n'Droppen in ein Gadget.
Nun meine Frage:
Was muss ich machen, wenn ich ein ListviewGadget (oder was auch immer) habe, und daraus etwas ziehen möchte, was ich zum Beispiel in einem anderen Programm, meinetwegen wieder ein Programm mit ListviewGadget ... benutzen möchte.
Ich möchte eine Art Dateianzeiger machen.
So wie man es vom Arbeitsplatz her kennt.
Man kann so viele Arbeitsplätze öffnen, wie man möchte, und Dateien unter einander verschieben.
Mir würde es schon reichen, wenn ich eine Datei in mein Gadget ziehe, dass diese als Item angezeigt wird:
Da habe ich diesen Code gefunden und mit dem oben genannten gemischt.
Code: Alles auswählen
; French forum: http://www.serveurperso.com/~cederavic/forum/viewtopic.php?t=239
; Author: Le Soldat Inconnu (updated for PB 4.00 by Andre)
; Date: 29. August 2003
; OS: Windows
; Demo: No
; Drag'n'Drop into a ListIcon
Global IsDraging, DragImageList, SourceGadget, SourceItem, TargetGadget, TargetItem
Declare WindowCallback(Window, message, wParam, lParam)
Procedure.l Triage(Liste.l, Colonne.l, File.s)
File = "#\" + LCase(File)
Path.s = GetPathPart(Left(File, Len(File) - 1))
Debug "Path = " + Path
ExistPath.s = ""
Index = 1
Depart = 0
NbElement = CountGadgetItems(Liste) - 1
Fin = NbElement
Debug Depart
Debug Fin
Repeat
Partie1.s = StringField(Path, Index, "\")
Debug "Partie1 = " + Partie1
If Partie1 <> ""
Test_Ok = 0
For n = Depart To Fin
File2.s = LCase("#\" + GetGadgetItemText(Liste, n, Colonne))
Debug "File2 = " + File2
Partie2.s = StringField(GetPathPart(File2), Index, "\")
Debug "Partie2 = " + Partie2 + " (index="+ Str(Index) + ")"
If Test_Ok = 0 And Partie1 = Partie2
Test_Ok = 1
Depart2 = n
EndIf
If Partie1 = Partie2
Fin2 = n
EndIf
Next
Debug "Depart2 = " + Str(Depart2)
Debug "Fin2 = " + Str(Fin2)
Depart = Depart2
Fin = Fin2
EndIf
ExistPath2.s = ExistPath + Partie1 + "\"
If Partie1 <> "" And FindString(LCase("#\" + GetGadgetItemText(Liste, Depart, Colonne)), ExistPath2, 1) = 1
ExistPath = ExistPath2
Index + 1
EndIf
Until Partie1 = "" Or FindString(LCase("#\" + GetGadgetItemText(Liste, Depart, Colonne)), ExistPath2, 1) = 0
; On affiche ici les résultats de la première partie de l'algo
Debug ">> Depart = " + Str(Depart)
Debug ">> Fin = " + Str(Fin)
Debug ">> ExistPath = " + ExistPath
Partie1.s = StringField(File, Index, "\")
Type1.s = Mid(File, Len(ExistPath + Partie1) + 1, 1)
Debug "Index = " + Str(Index)
Debug "Partie1 = " + Partie1
Debug File
Debug ExistPath + Partie1
Debug "Type1 = '" + Type1 + "'"
Depart = Depart - 1
Repeat
Depart + 1
File2.s = LCase("#\" + GetGadgetItemText(Liste, Depart, Colonne))
Partie2.s = StringField(File2, Index, "\")
Longueur.l = Len(ExistPath + Partie2)
If Longueur < Len(File2)
Type2.s = Mid(File2, Longueur + 1, 1)
Else
Type2.s = Mid(File2, Longueur, 1)
If Type2 <> "\" : Type2 = "" : EndIf
EndIf
Debug "File2 = " + File2
Debug "Partie2 = " + Partie2
Debug "Type2 = '" + Type2 + "'"
Until (Type1 = Type2 And Partie1 <= Partie2) Or (Type1 = "\" And Type2 = "") Or Depart > Fin Or Depart > NbElement
Debug ">> Depart = " + Str(Depart)
Debug "--------------------"
ProcedureReturn Depart
EndProcedure
Procedure ListIconGadgetXP(GadgetID.l, x.l, y.l, tx.l, ty.l, Colonne.s, largeur.l, Options.l)
ListIconGadget(GadgetID, x, y, tx, ty, Colonne, largeur, Options)
#LVM_SETEXTENDEDLISTVIEWSTYLE = 4150 : #LVS_EX_SUBITEMIMAGES = 2
hImageListS.l = SHGetFileInfo_("c:\", 0, @InfosFile.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_SYSICONINDEX | #SHGFI_SMALLICON)
ImageList_SetBkColor_(hImageListS, #CLR_NONE)
SendMessage_(GadgetID(GadgetID), #LVM_SETIMAGELIST, #LVSIL_SMALL, hImageListS)
SendMessage_(GadgetID(GadgetID), #LVM_SETEXTENDEDLISTVIEWSTYLE, #LVS_EX_SUBITEMIMAGES, #LVS_EX_SUBITEMIMAGES)
EndProcedure
Procedure AddGadgetItemXP(GadgetID.l, Pos.l, Texte.s, IconPath.s)
SHGetFileInfo_(IconPath, 0, @InfosFile.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_SYSICONINDEX | #SHGFI_SMALLICON)
If Pos = -1
Pos = CountGadgetItems(GadgetID) + 1
EndIf
; Structure LVITEM
; mask.l
; iItem.l
; iSubitem.l
; state.l
; stateMask.l
; pszText.l
; cchTextMax.l
; iImage.l
; lParam.l
; iIndent.l
; iGroupId.l
; cColumns.l
; puColumns.l
; EndStructure
var.LVITEM
var\mask = #LVIF_IMAGE | #LVIF_TEXT
var\iSubItem = 0
var\iItem = Pos
var\pszText = @Texte
var\iImage = InfosFile\iIcon
SendMessage_(GadgetID(GadgetID), #LVM_INSERTITEM, 0, @var)
EndProcedure
Procedure Open_Window()
If OpenWindow(0, 0, 0, 500, 200, "Ajouter des fichiers par glisser déposer", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
DragAcceptFiles_(WindowID(0), #True) ; activez le glisser déposer
SetWindowPos_(WindowID(0), -1, 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE) ; fenêtre toujours au premier plan
If CreateGadgetList(WindowID(0))
ListIconGadgetXP(1, 0, 0, 500, 200, "Fichiers", 495, 0) ; crée une listicongadget avec icônes systèmes
EndIf
EndIf
EndProcedure
Procedure DragAndDrop()
dropped.l = EventwParam()
num.l = DragQueryFile_(dropped, -1, "", 0)
For Index = 0 To num - 1
Size.l = DragQueryFile_(dropped, Index, 0, 0)
filename.s = Space(Size)
DragQueryFile_(dropped, Index, filename, Size + 1)
If FileSize(filename) = -2
If Right(filename, 1) <> "\" : filename = filename + "\" : EndIf
EndIf
Position = Triage(1, 0, filename)
AddGadgetItemXP(1, Position, filename, filename)
Next
DragFinish_(dropped)
EndProcedure
;- debut du programme
Open_Window()
SetWindowCallback(@WindowCallback())
Repeat
Event = WaitWindowEvent()
If Event = #WM_DROPFILES : DragAndDrop() : EndIf
Until Event = #PB_Event_CloseWindow
End
Procedure WindowCallback(Window, message, wParam, lParam)
result = #PB_ProcessPureBasicEvents
If message = #WM_NOTIFY
*nmhdr.NMHDR = lParam
If *nmhdr\hwndFrom = GadgetID(1) ; ListIconGadget
If *nmhdr\code = #LVN_BEGINDRAG
If *nmhdr\hwndFrom = GadgetID(1)
SourceGadget = 1
Else ; must be #ListIcon2, as we have allready checked, that it is only one of the 2
EndIf
*nmv.NMLISTVIEW = lParam
SourceItem = *nmv\iItem
DragImageList = SendMessage_(GadgetID(SourceGadget), #LVM_CREATEDRAGIMAGE, SourceItem, @UpperLeft.POINT)
If DragImageList
If ImageList_BeginDrag_(DragImageList , 0, 0, 0)
ImageList_DragShowNolock_(#True)
SetCapture_(GetParent_(GadgetID(SourceGadget)))
ShowCursor_(#False)
IsDraging = #True
EndIf ; check for ImageList_BeginDrag_()
EndIf ; check for DragImageList
EndIf ; check for #LVN_BEGINDRAG
EndIf ; check for right gadget
ElseIf message = #WM_MOUSEMOVE And IsDraging
ExamineDesktops()
ImageList_DragMove_(DesktopMouseX(), DesktopMouseY())
ImageList_DragShowNolock_(#False)
MouseX = lParam & $FFFF
MouseY = lParam >> 16
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
TargetGadgetID = ChildWindowFromPoint_(Window, MouseX, MouseY)
If TargetGadgetID = GadgetID(1)
TargetGadget = 1
Else
TargetGadget = -1
EndIf
If TargetGadget <> -1
hittestinfo.LV_HITTESTINFO
hittestinfo\pt\x = MouseX - GadgetX(TargetGadget)
hittestinfo\pt\y = MouseY - GadgetY(TargetGadget)
TargetItem = SendMessage_(GadgetID(TargetGadget), #LVM_HITTEST, 0, @hittestinfo)
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
ImageList_DragShowNolock_(#True)
ElseIf message = #WM_LBUTTONUP And IsDraging
ReleaseCapture_()
ImageList_EndDrag_()
ImageList_Destroy_(DragImageList)
ShowCursor_(#True)
IsDraging = #False
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
If TargetGadget <> -1
ItemText$ = GetGadgetItemText(SourceGadget, SourceItem, 0)
RemoveGadgetItem(SourceGadget, SourceItem)
AddGadgetItem(TargetGadget, TargetItem, ItemText$)
EndIf ; check TargetGadget
EndIf ; check Message
ProcedureReturn result
EndProcedure
Für ein bisschen drag'n'drop ist es aber sehr viel Code.
Gut, ein bisschen Code ist für das Icon-Aussehen verantwortlich, und es muss wohl das Bild beim Verschieben selbst gemalt werden.
Man könnte ja dann auch Bildchen ändern, je nach dem, wo man was hinzieht.
Für Buttons in Menüs hab ich auch mal nach Code gesucht, nix gefunden.
Wenn man zum Beispiel einen Button per Drag'n'Drop verschieben will.
Aber das muss man dann wohl etwas anders lösen.
Aber vielleicht geht es mit der gleichen Prozedur.
Am liebsten wäre mir ja sowas wie die Zwischenablage:
GetDragDropString()
Da sind dann alle markierten Dateien drin.
Und mit SetDragDropString()
kann man die Drag'n'Drop-Schleife initialisieren.
Vielleicht bräuchte man noch ein MouseOverItem(#GadgetID)
Ergebnis ist die Item-Position.
Ach manchmal macht es Spaß zu programmieren und dann gibt es wieder Momente, da sieht man den Wald nicht.

Vielen Dank, wenn ihr mir da mal einen Tipp geben könnt.

