C# WinForm中在窗口标题栏上加按钮

转自http://blog.163.com/da7_1@126/blog/static/104072678201001310219448/

         Windows   API中的HDC可以通过Graphics.FromHdc()转换为(创建出)System.Drawing.Graphics,然后就可以用.NET   Framework  GDI+提供的绘图功能方便地进行画图了。

在窗口标题栏上加按钮本来不是什么新鲜事了,我在VC++下早也实现过了(相信很多人也都实现过了)。今天一个朋友问我C#   WinForm下可否实现,我就顺便拿C#写了一个。

原理是:重写窗口过程(WndProc),处理一些非客户区消息(WM_NCxxxx),可以说本来没有什么新意,可是从写这个程序的过程中,我也学到了两个技巧:
1)、C#中重写窗口过程不用再调用SetWindowLong   API了,直接overide一个WndProc就可以了。
2)、Windows   API中的HDC可以通过Graphics.FromHdc()转换为(创建出)System.Drawing.Graphics,然后就可以用.NET   Framework   (GID+??)提供的绘图功能方便地进行画图了。终于可以抛开讨厌的GDI   API了(说实在话,在C#中调用Windows   API真的太麻烦了:)).


代码如下:
using   System;
using   System.Drawing;
using   System.Drawing.Drawing2D;
using   System.Collections;
using   System.ComponentModel;
using   System.Windows.Forms;
using   System.Data;
using   System.Runtime.InteropServices;
using   System.Diagnostics;
namespace   WindowsApplication2
{

    public   class   Form1   :   System.Windows.Forms.Form
   {


       private   System.ComponentModel.Container   components   =   null; 
       public   Form1()
       {
           InitializeComponent();
       }

       protected   override   void   Dispose(   bool   disposing   )
       {
           if(   disposing   )
           {
                 if   (components   !=   null)
                 {
                     components.Dispose();
                 }
           }
           base.Dispose(   disposing   ); 
       }

       #region   Windows   窗体设计器生成的代码
       private   void   InitializeComponent()
       {
           this.AutoScaleBaseSize   =   new   System.Drawing.Size(6,   14);
           this.ClientSize   =   new   System.Drawing.Size(292,   266);
           this.Name   =   "Form1 ";
           this.Text   =   "Form1 ";
           this.SizeChanged   +=   new   System.EventHandler(this.Form1_SizeChanged);
      }
      #endregion 

      [STAThread]
      static   void   Main()
      {
          Application.Run(new   Form1());
      }

      [DllImport   ( "User32.dll ")]
      private   static   extern   IntPtr   GetWindowDC(IntPtr   hwnd);

      [DllImport   ( "User32.dll ")]
      private   static   extern   int   ReleaseDC(IntPtr   hwnd,   IntPtr   hdc);

      [DllImport   ( "Kernel32.dll ")]
      private   static   extern   int   GetLastError();

      //标题栏按钮的矩形区域。
      Rectangle   m_rect   =   new   Rectangle(205,   6,   20,   20);
      protected   override   void   WndProc(ref   Message   m)
      {
           base.WndProc(ref   m);
           switch(m.Msg)
           {
                   case   0x86://WM_NCACTIVATE
                         goto   case   0x85;
                   case   0x85://WM_NCPAINT 
                   {
                        IntPtr   hDC   =   GetWindowDC(m.HWnd);
                        //把DC转换为.NET的Graphics就可以很方便地使用Framework提供的绘图功能了 
                        Graphics   gs   =   Graphics.FromHdc(hDC);
                        gs.FillRectangle(new   LinearGradientBrush(m_rect,   Color.Pink,   Color.Purple,                                                                                               LinearGradientMode.BackwardDiagonal),   m_rect); 
                        StringFormat   strFmt   =   new   StringFormat(); 
                        strFmt.Alignment   =   StringAlignment.Center;
                        strFmt.LineAlignment   =   StringAlignment.Center; 
                        gs.DrawString( "√ ",   this.Font,   Brushes.BlanchedAlmond,   m_rect,   strFmt); 
                        gs.Dispose(); 
                        //释放GDI资源
                        ReleaseDC(m.HWnd,   hDC); 
                        break; 
                     }
                     case   0xA1://WM_NCLBUTTONDOWN
                     {
                         Point   mousePoint   =   new   Point((int)m.LParam);
                         mousePoint.Offset(-this.Left,   -this.Top); 
                         if(m_rect.Contains(mousePoint))
                         {
                             MessageBox.Show( "hello "); 
                         }
                         break;
                     }
                }
           }

          //在窗口大小改变时及时更新按钮的区域。 
          private   void   Form1_SizeChanged(object   sender,   System.EventArgs   e)
          {
               m_rect.X   =   this.Bounds.Width   -   95;
               m_rect.Y   =   6;
               m_rect.Width   =   m_rect.Height   =   20;
          } 
      } 
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值