2014-03-06 34 views
1

如何从BrushHPENPen获得HBRUSH
我不知道双方有什么联系吗?在WinApi中使用C#笔和笔刷?

(我想用未在.NET's System.DrawingDrawRoundRect/CreateRoundRectRgn实现WINAPI的功能,我想,而不是用刷子从.NET为我自己创建它们)。

回答

1

我不不再有原始资料来源,甚至可能是SO项目。无论如何,这里有一类人提供了一段时间后,我用:

/// <summary> 
/// Collection of often-used classes and methods for easy access. 
/// </summary> 
public class RoundedDrawing 
{ 
    private static GraphicsPath GetRoundedRectanglePath(Int32 x, Int32 y, Int32 width, Int32 height, Int32 radius) 
    { 
     GraphicsPath path = new GraphicsPath(); 
     path.AddLine(x + radius, y, x + width - radius, y); 
     if (radius > 0) 
      path.AddArc(x + width - 2 * radius, y, 2 * radius, 2 * radius, 270.0f, 90.0f); 
     path.AddLine(x + width, y + radius, x + width, y + height - radius); 
     if (radius > 0) 
      path.AddArc(x + width - 2 * radius, y + height - 2 * radius, 2 * radius, 2 * radius, 0.0f, 90.0f); 
     path.AddLine(x + width - radius, y + height, x + radius, y + height); 
     if (radius > 0) 
      path.AddArc(x, y + height - 2 * radius, 2 * radius, 2 * radius, 90.0f, 90.0f); 
     path.AddLine(x, y + height - radius, x, y + radius); 
     if (radius > 0) 
      path.AddArc(x, y, 2 * radius, 2 * radius, 180.0f, 90.0f); 
     return path; 
    } 

    /// <summary> 
    /// Fills the interior of a rounded rectangle. 
    /// </summary> 
    public static void FillRoundedRectangle(Graphics graphics, Brush brush, float x, float y, float width, float height, float radius) 
    { 
     FillRoundedRectangle(graphics, brush, (Int32)x, (Int32)y, (Int32)width, (Int32)height, (Int32)radius); 
    } 

    /// <summary> 
    /// Fills the interior of a rounded rectangle. 
    /// </summary> 
    public static void FillRoundedRectangle(Graphics graphics, Brush brush, Rectangle rect, Int32 radius) 
    { 
     FillRoundedRectangle(graphics, brush, rect.Left, rect.Top, rect.Width, rect.Height, radius); 
    } 

    /// <summary> 
    /// Fills the interior of a rounded rectangle. 
    /// </summary> 
    public static void FillRoundedRectangle(Graphics graphics, Brush brush, RectangleF rect, float radius) 
    { 
     FillRoundedRectangle(graphics, brush, (Int32)rect.Left, (Int32)rect.Top, (Int32)rect.Width, (Int32)rect.Height, (Int32)radius); 
    } 

    /// <summary> 
    /// Fills the interior of a rounded rectangle. 
    /// </summary> 
    public static void FillRoundedRectangle(Graphics graphics, Brush brush, Int32 x, Int32 y, Int32 width, Int32 height, Int32 radius) 
    { 
     using (GraphicsPath path = GetRoundedRectanglePath(x, y, width, height, radius)) 
      graphics.FillPath(brush, path); 
    } 

    /// <summary> 
    /// Draws the outline of a rounded rectangle. 
    /// </summary> 
    public static void DrawRoundedRectangle(Graphics graphics, Pen pen, float x, float y, float width, float height, float radius) 
    { 
     DrawRoundedRectangle(graphics, pen, (Int32)x, (Int32)y, (Int32)width, (Int32)height, (Int32)radius); 
    } 

    /// <summary> 
    /// Draws the outline of a rounded rectangle. 
    /// </summary> 
    public static void DrawRoundedRectangle(Graphics graphics, Pen pen, Rectangle rect, Int32 radius) 
    { 
     DrawRoundedRectangle(graphics, pen, rect.Left, rect.Top, rect.Width, rect.Height, radius); 
    } 

    /// <summary> 
    /// Draws the outline of a rounded rectangle. 
    /// </summary> 
    public static void DrawRoundedRectangle(Graphics graphics, Pen pen, RectangleF rect, float radius) 
    { 
     DrawRoundedRectangle(graphics, pen, (Int32)rect.Left, (Int32)rect.Top, (Int32)rect.Width, (Int32)rect.Height, (Int32)radius); 
    } 

    /// <summary> 
    /// Draws the outline of a rounded rectangle. 
    /// </summary> 
    public static void DrawRoundedRectangle(Graphics graphics, Pen pen, Int32 x, Int32 y, Int32 width, Int32 height, Int32 radius) 
    { 
     using (GraphicsPath path = GetRoundedRectanglePath(x, y, width, height, radius)) 
      graphics.DrawPath(pen, path); 
    } 
} 

只是做任何PaintPaintBackground事件在那里你递了Graphics对象中调用。将其与其他任何东西一起传递,并绘制圆形的东西。

这是一个选项,保持所有的.NET在没有外部P /调用。

+0

这是一个很好的选择,现在经过我的点。但它不能成为这个问题的答案(关于画笔和手柄)。 Thx分享! – Bitterblue

+0

我想我想说的是,为什么要使用P/invoke路线呢?似乎很多额外的麻烦,没有更好的结果。工作更聪明,不难? – DonBoitnott

+0

现在对我来说“取消”我的项目已经太晚了。我有一个为我导入WinApi的大型图书馆。我通过导入lib来开始一个新项目。但你的回答很好,帮助了我。这不是我要求的。 :) – Bitterblue

2

Brush类确实有一个名为nativeBrush的私有字段,它将HBRUSH句柄作为IntPtr保存。

因为它是一个私人领域,它可以与任何修改的.Net改变,但如果你不介意使用一些狡猾的,脆的反射来获取其价值,你可以做一些讨厌这样的:

Brush brush = ...the brush that you want to get at the handle for 
FieldInfo field = typeof(Brush).GetField("nativeBrush",BindingFlags.NonPublic|BindingFlags.Instance); 
IntPtr hbrush = (IntPtr)field.GetValue(brush); 

Pen还有一个类似的字段叫做nativePen,您可以使用类似的反射代码进行访问。

但是,如果您可以使用GraphicsPath作为上面的Don展示,那么风险就会小得多。

还检查了this article on creating rounded rectangles using GraphicsPath

+0

我认为'hbrush'值,它看起来像一个有效的指针地址,但我不能让WinApi填充任何与我的画笔中的颜色。尽管如此,.NET正确填充它。 – Bitterblue