【问题标题】:I can't break out of my ClipRectangle and I want to cry我无法摆脱我的 ClipRectangle 我想哭
【发布时间】:2011-08-12 22:04:31
【问题描述】:

当覆盖自定义控件的 OnPaint 方法时,我得到了一个 PaintEventArgs,它包含一个 Graphics 对象和一个 ClipRectangle。 ClipRectangle 对于我的口味来说太小了,所以我想将它扩展 100 像素,或者完全忽略它。

无论我做什么,我似乎都无法摆脱 ClipRectangle。到目前为止,我已经尝试过:

e.ClipRectangle.Inflate(100, 0);
e.Graphics.ResetClip();
e.Graphics.SetClip(new Rectangle(x, y, w, h));

父控件正在调用 Invalidate(true)(强制所有子控件的子控件无效)。

我还进行了一些谷歌搜索并查看了 bob powell 的网站,但找不到 nuffin。

ResetClip 将 Graphics 对象的剪辑区域重置为一个无限大的 Rectangle,但 Graphics 对象仍继续使用提供的 ClipRectangle。

帮助。

【问题讨论】:

  • 调用者必须控制绘制的内容。您应该在拥有控件之一上调用 Invalidate() 以便整个区域无效 -> 计划重绘
  • 我认为调用者有权指定要绘制的区域是正确的。问题是,我是调用者,我正常调用 Invalidate,没有任何限制。
  • 如果重绘发生,Windows API 将一个剪辑区域传递给 WM_PAINT,因为只有部分控件需要重绘,例如如果您最小化了仅部分覆盖控件的窗口。我假设 ClipRectangle 只是给你一个更友好的剪辑区域视图,但如果你调用 Invalidate,我不希望有一个剪辑区域。该控件是否被其他控件部分覆盖?你能显示简单的重现代码吗?
  • 顺便说一下,+1 只是为了标题。

标签: c# winforms custom-controls system.drawing


【解决方案1】:

回顾:听起来您有一个带有自定义绘制方法的子控件。您希望在大于控件边界本身的区域中绘制控件。例如,如果您将控件放置在 (10, 10, 100, 100),您希望在 (0, 10, 110, 100) 处绘制区域。

您不能完全这样做,传递给paint方法的控件HDC是用于该控件的本机窗口句柄。它被操作系统和 AFAIK 剪裁,没有办法在它之外绘制 HDC 给 paint 方法。

你可以做什么:一种选择是覆盖父窗口的create方法并删除窗口样式WS_CLIPCHILDREN (0x02000000),然后在父窗口的paint方法中绘制子窗口。

另一种选择是扩展子窗口的区域,使其包含您要绘制的区域。如果您还覆盖控件的 OnPaintBackground 方法,则可以防止背景绘制清除父级的渲染。这是有问题的,因为父级将剪切子级的区域而不刷新它。因此,您仍然需要删除父级的 WS_CLIPCHILDREN 才能使其工作。

我敢肯定还有其他的可能性,基本上都是一样的结果,你不能那样做。

【讨论】:

  • 我有一个自定义父控件和一个自定义子控件,其中包含标准控件。您的帖子帮助我找到了问题所在。 ClipRectangle 没问题:自定义子控件正在剪切其文本框。突破不是解决方案,首先推理它为什么会被剪裁。感谢您让我走上正轨!
【解决方案2】:

Rectangle 是一个结构,而不是一个类 - 它作为值传递,所以调用 e.ClipRectangle.Inflate(100, 0); 在理论上也无济于事。

接下来你要知道e.Graphics与硬件设备上下文有关,所以Windows不会让你扩展绘画区域。解决方案是获取父窗口的设备上下文,然后在您想要的任何地方进行绘制。这是怎么做的:

[DllImport("User32.dll")]
static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("User32.dll")]
static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);

IntPtr dcPtr = GetDC(this.ParentForm.Handle);
Graphics g = Graphics.FromHdc(dcPtr);

// your code here

// don't forget to release it
g.Dispose();
ReleaseDC(this.ParentForm.Handle, dcPtr);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-05
    • 1970-01-01
    • 1970-01-01
    • 2018-01-14
    • 2011-11-29
    • 1970-01-01
    相关资源
    最近更新 更多