问题描述
自学C#差不多一星期,之前大一学习过C和C++,之后接触过学校组织的一星期java实习培训,想了想选择C#了。这几天宅宿舍天天写,参考各种资料终于写成了这个截图工具。跟QQ截图很像,不过没有自动选框功能和截图后涂鸦编辑功能。新手代码很乱。。附上核心代码。完整工程文件和源代码见这里http://download.csdn.net/detail/justlovediaodaio/4620457环境VS2012ForDesktop,NetFramework4.5.
usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.IO;usingSystem.Linq;usingSystem.Text;usingSystem.Text.RegularExpressions;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;namespaceCatchScreen{//定义委托publicdelegatevoidSetICS(boolisCatchScreen);publicpartialclassCatch:Form{//鼠标位置的枚举privateenumMouseLocation{LeftUpPoint,LeftDownPoint,RightUpPoint,RightDownPoint,LeftLine,RightLine,UpLine,DownLine,InRectangle,OutOfRectangle}privateMouseLocationmouseLocation;//定义该委托的事件publiceventSetICSSetICSEvent;//截屏原始图片privateBitmaporiginBmp;//鼠标左键按下的坐标privatePointmouseDownPoint;//调节截图框时的固定不动点privatePointfixedPoint;//是否允许绘制矩形截图状态privateboolisDraw;//截图完成状态privateboolisCatched;//是否允许调节矩形框privateboolisAdjust;//绘制的截图矩形框privateRectanglerect;publicCatch(){InitializeComponent();}//将当前屏幕截图,显示到全屏无标题栏窗体上privatevoidCatch_Load(objectsender,EventArgse){//设置截图状态为开始SetICSEvent(true);//隐藏窗体,保证截屏图片为当前屏幕而不是被窗体覆盖this.Hide();//以当前窗口大小(窗口默认最大化,即全屏)创建截屏空白图片this.originBmp=newBitmap(this.Width,this.Height);//以截屏图片作为画板using(Graphicsgs=Graphics.FromImage(originBmp)){//复制当前屏幕到画板上,即将截屏图片的内容设置为当前屏幕gs.CopyFromScreen(0,0,0,0,this.Size);}//将截屏图片设为窗体背景this.BackgroundImage=newBitmap(this.originBmp);//添加截屏时的黑色遮罩,即在窗体背景上绘制全屏半透明黑色填充矩形using(Graphicsblackgs=Graphics.FromImage(this.BackgroundImage)){using(SolidBrushbackBrush=newSolidBrush(Color.FromArgb(100,0,0,0))){blackgs.FillRectangle(backBrush,0,0,this.Width,this.Height);}}//显示窗体this.Show();//激活当前窗体,使之具有焦点。主要针对win8Metro界面的截图。this.Activate();}//右键点击动作privatevoidCatch_MouseClick(objectsender,MouseEventArgse){if(e.Button==MouseButtons.Right){//开始绘制矩形框前,即初始状态,直接退出截图if(isCatched==false){this.Close();}//若矩形框已绘制,设定状态为初始状态,设定矩形各参数为0,//刷新窗体重绘,以清除已绘制的矩形,重新开始截图,即撤销功能。else{this.isCatched=false;this.isAdjust=false;this.isDraw=false;this.rect=newRectangle(0,0,0,0);this.Refresh();}}}//鼠标左键按下开始截图privatevoidCatch_MouseDown(objectsender,MouseEventArgse){if(e.Button==MouseButtons.Left){//未捕获时,设定状态为允许绘制矩形if(isCatched==false){this.isDraw=true;}else{//捕获完成后在矩形框内按下左键,设置状态为调节矩形框位置和大小//为方便使用,矩形框内外以及边和顶点的判定都为目标附近if(MousePosition.X>rect.Left-3&&MousePosition.X<rect.Right+3&&MousePosition.Y>rect.Top-3&&MousePosition.Y<rect.Bottom+3){this.isAdjust=true;}}//记下鼠标左键按下的坐标,设置显示光标this.CursorLocation();this.mouseDownPoint=newPoint(e.X,e.Y);}}privatevoidCatch_MouseMove(objectsender,MouseEventArgse){//移动鼠标绘制矩形if(this.isDraw==true){//鼠标按下并移动设定状态为已捕获this.isCatched=true;//记录矩形左上角点的坐标PointleftUpPoint=newPoint(this.mouseDownPoint.X,this.mouseDownPoint.Y);if(e.X<this.mouseDownPoint.X)leftUpPoint.X=e.X;if(e.Y<this.mouseDownPoint.Y)leftUpPoint.Y=e.Y;//获取矩形的长和宽intwideth=Math.Abs(this.mouseDownPoint.X-e.X);intheight=Math.Abs(this.mouseDownPoint.Y-e.Y);//防止分辨率为0的截图区域if(wideth==0)++wideth;if(height==0)++height;//记录绘制的矩形this.rect=newRectangle(leftUpPoint.X,leftUpPoint.Y,wideth,height);//刷新窗体,以触发OnPain事件重绘窗体this.Refresh();}//调节矩形框else{if(isCatched==true){//捕获完成,按下左键前显示当鼠标在矩形框上时的形状if(isAdjust==false){this.CursorLocation();}else{//计算调节矩形框的大小和位置PointleftUpPoint=newPoint(this.fixedPoint.X,this.fixedPoint.Y);if(e.X<this.fixedPoint.X)leftUpPoint.X=e.X;if(e.Y<this.fixedPoint.Y)leftUpPoint.Y=e.Y;intwideth=Math.Abs(this.fixedPoint.X-e.X);intheight=Math.Abs(this.fixedPoint.Y-e.Y);switch(mouseLocation){//校正以上计算的矩形框位置以及大小caseMouseLocation.InRectangle:leftUpPoint.X=this.fixedPoint.X+e.X-this.mouseDownPoint.X;leftUpPoint.Y=this.fixedPoint.Y+e.Y-this.mouseDownPoint.Y;wideth=this.rect.Width;height=this.rect.Height;//防止矩形框移出屏幕外if(leftUpPoint.X<0)leftUpPoint.X=0;if(leftUpPoint.Y<0)leftUpPoint.Y=0;if(leftUpPoint.X+wideth>=this.Width)leftUpPoint.X=this.Width-wideth-1;if(leftUpPoint.Y+height>=this.Height)leftUpPoint.Y=this.Height-height-1;break;caseMouseLocation.LeftLine:caseMouseLocation.RightLine:leftUpPoint.Y=this.rect.Y;height=this.rect.Height;break;caseMouseLocation.UpLine:caseMouseLocation.DownLine:leftUpPoint.X=this.rect.X;wideth=this.rect.Width;break;}//防止分辨率为0的截图区域if(wideth==0)++wideth;if(height==0)++height;//改变矩形框,刷新重绘this.rect=newRectangle(leftUpPoint.X,leftUpPoint.Y,wideth,height);this.Refresh();}}}}
解决方案
解决方案二:
//重载OnPaint事件,窗体每次重绘所调用的函数protectedoverridevoidOnPaint(PaintEventArgse){base.OnPaint(e);//防止窗体第一次显示时绘出分辨率显示if(this.rect.Width!=0){//向窗体添加画板,绘制矩形Graphicsgs=e.Graphics;//绘制截屏图片上的矩形框选中部分到当前画板上的矩形框部分,以覆盖黑色遮罩gs.DrawImage(this.originBmp,this.rect,this.rect,GraphicsUnit.Pixel);//定义画笔using(PenlinePen=newPen(Color.FromArgb(255,0,174,255),1)){//绘制矩形gs.DrawRectangle(linePen,this.rect);//绘出线条上的点using(SolidBrushpointBrush=newSolidBrush(Color.FromArgb(255,0,174,255))){//顶点gs.FillRectangle(pointBrush,this.rect.X-2,this.rect.Y-2,4,4);gs.FillRectangle(pointBrush,this.rect.Right-2,this.rect.Y-2,4,4);gs.FillRectangle(pointBrush,this.rect.X-2,this.rect.Bottom-2,4,4);gs.FillRectangle(pointBrush,this.rect.Right-2,this.rect.Bottom-2,4,4);//中点gs.FillRectangle(pointBrush,this.rect.X-2,(this.rect.Y+this.rect.Bottom)/2-2,4,4);gs.FillRectangle(pointBrush,(this.rect.X+this.rect.Right)/2-2,this.rect.Y-2,4,4);gs.FillRectangle(pointBrush,(this.rect.X+this.rect.Right)/2-2,this.rect.Bottom-2,4,4);gs.FillRectangle(pointBrush,this.rect.Right-2,(this.rect.Y+this.rect.Bottom)/2-2,4,4);}}//定义分辨率文字显示背景画刷,ARGB值。using(SolidBrushbackBrush=newSolidBrush(Color.FromArgb(150,0,0,0))){//绘制分辨率文字背景//靠近屏幕上方和右边缘调整背景绘图位置,避免超出屏幕范围if(this.rect.Y<16){if(this.rect.X+70>this.Width-71)gs.FillRectangle(backBrush,this.rect.X-71,this.rect.Y,70,15);elsegs.FillRectangle(backBrush,this.rect.X,this.rect.Y,70,15);}else{if(this.rect.X>this.Width-71)gs.FillRectangle(backBrush,this.rect.X-71,this.rect.Y-16,70,15);elsegs.FillRectangle(backBrush,this.rect.X,this.rect.Y-16,70,15);}}//定义绘制文字字体using(FontdrawFont=newFont("Arial",9)){//定义分辨率文字画刷using(SolidBrushdrawBrush=newSolidBrush(Color.White)){//获取分辨率文字stringratio=this.rect.Width.ToString()+"x"+rect.Height.ToString();//绘制分辨率文字if(this.rect.Y<16){if(this.rect.X>this.Width-71)gs.DrawString(ratio,drawFont,drawBrush,newPoint(this.rect.X-71,this.rect.Y));elsegs.DrawString(ratio,drawFont,drawBrush,newPoint(this.rect.X,this.rect.Y));}else{if(this.rect.X>this.Width-71)gs.DrawString(ratio,drawFont,drawBrush,newPoint(this.rect.X-71,this.rect.Y-16));elsegs.DrawString(ratio,drawFont,drawBrush,newPoint(this.rect.X,this.rect.Y-16));}}}}}
解决方案三:
//重载OnPaint事件,窗体每次重绘所调用的函数protectedoverridevoidOnPaint(PaintEventArgse){base.OnPaint(e);//防止窗体第一次显示时绘出分辨率显示if(this.rect.Width!=0){//向窗体添加画板,绘制矩形Graphicsgs=e.Graphics;//绘制截屏图片上的矩形框选中部分到当前画板上的矩形框部分,以覆盖黑色遮罩gs.DrawImage(this.originBmp,this.rect,this.rect,GraphicsUnit.Pixel);//定义画笔using(PenlinePen=newPen(Color.FromArgb(255,0,174,255),1)){//绘制矩形gs.DrawRectangle(linePen,this.rect);//绘出线条上的点using(SolidBrushpointBrush=newSolidBrush(Color.FromArgb(255,0,174,255))){//顶点gs.FillRectangle(pointBrush,this.rect.X-2,this.rect.Y-2,4,4);gs.FillRectangle(pointBrush,this.rect.Right-2,this.rect.Y-2,4,4);gs.FillRectangle(pointBrush,this.rect.X-2,this.rect.Bottom-2,4,4);gs.FillRectangle(pointBrush,this.rect.Right-2,this.rect.Bottom-2,4,4);//中点gs.FillRectangle(pointBrush,this.rect.X-2,(this.rect.Y+this.rect.Bottom)/2-2,4,4);gs.FillRectangle(pointBrush,(this.rect.X+this.rect.Right)/2-2,this.rect.Y-2,4,4);gs.FillRectangle(pointBrush,(this.rect.X+this.rect.Right)/2-2,this.rect.Bottom-2,4,4);gs.FillRectangle(pointBrush,this.rect.Right-2,(this.rect.Y+this.rect.Bottom)/2-2,4,4);}}//定义分辨率文字显示背景画刷,ARGB值。using(SolidBrushbackBrush=newSolidBrush(Color.FromArgb(150,0,0,0))){//绘制分辨率文字背景//靠近屏幕上方和右边缘调整背景绘图位置,避免超出屏幕范围if(this.rect.Y<16){if(this.rect.X+70>this.Width-71)gs.FillRectangle(backBrush,this.rect.X-71,this.rect.Y,70,15);elsegs.FillRectangle(backBrush,this.rect.X,this.rect.Y,70,15);}else{if(this.rect.X>this.Width-71)gs.FillRectangle(backBrush,this.rect.X-71,this.rect.Y-16,70,15);elsegs.FillRectangle(backBrush,this.rect.X,this.rect.Y-16,70,15);}}//定义绘制文字字体using(FontdrawFont=newFont("Arial",9)){//定义分辨率文字画刷using(SolidBrushdrawBrush=newSolidBrush(Color.White)){//获取分辨率文字stringratio=this.rect.Width.ToString()+"x"+rect.Height.ToString();//绘制分辨率文字if(this.rect.Y<16){if(this.rect.X>this.Width-71)gs.DrawString(ratio,drawFont,drawBrush,newPoint(this.rect.X-71,this.rect.Y));elsegs.DrawString(ratio,drawFont,drawBrush,newPoint(this.rect.X,this.rect.Y));}else{if(this.rect.X>this.Width-71)gs.DrawString(ratio,drawFont,drawBrush,newPoint(this.rect.X-71,this.rect.Y-16));elsegs.DrawString(ratio,drawFont,drawBrush,newPoint(this.rect.X,this.rect.Y-16));}}}}}
解决方案四:
//放开鼠标左键,设置状态privatevoidCatch_MouseUp(objectsender,MouseEventArgse){if(e.Button==MouseButtons.Left){//不允许绘制和调整this.isDraw=false;this.isAdjust=false;}}//鼠标双击复制截图到剪贴板并存储privatevoidCatch_MouseDoubleClick(objectsender,MouseEventArgse){if(e.Button==MouseButtons.Left&&isCatched==true){//新建矩形大小的图片,并作为画板Bitmapbmp=newBitmap(rect.Width,rect.Height);using(Graphicsgs=Graphics.FromImage(bmp)){//从原始截屏图片originBmp上截取指定的矩形部分rect到图片画板bmp的指定部分,单位为像素。gs.DrawImage(this.originBmp,newRectangle(0,0,this.rect.Width,this.rect.Height),this.rect,GraphicsUnit.Pixel);}//复制到剪贴板Clipboard.SetImage(bmp);SaveFile(bmp);}}//储存图片privatevoidSaveFile(Bitmapbmp){//用当前时间作为文件名stringtime=DateTime.Now.ToString();//去除时间中的非法字符stringfilename=null;foreach(charsymbolintime){if(symbol!='/'&&symbol!=':'&&symbol!='')filename+=symbol;}saveFileDialog1.FileName="截图"+filename;if(saveFileDialog1.ShowDialog()==DialogResult.OK){//存储为jpeg或者png格式switch(saveFileDialog1.FilterIndex){case0:bmp.Save(saveFileDialog1.FileName,System.Drawing.Imaging.ImageFormat.Png);break;case1:bmp.Save(saveFileDialog1.FileName,System.Drawing.Imaging.ImageFormat.Jpeg);break;default:bmp.Save(saveFileDialog1.FileName,System.Drawing.Imaging.ImageFormat.Jpeg);break;}}//退出截图this.Close();}//窗口关闭时设置主窗口的截图状态标记privatevoidCatch_Closing(objectsender,EventArgse){SetICSEvent(false);}//判定并记录鼠标与矩形框的位置关系,改变鼠标形状,并记录下矩形框上的一个标记点,//用作计算调节矩形框时矩形框的位置及大小privatevoidCursorLocation(){intmouseX=Control.MousePosition.X;intmouseY=Control.MousePosition.Y;//鼠标在矩形内if(mouseX>rect.Left+2&&mouseX<rect.Right-2&&mouseY>rect.Top+2&&mouseY<rect.Bottom-2){Cursor.Current=Cursors.SizeAll;if(this.isAdjust==true){this.mouseLocation=MouseLocation.InRectangle;this.fixedPoint=newPoint(this.rect.Left,this.rect.Top);}}//鼠标在矩形外elseif(mouseX<rect.Left-2||mouseX>rect.Right+2||mouseY<rect.Top-2||mouseY>rect.Bottom+2){Cursor.Current=Cursors.Default;this.mouseLocation=MouseLocation.OutOfRectangle;}//鼠标在矩形上else{//鼠标在矩形的左边宽以及顶点上if(mouseX>rect.Left-3&&mouseX<rect.Left+3){if(mouseY>rect.Top-3&&mouseY<rect.Top+3){Cursor.Current=Cursors.SizeNWSE;if(this.isAdjust==true){this.mouseLocation=MouseLocation.LeftUpPoint;this.fixedPoint=newPoint(this.rect.Right,this.rect.Bottom);}}elseif(mouseY>rect.Bottom-3&&mouseY<rect.Bottom+3){Cursor.Current=Cursors.SizeNESW;if(this.isAdjust==true){this.mouseLocation=MouseLocation.LeftDownPoint;this.fixedPoint=newPoint(this.rect.Right,this.rect.Top);}}else{Cursor.Current=Cursors.SizeWE;if(this.isAdjust==true){this.mouseLocation=MouseLocation.LeftLine;this.fixedPoint=newPoint(this.rect.Right,this.rect.Top);}}}//鼠标在矩形的右边宽以及顶点上elseif(mouseX>rect.Right-3&&mouseX<rect.Right+3){if(mouseY==rect.Top){Cursor.Current=Cursors.SizeNESW;if(this.isAdjust==true){this.mouseLocation=MouseLocation.RightUpPoint;this.fixedPoint=newPoint(this.rect.Left,this.rect.Bottom);}}elseif(mouseY>rect.Bottom-3&&mouseY<rect.Bottom+3){Cursor.Current=Cursors.SizeNWSE;if(this.isAdjust==true){this.mouseLocation=MouseLocation.RightDownPoint;this.fixedPoint=newPoint(this.rect.Left,this.rect.Top);}}else{Cursor.Current=Cursors.SizeWE;if(this.isAdjust==true){this.mouseLocation=MouseLocation.RightLine;this.fixedPoint=newPoint(this.rect.Left,this.rect.Top);}}}//鼠标在矩形的长上else{if(mouseY>rect.Top-3&&mouseY<rect.Top+3){Cursor.Current=Cursors.SizeNS;if(this.isAdjust==true){this.mouseLocation=MouseLocation.UpLine;this.fixedPoint=newPoint(this.rect.Left,this.rect.Bottom);}}else{Cursor.Current=Cursors.SizeNS;if(this.isAdjust==true){this.mouseLocation=MouseLocation.DownLine;this.fixedPoint=newPoint(this.rect.Left,this.rect.Top);}}}}}//按下ESC键退出截图privatevoidCatch_KeyDown(objectsender,KeyEventArgse){if(e.KeyValue==27){this.Close();}}}}
解决方案五:
支持一下,不过希望你能突出重点,而不是什么代码都往上贴。整理出核心代码,你的收获以及和大家分享的经验恐怕更好。
解决方案六:
引用4楼的回复:
支持一下,不过希望你能突出重点,而不是什么代码都往上贴。整理出核心代码,你的收获以及和大家分享的经验恐怕更好。
再加一句上代码的时候最好用上这个东西不然代码多了看都懒得看而且缩进也没有
解决方案七:
代码可读性很差,你需要在一个团队里去提高自己
解决方案八:
写的很好,就是代码太长了。代码最好分类、什么是事件、什么是方法。归整一下
解决方案九:
屋顶上的女孩
解决方案十:
引用4楼的回复:
支持一下,不过希望你能突出重点,而不是什么代码都往上贴。整理出核心代码,你的收获以及和大家分享的经验恐怕更好。
楼主插入源代码好了一点
解决方案十一:
整套代码完整贴出来,对于需要的人来说是不错的。很快就运行成功,然后就可以在上面修修改改来测试一些想法。并且楼主程序主要表现的是一些细节,如果只是贴出核心代码就反应不出这些细节了。
解决方案十二:
LZ用了代码工具,但是没有把代码放在里面。
解决方案十三:
建议放到博客里面
解决方案十四:
哈哈哈,头像不错
解决方案十五:
牛逼啊学C#一周就能做出来..我连学习工作玩了5年半也写不出来啊..
解决方案:
引用5楼crystal_lz的回复:
[Quote=引用4楼的回复:]支持一下,不过希望你能突出重点,而不是什么代码都往上贴。整理出核心代码,你的收获以及和大家分享的经验恐怕更好。
再加一句上代码的时候最好用上这个东西不然代码多了看都懒得看而且缩进也没有
其实楼主已经加了
只是不知道代码要放到里面。。。
解决方案:
支持,技巧方面的东西,多多混CSDN就熟悉了