我正在尝试使用(这可能是我的问题)e.Graphics.CopyFromScreen()在我的控件的OnPaint()方法中准备一个背景,我可以在其上绘制控件的内容。目标是具有圆角和其他特定功能的工具提示,以替换默认的Windows工具提示。
理想情况下,工具尖端可以被抗锯齿并混合到背景中,但是在紧要关头我可以容忍一个混叠的边界。这可能也是必要的,因为控件通常会覆盖带有OpenGL叠加层的控件,整个混合过程可能会成为一场噩梦。
我创建了一个自定义用户控件,这是一个与我的应用程序主窗体相对应的持久实例,它覆盖了OnPaint和OnPaintBackground方法。然而,透明度的应用具有挑战性。据我所知,传递给paint方法的图形对象以当前VisibleClipBounds的副本开始,通常第一步是用纯色清除控件并开始绘制主要特征。我的第一个想法是绕过填充并开始绘制捕获的背景。对于第一次重绘,这可以正常工作,但后续重绘会保留以前的内容,而不是重新捕获背景。我希望CopyFromScreen会专门从其捕获中消除当前的绘图控件,以便从干净的基础开始,但事实并非如此,它会捕获新位置的矩形,包括前一个位置的图像(如果它在边界内)
其他解决方案及其排列,例如
SetStyle(ControlStyles.SupportsTransparentBackColor, True)
Me.BackColor = Color.Transparent
e.Graphics.Clear(Color.FromArgb(0,0,0,0))
迄今为止没有得到适当的结果。
我使用透明键颜色开始使用透明表单。这适用于别名,但使用表单作为工具提示似乎过多并导致恼人的工件(其中一些可以克服),例如任务栏按钮的临时存在,底层表单的焦点丢失以及主机表单标题中的后续视觉反馈酒吧的颜色。控件的重量要轻得多,但我很努力使它的工作与表格一样好。
此时我只是询问如何实现所需的结果以及CopyFromScreen是否是该解决方案的一部分。
答案 0 :(得分:2)
这是要阅读的大量文本 - 但要解决透明度以实现自定义形状/控件... Control.Region可以做同样的事情:
[DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
private static extern IntPtr CreateRoundRectRgn
(
int nLeftRect, // x-coordinate of upper-left corner
int nTopRect, // y-coordinate of upper-left corner
int nRightRect, // x-coordinate of lower-right corner
int nBottomRect, // y-coordinate of lower-right corner
int nWidthEllipse, // height of ellipse
int nHeightEllipse // width of ellipse
);
private void CreateRegion()
{
this.Region = System.Drawing.Region.FromHrgn(CreateRoundRectRgn(0, 0, Width, Height, 40, 40));
}
答案 1 :(得分:0)
如果您的控件设置为顶级窗口,并且您在Windows 7或8上运行它,请检查DwmEnableBlurBehindWindow。在参数结构中,我将enable设置为true,并为blur创建1x1像素的区域。将BackColor和TransparencyKey设置为Black,这为我提供了一个完全透明的窗口(带有鼠标传递),我可以使用完全alpha透明度(使用Graphics.FromHwnd)绘制32位图像。这种方法的一个好处是,如果窗口移动或背景改变,Windows DWM会完成所有工作 - 我不需要更新任何东西。