dotNet 桌面程序改造计划.下拉框篇.类似Word的颜色下拉框

先看图在说.

    

实现功能:

1)下拉出颜色选取对话框.

2)后台窗口不失去焦点.

3)点击更多调用windows标准颜色选取对话框选取颜色.

 

开发背景:

          在网上看到一些文章可以基本实现这些功能、但是大多使用前台窗口获得焦点后在迅速把焦点

转移到后台窗口的方法、或是将前台窗口 Show 出通过使去焦点来关闭前台窗口,或者干脆用个控件(用普通的控件如果如果范围超出后台窗口的范围就会被窗口遮挡)

Windows内置的菜单或下拉框都不会出现使、前台窗口触发失去焦点事件的事件、更不会被遮挡、抱着一个程序员执著的信念、在csdn论坛连发数贴(400 分啊)在加上不断的努力终于有所曾就。

在此感谢 csdn 的各位同僚朋友,没有你们就没有这个世界(哈)。

废话不多说了、进入正题。

 

程序实现代码解析:

    1)文章所用到的基础Windows API 类。

     using System;

using System.Runtime.InteropServices;

     /// <summary>

     /// 系统调用,都是Windows API 相关 注视的地方也许大家有用没有删除,具体说明情察看msdn

     /// </summary>

     public class SystemShell

     {

        

         public const int GWL_STYLE  = -16;

         //public const int GWL_EXSTYLE = -20;

         //public const int WS_VISIBLE =0x10000000;

         public const int WS_CHILDWINDOW = 0x40000000;

         //public const int WS_CLIPSIBLINGS = 0x04000000;

         //public const int  WS_CLIPCHILDREN = 0x02000000;      

         //public const int WS_BORDER = 0x00800000;

         //public const long WS_THICKFRAME = 0x00040000;

         //public const long WS_OVERLAPPED = 0x00000000;

         //public const long WS_DLGFRAME   =      0x00400000;

         //public const long WS_EX_TOOLWINDOW = 0x00000080;

 

         //public const int WM_NCPAINT =  0x0085;

         public const int  WM_ACTIVATEAPP = 0x 001C ;

         //public const int WM_ERASEBKGND = 0x0014;

 

         [DllImport("user32.dll", CharSet=CharSet.Auto)]

         public static extern long SetWindowLong(IntPtr hWnd, int nIndex, long dwNewLong);

 

         [DllImport("user32.dll", CharSet=CharSet.Auto)]

         public static extern long GetWindowLong( IntPtr hWnd,int nIndex);

 

 

         //[DllImport("user32.dll", CharSet=CharSet.Auto)]

         //public static extern int SendMessage(IntPtr hWnd ,  int msg , int wParam  ,int lParam );

 

         //[DllImport("user32.dll", CharSet=CharSet.Auto)]

         //public static extern int GetWindowRect (IntPtr hWnd , ref System.Drawing.Rectangle lpRect);

 

         private SystemShell()

         {

              //

              // TODO: 在此处添加构造函数逻辑

              //

         }

     }

 

 

 

本文章弹出窗口的基类(代码处理流程情根据标号浏览)

 

 

 

/// <summary>

/// NoActForm 实现弹出窗口的基类。

/// </summary>

public class NoActForm : System.Windows.Forms.Form

{

 

     /// <summary>

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

     /// </summary>

    

 

     private System.ComponentModel.Container components = null;

     public NoActForm():base()

     {

         //

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

         //

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

     {

         //

         // NoActForm

         //

         this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);

         this.ClientSize = new System.Drawing.Size(292, 273);

         //(1)不要标题图标 和 Text 属性,

         this.ControlBox = false;

         this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;

         this.Name = "NoActForm";

         this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;

         this.Load += new System.EventHandler(this.NoActForm_Load);

 

     }

     #endregion

 

     private void NoActForm_Load(object sender, System.EventArgs e)

     {

         //如果不是在设计模式

         if (!this.DesignMode)

         {

              //没有 Owner 是不行的

              if (this.Owner == null)

              {

                   throw new ApplicationException("not Owner Form");

              }

 

              this.ShowInTaskbar =false;

              //(2)关键在这里任何窗口子要加上 WS_CHILDWINDOW 样式即可

              long Style =  SystemShell.GetWindowLong(this.Handle,SystemShell.GWL_STYLE);

              Style |= SystemShell.WS_CHILDWINDOW;

              SystemShell.SetWindowLong(this.Handle,SystemShell.GWL_STYLE,Style);

         }

     }

