![]() |
ListView Drag&Drop mit OwnerDraw wird einfach nichts
Liste der Anhänge anzeigen (Anzahl: 1)
hallo,
ich habe 2 listview's wobei ich per Drag&Drop items von dem einen in den anderen ziehen kann. der empfänger der items hat jetzt ownerdraw := true gesetzt, und desweiteren färbe ich in diesem die spalten. das klappt auch alles, allerdings gibt es ein problem, wenn ich langsam aus den spalten "raus-dragge". Mein erklärung dafür ist ungefähr die folgende, allerdings fällt mir keine lösung mehr ein: ich halte mir eine referenz auf das listitem, über das ich gerade dragge (FLastDraggedOver) wenn ich jetzt mit der maus dieses listitem verlasse und in den freien bereich des listview gehe, wird noch einmal das letzte item neu gezeichnet(
Delphi-Quellcode:
). wenn jetzt noch ein teil des "Drag-Bildes" (wie soll ich es nennen, das teil halt das man als symbol für das gezogene item am mauszeiger sieht) über dem letzten item liegt, dann kommt es zu diesen unschönen effekten im bild. vermutlich wird wohl eine region erstellt wenn dort gemalt wird, und die verhindert wohl, dass mein item dahinter ordentlich dargestellt wird. hat jemand eine idee wie ich das verhondern kann? oder evtl das zeichnen des drag-images abfangen und dann noch korrekturen durchführen?
InvalidateRect(.., FLastDraggedOver.DisplayRect, ..)
hier sind noch die dragover und die drawitem des listviews der als empfänger dient:
Delphi-Quellcode:
viele grüße sebastianprocedure TFormConnectionMgr.ListViewSlotsDrawItem(Sender: TCustomListView; Item: TListItem; Rect: TRect; State: TOwnerDrawState); var CItem: TConnectionItem; i : integer; r, g, b: Byte; ValidSlot: boolean; oldcl : TColor; LVItem : TListItem; rc: TRect; p : TPoint; begin ValidSlot := false; ListViewSlots.Canvas.Brush.Color := RGB2TColor(255, 130, 130); CItem := FConnectionMgr.ConnectionItems[TSlotItemData(Item.Data).ItemHandle]; if Assigned(CItem) then begin i := CItem.IndexOfSlot(PChar(Item.Caption)); ValidSlot := (i > -1) and (CItem.Slots[i].Locked); end; if not FDragging then begin if (odSelected in State) or (odGrayed in State){ or (odFocused in State)} then begin with ListViewSlots.Canvas.Brush do if ValidSlot then Color := $00DF00 else Color := clRed; end else if ValidSlot then ListViewSlots.Canvas.Brush.Color := RGB2TColor(75, 255, 73); end else begin GetCursorPos(p); LVItem := ListViewSlots.GetItemAt(2, ListViewSlots.ScreenToClient(p).Y); ValidSlot := SenderAcceptsSourceInterface(LVItem, ListViewPublIntf.Selected); if (LVItem = Item) then // drawed item is below cursor begin with ListViewSlots.Canvas.Brush do if ValidSlot then Color := $00DF00 else Color := clRed end else // if not below cursor do only highlight if is drag selected // and of course if there is an Item under the mouse if Assigned(LVItem) and Assigned(Item.Data) and TSlotItemData(Item.Data).DragSelected then with ListViewSlots.Canvas.Brush do if ValidSlot then Color := $00DF00 else Color := clRed else begin // if not item below cursor and not item is dragged selected // treat it like non-dragging if Assigned(CItem) then begin i := CItem.IndexOfSlot(PChar(Item.Caption)); if (i > -1) and (CItem.Slots[i].Locked) then ListViewSlots.Canvas.Brush.Color := RGB2TColor(75, 255, 73); end; end; end; with ListViewSlots.Canvas do begin { pen.Width := 1; if odFocused in State then begin pen.Color := clBlack; pen.Style := psDot; end else begin Pen.Color := Color; Pen.Style := psSolid; end; } FillRect(Rect); with Item.DisplayRect(drLabel) do begin TextOut(Left + 2, Top + max(0, (Bottom - Top - TextHeight(Item.Caption)) div 2), Item.Caption); for i := 0 to Item.SubItems.Count - 1 do if LongBool(ListView_GetSubItemRect(Item.ListView.Handle, Item.Index, i + 1, LVIR_BOUNDS, @rc)) then with rc do TextOut(Left + 2, Top + max(0, (Bottom - Top - TextHeight(Item.SubItems[i])) div 2), Item.SubItems[i]); end; end; end; procedure TFormConnectionMgr.ListViewSlotsDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); var LVSource, LVSender : TListItem; r : TRect; begin Accept := false; if Assigned(FLastDraggedOver) then r := FLastDraggedOver.DisplayRect(drBounds); if not (Source.InheritsFrom(TListView) or (TListItem(Sender).ListView = ListViewPublIntf)) or not Sender.InheritsFrom(TListView) then begin ListViewPublIntf.DragCursor := crNoDrop; ListViewSlots.Selected := nil; if Assigned(FLastDraggedOver) then InvalidateRect(ListViewSLots.Handle, @r, true); FLastDraggedOver := nil; exit; end; LVSource := TListView(Source).Selected; LVSender := TListView(Sender).GetItemAt(2, Y); if not Assigned(LVSender) {or (((State = dsDragEnter) or (State = dsDragLeave)) and FDragging) } then begin ListViewPublIntf.DragCursor := crNoDrop; ListViewSlots.Selected := nil; if Assigned(FLastDraggedOver) then begin InvalidateRect(ListViewSLots.Handle, @r, true); PostMessage(self.Handle, CM_ERASEGHOST, 0, 0); end; FLastDraggedOver := nil; exit; end; if (FLastDraggedOver <> LVSender) then begin if Assigned(FLastDraggedOver) then begin r := FLastDraggedOver.DisplayRect(drBounds); InvalidateRect(ListViewSlots.Handle, @r, true); end; FLastDraggedOver := LVSender; r := LVSender.DisplayRect(drBounds); InvalidateRect(ListViewSlots.Handle, @r, true); end; Accept := SenderAcceptsSourceInterface(LVSender, LVSource); if Accept then ListViewPublIntf.DragCursor := crDefault else ListViewPublIntf.DragCursor := crNoDrop; Invalidate; end; |
AW: ListView Drag&Drop mit OwnerDraw wird einfach nichts
hallo, kann jemand das thema bitte schließen? es musste heißen ListviewSlots.Invalidate und nicht Invalidate...:evil:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:21 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz