仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 785|回复: 7
打印 上一主题 下一主题

[学习教程] NET网页编程之使用C#完成义务栏关照窗口

[复制链接]
谁可相欹 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 14:28:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
有时也搞不懂应该学那种;主要看你以后去的那个公司是使用哪种了。就像王千祥的课上说的:企业应用现在主要就三层(其实也差不多就是MVC):表示层(主要使用html写的,很简单)、业务逻辑层(主要就是应用服务器的)。最后就是数据层(其实就是学习数据库)作为程序员在享用的同时我们也不由要问:这究竟是怎样完成的呢?本文就使用VisualStudio.NetC#2005和.Net框架画图手艺来完成这类义务栏关照窗口。</P>简介
QQ和MSN的义务栏关照窗口很人道化,它能够在不丧失主窗体核心的条件下显现一个具有皮肤Skin的关照窗体,当它显现一段工夫后会主动消散,以是用户基本不必干涉它。
如许的关照窗体和一样平常的具有题目栏、体系图标和按钮的窗体没有太年夜的区分,窗体外表实在就是画上往的一张位图罢了,而窗体的浮动则会庞大一点,我们会用到.Net框架
的两重缓冲区画图手艺(拜见作者编译文章“Windows窗体的.Net框架画图手艺”)来包管挪动窗体时所显现的内容光滑且不闪灼,和利用P/Invoke平台挪用举行对Win32API
函数的挪用来完成不取得核心的窗体显现和非题目栏窗体拖动。两种位图的皮肤运转时的界面以下:
背景常识
关照窗口就是将一样平常的窗体附加上一层皮肤,这里所谓的皮肤就是一张位图图片,该位图图片经由过程窗体的OnPaintbackground事务被绘制到窗体外表,在附加位图之前必要调
整窗体的可视属性,因为绘制操纵是针关于窗体客户地区的,所谓客户地区就是指窗体题目栏下方和窗体边框之内的一切地区,以是必要将窗体的边框和表面属性FormBorderStyle调剂为:None,如许所绘制的图象就会添补全部窗体。
起首,我们会用到Region工具,Region工具能够准确的刻画出恣意外形的表面局限,经由过程一个位图图象创立Region工具后再将其传送给窗体的Region属性就能够使窗体依照Region所界说的表面显现出来。作为皮肤利用的位图文件能够经由过程任何图象编纂软件诸如:Photeshop来创立和编纂,只是注重一点,必要将图片的背景致调成特定色彩以便程序绘制时将其扫除,我们在这里利用的背景致为粉白色。为了可以让Region工具依照图象中感乐趣的内容边框来创立窗体,我们还必要利用GraphicsPath类将图象表面依照必定路径标注上去,稍后便依照该路径创立Region工具。
然后经由过程窗体的画图事务将位图的内容显现在窗体外表,我们没有间接利用OnPaintbackground事务而是重载了该办法,如许做的优点就是一些低层的绘制操纵还持续交由.Net框架运转时来处置,我们只思索实践必要的绘制操纵便可。在OnPaintbackground办法中我们启用了两重缓冲区画图手艺,所谓该手艺就是指先在内存中的一块画布上把将要显现的图象显现出来或举行处置,比及操纵完成再将该画布上所显现的图象安排到窗体外表,如许的机制能够十分无效的下降闪灼的呈现,使图象显现加倍光滑。
关照窗体从屏幕的右下方举行升起停止一段工夫后再渐渐回落,这里必要用到前往屏幕地区的巨细局限的.Net框架办法Screen.GetWorkingArea(WorkAreaRectangle),经由过程必定算法盘算出关照窗体显现前的初始地位。
最初,我们将要显现的文本依照必定格局和Rectangle工具所指定的地区局限绘制到窗体外表。关照窗体的封闭操纵是经由过程设定一个地区,当用户用鼠标单击时检测单击坐标是不是在该地区内,若在地区内就能够实行埋没关照窗体的代码。
我们注重了,当QQ和MSN的关照窗口显现时其主窗体的核心没有丧失,也就是说程序未将本身的核心转移到显现的关照窗体上。经由测试,我们不管怎样挪用.Net框架供应的窗体显现例程比如:Form.Show都没法包管主窗体的核心不丧失,在VC情况下我们可使用Win32API的ShowWindows函数来完成庞大的窗体显现操纵,可是.Net框架基本没有供应相似的办法,那末我们可否经由过程.Net框架挪用该API函数来显现窗体呢?
幸亏.Net框架供应了P/Invoke平台挪用,使用平台挪用这类服务,托管代码就能够挪用在静态链接库中完成的非托管函数,并能够封送其参数,我们能够轻松的显现但不取得核心的窗体。程序顶用到的WindowsAPI和常量的界说都保留在WinUser.h头文件中,其对应的静态链接库文件就是user32.dll,利用.Net框架供应的DllImportAttribute类对导进的函数举行界说,然后就能够十分便利的在程序中挪用该函数了。
因为我们将关照窗体的题目栏埋没了,以是对窗体拖动操纵还必要我们本人下手举行处置。本文先容了怎样加倍高效的举行拖动窗体操纵,有些网友在关于非题目栏拖动窗体编程时倾向组合利用鼠标事务来举行,如许做的实质没有任何不当,可是频仍的事务呼应和处置反而使程序功能有所下降。我们将持续利用Win32API的底层处置办法来办理该成绩,就是向窗体发送题目栏被单击的动静,摹拟实践的拖动操纵。
我们会经由过程2个计时器来完成窗体的显现、停止和埋没,经由过程设置速率变量能够改动窗口显现和埋没的速率。
[DllImportAttribute("user32.dll")]
publicstaticexternintSendMessage(IntPtrhWnd,intMsg,intwParam,intlParam);
//发送动静//winuser.h中有函数原型界说
[DllImportAttribute("user32.dll")]
publicstaticexternboolReleaseCapture();//开释鼠标捕获winuser.h
[DllImportAttribute("user32.dll")]//winuser.h
privatestaticexternBooleanShowWindow(IntPtrhWnd,Int32nCmdShow);
SendMessage向动静轮回发送题目栏被按下的动静来摹拟窗体的拖动,ShowWindow用来将特定句柄的窗体显现出来,注重第二个参数nCmdShow,它暗示窗体应当如何显现出来,而我们必要窗体不取得核心显现出来,SW_SHOWNOACTIVATE能够满意我们请求,持续在WinUser.h文件中搜刮找到该常量对应的值为4,因而我们就能够如许挪用来显现窗体了:
ShowWindow(this.Handle,4);
我们创立了一个自界说函数ShowForm用来封装下面的ShowWindow用来是显现窗体,同时传送了所用到的几个Rectangle矩形地区工具,最初挪用ShowWindows函数将窗体显现出来,代码片断以下:
publicvoidShowForm(stringftitletext,stringfcontenttext,RectanglefRegionofFormTitle,
RectanglefRegionofFormTitlebar,RectanglefRegionofFormContent,RectanglefRegionofCloseBtn)
{
titleText=ftitletext;
contentText=fcontenttext;
WorkAreaRectangle=Screen.GetWorkingArea(WorkAreaRectangle);
this.Top=WorkAreaRectangle.Height+this.Height;
FormBorderStyle.=FormBorderStyle.None;
WindowState=FormWindowState.Normal;
this.SetBounds(WorkAreaRectangle.Width-this.Width,
WorkAreaRectangle.Height-currentTop,this.Width,this.Height);
CurrentState=1;
timer1.Enabled=true;
TitleRectangle=fRegionofFormTitle;
TitlebarRectangle=fRegionofFormTitlebar;
ContentRectangle=fRegionofFormContent;
CloseBtnRectangle=fRegionofCloseBtn;
ShowWindow(this.Handle,4);//#defineSW_SHOWNOACTIVATE
}
CurrentState变量暗示窗体的形态是显现中、停止中仍是埋没中,两个计时器依据窗体分歧形态对窗体的地位举行变动,我们会利用SetBounds来实行该操纵:
this.SetBounds(WorkAreaRectangle.Width-this.Width,WorkAreaRectangle.Height-currentTop,this.Width,this.Height);
当窗体必要升起时将窗体的Top属性值不休削减,而窗体回落时将Top属性值增添并凌驾屏幕的高度窗体就消散了,固然道理很复杂但仍需准确把持。
SetBackgroundBitmap函数起首将窗体背景图象保留到BackgroundBitmap变量中,然后依据该位图图象表面和通明色创立Region,BitmapToRegion就用于完成Bitmap到Region的转换,程序再将这个Region付值给窗体的Region属性以完成不划定规矩窗体的创立。
publicvoidSetBackgroundBitmap(Imageimage,ColortransparencyColor)
{
BackgroundBitmap=newBitmap(image);
Width=BackgroundBitmap.Width;
Height=BackgroundBitmap.Height;
Region=BitmapToRegion(BackgroundBitmap,transparencyColor);
}
publicRegionBitmapToRegion(Bitmapbitmap,ColortransparencyColor)
{
if(bitmap==null)
thrownewArgumentNullException("Bitmap","Bitmapcannotbenull!");
intheight=bitmap.Height;
intwidth=bitmap.Width;
GraphicsPathpath=newGraphicsPath();
for(intj=0;j<height;j++)
for(inti=0;i<width;i++)
{
if(bitmap.GetPixel(i,j)==transparencyColor)
continue;
intx0=i;
while((i<width)&&(bitmap.GetPixel(i,j)!=transparencyColor))
i++;
path.AddRectangle(newRectangle(x0,j,i-x0,1));
}
Regionregion=newRegion(path);
path.Dispose();
returnregion;
}
关照窗体背景和笔墨的绘制在重载的OnPaintBackground办法中完成,并且使用了两重缓冲区手艺来举行绘制操纵,代码以下:
protectedoverridevoidOnPaintBackground(PaintEventArgse)
{
Graphicsgrfx=e.Graphics;
grfx.PageUnit=GraphicsUnit.Pixel;
GraphicsoffScreenGraphics;
BitmapoffscreenBitmap;
ffscreenBitmap=newBitmap(BackgroundBitmap.Width,BackgroundBitmap.Height);
ffScreenGraphics=Graphics.FromImage(offscreenBitmap);
if(BackgroundBitmap!=null)
{
offScreenGraphics.DrawImage(BackgroundBitmap,0,0,
BackgroundBitmap.Width,BackgroundBitmap.Height);
}
DrawText(offScreenGraphics);
grfx.DrawImage(offscreenBitmap,0,0);
}
上述代码起首前往窗体绘制外表的Graphics并保留在变量grfx中,然后创立一个内存Graphics工具offScreenGraphics和内存位图工具offscreenBitmap,将内存位图工具的援用付值给offScreenGraphics,如许一切对offScreenGraphics的绘制操纵也都同时感化于offscreenBitmap,这时候就将必要绘制到关照窗体外表的背景图象BackgroundBitmap绘制到内存的Graphics工具上,DrawText函数依据必要显现笔墨的巨细和局限挪用Graphics.DrawString将笔墨显现在窗体的特定地区。最初,挪用Graphics.DrawImage将内存中已绘制完成的图象显现到关照窗体外表。
我们还必要捕捉窗体的鼠标操纵,有三个操纵在这里举行,1、处置拖动窗体操纵,2、处置关照窗体的封闭操纵,3、内容地区的单击操纵。三个操纵都必要检测鼠标确当前地位与每一个Rectangle地区的包括干系,只需单击落在特定地区我们就举行响应的处置,代码以下:
privatevoidTaskbarForm_MouseDown(objectsender,MouseEventArgse)
{
if(e.Button==MouseButtons.Left)
{
if(TitlebarRectangle.Contains(e.Location))//单击题目栏时拖动
{
ReleaseCapture();//开释鼠标捕获
SendMessage(Handle,WM_NCLBUTTONDOWN,HT_CAPTION,0);//发送左键点击的
//动静至该窗体(题目栏)
}
if(CloseBtnRectangle.Contains(e.Location))//单击Close按钮封闭
{
this.Hide();
currentTop=1;
}
if(ContentRectangle.Contains(e.Location))//单击内容地区
{
System.Diagnostics.Process.Start("http://www.Rithia.com");}
}
}
结论
该程序能够很好的举行关照窗体的显现、停止和埋没操纵,而且具有复杂的换肤机制,在使用了两重缓冲区画图手艺后,能够包管窗体的绘制光滑且没有闪灼。
效率会有不少的变化。而实际上java是基于堆栈机器来设计,这和我们常见的基于寄存器的本地机器是差异比较大的。总体来说,这是一种虚拟机的设计思路。
简单生活 该用户已被删除
沙发
发表于 2015-1-18 14:42:39 | 只看该作者
是目前ASP在UNIX/Linux上的应用可以说几乎为0)。所以平台的局限性和ASP自身的安全性限制了ASP的广泛应用。
第二个灵魂 该用户已被删除
板凳
发表于 2015-1-23 19:27:35 | 只看该作者
市场决定一切,我个人从经历上觉得两者至少在很长时间内还是要共存下去,包括C和C++,至少从找工作就看得出来,总不可能大家都像所谓的时尚一样,追捧一门语言并应用它。
深爱那片海 该用户已被删除
地板
发表于 2015-2-7 00:34:17 | 只看该作者
asp.net空间的支持有:ASP.NET1.1/虚拟目录/MicrosoftFrontPage2000扩展/CDONTS,同时他的网站上也提供了Asp.net的使用详解和程序源代码,相信对使用ASP.NET编程的程序员来说会非常有用哦!
再见西城 该用户已被删除
5#
发表于 2015-2-19 07:27:38 | 只看该作者
可以看作是VC和Java的混合体吧,尽管MS自己讲C#内核中更多的象VC,但实际上我还是认为它和Java更象一些吧。首先它是面向对象的编程语言,而不是一种脚本,所以它具有面向对象编程语言的一切特性。
乐观 该用户已被删除
6#
发表于 2015-3-6 14:15:55 | 只看该作者
我的意思是.net好用,从功能上来说比JAVA强还是很明显的。
只想知道 该用户已被删除
7#
发表于 2015-3-13 03:09:27 | 只看该作者
Servlet的形式和前面讲的CGI差不多,它是HTML代码和后台程序分开的。它们的启动原理也差不多,都是服务器接到客户端的请求后,进行应答。不同的是,CGI对每个客户请求都打开一个进程(Process)。
透明 该用户已被删除
8#
发表于 2015-3-20 11:08:22 | 只看该作者
使用普通的文本编辑器编写,如记事本就可以完成。由脚本在服务器上而不是客户端运行,ASP所使用的脚本语言都在服务端上运行,用户端的浏览器不需要提供任何别的支持,这样大提高了用户与服务器之间的交互的速度。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 13:44

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表