gpt4 book ai didi

delphi - 在 Delphi 中使自定义拖动图像不透明

转载 作者:行者123 更新时间:2023-12-03 14:43:42 25 4
gpt4 key购买 nike

我已经毫无问题地实现了自定义拖动图像。

我从 TDragControlObject 继承一个类并重写其 GetDragImages 函数,将位图添加到TDragImageList,使白色像素透明。

它有效,白色像素不可见(透明),但其余位图不是不透明的。

有没有办法改变拖动对象的这种行为?

enter image description here

最佳答案

您可以使用ImageList_SetDragCursorImage 。这通常用于提供拖动图像与光标图像的合并图像,然后通常隐藏真实光标以防止混淆(显示两个光标)。

系统不会像拖动图像那样将光标图像与背景混合。因此,如果您以相同的偏移量提供与光标图像相同的拖动图像,并且不隐藏实际光标,则最终会得到带有光标的不透明拖动图像。 (类似地,可以使用空的拖动图像,但我发现前一种设计更容易实现。)

以下示例代码 (XE2) 在 W7x64 和 XP 虚拟机中进行了测试。

unit Unit1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Vcl.StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button2MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Button2StartDrag(Sender: TObject; var DragObject: TDragObject);
procedure Button2EndDrag(Sender, Target: TObject; X, Y: Integer);
private
FDragObject: TDragObject;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses
commctrl;

{$R *.dfm}

type
TMyDragObject = class(TDragObjectEx)
private
FDragImages: TDragImageList;
FImageControl: TWinControl;
protected
function GetDragImages: TDragImageList; override;
public
constructor Create(ImageControl: TWinControl);
destructor Destroy; override;
end;

constructor TMyDragObject.Create(ImageControl: TWinControl);
begin
inherited Create;
FImageControl := ImageControl;
end;

destructor TMyDragObject.Destroy;
begin
FDragImages.Free;
inherited;
end;

function TMyDragObject.GetDragImages: TDragImageList;
var
Bmp: TBitmap;
Pt: TPoint;
begin
if not Assigned(FDragImages) then begin
Bmp := TBitmap.Create;
try
Bmp.PixelFormat := pf32bit;
Bmp.Canvas.Brush.Color := clFuchsia;

// 2px margin at each side just to show image can have transparency.
Bmp.Width := FImageControl.Width + 4;
Bmp.Height := FImageControl.Height + 4;
Bmp.Canvas.Lock;
FImageControl.PaintTo(Bmp.Canvas.Handle, 2, 2);
Bmp.Canvas.Unlock;

FDragImages := TDragImageList.Create(nil);
FDragImages.Width := Bmp.Width;
FDragImages.Height := Bmp.Height;
Pt := Mouse.CursorPos;
MapWindowPoints(HWND_DESKTOP, FImageControl.Handle, Pt, 1);
FDragImages.DragHotspot := Pt;
FDragImages.Masked := True;
FDragImages.AddMasked(Bmp, clFuchsia);
finally
Bmp.Free;
end;
end;
Result := FDragImages;
end;

//--

procedure TForm1.Button2MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
(Sender as TWinControl).BeginDrag(False);

// OnStartDrag is called during the above call so FDragImages is
// assigned now.
// The below is the only difference with a normal drag image implementation.
ImageList_SetDragCursorImage(
(FDragObject as TMyDragObject).GetDragImages.Handle, 0, 0, 0);
end;

procedure TForm1.Button2StartDrag(Sender: TObject; var DragObject: TDragObject);
begin
DragObject := TMyDragObject.Create(Sender as TWinControl);
DragObject.AlwaysShowDragImages := True;
FDragObject := DragObject;
end;

end.


上述代码的屏幕截图:

enter image description here

(注意,实际光标是crNoDrop,但捕获软件使用默认光标。)

如果您想了解系统对图像的实际处理方式,请更改上面的 ImageList_SetDragCursorImage 调用以提供热点,例如

ImageList_SetDragCursorImage(
(FDragObject as TMyDragObject).GetDragImages.Handle, 0, 15, 15);
// ShowCursor(False); // optional

现在您将能够同时看到半透明和不透明图像。

关于delphi - 在 Delphi 中使自定义拖动图像不透明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13890680/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com