zoukankan      html  css  js  c++  java
  • C#实现在WinForm窗口标题栏上添加按钮

    转载:http://www.csharpwin.com/csharpspace/10544r8802.shtml

    在窗口标题栏上加按钮本来不是什么新鲜事了,我在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
    {
      
    /// <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窗口标题栏上添加按钮,希望对你有所帮助。
  • 相关阅读:
    计算机网络中的码元的理解
    屏幕扩展,屏幕相对位置的设置
    wireshark使用入门
    Http下载文件的登录验证
    正则-连续相同的单词
    文件系统和数据库索引用B树而不是红黑树的原因
    红黑树的突破点
    Win 10 Revit 2019 安装过程,亲自踩的一遍坑,有你想要的细节
    Java拦截器的实现原理
    根据进程数,资源数判断是否发生死锁
  • 原文地址:https://www.cnblogs.com/lscy/p/2021761.html
Copyright © 2011-2022 走看看