分享
 
 
 

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

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

先看图在说.

实现功能:

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 = 0x001C;

//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 下拉框

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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有