c# paint事件中无法手动释放Graphics资源 希望指点

Y251673671 2010-11-21 02:40:17
网上找了一个桌面飘雪的代码 有个疑惑就是 窗体重新绘制时 Form1_paint事件中如果 手动释放 Graphics资源时 运行到Application.Run(new From1());会提示参数错误 这是为什么 我是新手 希望高手指点
关于c#里面资源释放的问题一直不清楚

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace svchost
{
public partial class MainForm : Form
{
#region SnowFlake类

private class SnowFlake
{
public float Rotation;
public float RotVelocity;
public float Scale;
public float X;
public float XVelocity;
public float Y;
public float YVelocity;
}

#endregion

#region 属性

private Bitmap m_Snow;

/// <summary>
/// The (cached) Image of a 32x32 snowflake
/// </summary>
private Bitmap Snow
{
get
{
if (m_Snow == null)
{
m_Snow = new Bitmap(Image.FromFile(Application.StartupPath + "\\snow.png"));
}

return m_Snow;
}
}

/// <summary>
/// 通过逼近的方式扫描图片的轮廓
/// </summary>
/// <param name="bitmap">要扫描的图片</param>
/// <returns></returns>
private static Bitmap CalculateControlGraphicsPath(Bitmap bitmap)
{
// GraphicsPath graphicsPath = new GraphicsPath();
//将图片的(0,0)处的颜色定义为透明色
Color transparentColor = bitmap.GetPixel(0, 0);
//存储发现的第一个不透明的象素的列值(即x坐标),这个值将定义我们扫描不透明区域的边缘
string str = "";
//从纵向开始
for (int y = 0; y < bitmap.Height; y++)
{
// opaquePixelX = 0;
for (int x = 0; x < bitmap.Width; x++)
{

if (bitmap.GetPixel(x, y) == transparentColor)
{
str+=bitmap.GetPixel(x,y ).ToString();
bitmap.SetPixel(x, y, Color.White);
}
str += "\r\n";
}
}
// MessageBox.Show(str);
return bitmap;
}
#endregion

private static readonly Random Random = new Random();
[DllImport("User32.dll")]
private static extern IntPtr GetForegroundWindow();
/// <summary>
/// 当前活动的雪花对象集合。
/// </summary>
private readonly List<SnowFlake> SnowFlakes = new List<SnowFlake>();
private string Cur = GetForegroundWindow().ToString();
private int Tick = 0;
public MainForm()
{
InitializeComponent();

//开启双缓冲自定义窗体样式。
SetStyle(
ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint |
ControlStyles.DoubleBuffer, true);

Location = new Point(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y);
Width = Screen.PrimaryScreen.Bounds.Width;
Height = Screen.PrimaryScreen.Bounds.Height;
clsMCI mp3 = new clsMCI();
mp3.FileName = Application.StartupPath + "\\1.mp3";
mp3.play();
}

private void MainForm_Load(object sender, EventArgs e)
{
Timer timer = new Timer();
timer.Interval = 40;
timer.Tick += OnTick;
timer.Start();
}

/// <summary>
/// 创建/移动和删除雪花,使得窗体刷新。
/// </summary>
/// <param name="sender">-</param>
/// <param name="args">-</param>
private void OnTick(object sender, EventArgs args)
{
Tick++;

//衍生新的雪花
if (Tick % 3 == 0 && Random.NextDouble() < 0.70)
{
SnowFlake s = new SnowFlake();
s.X = Random.Next(-50, Width + 50);
s.Y = Random.Next(-20, -7);
s.XVelocity = (float)(Random.NextDouble() - 0.5f) * 2f;
s.YVelocity = (float)(Random.NextDouble() * 3) + 1f;
s.Rotation = Random.Next(0, 359);
s.RotVelocity = Random.Next(-3, 3) * 2;

if (s.RotVelocity == 0)
{
s.RotVelocity = 3;
}

// s.Scale = (float)(Random.NextDouble() / 2) + 0.75f;
s.Scale = (float)(Random.NextDouble() / 2) + 0.5f;
SnowFlakes.Add(s);
}

//需要移除的雪花。
List<SnowFlake> del = new List<SnowFlake>();
foreach (SnowFlake s in SnowFlakes)
{
s.X += s.XVelocity;
s.Y += s.YVelocity;
s.Rotation += s.RotVelocity;

s.XVelocity += ((float)Random.NextDouble() - 0.5f) * 0.7f;
s.XVelocity = Math.Max(s.XVelocity, -2f);
s.XVelocity = Math.Min(s.XVelocity, +2f);

if (s.Y > Height - 50)
{
del.Add(s);
// SnowFlakes.Remove(s);
}
}

//删除
foreach (SnowFlake s in del)
{
SnowFlakes.Remove(s);
}

//刷新
Refresh();
}

private void MainForm_Paint(object sender, PaintEventArgs e)
{
// 绘制满天飞舞的雪花。
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias; //高速绘制,可以视硬件情况改为高质量绘图。
// g.SmoothingMode = SmoothingMode.HighQuality;
foreach (SnowFlake s in SnowFlakes)
{
g.ResetTransform();
g.TranslateTransform(-16, -16, MatrixOrder.Append); //平移
g.ScaleTransform(s.Scale, s.Scale, MatrixOrder.Append); //缩放
g.RotateTransform(s.Rotation, MatrixOrder.Append); //旋转
g.TranslateTransform(s.X, s.Y, MatrixOrder.Append); //平移
g.DrawImage(Snow, 0, 0); //绘制
}
// g.Dispose(); //这里释放 会提示错误怎么回事呢?
}

/// <summary>
/// 双击时关闭程序。
/// </summary>
/// <param name="sender">-</param>
/// <param name="e">-</param>
private void notifyIcon1_DoubleClick(object sender, EventArgs e)
{
notifyIcon1.Visible = false; //清除工具栏图标。
Close();
}

/* #region 辅助函数

/// <summary>
/// 绘制一片雪花在指定的Graphics对象上。
/// </summary>
/// <param name="g">Graphics对象</param>
/// <param name="b">中间部分的画刷</param>
/// <param name="p">线条颜色</param>
private static void DrawSnow(Graphics g, Brush b, Pen p)
{
const int a = 6;
const int a2 = a + 2;
const int r = 2;

g.DrawLine(p, -a, -a, +a, +a);
g.DrawLine(p, -a, +a, +a, -a);

g.DrawLine(p, -a2, 0, +a2, 0);
g.DrawLine(p, 0, -a2, 0, +a2);

g.FillEllipse(b, -r, -r, r * 2, r * 2);
}

#endregion
*/


}

}
...全文
420 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
Y251673671 2010-11-22
  • 打赏
  • 举报
回复
哦 有点明白了 所有的控件的paint事件里面都一样的么?
xiehuanxie 2010-11-21
  • 打赏
  • 举报
回复
这是传过来的参数, 并不是你创建的, 为什么要释放?
后面还有方法会用到。
Y251673671 2010-11-21
  • 打赏
  • 举报
回复
楼上的能仔细说明一下么 是系统在绘制结束时 自动释放的?
jshi123 2010-11-21
  • 打赏
  • 举报
回复
Paint事件方法中,不能释放e.Graphics对象

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