VB鼠标绘图基础资料总结

VB鼠标绘图基础资料总结

鉴于上半年编写过鼠标绘图的程序,在此将以前搜集的资料总结一下,给那些以前和我一样到处搜索的VB爱好者们一点方便,同时欢迎交流和指正。
这里我尽量写的罗嗦又罗嗦一些,希望大家不要怪我。因为我们很多的资料都是理论性太强了,实用性或者说教人怎么用,太弱了。我希望能够罗嗦明白一点。
我也是一个VB刚刚入门的人,把有限的经验写出来和大家分享。

前言
鼠标绘图可以说是每一个VB编程者都想必定要尝试和锻炼的一个项目。学会了鼠标绘图,你就学会了Windows的鼠标操作,屏幕模映射模式,绘图模式,Windows的GDI(图形设备接口)。
你会知道,计算机的设备都是有限的,也就是说资源是有限的,这里的资源,就是说的内存,计算机屏幕,鼠标还有键盘,还有一些GDI对象,比如说画笔,画刷,调色板。
有些资源,你用了别人(这里说的是别的应用程序)就不能够用,比如说你的应用程序捕捉了鼠标(至于为什么要捕捉鼠标,后面再说),却不释放鼠标,这样别人的应用程序就得不到鼠标消息(不懂Windows消息机制的人应该稍微学习一下Windows的消息,和消息响应机制。鼠标绘图不就是Windows把消息传给我们的程序,然后有我们的程序处理么。。。)了,别人的应用程序就没有办法用鼠标操作了。所以独占系统资源的应用程序,应该是一个程序员竭力避免的。也是操作系统不允许的。操作系统就是一个调剂应用程序的大程序,也是一个管理硬件,分配资源的底层程序,它的级别比你的程序的级别高,所以它能够管你的应用程序。你要使用系统资源,就必须向操作系统请求,得到分配之后,你才可以使用。
鼠标绘图,就是在一个画布(你的应用程序的客户区),上使用鼠标画画。画出来的是矢量模式的图形,你也可以转换为栅格模式的图像。这里,你要理解的是:什么是客户区,相信很多人编程序很久了,都不知道什么是客户区。什么是矢量模式的图形,什么又是栅格模式的图像,等等相关问题。
VB编程有一个好处,就是起点高,不像VC那样什么都要你自己弄,一点东西不会,你就会卡得死死的。控件拖放是多么的惬意啊,每一个程序员都应该站在别人的肩膀上,写自己的程序。
我在写程序的过程中,就是在别人的程序基础上,通过改进或者修改,运用综合和分析的基本思想,编自己的程序。这就叫做“拿来主义”。当然,同样作为一个程序员,在使用了别人的东西之后,要对别人保有基本的尊重,比如保留别人的版权声明(如果有的话,或者你知道的话);发邮件给他本人,告诉他你用了他的东西,向他请教问题;在程序的关于对话框中,对无偿或者有偿提供了各种帮助的人,表示感谢;同时也声明自己的版权,保留权利,提出警告等等。

下面,我就把自己以前收集的关于鼠标绘图的资料进行一个汇总,并把自己在编程序的过程中得到的经验总结一下。

首先,给大家一个目录索引。
1、界面制作
2、鼠标功能和操作
3、客户区,窗口,屏幕
4、滚动绘图区
5、屏幕映射模式,绘图模式
、橡皮筋框的原理
、GDI和绘图函数
、画笔,画刷,填充模式
、绘图步骤
、绘图结果的保存
、结语

界面制作
界面的制作永远令人心烦,你有可能用一天就写完了你的代码,但是你的界面你可能会消耗你一个星期的时间。所以这里我提了一下界面制作的问题。同样,制作好的界面,可以在别人的基础上做,也可以自己做(如果你有时间和耐性的话)。由于制作界面不是一篇文字能够说明的,所以这里我提供自己的界面给大家。很简单,不要见笑。同时也提供源代码,不要给我发邮件,因为我可能没有时间回复你要源代码的要求。请登陆我的邮箱:@.com,密码是:。登陆之后进入送件箱,在邮件地址中写下你自己的邮箱,转发到你自己的邮箱即可。不过拜托你不要修改密码,毕竟不是你一个人要用的。
我的界面如下图:

