我想让窗体始终有XP标题栏,在网上找了一些资料,自己也改了一下
程序运行时,XP标题栏已经能够画出来,但时如果改变窗体的大小(最大化,增加宽度)就会出现如下错误,请高手解答
(资源文件这里应该没有问题)
未处理的“System.NullReferenceException”类型的异常出现在 system.windows.forms.dll 中。其他信息: 未将对象引用设置到对象的实例。//--------------------代码如下------------------------------------------------------using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Resources;
using System.Reflection;namespace Cool
{
/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
private int ititleleftWidth;
private int ititleleftHeight;
private int iTop_Right_Width;
private int iTop_Right_Height;
        private ResourceManager rm;
private Bitmap titlemiddle;
private Bitmap titleleft;
private Bitmap bottom;
private Bitmap right;
private Bitmap left;
private Bitmap system3back;
private Bitmap system3max;
private Bitmap systembutton;
private Brush brush;

Graphics g;
private System.Windows.Forms.Label Linfo;
private System.Windows.Forms.Button btnopen2;
private System.Windows.Forms.Label LY;
private System.Windows.Forms.Button btnClose;
public Form1()
{   InitializeComponent(); 

    rm = new ResourceManager("Cool.XPResources", Assembly.GetExecutingAssembly());
titleleft = (Bitmap)rm.GetObject("titleleft.jpg");
titlemiddle = (Bitmap)rm.GetObject("titlemiddle.jpg");
system3back = (Bitmap)rm.GetObject("system3back.jpg");
system3max = (Bitmap)rm.GetObject("system3max.jpg");
bottom = (Bitmap)rm.GetObject("bottom.jpg");
right = (Bitmap)rm.GetObject("right.jpg");
left = (Bitmap)rm.GetObject("left.jpg");

if(this.WindowState == System.Windows.Forms.FormWindowState.Maximized )
systembutton =  system3back;
else
systembutton =  system3max;

} /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null) 
{
components.Dispose();
}
}
base.Dispose( disposing );
} #region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.btnClose = new System.Windows.Forms.Button();
this.Linfo = new System.Windows.Forms.Label();
this.btnopen2 = new System.Windows.Forms.Button();
this.LY = new System.Windows.Forms.Label();
this.SuspendLayout();
// 
// btnClose
// 
this.btnClose.Location = new System.Drawing.Point(96, 104);
this.btnClose.Name = "btnClose";
this.btnClose.Size = new System.Drawing.Size(75, 48);
this.btnClose.TabIndex = 0;
this.btnClose.Text = "关闭";
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
// 
// Linfo
// 
this.Linfo.Location = new System.Drawing.Point(136, 176);
this.Linfo.Name = "Linfo";
this.Linfo.TabIndex = 1;
// 
// btnopen2
// 
this.btnopen2.Location = new System.Drawing.Point(184, 256);
this.btnopen2.Name = "btnopen2";
this.btnopen2.TabIndex = 2;
this.btnopen2.Text = "打开窗体2";
this.btnopen2.Click += new System.EventHandler(this.btnopen2_Click);
// 
// LY
// 
this.LY.Location = new System.Drawing.Point(144, 216);
this.LY.Name = "LY";
this.LY.TabIndex = 3;
// 
// Form1
// 
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(504, 392);
this.Controls.Add(this.LY);
this.Controls.Add(this.btnopen2);
this.Controls.Add(this.Linfo);
this.Controls.Add(this.btnClose);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.DoubleClick += new System.EventHandler(this.Form1_DoubleClick);
this.ResumeLayout(false); }
#endregion /// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main() 
{
Application.Run(new Form1());
}


protected override void OnPaint(PaintEventArgs e)
{   base.OnPaint (e);
g=e.Graphics;
DrawTop_Left(g);//画标题栏左边 
DrawTop_Right(g);//画标题栏右边
DrawTop_Middle(g);//画标题栏中间
g.Dispose();
g = null;
}

