【问题标题】:How can I clear TCanvas? Or any other solution如何清除 TCanvas?或任何其他解决方案
【发布时间】:2011-03-14 16:03:09
【问题描述】:

我正在使用这个 TCanvas 为我的鼠标绘制光标

Canv := TCanvas.Create;
Canv.Handle := GetWindowDC(0);

.... 对于每个老鼠事件,请执行以下操作

Bitmap:=TBitmap.Create;
CursorInfo.cbSize := sizeof(CursorInfo);
GetCursorInfo(CursorInfo);

Bitmap.Width := 32;
Bitmap.Height := 32;
Bitmap.Transparent:=true;

DrawIconEx(Bitmap.Canvas.Handle, 0,0, CursorInfo.hCursor, 32,32, 0,0, DI_NORMAL) ;

Bitmap.Canvas.Brush.Color := RGB(250,250,250);
Bitmap.Canvas.FloodFill(31,0, clWhite, fsSurface);
Bitmap.Canvas.FloodFill(0,0, clWhite, fsSurface);

currentX:=getcurrentxpos;
currentY:=getcurrentypos;

Canv.Draw(currentX,currentY,Bitmap);
Bitmap.Free;

问题不只是显示单个光标,而是生成mouse trails。我可以在鼠标移动时清除整个画布吗? (虽然听起来不是一个好主意)。也许我可以通过执行该代码的反向操作来清除我以前的Canv.Draw(如果可能的话)?关于如何显示光标有什么建议吗?

编辑: 尝试在设置位图宽度和高度后插入另一个Canv.Draw(currentX,currentY,Bitmap);...现在的问题是我有一条白色轨迹(而不是鼠标轨迹),干净得多,但仍然没有好处。

【问题讨论】:

    标签: delphi cursor multiple-mice


    【解决方案1】:

    您在桌面上绘图,这是您不应该做的事情,因为它不可靠。据我了解,您希望找到一种在桌面上绘制鼠标光标的方法,当鼠标再次移动时,“撤消”您的最后一次绘制并在新坐标处重新绘制鼠标。想象一下:您将鼠标移到备忘录框上的某个位置,将手移到键盘上,键入内容,然后再次移动鼠标。老鼠下的形象变了!

    你可以做什么:创建一个鼠标光标形状的表单,有已知的技术可以做到这一点。让你的伪光标保持在顶部(你也会遇到一些问题,因为 Windows 不再喜欢保持在顶部的东西)。这并不容易,但它是易于管理的,而且是按规则进行的。


    对您目前所获得的内容进行一点代码审查,因为我发现了我认为这是一个错误的地方,您应该知道这一点。修复此问题不足以解决您的问题,您需要停止在桌面上绘图:

    不要释放保存透明光标图像的位图,在应用程序的生命周期内保留它:您将节省 RAM 和 CPU。这对于需要对老鼠的运动做出反应的东西至关重要。

    【讨论】:

    • 哦,是的,谢谢,我决定将“光标整形”代码放在 FormCreate 中,并将 Bitmap.Free 放在 FormDestroy 中。如果我使用表单,Canvas 的 X、Y 坐标是否相当于表单的顶部、左侧属性?
    • 我不明白你的问题 :( 我建议为鼠标使用 TForm。从普通的方形 TForm 开始,当它起作用时,将其“塑造”成鼠标光标。简单地缓存 Bitmap 并没有多大帮助,因为您无法控制谁将什么写入桌面。
    • 哦,对不起,如果我不清楚,我指的是表格的定位。我如何定位它?我应该使用 top 和 left 属性吗? (我提到了画布的 x 和 y 坐标,因为我想知道它们是否相似)。还有一件事,如果光标形状的表格在上面,焦点仍然可以放在我的主要表格上吗?谢谢你的帮助。 :D
    • 您使用 Left 和 Top 移动表单。您需要考虑光标的“热点”(对于普通的箭头光标,热点似乎在左上角,箭头的右端;对于用于编辑,我认为热点在“我”的中间;不了解其他人,也不知道如何以编程方式阅读)。对于您将使用的表单类型(无边框),绘图从顶部和左侧开始。最后,光标形状的表单不需要抓住焦点。
    • 我在将它塑造成光标时遇到了一些麻烦……但除此之外它工作得很好。谢谢! :D
    【解决方案2】:

    我将向您展示一种与我之前建议您的方法不同的方法。
    您使用Canvas.CopyRect 将您的画布存储在某个临时画布中。当您的鼠标首次悬停在画布上时。
    然后,当您移动鼠标时,首先将临时画布复制到目标画布,然后绘制光标。

    【讨论】:

    • 我尝试了这个解决方案,但是很难跟踪所有鼠标光标及其之前的位置。不过谢谢你的回答,我很感激。
    【解决方案3】:

    有一个参考图像(这是您的画布在没有绘制鼠标光标的情况下应该看起来的样子),将其复制到一个临时位图,然后在该临时位图上绘制您的光标。最后,在画布上绘制您的图像。

    它还允许您非常轻松地进行更复杂的临时叠加:您只需根据 Z 顺序将它们绘制在参考位图的顶部。由于它们没有接触背景,因此您不必担心清除鬼影。

    【讨论】:

    • 如果背景发生变化(很多),这仍然有效吗?背景是应用程序本身,因此用户会进行一些打字和其他操作……而且它会经常变化,几乎与鼠标移动一样频繁。
    • 这与我给出的解决方案相同。
    猜你喜欢
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-08
    • 2012-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多