鼠标功能和操作
鼠标一般有两个键,中键滚轮可以不考虑,因为在鼠标绘图过程中几乎不用。
正是由于有两个键,所以就要动动脑子,想想怎样把它们全部派上用场。在程序里,我们使用取色工具的时候,就用左键点击取得前景色,右键点击取得背景色,很好的利用了这两个键。
它的功能就是点击,拖拉,移动。
你点击,可能是要画点,点多大,就看你的画笔,画刷的大小了。拖拉,一般用于画直线,矩形,和椭圆之类。你移动它,是要改变你绘图的位置,绘制图形的大小或者使用鼠标随意绘图。
鼠标的的操作当然是看使用者的意图了,点击可能是要选择,要绘图,拖拉可能就是要选择范围,绘制图形;移动就是你要干点别的。所以你在使用的过程中,当然不希望你的鼠标不听你的话,你要点的时候,就是什么也点不出来,你松开了鼠标,但是程序却还在绘图(只要你移动鼠标的话)。所以我们要在应用程序中完全控制自己的鼠标,按自己的意愿工作,就得判断鼠标的状态,是按下了,哪个键按下了,有没有移动,松开了没有,等等,对这些情况,然后正确响应鼠标消息。不过由于绘图有很多工具,所以我们要设置一些变量来标志我们正在使用的工具,从而在响应鼠标的各种消息时,根据工具的不同,绘出不同的效果来。比如画点,喷枪效果,取色工具,填充工具,选择工具等等。

之所以谈谈鼠标操作,是因为每一次绘图都是按照一定的步骤进行的,每个步骤响应的消息也不一样。在我的程序中,我觉得应该是在鼠标按下的状态下进行绘图操作。对于画直线,就有三个步骤。第一步,先单击(响应鼠标按下,松开的消息)确定一个起点,第二步移动到目的位置(响应鼠标移动的消息),第三步单击确定终点(响应鼠标按下,松开的消息)。可见,单单这样一个简单的绘直线操作中,就对鼠标的几种消息都有响应。所以我们在选中了每一个绘图工具之后,都应该详细考虑在每一个步骤中如何响应鼠标的三个基本消息(按下,移动,松开),这可是个比较重要的问题。

鼠标光标的问题:相信有些人还是有疑惑的,所以这里罗嗦一下。如果你想在你的窗口的某个控件上使用不同于Windows的默认光标,请这样做:把这个控件的MousePointer=vbCustom(它的值为99,表示是用户自定义的,所以你也可以在程序中使用MousePointer=99),然后再把MouseIcon的Icon改为你自定义的光标文件(点旁边的"Icon..."按钮,然后选择一个光标文件)。当然你也可以响应此控件的MouseMove消息来改变:
MousePointer=vbCustom
MouseIcon=LoadPicture("cursor.cur")
同时不要忘记在Form的MouseMove消息中改回来,只要这一句就够了:MousePointer=vbDefault,不然的话,你的Form上面就老是只有你自己定义的光标了。

题外话:如果你有四个鼠标的话,你怎么响应你的鼠标消息,Windows需要你自己响应吗?(个人认为不会,不过可能需要互斥的处理每个鼠标的消息)说不定有一天,你可能会和别人(或许是你的Lover)一起画画呢,那样就不用抢鼠标了。。。

