繁体   English   中英

使用Delphi绘制和清除桌面画布

[英]Drawing and clearing the desktop canvas with Delphi

我正在尝试通过使用桌面画布并直接对其进行绘制来绘制整个屏幕。 问题是我无法清除该桌面画布。 我尝试将canvas.pen.style设置为psNotXOR并绘制旧图像,但是不幸的是,这不够可靠,在某些情况下仍存在一些剩余物。

我需要在鼠标悬停在窗口/控件周围时在其周围绘制一个选择矩形。

清除后,您无需再写关于哪个工件存在问题的操作系统。

至少在激活桌面合成的情况下,直接绘制到桌面上并进行XOR绘画是一个非常糟糕的主意(请参阅本博客文章中的 “从屏幕上绘画并阅读-Baaaad!”)。 除了对性能的负面影响外,您无法确定同时会发生其他绘画以及哪些效果和动画会改变显示的内容,因此,简单的XOR可能不足以完全擦除所有内容。

一种可能的实现方式是在桌面上放置一个透明的叠加窗口,并在其上绘制橡皮筋选择器。 如果大小更改应该足够,则使整个窗口无效,无需擦除旧的选择线。 如果移除覆盖层,该线也将消失。 桌面合成将确保不会发生闪烁。 但是,在选择区域时切换应用程序会出现问题,您需要抓住这一点并立即取消选择。

编辑:

我刚刚使用Delphi 2009和以下测试应用程序对其进行了测试:

  • FormStyle设置为fsStayOnTopAlphaBlend设置为True的表单
  • 与重写的CreateParams()方法一起添加WS_EX_TRANSPARENT扩展样式标志

我可以将所有鼠标单击传递到基础窗口,同时能够在它们之上绘制一个窗口。 这应该使您入门。

我过去做过类似的事情,但从来没有想过可以接受的解决方案。

请考虑一下,尽管您可以向桌面HWND发送无效命令。

由于桌面是经过修改的listview控件,因此您应该可以使用类似

procedure InvalidateDesktop;
begin
  RedrawWindow(GetDesktopWindow, 0, 0, RDW_INVALIDATE);

  //if that doesn't work then try this:
  //Sendmessage(GetDesktopWindow, wm_setredraw, 1, 0);
end;

那可能会满足您的要求,我还没有对其进行测试,因为我只是将它作为示例。

问题是Windows不会向我返回鼠标背后的控件

我认为您需要为此挂钩鼠标事件消息-挂钩消息然后为您提供鼠标悬停的窗口句柄。

查找SetWindowsHookEx(WH_MOUSE ,,,)和MOUSEHOOKSTRUCT。

这是我们在应用程序中执行的操作:

    FBitmap.Canvas.Brush.Color := clWhite;
    FBitmap.Canvas.FillRect(FBitmap.Canvas.ClipRect);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM