I still can't figure out what's wrong with the code, but I found a workaround ... it's kludgy to be sure but it does get the job done. Since drag-and-drop is eminently a manual process, the clearing and resetting of an image list won't break the bank or slow your code, but it's still unsettling.
The solution consists in a few changes:
TPlainDragControlObject = class(TDragControlObject)
private
fDragImageList : TDragImageList;
fImageIndex : Integer ;
protected
function GetDragImages : TDragImageList; override;
public
constructor Create(aControl: TControl); override;
Property DragImageList : TDragImageList read fDragImageList write fDragImageList;
Property ImageIndex : integer read fImageIndex write fImageIndex;
end;
The Drag object is a bit more complex with a constructor and two straightforward properties. Also, it no longer rely on an image list control, instead it manages its own image list, which makes me wonder if in fact I need it to descend from TDragControlObject vesus TDragObject, but I am splitting hair...
The Second change consists in replacing the image list with four images. This is merely for simplicity's sake since I don't remember off-hand how to grab an image out of an image list, so I resorted to the (admittedly) quick and dirty solution of creating four images that I will use to load the image list of the drag object. In a real-life project, that will most likely be suboptimal but since is for demonstration purposes we'll go with it.
The third (and more important change) occurs in the OnStartDrag event handler of the list view:
procedure TForm1.ListBox1StartDrag(Sender: TObject; var DragObject: TDragObject);
var anItemIndex : integer;
anImage : TImage ;
begin
lbl_Result.Caption := 'We Show the result of the drag here';
If Sender is TListBox
then begin
DragObject := TPlainDragControlObject.Create(Sender as TListBox);
anItemIndex := ListBox1.ItemIndex;
case anItemIndex of
Accept_Idx : anImage := img_Accept;
Cog_Idx : anImage := img_Cog ;
X_Idx : anImage := img_X ;
Power_Idx : anImage := img_Power ;
end;
With TPlainDragControlObject(DragObject) do
begin
fDragImageList.Add(anImage.Picture.Bitmap,Nil);
fImageIndex := anItemIndex;
end;
end;
end;
We are creating a new drag object for each drag and drop operation but now, we're populating its drag image list with a lone image selected based on the item index of the list view. That's it.
With these changes in mind, the drag-and-drop operation works as expected but it is still unsettling: why carry an image list if the code is meant to always work with the image at index 0?
Anyway, this solution works for now and I can revert back to figuring out how to change the image mid-flight...