客户区,窗口,屏幕
在VB程序中,一般使用PictureBox控件来做绘图区。由于有工具条,状态栏等控件还有绘图工具箱,颜料盒的存在,PictureBox一般不会占满所有的客户区。
就我个人的理解,客户区就是用户可以自由使用的窗口部分。也就是除了标题栏,菜单,滚动条,边框,工具条,状态栏之外的区域。之所以除了这些区域,是因为你在绘图程序中怎么绘图,Windows也不会让你把图形画到这些窗口部分的上面的。文字处理程序也是这样的。因为这些范围不属于用户可以自由操作的区域,所以除了这些区域之外的窗口部分,就叫做客户区。有时候,客户区还可能包括工具条,和状态栏占用的那部分区域,这是因为一般的程序中工具条和状态栏占用的区域,会由于二者的隐藏而重新给用户使用,所以我觉得客户区应该包括工具条和状态栏占用的那部分窗口,因为这些是可以给用户自由使用的,毕竟没有工具条和状态栏,我们也照样使用程序,而且绘图的区域更大一点。
理解了客户区,窗口的理解就很容易了,就是你的应用程序占用屏幕的那一部分,你的窗口中的任何内容都不会绘制到别的应用程序的窗口中去。别人的也不会绘制到你的窗口中去。也就是说你在你的应用程序的窗口中看不到别的应用程序的窗口中的内容。
至于屏幕,这个就不用解释了吧,你只用一个屏幕(显示器的显示部分),你肯定不可能看到屏幕之外的东西吧。不过你要是有两个显示器的话,你把窗口移动到屏幕边缘,你会在另一个屏幕中看到在这一个屏幕中看不到的那部分窗口。你要是有三个屏幕的话,hoho,那就爽死了!!!罗嗦了这么多,宗旨就是,系统资源是有限的,每个窗口会占用一部分屏幕,客户区和每个控件(可见的)也会占用一部分窗口。这些东西都会用光的(算我没说)。

滚动绘图区
我说的绘图区,在VB里面就是那个PictureBox控件,但是PictureBox不支持滚动。图片大了有的部分就不显示出来,所以我们自己要让他能够滚动显示超过PictureBox大小的内容。我不知道什么方法是最好的,但是,经历过一些事情之后,我觉得完成任务的方法是最好的方法。有时候,你可能为了寻找一种高效的,速度快的方法,或者说技术含量更高的方法,浪费了很多时间,还没有达到目的。而在这个时间里,你如果用最笨的方法,也许早就实现了你的功能。
这里,奇技淫巧是我不提倡的。毕竟方法技巧不是目的,只是完成任务的手段。我随便找了一种方法,能够滚就行。

