MDI父窗体添加背景、背景上显示自动换行文本并解决闪烁的问题

      
原理:MDI窗口有一个叫MdiClient的窗口对象作为主背景窗口,要修改MDI窗口的背景就是修改该MdiClient对象的背景
          一个MDI应用的主框架窗口包含一个特殊的子窗口称为MDICLIENT窗口。MDICLIENT窗口负责管理主框架窗口的客户区。
          MDICLIENT窗口本身有自己的子窗口即由CMDIChildWnd派生的文档窗口,也就是MDI子窗口。
          MDI主框架窗口负责管理MDICLIENT子窗口。当控制条(菜单条,状态条等)发生变化时,MDI主框架窗口重新配置MDICLIENT窗口。
          MDICLIENT子窗口负责管理全部的MDI子窗口。父窗口负责将某些命令传递到子窗口。
          因此,消息队列发向MDI子窗口的消息由MDICLIENT窗口负责传递,发向MDICLIENT窗口和MDI子窗口的消息由主框架窗口负责传递。
          这样,我们可以在主框架窗口截获关于MDICLIENT窗口的重画消息然后加入自己设计的代码。
          对MDI客户窗口编程有一定的难度。原因是MDIFrameWnd的客户区完全被MDICLIENT窗口覆盖掉了。
          这样,MDI主窗口类MDIFrameWnd的背景色和光标都不起作用。
          同时,微软并不支持将MDICLIENT窗口作为子类,MDICLIENT窗口只能使用标准的背景色和光标。
方法:MdiClient是作为MDI窗口的一个ChildControl的形式存在的,因此我们可以通过遍历MDI窗口的Controls对象集来获得

步骤:
1、在Properties/Resources.resx中添加名称为"bj"的背景图片 

2、在Main方法中添加BackgroundNoSplash();

 

public Main()
        {
		InitializeComponent();
		//给MDI 父窗体添加背景和解决闪烁的问题
            BackgroundNoSplash();
        }

以下代码复制到MDI主窗体代码中
     
  // 主窗体背景设置      
     MdiClient mdiClient = new MdiClient();  //结合上面的说明来看:定义一个MdiClient
        string webMessage="原理:MDI窗口有一个叫MdiClient的窗口对象作为主背景窗口,要修改MDI窗口的背景就是修改该MdiClient对象的背景。一个MDI 应用的主框架窗口包含一个特殊的子窗口称为MDICLIENT窗口。";  
		       //一个在主窗体上显示的通知消息文本
	 private void BackgroundNoSplash()
        {
            foreach (Control var in this.Controls) //遍历控件集合
            {
                if (var is MdiClient) //找到MdiClient控件
                {
                    mdiClient = var as MdiClient;//把Control类型的var转换为MdiClient类型
                    break;//一旦找到MdiClient就跳出循环
                }
            }


            if (mdiClient != null)
            {
                mdiClient.Paint += new PaintEventHandler(OnMdiClientPaint);//调用OnMdiClientPaint事件
                System.Reflection.MethodInfo mi = (mdiClient as Control).GetType().GetMethod("SetStyle", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                mi.Invoke(mdiClient, new object[] { ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer
                 | ControlStyles.ResizeRedraw, true });
                //双缓冲解决闪烁
            }
        }
        
        private void OnMdiClientPaint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.DrawImage(Properties.Resources.bj, new Rectangle(0, 0, mdiClient.Width, mdiClient.Height));//绘制image,图片是资源里的bj,并指定位置和高宽
            
       //绘制右下角的版本号文本,如果你不需要可以删除
        string ver = "版本:1.0.0.2";       
        SizeF sizef = e.Graphics.MeasureString(ver, this.Font);//计算绘制ver文本所需的大小
        g.DrawString(ver, this.Font, new SolidBrush(Color.White), mdiClient.Width - sizef.Width-2, mdiClient.Height - sizef.Height-2);


       //绘制通知信息,如果你不需要可以删除,这里显示的文本,可以自动换行
        SizeF size = e.Graphics.MeasureString(webMessage, this.Font, mdiClient.Width);//计算绘制webMessage文本所需的大小,并定义窗口的宽度为绘制的最大宽度
            RectangleF rf = new RectangleF(10, 10, size.Width, size.Height);//实例化一个矩形框,宽度为窗口宽度稍小点
         //   g.DrawRectangle(Pens.Red, rf.Left, rf.Top, rf.Width, rf.Height);
            g.DrawString(webMessage, this.Font, Brushes.White, rf);//在矩形框里绘制文本
        }


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值