按钮winform C#上的大红十字 [英] Big red cross on buttons winform C#

查看:85
本文介绍了按钮winform C#上的大红十字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

I am working on windows application and in one of my system it shows red big cross on buttons only when I am using application for long time.
I am using paint event of button for giving it 3D effect.
For that I am using following code:

  [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 button1_Paint(object sender, PaintEventArgs e)
        {
          
                var button1 = sender as Button;
                button1.Region = System.Drawing.Region.FromHrgn(CreateRoundRectRgn(2, 2, button1.Width, button1.Height, 2, 2));

                ControlPaint.DrawBorder3D(e.Graphics, ((Control)sender).ClientRectangle, Border3DStyle.Raised);

          
        }

Please provide solution to this porblem. 
Thanks in Advance.





我是什么尝试过:



我试图在paint事件中最后处理图形对象,但它引发了空引用错误。



What I have tried:

I have tried to dispose the graphic object at the end within paint event but it is raising null reference error.

推荐答案

首先,不要尝试在Paint事件中处理图形上下文:它不适合你玩! :笑:只展开你创建的图形对象。



如果你看一下文档: CreateRoundRectRgn函数(Windows) [ ^ ]它清楚地说:

当您不再需要HRGN对象时,请调用DeleteObject函数将其删除。

您没有这样做,因此系统的句柄用完了,你得到问题。

创建你的区域并保存它,然后使用DeleteObject在你完成它时释放句柄:

First off, don't try to Dispose the Graphics context in a Paint event: it isn't yours to play with! :laugh: Only Dispose Graphics objects you create.

Have said that, if you look at the documentation: CreateRoundRectRgn function (Windows)[^] it clearly says:
"When you no longer need the HRGN object call the DeleteObject function to delete it."
You aren't doing that, so the system is running out of handles, and you get problems.
Create your region and save it, then use DeleteObject to release the handle when you are finished with it:
InPtr hRgn = CreateRoundRectRgn(2, 2, button1.Width, button1.Height, 2, 2);
button1.Region = System.Drawing.Region.FromHrgn(hRgn);
ControlPaint.DrawBorder3D(e.Graphics, ((Control)sender).ClientRectangle, Border3DStyle.Raised);
DeleteObject(hRgn);



您还需要添加DllImport:


You'll need to add the DllImport as well:

DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeleteObject([In] IntPtr hObject);



[edit]拼写错误[/ edit]


[edit]typos[/edit]


使用P / Invoke通常是一个坏主意,因为在纯.NET FCL中实现一些你不能做的事情并不重要。这不仅会使代码更容易出错,而且更糟糕的是,您会损害平台兼容性。你已经证明了导致内存泄漏的错误,没有处理区域。



你为什么要这样做呢?如果您需要创建任何 Region 实例,请使用.NET FCL, System.Drawing

地区类(System.Drawing)



您可以创建Windows可以创建的任何类型的区域;您可以创建不同的区域并将它们与 GraphicsPath 的实例组合在一起,等等。



此类仍在内部使用非托管资源,因此您需要对其进行处理。无论如何,您需要处理实现接口 System.IDisposable 的所有对象的所有实例。最可靠的方法是使用语句:

使用声明(C#参考)

另见 IDisposable Interface(System)



-SA
It's generally a bad idea to use P/Invoke when it is not critically important to achieve something which you cannot do in pure .NET FCL. Not only it makes the code more error-prone, but, worse, you compromise your platform compatibility. And you already demonstrated the bug leading to the memory leak, the failure to dispose a region.

Why would you do it in your case? If you need to create any Region instance, do it with .NET FCL, System.Drawing:
Region Class (System.Drawing).

You can create any kind of region Windows can create; you can create different regions and combine them with instanced of GraphicsPath and so on.

This class still uses unmanaged resource internally, so you need to dispose it. Anyway, you need to dispose all instance of all objects implementing the interface System.IDisposable. The most reliable way to do this is using statement:
using Statement (C# Reference),
see also IDisposable Interface (System).

—SA


这篇关于按钮winform C#上的大红十字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