屏幕映射模式,绘图模式
屏幕映射模式说的是这么回事:就是图形显示的度量问题。你的显示器可能是17英寸的纯平彩显(这个17英寸指的是对角线的长度),17英寸是多少厘米?43.18厘米(1英寸等于2.54厘米)。那么又是多少像素呢?如果你的显示器是使用1024*960像素模式的,你自己算算17英寸有多少像素,如果分辨率是800*600像素模式的,再算算。如果说你的直线有3厘米长,但是在屏幕上呢,显示器总是用像素来度量的,所以它要转换为像素的度量,大约。而且,外国佬们最喜欢用的度量单位是英寸,VB里面的控件的宽高总是使用缇(Twips)(缇:计量单位,等于“磅”的 1/20,英寸的 1/1440。一厘米有 567 缇。像素(Pixels):监视器或打印机分辨率的最小单位。如果你右键单击桌面,选择属性,选择“设置”选卡,单击高级按钮。里面就会出现DPI设置。一般为“正常尺寸(96 DPI)”。DPI的意思就是 DPI (Dots per Inch)。因此我们可以得到如下换算公式:1 Twip = 1440 TPI / 96 DPI = 15 Pixels。顺便说点别的计量单位:
磅:指打印的字符的高度的度量单位。1 磅等于 1/72 英寸,或大约等于 1 厘米的 1/28。
英寸:2.54 厘米
屏幕的映射模式就是说像素的长宽比,如果是1:1的话,就是像素就表现为一个正方形,如果不是的话,就是长方形。还有映射模式中提到就是用一厘米代替一米(甚至更多),因为我们的显示器只有那么大,要在这么小的屏幕上显示世界,就只有通过映射的方式把大的长度或者宽度映射到小的。这一点很像地图的比例尺,1比多少万。

绘图模式说的又是另外一回事。在VB中用的是PictureBox的DrawMode属性来设置的。要了解绘图模式,先得说一下前景色和背景色。前景色就是画布上所画图形的颜色,背景色就是画布的颜色,如果前景色和背景色是一样的,你将看不到所绘制的图形。至于怎么选择前景色和背景色,就要看你的美术功底和欣赏力了。这里假设前景色是黑色,背景色是白色,当你用鼠标绘图的时候,对于复制模式(DrawMode=vbCopyPen),你画一条黑线就是一条黑线,前景色改为绿色,画一条绿线就是一条绿线;对于反转绘图模式(DrawMode=vbInvert),你的前景色不论是黑色的还是红色的,你画的线条就永远是背景色的反转色--黑色,也就是说,不管前景色是什么颜色,你画直线,在屏幕上看到的都是黑色(背景色的反转色,背景色为白色的时候)。利用这一个特性,我们就可以基本实现橡皮筋的技术了(见后面叙述)。

橡皮筋框的原理
橡皮筋框的功能就像这样:用鼠标点中起始位置,按住鼠标键,移动鼠标,这时鼠标的当前位置就偏离了起始位置,然后就用PictureBox的Line函数,在鼠标的起始位置和当前位置之间划出一个矩形框。“橡皮筋”这个术语就是因为这个框会随着鼠标的移动增大和减小而得名。当你松开鼠标按键的时候,这个框就会保留在屏幕上。这个提示就告诉了你如何使用Visual Basic创建一个橡皮筋框。

使用Line方法在窗体或者Picture Box控件里画一个框是很容易的,但是橡皮筋这个功能需要你在鼠标移动和画新框的时候让以前画的的框消失。解决这个问题的方法就在DrawMode属性里。DrawMode的缺省设置是vbCopyPen,绘制一根实线,但是这不符合我们的要求。相反,我们会使用vbInvert这个设置,这就意味着像Line方法这样的划线操作会使用与窗体或者Picture Box控件已有颜色相反的色调。因此,如果背景色是白色,那么vbInvert就会画一条黑线,反过来也一样。调色板里的任何颜色都是这样的,这就解决了两个问题:

这个框相对于背景而言总是可见的。
如果我们再次这个框再画一遍,那么颜色就会再次反转,成为与原始颜色相同的值,这样窗口就不见了。

那么,方法就是下面这样的:
当用户按鼠标键的时候,鼠标当前的坐标会被记录下来。这会用于定位框的角。同时,将“Drawing”标记(flag)设置为真(True)。
当鼠标移动的时候,前一个框会被重新画一次从而被删掉。这一步在第一次划框的时候是没有的,但是在后来画框都需要这一步。
当鼠标移动的时候,在鼠标起始坐标和新坐标之间画一个框。
当鼠标键被放开的时候,将“Drawing”标记设置为假(False)。

时间: 2024-10-03 23:39:23

VB鼠标绘图基础资料总结的相关文章

VB实现鼠标绘图实例代码_vb

本文所述为VB实现鼠标绘图的实例,该实例实现线条颜色和线宽可自设,当按下鼠标按键时绘图开始并记录最初的起点,如果不是处在绘图状态则退出该过程,如果处在绘图状态则从起点到目前鼠标所在点绘制直线,然后将当前鼠标所在点作为新的起点,当释放鼠标按键时绘图结束. 具体的功能代码如下: VERSION 5.00 Object = "{F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.2#0"; "comdlg32.ocx" Begin VB.For

《交互式程序设计 第2版》一3.4 Processing绘图基础

3.4 Processing绘图基础 因为Processing是为艺术家提供的工具,所以它简化了很多任务,其中最重要的一个任务是绘图.第8章和第9章会介绍利用矢量和位图绘图.第13章将介绍图形库OpenGL(Open Graphics Library)和一些3D(3 Dimension,三维)基础,以及如何创建复杂的绘图系统.在本节,你将学习如何绘制简单的形状和线条,以及如何创建颜色去填充它们. 3.4.1 rect().ellipse()和line()方法 有3个最简单的绘图方法rect().

Android中Canvas绘图基础详解(附源码下载)

Android中,如果我们想绘制复杂的自定义View或游戏,我们就需要熟悉绘图API.Android通过Canvas类暴露了很多drawXXX方法,我们可以通过这些方法绘制各种各样的图形.Canvas绘图有三个基本要素:Canvas.绘图坐标系以及Paint.Canvas是画布,我们通过Canvas的各种drawXXX方法将图形绘制到Canvas上面,在drawXXX方法中我们需要传入要绘制的图形的坐标形状,还要传入一个画笔Paint.drawXXX方法以及传入其中的坐标决定了要绘制的图形的形状

cvset*d-在实现鼠标绘图时,使用cvSet2D来画轨迹,为什么在边缘处出界。求指点。

问题描述 在实现鼠标绘图时,使用cvSet2D来画轨迹,为什么在边缘处出界.求指点. 下面是代码, /* 创建白色图像,通过鼠标左键绘图,右键实现橡皮擦功能 */ #include <iostream> #include <opencv2/opencv.hpp> #include <opencv2/highgui/highgui.hpp> using namespace std; using namespace cv; bool LFlag = false; bool

vb编程-谁用VB opengl给点资料

问题描述 谁用VB opengl给点资料 众神们好,有用VB OpenGL的么,支援点资料吧!举步维艰啊!大家交流下 解决方案 http://wenku.baidu.com/link?url=wPVvct4JMeRsXuhiv8taARsvNx7W555krBe98vaRu1Aw7bfVgREhSuxB9B0RAiTgqN0XhK8m2vXFksv36Te5-9qnWYhR4cG9PXxVMp8076q 解决方案二: vb中使用openGL-资料收集OpenGL 学习资料opengl 光照资料

C#鼠标绘图程序的问题

问题描述 做了一个绘图程序在鼠标移动时候能画出线来,但是为了使鼠标的移动不会产生很多条线,只有一条线跟着鼠标在画.在MouseMove事件中画线之前加了这个方法graphics.clear()这样解决了留下鼠标轨迹的问题,但是画第2条线的时候第一条线也会被清除掉,请问怎么解决这问题 解决方案 解决方案二:第一种方法:画第二条线之前,使用背景色重画第一条线.(不推荐)第二种方法:在类中定义记录需要画线的数据的成员,在MouseMove消息中,更新数据,执行Invalidate();在Paint事件

在asp.net中使用vb.net绘图

问题描述 在asp.net中使用vb.net绘图 asp.net中编程语言为vb.net,要绘图使用的是Graphics类,那么对于Graphics怎样初始化,定义为 dim gg as Graphics 在使用的时候用的是 gg.DrawBezier(p, wallline(aa).start1, wallline(aa).control11, wallline(aa).control21, wallline(aa).endpoint1) 报错为 :未将对象引用设置到对象的实例. 解决方案 h

使用触发器控制用户删除业务往来中使用的基础资料

本文转载:http://www.csframework.com/archive/1/arc-1-20120526-1945.htm   比如说货品资料,如果这个货品有了业务上的往来,比如采购和销售单使用该货品,在基础资料就不能删除该货品,这样的约束如何实现? 有下面两种常见处理方式: 1. 在DAL层的Delete方法中控制,删除前查询业务往来表,如果有使用该基础资料就抛出异常终止删除. 2. 使用DELETE触发器实现. 3. 使用主外键约束 下面是使用触发器实现的代码: ALTER TRIG

MFC绘图基础 .

from:http://blog.csdn.net/leolee82/article/details/6992590 先认识一下MFC中的一些和绘图有关的结构体和类 1.点 (1)点结构POINT点数据结构POINT用来表示一点的x.y坐标: typedef struct tagPOINT { LONG x; LONG y; } POINT; (2)点类CPoint 点类CPoint为一个没有基类的独立类,封装了POINT结构,有成员变量x和y 其构造函数有5种: CPoint( ); CPoi