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

时间:2009-11-02 16:01:01

标签: delphi graphics canvas desktop

我正在尝试使用桌面画布绘制整个屏幕并直接绘制到它。问题是我无法清除桌面画布。我已经尝试将canvas.pen.style设置为psNotXOR并绘制旧图像但不幸的是,这不够可靠,并且在某些情况下仍然存在一些遗留问题。

当鼠标悬停在窗口/控件上时,我需要绘制一个选择矩形。

4 个答案:

答案 0 :(得分:5)

清除后,您不会在操作系统上写下有关人工制品问题的操作系统。

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

实现它的一种可能方法是桌面尺寸的透明覆盖窗口,并在其上绘制橡皮筋选择器。如果大小更改应该足够,则无效整个窗口,无需删除旧的选择行。如果覆盖被移除,那么线也将消失。桌面组合将确保不会发生闪烁。但是,在选择区域时切换应用程序会有问题,您需要抓住这个并立即取消选择。

修改

我刚刚使用Delphi 2009测试它,并使用以下测试应用程序:

  • FormStyle设置为fsStayOnTopAlphaBlend设置为True的表单
  • 使用重写的CreateParams()方法添加WS_EX_TRANSPARENT扩展样式标记

我可以将所有鼠标点击传递到底层窗口,同时能够绘制到它们顶部的窗口中。这应该可以帮到你。

答案 1 :(得分:0)

过去我做过这样的事情,我从未想出过可接受的解决方案。

考虑一下,虽然您可以向桌面HWND发送无效命令。

由于桌面是经过修改的列表视图控件,因此您应该能够使用类似

的内容
procedure InvalidateDesktop;
begin
  RedrawWindow(GetDesktopWindow, 0, 0, RDW_INVALIDATE);

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

这可能会做你想要的,我还没有测试过,因为我刚刚把它作为例子。

答案 2 :(得分:0)

  
    

问题是Windows不会返回鼠标后面的控件

  

我认为你需要为此挂钩鼠标事件消息 - 钩子消息然后会给你鼠标结束的窗口句柄。

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

答案 3 :(得分:-2)

我们在应用中采用以下方式:

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