     /// <summary>

     /// 自己定义的show

     /// </summary>

     /// <param name="Ctl">要在那个控件附近show 出本窗口</param>

     public virtual void Show(Control Ctl)

     {

         //取得控件在屏幕的位置

         Rectangle rect = Ctl.RectangleToScreen(new Rectangle(0,0,Ctl.Width,Ctl.Height));

                      

        

         this.Left=rect.Left;

         this.Top=rect.Top+Ctl.Height;

 

         Rectangle ScreenRect =  Screen.PrimaryScreen.WorkingArea;

         if( this.Right > ScreenRect.Width || this.Bottom > ScreenRect.Height)

         {

              this.Left=rect.Left  - this.Width + Ctl.Width;

              this.Top=rect.Top - this.Height;

         }   

         this.Show();

     }

 

     /// <summary>

     /// 重写 WndProc

     /// </summary>

     /// <param name="m"></param>

     protected override void WndProc(ref Message m)

     {

         //(3)如果整个程序失去就隐藏

         if (m.Msg==SystemShell.WM_ACTIVATEAPP && m.WParam==IntPtr.Zero)

         {

              this.Hide();

         }

         base.WndProc (ref m);

     }

}

 

具体实现(代码处理流程情根据标号浏览)

 

 

     /// <summary>

     /// ColorSelectForm 的摘要说明。

     /// (1)继承 NoActForm

     /// </summary>

     public class ColorSelectForm : NoActForm

     {

         /// <summary>

         ///

         /// </summary>

         public delegate void MouseSelectColor(Color SelectColor);

         /// <summary>

         /// 2)颜色选取事件当本窗口 获得颜色时触发

         /// </summary>

         public event MouseSelectColor SelectColor;

         private Control  _ShowCtl;

         private System.Windows.Forms.PictureBox pictureBox1;

         private System.Windows.Forms.Label label1;

         private System.Windows.Forms.ColorDialog colorDialog1;

         /// <summary>

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

         /// </summary>

         private System.ComponentModel.Container components = null;

 

         public ColorSelectForm():base()

         {

              //

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

              //

              InitializeComponent();

              this.MouseDown+=new MouseEventHandler(ColorSelectForm_MouseDown);

              this.MouseMove+=new MouseEventHandler(ColorSelectForm_MouseMove);

              //

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

         {

              System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(ColorSelectForm));

              this.pictureBox1 = new System.Windows.Forms.PictureBox();

              this.label1 = new System.Windows.Forms.Label();

              this.colorDialog1 = new System.Windows.Forms.ColorDialog();

              this.SuspendLayout();

              //

              // pictureBox1

              //

              this.pictureBox1.Cursor = System.Windows.Forms.Cursors.Cross;

              this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Top;

              //(3) pictureBox1.Image 放一个色盘 图

              this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));

              this.pictureBox1.Location = new System.Drawing.Point(0, 0);

              this.pictureBox1.Name = "pictureBox1";

              this.pictureBox1.Size = new System.Drawing.Size(194, 289);

              this.pictureBox1.TabIndex = 0;

              this.pictureBox1.TabStop = false;

              //

              // label1

              //

              this.label1.BackColor = System.Drawing.SystemColors.Control;

              this.label1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;

              this.label1.Dock = System.Windows.Forms.DockStyle.Fill;

              this.label1.Location = new System.Drawing.Point(0, 289);

              this.label1.Name = "label1";

              this.label1.Size = new System.Drawing.Size(194, 25);

              this.label1.TabIndex = 1;

              this.label1.Text = " 更多....";

              this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;

              //

              // ColorSelectForm

              //

              this.AutoScale = false;

              this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);

              this.ClientSize = new System.Drawing.Size(194, 314);

              this.ControlBox = false;

              this.Controls.Add(this.label1);

              this.Controls.Add(this.pictureBox1);

              this.Cursor = System.Windows.Forms.Cursors.Cross;

              this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;

              this.Name = "ColorSelectForm";

              this.Text = "";

              this.ResumeLayout(false);

 

         }

         #endregion

         /// <summary>

         /// (4) 封装 Show

         /// </summary>

         /// <param name="Ctl"></param>

         public override void Show(Control Ctl)

         {

              _ShowCtl =Ctl;

             

              Owner.Cursor = Cursors.Cross;

              base.Show(Ctl);

              //show 后立刻捕捉鼠标

              this.Capture=true;

         }

         /// <summary>

         /// (6)如果鼠标按下进行一系列处理

         /// </summary>

         /// <param name="sender"></param>

         /// <param name="e"></param>

         private void ColorSelectForm_MouseDown(object sender, MouseEventArgs e)

         {

              //释放鼠标

              this.Capture=false;

              Point pt = Control.MousePosition;

              Color cl =Color.Empty;

              while(true)

              {

                   //是否在窗口范围内

                   if(!(pt.X> this.Right || pt.X < this.Left|| pt.Y>this.Bottom || pt.Y< this.Top))

                   {

                       //label1 在屏幕上的位置

                       Rectangle rect =label1.RectangleToScreen(new Rectangle(0,0,label1.Width,label1.Height));

                  

                       //如果鼠标点击在  label1 上弹出 colorDialog1

                       if (!(pt.X> rect.Right || pt.X < rect.X|| pt.Y> rect.Bottom || pt.Y < rect.Y))

                       {

                            if (colorDialog1.ShowDialog() == DialogResult.OK )

                            {

                                 cl = colorDialog1.Color;

                            }

                            break;

                       }

                      

                       //取上方  pictureBox  在屏幕上的位置

                       rect =pictureBox1.RectangleToScreen(new Rectangle(0,0,pictureBox1.Width ,pictureBox1.Height));

                       //判断鼠标是否点击到了 pictureBox1

                       if (!(pt.X> rect.Right || pt.X < rect.X|| pt.Y> rect.Bottom || pt.Y < rect.Y))

                       {

                            //根据鼠标位置得到选择颜色

                            Bitmap bmp = (Bitmap)this.pictureBox1.Image;

                            cl = bmp.GetPixel(e.X,e.Y);

                           

 

                       }

                           

 

                      

                   }

                   break;

              }

              Owner.Cursor = Cursors.Default ;

              //如果 SelectColor 事件被映射,而且颜色已经被选择

              if (SelectColor!=null && cl!= Color.Empty)

              {

                   //触发颜色选取事件

                   SelectColor(cl);

              }

              this.Dispose();

             

         }

         /// <summary>

         /// (5)如果鼠标进入 label1 的范围将 label1  BackColor 属性改变

         /// 类是鼠标悬停的感觉.

         /// </summary>

         /// <param name="sender"></param>

         /// <param name="e"></param>

         private void ColorSelectForm_MouseMove(object sender, MouseEventArgs e)

         {

              Point pt = Control.MousePosition;

              Color cl = SystemColors.Control;

              if(!(pt.X> this.Right || pt.X < this.Left|| pt.Y>this.Bottom || pt.Y< this.Top))

              {

                   Rectangle rect =label1.RectangleToScreen(new Rectangle(0,0,label1.Width,label1.Height));

 

                   if (!(pt.X> rect.Right || pt.X < rect.X|| pt.Y> rect.Bottom || pt.Y < rect.Y))

                   {

                       cl = Color.FromArgb(224, 224, 224);

                   }

                  

              }

                   label1.BackColor=cl;  

             

         }

     }

 

 

 

 

调用颜色选取窗口(很简单不注视了)

 

private void button1_Click(object sender, System.EventArgs e)

         {

              ColorSelectForm ColorForm  = new ColorSelectForm();

              ColorForm.Owner=this;

              ColorForm.SelectColor+=new ColorSelectForm.MouseSelectColor(ColorForm_SelectColor);

              ColorForm.Show(sender as Button);

             

         }

 

         private void ColorForm_SelectColor(Color SelectColor)

         {

              button1.BackColor=SelectColor;

         }

备注:
    组合下拉框
    
    Grid 下拉框


    以上代码均以实现正在整理中,近期发表

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值