private void DrawTop_Left(Graphics g)
{//画标题栏左边(左上角)
brush = new TextureBrush(titleleft, new Rectangle(0, 0, titleleft.Width, titleleft.Height));
g.FillRectangle(brush, 0, 0, titleleft.Width, titleleft.Height);
brush.Dispose();
brush = null;
this.ititleleftWidth = titleleft.Width;
this.ititleleftHeight = titleleft.Height;
titleleft.Dispose();
this.titleleft = null;
GC.Collect();
} private void DrawTop_Right(Graphics g)
{//画标题栏右边(右上角)
iTop_Right_Width = systembutton.Width;
iTop_Right_Height = systembutton.Height;
brush = new TextureBrush(systembutton, new Rectangle(0, 0, systembutton.Width , systembutton.Height));
g.FillRectangle(brush,this.Width - systembutton.Width,0,systembutton.Width,systembutton.Height);
brush.Dispose();
brush = null;
systembutton.Dispose();
this.systembutton = null;
GC.Collect();
} private void DrawTop_Middle(Graphics g)
{//画标题栏中间
brush = new TextureBrush(titlemiddle,new Rectangle(0, 0, titlemiddle.Width  , titlemiddle.Height));
g.FillRectangle(brush,ititleleftWidth ,0, this.Width - ititleleftWidth - iTop_Right_Width , titlemiddle.Height);
brush.Dispose();
brush = null;
titlemiddle.Dispose();
this.titlemiddle = null;
System.GC.Collect();
} private void Form1_DoubleClick(object sender, System.EventArgs e)
{
try
  {
  if(WindowState == FormWindowState.Normal)
  {   
  WindowState = FormWindowState.Maximized;
  systembutton = system3back;
  this.Invalidate();
  }
  else if(WindowState == FormWindowState.Maximized)
  {  
  WindowState = FormWindowState.Normal;
  systembutton = system3max;
  this.Invalidate();
  }
  }
  catch(System.Exception err)
  {
  MessageBox.Show(err.Message);
  }
} private void Form1_Load(object sender, System.EventArgs e)
{
this.MinimumSize = new Size(200,200);//防止窗体被缩小成一个点,最好给窗口的MinimumSize赋上一个适当的值,例如200,200
this.Width = system3max.Width * 10;//为什么要是标题右边图的整数倍呢
} private void btnClose_Click(object sender, System.EventArgs e)
{
Application.Exit();
} private void btnopen2_Click(object sender, System.EventArgs e)
{
this.Width = this.Width + 20;
this.Invalidate();
}
}
}

解决方案 »

  1.   

    g.Dispose();
    g = null;不要。
      

  2.   

    把以下代码去掉就可以了.
    titleleft.Dispose();
    this.titleleft = null;
    systembutton.Dispose();
    this.systembutton = null;
    titlemiddle.Dispose();
    this.titlemiddle = null;因为你把他们都Dispose掉下次再执行OnPain的时候就没图像了.
      

  3.   


    to hyj_828(水梦) lidong6(立冬) ,感谢二位,问题解决了
    不好意思再问个问题,为什么不要下面这句,右上角的三个按钮(是一张图片)是先画右半部再画左半部昵
    等下结贴
    this.Width = system3max.Width * 10;//为什么要是标题右边图的整数倍呢
      

  4.   

    lidong6(立冬)
    我的意思是 如果不要下面这句,右上角的三个按钮(是一张图片)是我如下描述画出来的,是不行的
    正常情况是
     最小化按钮,最大化按钮(或者还原按钮),关闭按钮
    而现在是
     半个最大化按钮(或者还原按钮),关闭按钮,最小化按钮,半个最大化按钮(或者还原按钮)好像你要画的图形是"()",它画出来的是")("  ,当然不行
    不知你明白我的意思么?
    this.Width = system3max.Width * 10;//为什么要是标题右边图的整数倍呢
      

  5.   

    我这里没有图片看不到效果,没法进一步测试.但有一点是肯定的:
    this.Width = system3max.Width * 10这句不是必须的,因为不可能由于重画窗体就要限制窗体的宽度.如果非要这样才能正常的话,就说明前面的代码哪里有问题.就像出现半个最大化按钮这个问题.你再检查一下重画代码.
      

  6.   

    lidong6(立冬)
    图片效果http://img.tianyablog.com/photo/2006/1/13/1215297_5736451.jpg
      

  7.   

    代码也就这几行,实在搞不懂.
    brush = new TextureBrush(systembutton, new Rectangle(0, 0, systembutton.Width , systembutton.Height));
    //上行取图片,从图片的左上角开始.长度和宽度为本身的长度和宽度,全部取出来.
    g.FillRectangle(brush,this.Width - systembutton.Width,0,systembutton.Width,systembutton.Height);
    //画的区域,起始点的X应该是窗体的宽度减去图片的宽度,这样水平方向刚好画图片一次,
    起始点的Y就是图片的高度.按效果来看,难道是取图片时出错?