saptechnique

Better late than never. - 郭富

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

WinForm怎么在窗口标题栏上添加按钮?都是重写窗口过程(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

{

  /// <summary>

  /// Form1 的摘要说明。

  /// </summary>

  public class Form1 : System.Windows.Forms.Form

  {

    /// <summary>

    /// 必需的设计器变量。

    /// </summary>

    private System.ComponentModel.Container components = null;

    public Form1()

    {

      //

      // Windows 窗体设计器支持所必需的

      //

      InitializeComponent();

      //

      // TODO: 在 InitializeComponent 调用后添加任何构造函数代码

      //

    }

    /// <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()

    {

      //

      // Form1

      //

      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

    /// <summary>

    /// 应用程序的主入口点。

    /// </summary>

    [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, 4, 16, 16);

    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 = 4;

      m_rect.Width = m_rect.Height = 16;

    }

  }

}

    以上介绍的是C#实现在WinForm窗口标题栏上添加按钮,希望对你有所帮助

本文来自: IT知道网(http://www.itwis.com) 详细出处参考:http://www.itwis.com/html/net/winform/20110420/10216_2.html

posted on 2011-10-20 10:45  guofu  阅读(724)  评论(0编辑  收藏  举报