欢迎光临
我们一直在努力

dotNet 桌面程序改造计划.下拉框篇.类似Word的颜色下拉框-.NET教程,评论及其它

建站超值云服务器,限时71元/月

实现功能:

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

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

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » dotNet 桌面程序改造计划.下拉框篇.类似Word的颜色下拉框-.NET教程,评论及其它
分享到: 更多 (0)

相关推荐

  • 暂无文章