范文一:Win32汇编基础教程(整理)
1.32位环境简介
在Dos下编汇编程序,我们可以管理系统的所有资源,我们可以改动系统中所有的内存,如自己改动内存控制块来分配内存,自己修改中断向量表来截获中断等,对其他操作也是如此,如我们对键盘端口直接操作就可以把键盘屏蔽掉,可以这样来描述Dos系统:系统只有一个特权级别,在编程上讲,任何程序和操作系统都是同级的,所以在Dos下,一个编得不好的程序会影响其他所有的程序,如一个程序把键盘口中断关掉了,所有程序就都不能从键盘获得键入的数据,直到任何一个程序重新打开键盘为止,一个程序陷入死循环,也没有其他程序可以把它终止掉。Dos下的编程思路是“单任务”的,你只要认为你的程序会按照你的流程一步步的执行下去,不必考虑先后问题(当然程序可能会被中断打断,但你可以认为它们会把环境恢复,如果中断程序没有把环境恢复,那是他们的错)。
在内存管理方式上,Dos汇编和Win32汇编也有很多的不同:Dos工作在实模式下,我们可以寻址1M的内存,寻址时通过段寄存器来制定段的初始地址,每个段的大小为64K,超过1M的部分,就只能把他作为XMS使用,也就是说,只能用作数据存放使用而无法在其中执行程序。
而Windows在保护模式下执行,这里所有的资源对应用程序来说都是被“保护”的:程序在执行中有级别之分,只有操作系统工作在最高级--0级中,所有应用程序都工作在3级中(Ring3), 在Ring3中,你无法直接访问IO端口,无法访问其他程序运行的内存,连向程序自己的代码段写入数据都是非法的,会在Windows的屏幕上冒出一个熟悉的蓝屏幕来。只有对Ring0的程序来说,系统才是全开放的。
在内存方面,Windows使用了处理器的分页机制,使得对应用程序来说,所有的内存都是“平坦”的,你不必用一个段寄存器去指定段的地址,因为在保护模式下,段寄存器的含义是不同的(可以参见80386手册方面的书籍),你可以直接指定一个32位的地址来寻址4GB的内存。
在程序结构方面,Windows程序也有很大的不同,它是“基于消息”的,你可以想象这样一个常见的Windows窗口,上面有几个按钮,如果你用Dos编程的思路去考虑,你会发现实现它很困难:鼠标移动到窗口边缘时拖动会改变窗口大小,鼠标点击按钮时再做要做的事,你会发现,你的程序自开始执行后就在等待,你不知道鼠标先会点什么地方,实际上你是在等待所有可能的事情的发生。而在Dos下,你可以只顾自己先执行,需要用户输入时,再停下来,你不输入我就不再执行,而且,我让你输入数据A你就不能输入数据B。 好了,言归正传,因
2.Win32A***编译器
Win32A***的编译器最常用的有两种:Borland公司的Tasm5.0和Microsoft的Masm6.11以上版本,两种编译器各有自己的优缺点,Tasm带了一个不大不小的Import库,而Masm没有带,但Masm在代码的优化上面好象比Tasm做得好,但它却不带Import库。看来使用哪一种编译器还是比较难选择的,但Steve Hutchesson给了我们一个答案,他为Masm建立了一个很全的Import库,基本上包括了Windows绝大部分的Api函数,这些库、include文件和其他工具还有Masm6.14版本一起做成了一个 Masm32编译器 -- Masm32V5。这样一来,我们用汇编编程就象用C一样方便。
因为有了Masm32V5,所以就我个人而言,我推荐使用Masm作为Win32A***的编译工具,但Masm和Tasm的宏语法有很多的不同,我的这个教程是以Masm格式写的。
3.Masm32的环境设置
在Win32编程中,由于Windows有很多的数据结构和定义,这些都放在include文件中,还有连接时要用到Import库(通俗的讲就是Windows提供的DLL文件中的函数列表,也就是告诉程序到哪里去调用API函数),这些都放在include 和lib目录中。我们在编译时要指定以下的系统环境:
set include=\Masm32v5\Include
set lib=\Masmv5\lib
set path=\Masmv5\Bin
这样编译器就会到正确的路径中去找 include 文件和 lib 文件。你可以自己在 autoexec.bat 文件中加上以上语句,为了产生Windows的PE格式的执行文件,在编译和连接中要指定相应的参数:
编译: Ml /c /coff 文件名.asm
连接: Link /SUBSYSTEM:WINDOWS OBJ文件名.obj 资源文件名.res
为了不在每次编译时都要打这么多的参数,我们可以用 nmake 文件来代为执行,nmake 是代码维护程序,他会检查 .asm .obj .exe .res 等文件的时间,如果你更新了源程序,他会自动执行编译程序或连接程序产生相应的文件。你可以在文件名为 makefile 的文件中指定使用的编译器和连接程序以及相应的参数,下面是一个 makefile 文件的例子:
NAME = Clock
OBJS = $(NAME).obj
RES = $(NAME).res
$(NAME).exe: $(OBJS) $(RES)
Link /DEBUG /SUBSYSTEM:WINDOWS $(OBJS) $(RES) $(RES): $(NAME).rc
Rc $(NAME).rc
.asm.obj:
Ml /c /coff $(NAME).asm
文件告诉 nmake程序,程序名为 clock,产生 clock.exe 文件需要 clock.obj和 clock.res 文件,而产生 clock.res 文件需要 clock.rc 文件,产生 clock.obj 文件要用到 clock.asm 文件,至于是否需要执行 ml, link 和 rc,程序会根据文件的时间自动判断。 Win32汇教程二
Win32汇编程序的结构和语法
Win32A***程序的结构和语法
让我们先来看看一个最简单的Win32汇编程序:
.386
.model flat, stdcall
o
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
szCaption db 'Win32汇编例子',0
szText db 'Win32汇编,Simple and powerful!',0
.code
start:
invoke MessageBox,NULL,addr szText,addr szCaption,MB_OK
invoke ExitProcess,NULL
end start
这就是一个能执行的最简单的Win32汇编程序,下面我简单地介绍一下各部分的作用:
.386
这条语句和Dos下汇编是一样的,是告诉编译器我们要用到80386的指令集,因为32位汇编程序要用到32位的寄存器如eax,ebx等,所以这一句是必须的,当然,你也可以用.486,.586等,当用到特权指令时,还可以用 .386p,.486p等等。
.model flat,stdcall
.model告诉编译器程序的模式,编过Dos汇编的人可能知道在Dos程序的模式有tiny,small,...huge 等,它指定了程序内存寻址模式,在huge等模式下,内存寻址和子程序调用将用Far的格式,但在Win32汇编中,你只能使用一个模式即 flat 模式,因为对Win32程序来说,内存是连续的一个4GB的段,无所谓小或大的模式。而stdcall 告诉编译器参数的传递方式,在调用子程序时,参数是通过堆栈传递的,参数的传递方式有三种,stdcall,c 和 pascal,stdcall 指定了参数是从右到左压入堆栈的,比如说对一个Windows API 如 MessageBox,在手册中是如此定义的:
int MessageBox(
HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType // style of message box );
那么在汇编中我们就可以这样调用它:
push uType
push lpCaption
push lpText
push hWnd
call MessageBox
大家要注意最右面的参数是最后一个进堆栈的,当然,我们不必这样麻烦的调用一个 API,因为Masm中的一个宏语句不但帮助我们完成了所有的压栈操作,还帮我们检查参数的个数是否正确,那就是 invoke 语句,我们可以把上面的语句换成 invoke MessageBox,hWnd,lpText,lpCaption,uType 就行了。如本程序中代入实际参数就成了 invoke MessageBox,NULL,addr szText,addr szCaption,MB_OK。
include 语句
include 语句包含了一些系统的定义和API函说明,其中所有的Windows 数据结构定义和常量定义包含在 windows.inc 中,而其他 API函数的说明包含在 xxx.inc 中, 如查 Microsoft Win32 Programmer's Reference 知道 ExitProcess包含在kernel32.dll 中,那么我们就要在程序中包括 include kernel32.inc 和 includelib kernel32.lib语句,否则在编译时会出现 API 函数未定义的错误。而 MessageBox 在 user32.dll 中,那么我们就要在程序中包括 include user32.inc 和 includelib user32.lib语句
.data 或 .data?
指明了接下来是数据段,.data 定义了预定义的变量,.data?定义了未初始化的变量, .code
指明了接下来是代码段,我们的所有代码都放在这里。最后的一句 start 语句指定了程序开始执行的语句。程序中的 ExitProcess 是一个标准的 Win32 API,对应 Dos汇编中的 int 20h 或 mov ah,4ch/int 21h,也就是程序退出。而 MessageBox 也是一个标准的 API,功能是在屏幕上显示一个消息框,具体的参数上面已经解释过了还有要注意的是 invoke MessageBox,NULL,addr szText,addr szCaption,MB_OK 语句中, MB_OK 和 NULL 已经预定义在 Windows.inc 中。
Win32汇编教程三
一个简单的对话框 --- 兼谈资源文件的使用
Windows 的资源文件
不管在Dos下编程还是在Windows下编程,我们总是要用到除了可执行文件外的很多其他数据,如声音数据,图形数据,文本等等,在Dos下编程,我们可以自己定义这些文件的格式,但这样一来就造成了很多资源共享的问题,大家可能还记的Dos下的很多游戏,它们的图形都是按自己的格式存放的,你无法用标准的看图软件来看。也无法把它另存为其他格式。虽然在Win32编程中,我们仍然可以这样做,但Win32编程给了我们一个方案 ---- 就是格式统一的资源文件,把字符串、图形、对话框包括上面的按钮,文本等定义到一个资源文件中,
就可以方便的在不同的文件中使用它,最重要的是,如果我们用自己的文件格式,使用时就要涉及到这些文件的读写操作,比较复杂,但使用资源文件时,Windows提供了一系列的API来装入资源。非常方便。现在,让我们来看一个很简单的资源文件的源文件,它的扩展名是 .rc,当它用资源编译器编译以后产生 .res 文件就可以在 link的时候连入.exe 文件中:
,i nclude #define DLG_MAIN 1 DLG_MAIN DIALOGEX 0, 0, 236, 185 STYLE DS_MODALFRame | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SY***ENU CAPTION "对话框模板" FONT 9, "宋体" BEGIN DEFPUSHBUTTON "退出",IDOK,177,163,50,14 CONTROL "",-1,"Static",SS_ETCHEDHORZ,7,155,222,1 END 现在我简单解释一下 .rc文件的语法: ,i nclude #define DLG_MAIN 1 -- 类似于 .asm 文件的 equ 语句,和汇编源程序一样,这些定义是为了程序的可读性。 DLG_MAIN DIALOGEX 0,0,236,185 Windows的.rc文件可以定义 BITMAP(位图),CURSOR(光标),ICON(图标),ACCELERATORS(加速键),DIALOG(对话框),MENU(菜单),STRINGTABLE(字符串表),RCDATA(自定义资源)等8种资源, 位图定义: nameID BITMAP [load-mem] filename 光标定义: nameID CURSOR [load-mem] filename 图标定义: nameID ICON [load-mem] filename 加速键定义: acctablename ACCELERATORS [optional-statements] BEGIN event, idvalue, [type] [options] . . . END 等等,具体的定义和参数可以参考 Masm32v5 中的 Rc.hlp 帮助文件。我们可以用资源编辑器来所见即所得地编辑资源,也可以在文本编辑器中用上面这些语句自己定义资源。 在程序中使用资源 在程序中,要使用资源之前必须先装如内存,Windows定义了一系列的API来装入资源,如 LoadMenu,LoadString,LoadBitmap 等等,如 LoadBitmap 的定义: HBITMAP LoadBitmap( HINSTANCE hInstance, // handle of application instance LPCTSTR lpBitmapName // address of bitmap resource name ); 这些Load函数的返回值是一个句柄,调用参数中一般至少为两项: hInstance 和 ResouceName,这个 ResouceName(如BitmapName,MenuName)就是在资源文件中的 #define 指定的值,如果你用 #define MY_ICON 10/ MY_ICON ICON "Main.ico" 定义了一个图标,那么在程序中要使用 Main.ico 图标就可以用 LoadIcon(hInstance,10) 来装入已经定义为10号的图标文件。另一个参数 hInstance 是执行文件的句柄,它对应资源所在的文件名,你可以在程序开始执行时用 invoke GetModuleHandle,NULL 获得 hInstance。另外一些资源并不是显式地装入的,如对话框资源,它是在建立对话框的函数中由Windows自己装入的,如下面例子中的 invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,0 ,是在屏幕上显示一个资源文件中已经定义好了的对话框,就并不存在 LoadDialogBox 之类的API来先装入对话框。 Win32A*** - 显示一个对话框 介绍了这么多相关的东西,现在让我们来看看如何显示一个对话框,源程序如下: .386 .model flat, stdcall option casemap :none ; case sensitive include windows.inc include user32.inc include kernel32.inc include comctl32.inc include comdlg32.inc includelib user32.lib includelib kernel32.lib includelib comctl32.lib includelib comdlg32.lib DLG_MAIN equ 1 .data? hInstance dd ? szBuffer db 256 dup (?) _ProcDlgMain PROTO :DWORD,:DWORD,:DWORD,:DWORD .data .code ;******************************************************************** _ProcDlgMain proc uses ebx edi esi, \ hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD mov eax,wMsg .if eax == WM_CLOSE invoke EndDialog,hWnd,NULL .elseif eax == WM_INITDIALOG .elseif eax == WM_COMMAND mov eax,wParam .if eax == IDOK invoke EndDialog,hWnd,NULL .elseif eax == IDCANCEL invoke EndDialog,hWnd,NULL .endif .else mov eax,FALSE ret .endif mov eax,TRUE ret _ProcDlgMain endp ;******************************************************************** start: invoke InitCommonControls invoke GetModuleHandle,NULL mov hInstance,eax invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,0 invoke ExitProcess,NULL end start 看了前面几篇文章以后,这儿的大部分语句应该是很熟悉了,我来讲解几句新的语句: _ProcDlgMain PROTO :DWORD,:DWORD,:DWORD,:DWORD PROTO 语句类似于C语言中的函数定义,在Win32汇编中,如果子程序的定义在引用以后,你就必须先定义,当然,这个定义是针对 invoke 语句和其他带参数的调用的,如果你的子程序没有参数,你就可以用 call 指令去调用它而不是用宏指令 invoke,这时候你就不必声 明这个函数。 _ProcDlgMain proc uses ebx edi esi, \ hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD 这个定义 proc 的语句应该是不陌生的,要重复讲解一下的是 uses 和 下面的参数,uses 下的寄存器表示要编译器自动插入保存及恢复这些寄存器的指令,\ 是在 Masm32 中接下一行的符号,表示下一行是本行的继续内容,以避免一行中的内容过长。下面的 hWnd:DWORD 等语句定义了调用这个子程序的参数,如果有以下定义 MyProc proc dwPara1:DWORD,dwPara2:DWORD,dwPara3:DWORD,然后你用 invoke MyProc 1,2,3 来调用它,那么,1,2,3 将分别被赋值给 dwPara1,dwPara2,dwPara3,你可以在子程序中使用这些传递过来的参数。如果参数的类型是双字,那么:DWORD 可以省略。 .if/.else/.elseif/.endif 这些语句是宏指令,实际上不说你也知道它们的意思,有了这些宏指令,我们就可以把汇编编得象C一样结构清晰,而不必老是看到 jmp 指令了,当然,这只不过编译器帮你做了这些事情而已,如果你去反汇编一下,你开始会看到一大堆 jmp 指令,.if 的格式如下 .if eax == 1 如果eax等于1 .if eax != 1 如果eax不等于1 .if eax != 1 && ebx != 2 如果eax不等于1且ebx不等于2 .if eax == 1 || ebx == 2 如果eax等于1或者ebx等于2 其他的宏指令还有 .while/.endw .break 等等,可以参考 Masm32V5 的帮助文件 Masm32.hlp 最后要讲到的就是 DialogBoxParam 这个API了,在Windows中,所有的窗口都要指定一个子程序,当Windows检测到鼠标、定时器等和这个窗口有关的动作时,它回调用这个子程序,这就是Windows基于消息的体系的最基本的概念,换句话说,在Dos下,我们通过INT指令调用系统,而在Windows 下,有很多时候是你指定子程序地址让Windows来调用你。 invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,0中的 offset _ProcDlgMain 就指定了如果有消息发生,Windows就来执行这个子程序,参数中的 DLG_MAIN 就是在资源文件中定义的对话框模板编号另外,在_ProcDlgMain 子程序中,Windows传给我们4个参数hWnd,wMsg,wParam,lParam,其中,hWnd是对话框的窗口句柄,wMsg表示现在发生的消息事件,如这个对话框初始化时Windows会以WM_INITDIALOG为消息调用,关闭时为WM_CLOSE,按下对话框上的按钮时为WM_COMMAND等,wParam和lParam是附加的参数,对应不同的消息对应不同定义,具体可以参考Win32 Programmer's reference。 Win32汇编教程四 编写一个简单的窗口 有关窗口的基本知识 窗口是屏幕上的矩形区域。一个窗口可以从键盘或者鼠标接受用户的输入,并在其内部显示图形输出。一个应用程序窗口通常包含程序的标题条、菜单、边框,滚动条。其中,对话框也是一种窗口。不同的是,对话框表面通常包含几个其它窗口,称之为“子窗口”。这些子窗 口的形式有压入按钮、单选按钮、复选框、文本输入区域、列表框和滚动条等。 用户将这些窗口看成屏幕上的对象,可以通过按下一个按钮或者滚动一个滚动条与这些对象直接交互。 窗口以“消息”的形式接收窗口的输入,窗口也用消息与其它窗口通讯。比如在程序窗口的大小改变时,字处理器会重新格式化其中的文本。窗口大小改变的细节是由操作系统处理的,但程序能够响应这个系统功能。当用户改变窗口的大小时,Windows给程序发送一条消息指出新窗口的大小。然后,程序就可以调整窗口中的内容,以响应大小的变化。程序创建的每一个窗口都有相关的窗口过程。也就是给这个窗口指定一个子程序(窗口过程),Windows通过调用它来给窗口发送消息。窗口过程再根据此消息进行处理,然后将控制返回给Windows。 窗口在“窗口类”的基础上创建的。Windows定义了确省的窗口过程,如果你对所有的消息都让Windows自己处理,那么你就能得到一个标准的窗口,同样,你也可以选择处理自己感兴趣的消息,这样,相当于产生了不同的子类,也就形成了不同的应用程序。同样,子窗口也是基于同一个窗口类,并且使用同一个窗口过程。例如,所有Windows 程序中的所有按钮都基于同一窗口类。这个窗口类有一个处理所有按钮消息的窗口过程,但是,如果你按自己的设想设计一个按钮,如想把按钮的表面换成位图,你就可以自己处理按钮窗口的 WM_PAINT 消息,当 Windows 需要画按钮表面的时候,你就可以随自己的意思去画。 Windows程序开始执行后,Windows为该程序创建一个“消息队列”。这个消息队列用来存放该程序可能创建的各种不同窗口的消息。程序中有一段代码,叫做“消息循环”, 它用来从队列中取出消息,并且将它们创建一个窗口的过程如下: 取得程序的实例句柄(hInstance) 注册窗口类,实际上就是为你的窗口指定处理消息的过程,定义光标,窗口风格,颜色等参数 创建窗口 显示窗口 然后进入消息循环,也就是不停地检测有无消息,并把它发送给窗口进程去处理。 创建一个窗口的代码在不同的程序中实际上是几乎一模一样的,所以你编一个新的程序时可以把这一段拷来拷去,稍微修改一下就行,程序的大部分代码实际上是用在窗口过程中,因为这才是不同程序的不同之处。窗口过程的编程要点如下: 从Windows传给窗口过程的参数 uMsg 得到消息类型,并转到不同的分枝去处理。 对自己已经处理的消息,返回 Windows 时必须在eax 中返回0。 自己不处理的消息,必须调用 DefWindowProc 处理,并把返回值传回Windows,否则,Windows会无法显示。 uMsg 参数中指定的消息有280多种,实际上我们需要处理的只有重要的几种,如Windows在创建的时候会发送 WM_CREATE 消息,我们就可以在这时候初始化,分配内存等等,而退出时会发送 WM_CLOSE,我们就可以进行释放内存等清除工作,当Windows上的菜单或按钮被按下时发送 WM_COMMAND 消息等等,具体可以参考 Win32 Programmer's Reference。下面,我们来看一个创建窗口的简单程序。 一个创建窗口的程序 .386 .model flat, stdcall option casemap :none ; case sensitive include windows.inc include user32.inc include kernel32.inc include comctl32.inc include comdlg32.inc include gdi32.inc includelib user32.lib includelib kernel32.lib includelib comctl32.lib includelib comdlg32.lib includelib gdi32.lib IDI_MAIN equ 1000 ;icon IDM_MAIN equ 4000 ;menu IDM_EXIT equ 4001 .data? hInstance dd ? hWinMain dd ? hMenu dd ? szBuffer db 256 dup (?) .data szClassName db "Windows Template",0 szCaptionMain db '窗口模板',0 .code start: call _WinMain invoke ExitProcess,NULL _WinMain proc local @stWcMain:WNDCLASSEX local @stMsg:MSG invoke InitCommonControls invoke GetModuleHandle,NULL mov hInstance,eax invoke LoadIcon,hInstance,IDI_MAIN mov hIcon,eax invoke LoadMenu,hInstance,IDM_MAIN mov hMenu,eax ;*************** 注册窗口类 ***************************************** invoke LoadCursor,0,IDC_ARROW mov @stWcMain.hCursor,eax mov @stWcMain.cbSize,sizeof WNDCLASSEX mov @stWcMain.hIconSm,0 mov @stWcMain.style,CS_HREDRAW or CS_VREDRAW mov @stWcMain.lpfnWndProc,offset WndMainProc mov @stWcMain.cbClsExtra,0 mov @stWcMain.cbWndExtra,0 mov eax,hInstance mov @stWcMain.hInstance,eax mov @stWcMain.hIcon,0 mov @stWcMain.hbrBackground,COLOR_WINDOW + 1 mov @stmov @stWcMain.lpszMenuName,0 invoke RegisterClassEx,addr @stWcMain ;*************** 建立输出窗口 *************************************** invoke CreateWindowEx,WS_EX_CLIENTEDGE,\ offset szClassName,offset szCaptionMain,\ WS_OVERLAPPEDWINDOW OR WS_VSCROLL OR WS_HSCROLL,\ 0,0,550,300,\ NULL,hMenu,hInstance,NULL invoke ShowWindow,hWinMain,SW_SHOWNORMAL invoke UpdateWindow,hWinMain ;*************** 消息循环 ******************************************* .while TRUE invoke GetMessage,addr @stMsg,NULL,0,0 .break .if eax == 0 invoke TranslateMessage,addr @stMsg invoke DispatchMessage,addr @stMsg .endw ret _WinMain endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> WndMainProc proc uses ebx edi esi, \ hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD mov eax,uMsg .if eax == WM_CREATE mov eax,hWnd mov hWinMain,eax call _Init ;******************************************************************** .elseif eax == WM_COMMAND .if lParam == 0 mov eax,wParam .if ax == IDM_EXIT call _Quit .endif .endif ;******************************************************************** .elseif eax == WM_CLOSE call _Quit ;******************************************************************** .else invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .endif xor eax,eax ret WndMainProc endp _Init proc invoke SendMessage,hWinMain,WM_SETICON,ICON_***ALL,hIcon ret _Init endp ;******************************************************************** _Quit proc invoke DestroyWindow,hWinMain invoke PostQuitMessage,NULL ret _Quit endp ;******************************************************************** end start 窗口程序的分析 让我们来简单分析一下这个程序,首先程序调用 _WinMain,在_WinMain 中定义了两个局部变量 @stMsg 和 @stWinMain,数据类型分别是 MSG 和 WNDCLASSEX结构,在参考手册中,可以看到WNDCLASSEX定义了一个窗口的所有参数,如使用的菜单、光标、颜色、窗口过程等,接下来的一大堆 mov 指令实际上就是在填写这个数据结构,填写完成后,最重要的两句是 mov @stWcMain.lpfnWndProc,offset WndMainProc 定义了处理消息的窗口过程, mov @stWcMain.lpszClassName,offset szClassName 定义了你要创建的类的名称,然后就是使用 RegisterClassEx 注册这个窗口类,注意,这时候窗口并没有创建,你只不过是定义好了一个子类,接下去你要用你定义的类去创建一个窗口。也就是使用 CreateWindowEx 函数去创建它。在手册中,CreateWindowEx 是这样定义的: HWND CreateWindowEx( DWORD dwExStyle, // extended window style LPCTSTR lpClassName, // pointer to registered class name LPCTSTR lpWindowName, // pointer to window name DWORD dwStyle, // window style int x, // horizontal position of window int y, // int nWidth, // window width int nHeight, // window height HWND hWndParent, // handle to parent or owner window HMENU hMenu, // handle to menu, or child-window identifier HINSTANCE hInstance, // handle to application instance LPVOID lpParam // pointer to window-creation data ); 其中的参数 dwExStyle 是窗口的风格,lpClassName 就是我们自己定义的类的名字。如果大家要创建一个已经定义好的类,如 RichEdit 类等等,只要把 lpClassName 指向 "RichEdit32" 字符串就行了,当然这时就不用 RegisterClass 以及编写自己的窗口过程了。执行 CreateWindowEx 后,得到一个返回值就是窗口句柄,这个值在以后是要经常用到了,所以要先保存下来。这时窗口并没有在屏幕上显示出来,而是处于隐藏状态,我们要用 ShowWindow 来显示出窗口并用UpdateWindow 来绘窗口的内容。 窗口显示出来后,程序就进入一个循环----消息循环,前面我已经说过,作用是不停地接收 Windows 消息并发送给窗口过程去处理。GetMessage 从消息队列中取出一条消息,如果取得的消息不是 WM_QUIT,那么 GetMessage 返回一个非零值,否则返回零,这时候循环结束,程序执行 ExitProcess退回操作系统。TranslateMessage 将消息进行一些键盘转换,用于处理一些快捷键,DispatchMessage 将处理后的消息发回 Windows,由Windows调用窗口进程进行处理,当窗口进程处理完返回后,程序才从 DispatchMessage 返回,从而开始下一个 GetMessage 调用。这些函的参数可以参考手册。 窗口过程的分析 窗口过程有四个参数,hWnd 是本窗口的句柄,和创建窗口时返回的值相同,uMsg 是本次调用的消息类型,wParam 和lParam是消息的参数,其含义和数值根据消息的不同而不同。在本程序中,我们处理 WM_CREATE,WM_COMMAND 和 WM_QUIT 消息,然后返回0,对不处理的消息,使用 invoke DefWindowProc,hWnd,uMsg,wParam,lParam 来处理并直接用 ret 将返回值传回 Windows。在响应 WM_CLOSE 消息时,我们用 DestroyWindow 清除窗口并用 PostQuitMessage 产生一条 WM_QUIT 消息,从而使程序在 消息循环调用GetMessage 时返 回0,以结束消息循环并结束程序。 第一章 Origin 基础知识 Origin 是美国 Microcal 公司出的数据分析和绘图软件,编写此介绍时的最高版本为 7.0 http://www.originlab.com/ 特点:使用简单,采用直观的、图形化的、面向对象的窗口菜单和工具栏操作,全面支持鼠 标右键、支持拖方式绘图等。 两大类功能:数据分析和绘图。数据分析包括数据的排序、调整、计算、统计、频谱变换、 曲线拟合等各种完善的数学分析功能。准备好数据后,进行数据分析时,只需选择所要分析 的数据,然后再选择响应的菜单命令就可。 Origin 的绘图是基于模板的, Origin 本身提供 了几十种二维和三维绘图模板而且允许用户自己定制模板。绘图时,只要选择所需要的模板 就行。 用户可以自定义数学函数、 图形样式和绘图模板; 可以和各种数据库软件、 办公软件、 图像处理软件等方便的连接;可以用 C 等高级语言编写数据分析程序,还可以用内置的 Lab Talk 语言编程等。 一、工作环境 1.1 工作环境综述 类似 Office 的多文档界面,主要包括以 下几个部分: 1、 菜单栏 顶部 一般可以实现大部分 功能 2、 工具栏 菜单栏下面 一般最常用的 功能都可以通过此实现 3、绘图区 中部 所有工作表、绘图 子窗口等都在此 4、项目管理器 下部 类似资源管理 器,可以方便切换各个窗口等 5、状态栏 底部 标出当前的工作内 容以及鼠标指到某些菜单按钮时的说明 工作表 矩 阵 绘图 1.2 菜单栏 菜单栏的结构取决于当前的活动窗口 工作表菜单 绘图菜单 矩阵窗口 菜单简要说明: File 文件功能操作 打开文件、输入输出数据图形等 Edit 编辑功能操作 包括数据和图像的编辑等,比如复制粘贴清除等,特别注意 undo 功能 View 视图功能操作 控制屏幕显示, Plot 绘图功能操作 主要提供 5类功能: 1、几种样式的二维绘图功能,包括直线、描点、直线加符号、特殊线/符号、条形图、 柱形图、特殊条形图/柱形图和饼图 2、三维绘图 3、气泡/彩色映射图、统计图和图形版面布局 4、特种绘图,包括面积图、极坐标图和向量 5、模板:把选中的工作表数据到如绘图模板 Column 列功能操作 比如设置列的属性,增加删除列等 Graph 图形功能操作 主要功能包括增加误差栏、函数图、缩放坐标轴、交换 X 、 Y 轴等 Data 数据功能操作 Analysis 分析功能操作 对工作表窗口:提取工作表数据; 行列统计; 排序; 数字信号处理 (快速傅里叶变换 FFT 、 相关 Corelate 、 卷积 Convolute 、 解卷 Deconvolute ) ; 统计功能 (T -检验) 、 方差分析 (ANOAV ) 、 多元回归(Multiple Regression);非线性曲线拟合等 对绘图窗口:数学运算;平滑滤波;图形变换; FFT ;线性多项式、非线性曲线等各种 拟合方法 Plot3D 三维绘图功能操作 根据矩阵绘制各种三维条状图、表面图、等高线等 Matrix 矩阵功能操作 对矩阵的操作,包括矩阵属性、维数和数值设置,矩阵转置和取反, 矩阵扩展和收缩,矩阵平滑和积分等 Tools 工具功能操作 对工作表窗口:选项控制;工作表脚本;线性、多项式和 S 曲线拟合 对绘图窗口:选项控制;层控制;提取峰值;基线和平滑;线性、多项式和 S 曲线拟合 Format 格式功能操作 对工作表窗口:菜单格式控制、工作表显示控制,栅格捕捉、调色板等 对绘图窗口:菜单格式控制;图形页面、图层和线条样式控制,栅格捕捉,坐标轴样式 控制和调色板等 Window 窗口功能操作 控制窗口显示 Help 帮助 二、基本操作 作图的一般需要一个项目 Project 来完成, File -》 New 保存项目的缺省后缀为:OPJ 自动备份功能:Tools -》 Option -》 Open /Close 选项卡-》“Backup Project Before Saving” 添加项目:File -》 Append 刷新子窗口:如果修改了工作表或者绘图子窗口的内容, 一般会自动刷新, 如果没有请 Window -》 Refresh 第二章 简单二维图 2-1、输入数据: 一般来说数据按照 X Y坐标存为两列,假设文件为 sindata.dat ,如下格式: x sin(x) 0.0 0.000 0.1 0.100 0.2 0.199 0.3 0.296 ???? 输入数据请对准 data1表格点右键调出如下窗口,然后选择 Inport ASCII 找到 sindata.dat 文件打开就行 2-2、绘制简单二维图 按住鼠标左键拖动选定这两列数据,用下图最下面一排按钮就可以绘制简单的图形,按从左 到右三个按钮做出的效果分别如下: 2-3、设置列属性 双击 A 列或者点右键选则 Properties ,这里可以设置一些列的属性。 2-4、数据浏览 Data Display 动态显示所选数据点或屏幕点的 XY 坐标值 Data Selector 选择一段数据曲线,作出标志 一是鼠标,而是利用 Ctrl,Ctrl+Shift与左 右箭头的组合 Data Reader 读取数据曲线上的选定点的 XY 值 Screen Reader 读取绘图窗口内选定点的 XY 值 Enlarger 局部放大曲线 Zoom 缩放 注意利用方向键,以及与 Ctrl 和 Shift 的组合 2-5、定制图形: 2-5-1 定制数据曲线 用鼠标双击图线掉出下面窗口。 2-5-2 定制坐标轴:双击坐标轴得到,下图 上述四种模板再加上九屏图形模板就是 Origin 所提供的自带多图形模板。 4-3 在工作表中指定多个 X 列 对准 D 点右键选择 SetAs X设为 X 列得到 说明:默认 Y 与左侧最近的 X 轴关联,也就是 BC 与 A , EF 与 D 关联。 4-4 创建多层图形 Origin允许用户自己定制图形模板。 如果你已经创建了一个绘图窗口, 并将它存为模板, 以后就可以直接基于此模板绘图,而不必每次都一步步创建并定制同样的绘图窗口。 4-4-1 创建双层图 步骤: (1) 激活“Layers”的工作表窗口。 (2)单击“sinx”列的标题栏,使其高亮,表示该列被选中。 (3) 作出单层图 (4) 在激活 Layer 窗口的前题下, Tools -》 Layer ,如下图,这个工具包含两类:Add 图层和 Arrange 图层 双击图层 2做成右上图那样,然后 OK 4-4-2 关联坐标轴 Origin可以在各图层之间的坐标轴建立关联, 如果改变某一图层的坐标轴比例, 那么其 它图层的也相应改变。 做法双击:Layer 上的 2图标, 在调出的 Layer 对话框中点 Layer Properties , 然后选择 Link Axes Scales。 4-5 存为模板 File-》 Save Template As,以后就可以用此模板。 调用模板用此 上的最后一个 。 第五章 非线性拟合 拟合曲线的目的为要根据已知数据照出响应函数的系数。 5-1 使用菜单命令拟合 首先激活绘图窗口,选择菜单命令 Analysis ,则可以看到 5-2 使用拟合工具拟合 为了给用户提供更大的拟合控制空间, Origin 提供了三种拟合工具,即线性拟合工具、 多项式拟合工具、 S 拟和工具。具体自己去体会。 5-3 非线性最小平方拟合 NLSF 这是 Origin 提供的功能最强大、使用也最复杂的拟合工具。方法是 Analysis-》 Non-Linear Curve Fit-》 Advanced Fitting Tools或者 Fitting Wizad 具体的请自己体会。 高级模式 利用 Function-》 new 可以自定义拟合函数 基本模式,利用 new 可以自定 义拟合函数 Wizad模式 高级模式中利用 Action -》 Dataset 设置,在基本模式中用 Select Dataset设置。 第六章 数据分析 数据分析主要包含下面几个功能: 1. 简单数学运算(Simple Math) 2. 统计(Statistics ) 3. 快速傅里叶变换(FFT ) 4. 平滑和滤波(Smoothing and Filtering) 5. 基线和峰值分析 (Baseline and Peak Analysis) 6-1 简单数学运算 数据来自 Tutorial\Tutorial_1.dat,它的背景是对同一物理量进行三次测量得到的结 果。为清楚起见我们舍弃三个误差数列,并只绘制中间数据段的曲线。 6-1-1 算术运算 这是实现 Y=Y1(+-*/)Y2的运算,其中 Y 和 Y1为数列, Y2为数列或者数字。 命令为:Analysis -》 Simple Math 6-1-2 减去参考直线 激活曲线 Test3, Analysis -》 Subtract:Straight Line 此时光标自动变为 , 然后在窗口上双击左键定起始点, 然后再在终止点双击, 此时会 Test3曲线变为原来的减为这条直线后的曲线。 6-1-3 垂直和水平移动 垂直移动指选定的数据曲线沿 Y 轴垂直移动。步骤如下: 1. 激活数据曲线 Test3 2. 选择 est3, Analysis -》 Translate :Vertical 这时光标自动变为 3. 双击曲线 Test3上的一个数据点,将其设为起点。 4. 这是光标形状变为 ,双击屏幕上任意点将其设为终点。 这时 Origin 将自动计算起点和重点纵坐标的差值,工作表内 Test3列的值也自动更新 为原 Test3数列的值加上该差值,同时曲线 Test3也更新。 水平移动和次类似。 6-1-5 多条曲线平均 多条曲线平均是指在当前激活的数据曲线的每一个 X 坐标处,计算当前激活的图层内所 有数据曲线的 Y 值的平均值。 Analysisi -》 Average Multiple Curves 这个不知道那里出了问题,我的没测试成功,新曲线没有出现。 6-1-6 插值 插值是指在当前激活的数据曲线的数据点之间利用某种方法估计信的数据点。 Analysis-》 Interpolate and Extrapolate 6-1-7 微分 也就是求当前曲线的导数 , 命令为: Analysis-》 Calculus :Differentiate 6-1-7 积分 对当前激活的数据曲线用梯形法进行积分,命令为:Analysis -》 Calculus :Integrate 6-2 统计 包括:平均值(Mean )、标准差(Standard Deviation , Std , SD )、标准误差 (Standard Error of the Mean) 、最小值(Minimum )、最大值(Maximum )、百分位数(Percentiles )、 直方图(Histogram )、 T 检验(T-test for One or Two Populations )、方差分析(One-way ANOVA )、线性、多项式和多元回归分析(Linear 、 Polynomial and Multiple Regression Analysis ) 6-3 快速傅里叶变换 傅里叶分析把信号分解成不同频率的正弦函数的叠加,在信号是最重要的最基本的工具 之一。 一般包括 FFT 及定制频谱图,采样率,相关、卷积和去卷积 6-4 平滑和滤波 包括用 Savitzky-Golay 滤波器平滑,用相邻平均法平滑,用 FFT 滤波器平滑,数字滤 波器,如低通、高通、带通、带阻和门限滤波器。 6-5 基线和峰值分析 具体存在哪些方法,不多说,仅仅说一下 Origin 提供用来读取图形窗口上的数据和坐 标的几个工具,它们为: 屏幕读取工具 数据读取工具 数据选择工具 利用这些工具可以精确的读取数据等。 第七章 绘制三维图形 Origin 支持三种数据类型的三维绘图功能:XYY 工作表数据、 XYZ 工作表数据、矩阵数据, 但是三维表面图只能由矩阵数据创建。 下面以做一个最简单的正方体为例子说明。 7-1把工作表转为矩阵 7-1-1 导入数据 创建一个三维数据 文件 ,内容为 XYZ , 类似: x y z 1 1 10 1 2 10 1 3 10 1 4 10 1 5 10 ??? 并把最后一列 z(Y)设置为 z(z)。 7-1-2 类型转换 Origin有几种转换方法,这需要取决于工作表数据,对于有规律的数据,选择 Regular XYZ 就行,得到 Matrix5工作表(对例子来说为 100X100矩阵)。 7-2 创建三维表面图和等高线图 激活矩阵窗口,选择 Plot3D 中的相应命令,就可以会出想要的图。 菜单命令 含义 模板文件 3D Color Fill Surface 三维彩色填充表面图 MESH.OTP 3D X Constant with Base 三维 X 恒定、有基底表面图 XCONST.OTP 3D Y Constant with Base 三维 Y 恒定、有基底表面图 YCONST.OTP 3D Color Map Surface 三维彩色映射表面图 CMAP.OTP 3D Bars 三维条形表面图 3DBARS.OTP 3D Wire Frame 三维线框架面图 WIREFRM.OTP 3D Wire Surface三维线条表面图 WIREFACE.OTP Contour-Color Fill彩色填充等高线图 CONTOUR.OTP Contour-B/W Lines+Labels 黑白线条、具有数字标记的等 高线图 CONTLINE.OTP Gray Scale Map灰度映射等高线图 CONTOUR.OTP 因为数据太规律化,没法显示出各个命令的真正区别,特别是等高线的,一点也看不出来, 希望大家自己慢慢捉摸。 7-3 定制三维图形 激活图形窗口后,在 Format->Plot里设置图形的各个参数,随着图形的不同,这个选项也 不同。 当激活 3D 图形窗口后,会出现控制图形透射的控制按钮 3D 绘图功能非常强大, 选项也多得很, 希望大家在用到的时候仔细捉摸一下, 把你的图做得 清楚好看。 第八章 创建版面页 版面页(Layout )用于创建图形外观,项目中的任何绘图窗口和工作表窗口的图片都页面中 显示和排序。另外也可以向版面页中加入图形目标和文本,以加强外观的表现效果。 利用 File —》 new —》 Layout 或者工具栏上的 新建版面页。 添加的方法为在 Layout 上点右键-》ADD??或者从 Layout 菜单执行。 下面在 Layout1中把 Graph1和 shidata 放进来了,并添加了文本说明。 第十章 数据的输入输出 10-1 数据导入导出 导入数据用 Import 命令,注意调开窗口中的 Option 这个选项,这里可设置倒入数据的 很多选项。 数据导出:Export ASCII,会调出选项对话框,可以设置以何种方式分割数据列。 10-2 图形和版面的导出 激活绘图窗口, Edit-》 Copy Page就可以复制图像。 而 File -》 Export Page可以把图像存为图像文件。 10-3 在其它应用程序中使用 Origin 在装有 Origin 的机子上, Word 中可以直接插入 Origin 图像,并可以直接在 Word 中通 过双击这个图形来调用 Origin 来编辑图片。 插入方法:插入-》对象-》 Origin Graph,这将新建一个空白的 Origin 图形。 或者利用插入-》从文件创建,把以前做好的 Origin 文件插入进来。 下面为在 Word 中直接编辑 Origin 文件的窗口。 VB 驿站编辑 我们需要什么 我们需要什么?当我们在一个精彩的游戏世界中游历了一番之后,或 是惊叹于某一工具软件的小巧精致之余,多少总会产生些许编程的冲动。 编程吗,在以前如果你对电脑还是一个门外汉,那实在是一件可望而不可 及的事情。如果运用基于 DOS 下的编程语言,譬如 C 、 Qbasic 、 Pascal 等 等,真不知何年何月才能有所成就。 编程是需要天赋的,你必须在大脑中对整个程序有一个清晰的轮廓, 一个高效的流程,这并不是每个人都能做到的,你必须思之慎之,这也使 编程变成一件最枯燥无味的事情。但在第四代计算机语言(可视化编程) 出现后,可以确切的说它开发了人们的更多天赋,并不局限于那些头脑异 常清晰的人,每一个人都可以发现自己也可以编出一些从前不敢问津的程 序,想象力的充分发挥才是第四代语言的精粹。 Visual Basic(以下简称 VB )可以说是可视化语言的先驱了,而且它 也是可视化程度最高的一个,从几年前 VB 诞生之日起到现在,它已经经历 了五个版本,而且现在微软正在紧张的进行着 VB6.0的研制、测试,这么 高的更新率,不外乎说明两个问题:用户对 VB 的热衷,微软对 VB 的重视。 不可否认微软对市场的预测能力是极为高明的,而它强大的技术、财力支 持也使它在许多以前未进入的领域,在不长的时间内有成为最有力的竞争 对手,如 IE 之于浏览器领域,《帝国时代》之于游戏都是最好的例证。对 于 VB 现在也有一个很强的竞争对手――Delphi,有人把它称作 VB 杀手, 这显然有偏激之处, VB 的确有它的不足之处,但 Delphi 又何尝不是呢,而 且以微软对 VB 的倾心, VB 的功能必然会越来越强大。 VB 的诞生 VB 的出现可以说是 Microsoft Windows的日渐成熟的必然产物。 Microsoft Windows 为程序员和最终用户提供了一个共同的人机界面。对用 户, Windows 提供了一个图形鼠标的操作环境, 该环境对所有的应用程序都 一样;对于程序员, Windows 提供了一组预定义工具 ----称之为 Microsoft Windows 的软件开发工具箱 (SDK ) , 该工具能使程序员建立一个与 Windows 界面相同的应用程序,而且,程序员不必关心最终用户的硬件配置情况。 在这一开发环境中,程序员唯一困难的是 Microsoft SDK提供了六百多个 函数和与其一致的事件驱动(event-driven )编程技术。两种新方法的交 叉使众多的程序员重新陷入困境,程序员不仅要掌握程序驱动编程技术和 六百多个函数的功能,而且还得用 C 语言描述这些问题。因此一般情况下, 程序员首先要掌握 C 程序设计技术, 而后再开始学习 SDK 。 这样的条件下就 要求在 Microsoft 多任务环境下出现一种操作方便,使用简单的新工具----Visual Basic由此诞生。 何为可视 英文 Visual 的意思是“视觉的”,“可视的 Baisc”这个名字可能抽 象了点,但实际上它却是最直观的编程方法,之所以叫做“可视”,你只 要看到 VB 的界面就会明白,实际上你无需编程,就可以完成许多步骤。在 VB 中引入了控件的概念,在 Windows 中控件的身影无处不在,各种各样的 按钮、文本框、无线钮,都是控件的种类, VB 把这些控件模式化,并且每 个控件都有若干属性用来控制控件的外观,工作方法。这样你就可以象在 画板上一样,随意点几下鼠标,一个按钮就完成了,这些在以前的编程语 言下是要经过相当复杂的工作的。 第二章:事件、属性及数据类型 以后两章可能会比较枯燥,但不可否认也很重要,所以为了学好 VB ,我们 一定要打好基础才行。 一、事件 通过上一章的例子,你可能对“面向对象的编程”已经有了一定了解,它 是由事件驱动的,对于不同的对象,所能感应到的事件也会不同,譬如说 当你把鼠标移进某一区域时就会触发 MouseMove 事件,这很直观,也容易 理解,但也有些事件比较抽象,下面我来对一般的事件进行一下解释。 1. 窗体和图象框类事件 ?Paint 事件:当某一对象在屏幕中被移动,改变尺寸或清除后,程序 会自动调用 Paint 事件。 注意:当对象的 AutoDraw 属性为 True (-1)时,程序不会调用 Paint 事件。 ?Resize 事件:当对象的大小改变时触发 Resize 事件。 ?Load 事件:仅适用于窗体对象,当窗体被装载时运行。 ?Unload 事件:仅适用于窗体对象,当窗体被卸载时运行。 2.当前光标(Focus )事件 ?GotFocus 事件:当光标聚焦于该对象时发生事件。 ?LostFocus 事件:当光标离开该对象时发生事件。 注意:Focus 英文为“焦点”、“聚焦”之意,最 直观的例子是,比如有两个窗体,互相有一部分遮 盖,当你点下面的窗体时,它就会全部显示出来, 这时它处在被激活的状态,并且标题条变成蓝色, 这就是 GotFocus 事件, 而相反, 另外一个窗体被遮 盖,并且标题条变灰,称为 LostFocus 事件。上面 所说的“光标”并非指鼠标指针。 3.鼠标操作事件 ?Click 事件:鼠标单击对象。 ?DbClick 事件:鼠标双击事件。 ?MouseDown 、 MouseUp 属性:按下 /放开鼠标键事件。 ?MouseMove 事件:鼠标移动事件。 ?DragDrop 事件:拖放事件,相当于 MouseDown 、 MouseMove 和 MouseUp 的组合。 ?DragOver 事件:鼠标在拖放过程中就会产生 DragOver 事件。 4.键盘操作属性 ?KeyDown 、 KeyUp 事件:按键的按下 /放开事件。 ?KeyPress 事件:按键事件。 5.改变控制项事件 ?Change 事件:当对象的内容发生改变时,触发 Change 事件。最 典型的例子是文本框(TextBox ) 。 ?DropDown 事件:下弹事件, 仅用于组合框 (ComboBox ) 对象。 ?PathChange 事件:路径改变事件,仅用于文件列表框(FileBox ) 对象。 6.其他事件 ?Timer 事件:仅用于计时器,每隔一段时间被触发一次。 二、属性 每个对象都有它的属性,并且“Name”属性是共有的,有了“ Name ” 属性才可以在程序中进行调用。对于属性,可以在窗体的布局操作中完成, 也可以在程序运行中改变,这取决你的需要,但有些属性是只读的,它只 能在控件布局时改变。我将在以后的实例中具体介绍各个属性的作用。 三、数据类型 学过编程的人都知道大多数的计算机语言都规定了各自的数据类型, VB 也 不例外。其实,在一个最简单的程序中数据类型是可以不作规定的,也就 是说,变量可以使用各种类型,但是在一个复杂的程序里,这样做就很危 险,因为很可能给同一个变量赋予了不同的类型,而导致程序出错。所以, 为了程序的严谨和便于查看,正确的定义数据类型是必要的。定义数据的 另一个原因是,不同的数据占用不同的内存数量,譬如整型(Interger ) 数据占 2字节,而长整型数据占 4个字节,定义合适的数据类型,不管你 相信不相信,它可以节省内存! 1. VB 常用的数据类型有:整型(Integer ,表示 -32768至 32767之间 的整数) 、长整型(Long ,表示 -2,147,483,648至 2,147,483,647之 间的整数) 、 实型 (Single , 表示 -3.37E+38至 3.37E+38之间的实数) 、 双精度实型 (Double , 表示 -1.67E+308至 1.67E+308之间的实数) , 字符(String ,每个字符占一字节,可以储存 0~65,535个字符) ,布 尔(Boolean ,只有两个值 True/-1,或 False/0) 。 2. 数据类型的定义方法: ?定义变量最简单的方法是用“ Dim ”关键字,它的语法: Dim 【变量名】 As 【数据类型】 如:Dim Index As Integer 也可以在一行中定义多个变量,如: Dim Index As Integer , Dim Number As Long 把多个变量定义成同一类型可以写成: Dim Index , Number As Integer 更可以在定义时进行初赋值: Dim Index=3 有时为了简便,也以符号进行简单的定义,作用是和上面一样 的。整型可以用“ %”代替,长整型可以用“ &”代替,实型可 以用“ ! ”,双精度实型可以用“#”定义,如刚才的第一个例 子可以写成: Dim Index% 等价于 Dim Index As Integer ?对于常量的定义用 Const 定义,如:Const COLOR=255。 为了在程序中便于查阅,我们对变量和常量的写法进行规定, 变量一般用小写方式,常量则全部大写。 注意:使用常量的好处,对于程序中经常出现的数值,应设常 量等于它,这样一是书写方便,其二,如果要改变该数值,只 需改变定义常量的语句值, 而不需改变每个语句, 提高了效率。 ?数组的定义类似于变量定义, 所不同的是数组需要指定数组中的元素 个数,例如: Dim IntegerArray(99) As Integer 这个数组中包含 100个元素,脚标从 0到 99。 也可以指定脚标的起始值,例如: Dim IntegerArray(2 to 10) As Integer 这个数组含有九个元素,脚标从 2到 10。 还可以定义多维数组: Dim ThreeD(4,2 to 5,3 to 6) As Integer 上例定义了一个三维数组 (4×4×4) 。 记录的定义 记录定义是把控制权交给用户的方法,它让用户可 以定义自己的数据类型,它使用关键字“ Type ”, 方法是: Type 【数据类型标识符】 <域名> As <数据类型> <域名> As <数据类型> <域名> As <数据类型> ?????????? End Type 例如,定义一个地址数据: Type Address Street As String ZipCode As String Phone As String End Type 这个地址数据里包括三个属性,街区、邮政编码和 电话,可以把某数据定义成此类型: Dim MyHome As Address 要调用或改变“ MyHome ”的值时,类似于对对象的 属性的操作: 变量名 . 域名=“??” 为了简化书写重复的部分 , 可以用关键字“With”: With MyHome .Street =”阜成路” .ZipCode=”100037” .Phone=”12345678” End With 本章提要: ?VB 语法与 Basic 的异同 ?注释语句 ?长语句的分行 ?条件语句 ?循环语句 ?运算操作 ?数据定义与赋值 ?函数和过程 一、 VB 与 Basic ?VB 之所以叫做“Visual Basic”就是因为它使用了 Basic 语言作为代 码,所以它们之间有着千丝万缕的关系,如果学过 Basic 的话,看到 VB 的程序结构会感到很亲切。但 VB 作为新生物,也超越了 Basic 的限制,有了许多自己的特点: ?VB 建立了一种新的变量类型――货币型变量,通过使用仅带有二位 小数的货币变量, 就能避免因使用实型变量而带来的数值积累误差问 题。 ?VB 在调用函数(Function )时,必须在函数名后跟一对括号。 ?VB 对白兰地使用范围重新做了规范,在 Basic 里把隐含变量都当作 全局变量,而在 VB 里对隐含变量都当作局部变量。 ?VB 里的说明语句(Declare ) ,仅支持动态链结库(DLL )的子程序 和无变量函数。 ?使用数组,必须事先用 Dim 或 Redim 进行定义。 二、注释语句 在使用注释语句之前必须先了解注释的作用, 注释不仅仅是对程序的 解释,有时它对于程序的调试也非常有用,譬如说可以利用注释屏蔽 一条语句以观察变化,发现问题和错误。以后注释语句将是我们在编 程里最经常用到的语句之一。 在 VB 里,注释语句有两种,一种是用“Rem”关键字,这跟 DOS 里的 批处理文件的用法一样,还有一种是利用单引号“’”,例如:‘ Dim a As String 与 Rem Dim a As String 的作用是一致的。 三、长语句的分行 在比较早的版本中,因为没有象 C 等语言用“;”隔开语句与语句, VB 的语句是必须写在一行里的,不过后来版本的 VB 里如许用分行符 “_”把一个长语句分成若干行来存放。 四、条件语句 如果你学过任何一种编程的话,都会知道在程序里控制其流程 的有两种语句,条件与循环, VB 自然也不例外,其实不管哪种 语言, 条件和循环的样子都差不多, 只不过各有各的规矩罢了。 在条件语句里,我们先来学习“If??Then??”语句。 它的一般语法是: If <条件> Then <语句> <语句> ??? End If 与 C 语言不同, VB 的条件语句更符合英语的语法,如果 Then 后面所跟的语句只有一条,可以写成: If <条件> Then <语句> 而不用 End If。 有时我们还会用到 If <条件> Then <语句> Else <语句> End If 更可以在 Else 里在嵌套 If 语句,如: If <条件> Then <语句> Else If <语句> Else <语句> End If 所有这些可以用一个表格表示: 用了过多的 Else 后你会感到很不方便, 而且程序结构也不清晰, 所以大多数的语言还有 Select 语句帮助解决这个问题。 VB 里的 Select 语句的格式是这样的: Select Case <变量名> Case <情况 1=""> ?? Case <情况 2=""> ?? Case <情况 3=""> ?? ?? ?? Case Else ?? End Select 例如: Select Case a% Case 1 Print “a=1” Case 2 Print “a=2” Case Else Print “a does not equal to 1 or 2.” End Select 五、循环语句 循环结构是计算机语言里一种重要的结构,它的应用广泛,最 简单的例子是累加器的作用,还可以用于穷举法,更直观的例 子是把某件事重复指定的次数,这样就不用把要重复的语句输 入多次,而通过循环结构完成,非常方便。 C 语言里有一个“for”循环语句, VB 里也有“For”关键字, 作用也差不多,只是 VB 的“For”语句更容易理解。它的格式 是: For <循环变量>=<初赋值> To <终值> [Step <步长>] ?? ?? Next <循环变量> 在默认情况下, Step 被设为“1”,可以省略, Step 也可以设 为负值,例如: Dim a=0 For I=1 To 10 a=a+I Next I 这是一个最简单的累加器的例子, 把 1到 10累加在一起, 然后 赋值给“a”这样的效果和上面是一样的,只不过是倒着加罢 了,请看: Dim a=0 For I=10 To 1 Step – 1 a=a+I Next I While 语句也是一个很常用的循环语句,它的形式很多。 ?Do While …… Loop语句 ?While …… Wend 语句 ?Do …… Loop While While 后面都跟逻辑条件判断,“Do While ?? Loop 语句”和“While ?? Wend 语句”作用相似, 都是先判断 While 后面的条件是否为“真”,如果 为“真”则执行里面的语句,如果为“假”,则退 出循环,循环直至条件为“假”终止。“Do ?? Loop While ”与前两者的区别在于,它不管条件的 真假,都会先执行“Do”后面的语句,也就是说, 它至少执行语句一次。 与 While 用法相似的还有 Until 语句,它是直至条 件为真则终止循环,句式把 While 上述三个语句的 While 换成 Until 即可,但是因为容易记混,所以 我建议只用 While 即可。 Until <条件>可以相当于 While Not <条件>。 For 循环和 Whlie 循环应当根据适当的环境使用, 它们有时也可替换。 六、运算操作 1. 数学运算 ?+:加法运算,也适合于字符串的之间的合并运算。 ?-:加法运算。 ?*:乘法运算。 ?/:除法运算。 ?\:整除运算。 ?Mod :求余运算。例如:a Mod b表示 a 被 b 整除以后的余数。 ?^:幂运算。 A^B表示以 A 为底的 B 次方。 1. 关系运算 关系运算也称比较运算, 它表示不等式的真或假, VB 共提供六种运算 符,分别是 =(等于), >(大于), <(小于),>=(大于等于), <=(小于等于)和>=(小于等于)和><>(不等于)。 2. 逻辑运算 逻辑运算是对真或假的运算,我将列表说明: T――True F――False 七、 数据与定义 本标题的内容已经在上一章向大家详述过,在这里就不再重复。 八、函数与过程 函数与过程有许多相似的地方,它们之间最大也是最本质的区 别就在于,函数有一个返回值,而过程只是执行一系列动作, 所以可以简单的把函数理解成为一个变量, 而 VB 中的每个事件 都是一个过程,比如 Command1_Click()就是一个过程。 因为在程序设计中经常会有重复的地方,所以把它做成一个函 数或一个过程,在使用时进行调用,可以节省大量的输入代码 的时间, 而且使用函数和过程也便于程序的结构化和修改查看。 函数和过程都可以有参数,也可以没有参数。 关于函数和过程将在以后的章中配合实例讲解, 请您继续 VB 教 程。 第四章 按钮(一) 从本章开始我们将正式进入 VB 的编程世界,但这还仅仅是个开端,要 编出功能强大的软件,还要学很多东西,那就要看以后的 VB 高级教程了, 我也得努力学啊! 按钮是我们在 Windows 操作见到最多的控件,它们有着各种各样的功 能:“确认”、“取消”、“下一步”等等,这些都是按钮的表现,另外 还有很多图形话的按钮,其实它们并没什么不同,所有的按钮都是通过单 击(click )事件实现的,只不过是在外表不同罢了。下面就让我们建立一 个最简单的按钮, 双击工具箱的 CommandButton , 将在窗体上建立一个形如 图 4-1的按钮,它的缺省名(Name 属性)为 Command1,我们可 以把它改名为 cmdExit ,把 Caption 属性设为“退出”, 然后双击,按钮填 写代码: Private Sub cmdExit_Click() Unload Me End Sub 按下 F5或者工具条上的播放按钮,运行程序。图 4-2当你按下退出 按钮的时候, 就会自动退出程序, 原因是当你单击按钮时激活了它的 Click 事件,执行“Unload Me”语句,使得窗体被卸载。 上面举了一个比较简单的例子,下面的例子稍微复杂些: 新建窗体,控件布局如图 4-3所示,包括一个 List 控件,一个 Text 控件和两个按钮(Command1和 Command2), (比较简单的程序我们都采 用缺省名),对它们属性做如下修改: 把使用 Button1的 Enabled 属性设为 False (假) , 是使程序在初始时, 无法单击 Command1。按 F5,运行程序,图 4-4,复原按钮成为灰色,不可 选。 当然现在程序还什么也不能做,下面我们在程序中添加代码: 首先在 General 里声明全局变量: Dim StoreString As String '用来储存字符串 ※注意:为什么用全局变量? VB 里每一个小过程都相当于一个程序,程序里的变量称为局部变量,是只 能在程序内部使用的,而当程序调用结束后,由于从内存中被清除,所以 变量储存的值也就消失了,这里的全局变量是用来在过程中传递字符串。 接着填写以下代码: Private Sub Command1_Click() Text1.Text = StoreString Command1.Enabled = False End Sub Private Sub Command2_Click() StoreString = Text1.Text Text1.Text = Command1.Enabled = True End Sub 运行程序,如图 4-5。按下“清除”,文本框被清除,按下“复原”, 文本有被恢复,许多程序中的 Undo/Redo就是利用这个原理实现的,现在 知道为什么内存越多越好了吧。 我们在把程序修改一下, 把 Button2删除, Button1的 Enabled 属性改 为 True , Caption 改为“清除”,填写代码: Private Sub Command1_Click() If Command1.Caption = StoreString = Text1.Text Text1.Text = Command1.Caption = Else Text1.Text = StoreString Command1.Caption = End If End Sub 同样可以上面的功能,但是却少用了一个控件,控件使用少的程序启 动会快些。 下面的例子要更加复杂些,大家一定都用过 Windows 附件中的计算器, 它是一个标准的科学计算器, 利用 VB 我们也可以做到, 只是没有那么复杂, 四则运算而已。 先建立一个新的项目文件,里面包含一个 Form1的窗体。然后,添加 控件,包括一个 Text 框(Text1),和 17个按钮,这 17个按钮使用的名 称都是 Command1,只是 Index 属性不同,就好象一个数组,创立一组按钮 的方法是,先在窗体上建立一个按钮(Command1),然后在 Command1上击 鼠标右键,选择复制(Copy ),然后在窗体上任意部位击右键,选择粘贴 (Paste ),系统会提示是否创建控件组,选择“是”,重复上面步骤,直 至创立 17个按钮为止。各控件属性如下表: 如果想改变一些其他的属性, 比如字体, 可以自己定义一下 Font 属性, 如果相对多个控件的共同属性进行改变,可以在窗体上按下鼠标,拖动, 把多个控件一起选定,然后对它们的共同属性进行修改。 别看这个东西小,还费了近我两个小时呢,不觉大叹手生,里面也有 些地方很绕弯子,我尽量解释清楚。 在编写程序之前,我们先来回顾一下计算器的使用。 1. 按下数字键在液晶屏上会出现数字,这是最基本的功能。 2. 第一次按下运算键,再按下数字键,将重新输入第二个数字,再次按 下运算键,将算出前两个数的结果,然后按下数字键,将又重新输入 新的数字。 3. 输入数字后,按下“等于键”将仍输出原来的数字,输入运算符和第 二个数字后在按下“等于” ,将得到二者的结果。然后又重复第二、 三步。 4. 按下“清除” ,数据被全部清除。 了解了这些,我们一步一步实现。 先实现数据的输入,请看代码。 与未创立组的控件相比,它的事件里多了 Index 参数,组里所有的对 象都使用同一个事件。 先在 General 里声明窗体级全局变量: Dim Num1, Num2 As Single Dim StrNum1, StrNum2 As String Dim FirstNum As Boolean ' 判断是否是数字开头 因为 Text1里是存放字符串的,所以要把输入的数据进行运算,必须 把字符型变量转变为实型变量,分别用 Num1、 Num2和 StrNum1、 StrNum2进行存放。 在 Form_Load事件里给变量初赋值: Num1 = 0 Num2 = 0 StrNum1 = StrNum2 = FirstNum = True 因为 17个按钮使用的是同一事件,所以我们用一个 Select Case语句 区分各个按钮,双击任意按钮输入代码: Private Sub Command1_Click(Index As Integer) Select Case Index Case 0 To 9 If FirstNum Then StrNum1 = Str(Index)’实 型转字符型 FirstNum = False’初赋值 为假 Else ’非初赋值 StrNum1 = StrNum1 + Str(Index) End If Text1.Text = StrNum1’显示 <还有其他语句,等待插入> End Select End Sub 运行程序的话已经可以输入数据,下面我们来处理小数点。 在 General 里声明新的变量: Dim PointFlag As Boolean ' 判断是否已有小数点 我们知道小数点只能输入一次,一个数据中不能有多个小数点存在,所以 需要一个布尔变量做判断。 在 Form_Load里进行初赋值: PointFlag = False 在 Command 的单击事件里接着上面输入新的代码: Case 10 If Not PointFlag Then’如果没有小数点 If FirstNum Then’如果是第一个字符 StrNum1 = FirstNum = False Else StrNum1 = StrNum1 + End If Else ’已有小数点 Exit Sub’则退出单击事件 End If PointFlag = True Text1.Text = StrNum1 第四章 按钮(二) 下面会复杂一些,我们先跳过等号,而来处理四则运算: 先在 General 里声明新变量: Dim Runsign As Integer '储存运算符号 Dim SignFlag As Boolean ' 判断是否已有运算符号 然后在 Form_Load中进行初赋值: Runsign = 0 SignFlag = False 在接下的 Command1_Click中继续输入代码: Case 12 To 15 FirstNum = True’使下一次可以输入新数据 PointFlag = False ' 还原标记值 If SignFlag Then’前面已有运算符未运算 Call Run Else SignFlag = True StrNum2 = StrNum1’把字符串 1复制 给字符串 2 StrNum1 = End If Runsign = Index - 11 ‘储存键入的运算符 里面运算的部分我用了一个过程,是因为在按下等号时还会调用到运 算过程,这样可以减少代码的输入,也使程序便于浏览。建立过程 (Procedure ) , 可以在 General 部分直接输入, 也可以通过菜单里的“Add Procedure”添加。 Run 的代码如下: Sub Run() Num1 = Val(StrNum2) Num2 = Val(StrNum1) Select Case Runsign Case 1’加 equal = Num1 + Num2 Case 2’减 equal = Num1 - Num2 Case 3’乘 equal = Num1 * Num2 Case 4’除 equal = Num1 / Num2 End Select StrNum2 = Str(equal) StrNum1 = StrNum2 Text1.Text = StrNum2 End Sub 下面是其余的代码:(在 Command1_Click事件里,接着写 ) Case 11 If Not SignFlag Then Text1.Text = StrNum1 equal = Val(StrNum1) FirstNum = True PointFlag = False Else Call Run SignFlag = False End If Case Else’清除按钮 Call ClearData 里面又用到了一个 ClearData 过程,实际上就是 Form_Load里的变量初赋 值,代码如下: Sub ClearData() Num1 = 0 Num2 = 0 StrNum1 = StrNum2 = FirstNum = True PointFlag = False Runsign = 0 SignFlag = False Text1.Text = End Sub 这样完整的程序就完成了,本章介绍了 VB 的第一个控件――按钮,并且举 例,希望你继续看下一章――菜单。 下面给出完整的程序代码: Dim Num1, Num2 As Single Dim StrNum1, StrNum2 As String Dim FirstNum As Boolean '判断是否是数字开头 Dim PointFlag As Boolean '判断是否已有小数点 Dim Runsign As Integer '储存运算符号 Dim SignFlag As Boolean '判断是否已有运算符号 Sub ClearData() Num1 = 0 Num2 = 0 StrNum1 = SignFlag = False Text1.Text = Sub Run() Num1 = Val(StrNum2) Num2 = Val(StrNum1) Select Case Runsign Case 1 equal = Num1 + Num2 Case 2 equal = Num1 - Num2 Case 3 equal = Num1 * Num2 Case 4 equal = Num1 / Num2 End Select StrNum2 = Str(equal) StrNum1 = StrNum2 Text1.Text = StrNum2 End Sub Private Sub about_Click() MsgBox End Sub Private Sub Command1_Click(Index As Integer) Select Case Index Case 0 To 9 If FirstNum Then StrNum1 = Str(Index) FirstNum = False Else StrNum1 = StrNum1 + Str(Index) End If Text1.Text = StrNum1 Case 10 If Not PointFlag Then If FirstNum Then StrNum1 = FirstNum = False Else StrNum1 = StrNum1 + Else Exit Sub End If PointFlag = True Text1.Text = StrNum1 Case 12 To 15 FirstNum = True PointFlag = False ' 还原标记值 If SignFlag Then Call Run Else SignFlag = True StrNum2 = StrNum1 StrNum1 = End If Runsign = Index - 11 Case 11 If Not SignFlag Then Text1.Text = StrNum1 equal = Val(StrNum1) FirstNum = True PointFlag = False Else Call Run SignFlag = False End If Case Else Call ClearData End Select End Sub Private Sub Form_Load() Call ClearData End Sub 补充说明 按钮还有两个重要的属性 Default (默认属性)和 Cancel (取消属性), 两个属性都以布尔赋值,把 Default 设为 True ,则在按下回车键时,不论 焦点处于何处,都会触发该按钮的 Click 事件,而当 Cancel 属性被设为 True ,在按下 ESC 键时,该按钮的 Click 属性发生。下面举个例子: 建立一个新窗体和两个按钮, Name 属性分别为 cmdOK 和 cmdCancel ,把前 者的 Default 设为 True ,后者的 Cancel 设为 True , Caption 属性分别为 OK 和 Cancel 。如图 4-8。填写代码后运行: Private Sub cmdCancel_Click() MsgBox End Sub Private Sub cmdOK_Click() MsgBox End Sub 结果如图 4-9、 4-10: 快捷键大家一定都知道,在 VB 如何实现呢。其实很简单,在刚才的例子里 在建立一个按钮 Command1,把它的 Caption 属性设为 Click &ME,如图 4 -11,在 M 的下面有一条下划线,运行程序,当你按下 Alt+M的时候就触 发了 Command1_Click事件: Private Sub Command1_Click() MsgBox 据我所知,有许多用户有使用快捷键的习惯,注意细节上的问题能够使将 来你的程序得到更多人的欣赏,不是吗? 第五章 菜单 我们经常在 Windows 操作里遇到各种各样的菜单,菜单的操作把各种 命令结构化、分分类化,也节省了命令所占的空间,从作用上来讲,菜单 类似于按钮,但它只有一个事件――Click。 VB 作为 Windows 下的可视编程工具, 菜单的设计当然很容易实现, VB3.0按下 Ctrl+M, VB4.0以上的版本请按下 Ctrl+E, 便可呼叫出菜设计的窗口, 无论 VB 的版本,这个窗口的样式是大同小异的,请见图 5-1。 前面说过,菜单相当于简单的按钮,它有几个属性,其中的大部分我 们都曾经见过, 包括 Name 、 Caption 、 Index 、 Checked 、 Enabled 、 Visible 、 快捷键和热键等等。 其中 Name 是必须的。 下面请跟我一起设计第一个菜单。 首先在 Caption 添入“文件”, Name 为“mnuFile”, 按下 Next 按钮, 这样就建立了第一级菜单,注意菜单设计窗口的左中有四个箭头,按下向 右的箭头,出现了一排小点,如图 5-2,在 VB 里这叫缩排,这样就可以开 始建立第二级菜单。 小知识:实际上我们在生活就中经常用到缩排,写文章时开头 要空两格就是一种缩排,在编写程序时更需要缩排,这样使程 序结构化,便于观察,当然菜单设计里的缩排有更多的用处。 接着填写下一菜单项, Caption 为“新文件”, Name 为“mnuFileNew”, 按下 Next 键。 小知识:VB 一共如许建立 6级子菜单,如图 5-3,尽量不要建 立这样的菜单,要知道藏在越深处的菜单项越难以被人发现, 一个友好的程序界面应该让用户马上找到需要的命令。 接着重复以上步骤,创建以下三个菜单项: 我们在菜单里还经常看到把不同项分开的分隔条,在 VB 里也很容易做 到,把 Caption 设为“ -”(减号), Name 为 mnuBar1。最后增加这个菜单 条的最后一项, Caption 为“退出”, Name 为 mnuFileExit 。现在可以退出 菜单设计窗口,菜单如图 5-4。 怎么样, 经过几章的学习, 是不是觉得 Windows 世界也不是那么神秘? 也对,也不对。的确,我们很轻易的实现了这么多的功能,但如果你仔细 想想,我们的程序还什么也不会做呢!可以说是徒有其表,要实现强大的 功能,恐怕要学很长很长时间,而现在仅仅是个开头,并不是想入非非的 时候,我们还要继续努力! 现在再次按下 Ctrl+E,重回菜单设计窗口,接着添加菜单。(按下向 左的箭头,可以使菜单上升一级, Level 代表菜单的级别),根据下表添加 新的菜单项: 其中 Short-Cut 就是平常我们说的热键,你可以在菜单设计窗口中找 到,设置一个你需要的组合键,这样不论窗口的焦点处于何处,菜单在第 几层,只要按下热键,就相当于调用了该项的 Click 事件。结果如图 5-5。 从 Win95以来程序里引入了鼠标右键功能,使鼠标有了更大的用处, 在 VB 里我们也很容易实现。 打开 Form_MouseDown事件,该事件有两个参数:Button ,当按下左键 时 Button 返回 1,当按下右键时 Button 返回 2,; Shift ,是指在点击鼠 标时按下的键盘键,如 Shift 、 Ctrl 、 Alt ,这些我们将在以后讨论,但很 难避免在一章中不涉及到不该涉及的内容,学习时有个大概的理解即可。 下面在该事件里添加代码(效果如图 5-6): Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) If Button = 2 Then PopupMenu mnuEdit, vbPopupMenuLeftAlign Else Exit Sub End If End Sub 在上面的代码中我们用到了 PopupMenu 方法,它的语法是: object.PopupMenu 菜单名,标记, X 坐标, Y 坐标 标记是用来表明弹出菜单位于鼠标指针位置的,它有三个值: X 、 Y 值可以用来制定菜单弹出的位置,可以省略。 关于菜单的 Visible 、 Enabled 等属性请自己尝试。 第六章 输入(一) 我们为什么要设计计算机程序呢,当然是为了计算机能为我们完成工 作,但是要完成不同的任务,我们就必须对计算机下达命令,然后计算机 在把信息返馈回来――任务是否完成。以上就是所谓的人机对话或交互功 能,尤其是在 Windows 操作里我们需要进行更多的输入工作,我们需要填 写各种各样的表格,设置程序的重要参数,把数据输入给计算机,再又它 完成既定的工作就是今天我们本章要重点讨论的问题――在 VB 中如何建立 完整的输入机制。 在 VB 中提供了一个函数 InputBox 能帮助我们建立一个最简单的输入 窗体,语法如下: InputBox (prompt[,title][,default][,xpos][,ypos][,helpfile,context]) 该函数返回一个字符串表达式,其参数含义为:(“[]”表示可缺省) prompt――字符串表达式, 最大长度为 1024字符, 窗体上的提 示部分。 Title――字符串表达式,显示标题栏里的文本。 Default――字符串表达式,窗体中文本框的缺省值。 xpos ,ypos――数值表达式,以 Twips 为单位指定窗体出现在 屏幕上的位置。 helpfile――字符串表达式,是帮助文件的完整路径。 Context――数值表达式,指定适合的帮助主题。 可能你看了上面的说明并不明白,那么下面我们就用 Input 语句完成一个 最简单的程序。 小知识:屏幕坐标 在计算机的屏幕上也有一个类似于我们在中学里常用到的直角 坐标系,之不过它的原点不在左下,而是在屏幕的右上角,屏 幕的最右上方坐标为(0, 0),它的横坐标和我们的习惯是一 致的,而纵坐标则是越向下越大,不仅是屏幕,所有的对象里 都是一样,需要记清。见图 6-1 新建一个项目(project ),在 Form_load里填写一行代码: a$ = InputBox( 按下 F5运行程序,在 Form1出现之前先会弹出一个输入对话框,如图 6-2。这时,无论你按下 OK 还是 Cancel 都是没有区别的,因为我们并没 有对输入数据进行处理,下面我们完成一个更加复杂些的程序。 新建一个项目文件,把窗口布局成类似于图 6-3的结构,各对象属性如下 表: 本例中出现了一个 Frame1控件,它是一种框架,可以用来把窗体分成 好几个部分, 首先应该在窗体上画出 Frame1控件, 然后再选择相应的控件, 在 Frame1上描出轮廓,使其是出现在 Frame1之上,本例中除去两个按钮, 其余都在 Frame1上面。本例中用到了几组控件数组,其创建方法是,在选 定的点右键,选择 Copy ,再在窗体其他部位单击右键,选择 Paste 即可, 注意, 若要使粘贴的对象在 Frame1上, 请在 Frame1上单击右键选择 Paste 。 我们通过这个窗体,对输入框进行完整的控制,原理是这样的:当我 们把窗体中要填写的对输入框的参数完成后按下 OK 按钮,就会出现我们设 计的那个输入框,我们从输入框退出时则返回我们投票的结果,代码如下 . 窗体初次被装入时, Label1(3)、 Label(4)和 Text1(3)、 Text1(4)的 Enabled 属性都是 False ,我们需要通过改变 Check1的 Value (1,被选中, 0,未选中)是他们有效或无效。 声明全局变量(General ): Dim PosChk As Boolean ' 检查 X 、 Y 坐标是否有效 Check1_Click 事件: Private Sub Check1_Click() If Check1.Value = 1 Then Label1(3).Enabled = True Label1(4).Enabled = True Text1(3).Enabled = True Text1(4).Enabled = True PosChk = True Else Label1(3).Enabled = False Label1(4).Enabled = False Text1(3).Enabled = False Text1(4).Enabled = False PosChk = False End If End Sub 接着在按钮中填写代码: Private Sub Command1_Click(Index As Integer) Dim Prompt, Title, Default As String Dim xPos, yPos As Integer Select Case Index Case 0 Prompt = Text1(0).Text Title = Text1(1).Text Default = Text1(2).Text If PosChk Then xPos = Val(Text1(3).Text) yPos = Val(Text1(4).Text) a$ = InputBox(Prompt, Title, Default, xPos, yPos) Else a$ = InputBox(Prompt, Title, Default, xPos, yPos) End If Label1(5).Caption = Case 1 Unload Me End Select End Sub 按下 F5运行程序,你会看到这样的结果。图 6-4, 6-5。是不是有种受骗 的感觉,啊哟哟,可不是我的错,就是这么容易嘛! 从刚才的例子里,我们接触了一些 VB 中的输入方法,其实数据输入不 仅仅局限于向 Text 框中输入数据,数据的输入还有许多其他的方法,譬如 前面的 Check1也是向程序发出一定的信息,只要是通过操作向计算机发布 命令就可以叫做输入,下面我们来一一介绍。 首先要介绍的当然是输入用到最多的 Text 框。 Text 没有 Click 事件, 它的缺省事件是 Change , 也就是当 Text 框里的一旦内容改变就会激发该事 件发生,还是让我们用实例说话吧。 Text 有几个特殊的属性,一是 MultiLine (多行)属性, MultiLine 属 性为 False 的时候,不论文本有多长,它都会在一行里显示下去,换行符 无效,当它为 True 的时候,字符串显示到 Text 框边缘的时候就会自动换 行。另一个与之配合的属性是 ScrollBars 属性,它有 4个值, 0到 3,分 别是没有滚动条,水平滚动条,垂直滚动条,和二者都有,它是一个只读 属性,也就是说只有在程序设计过程中才能改变,而不能在程序运行中改 变,但是我们可以通过 API 解决运行中改变的问题,我们放在以后再讲。 PasswordChart 属性, 我们经常在程序操作中遇到要填写密码的部分, 为了 保密起见,在屏幕上显示的字符一般“*”表示,并且这时是无法用剪贴板 的,这在 VB 中非常容易做到,把 PasswordChart 中设一个用来代替字符串 的字符即可,并不一定是“*”哦。 下面我们完成一个有趣的小程序,是我以前遇到过的一个程序,我对 其进行了部分修改。程序的意思是这样的,假设你是一个司机应超速被警 察扣留,现在需要你向警察陈述你的理由,如果你的话能打动他,就可以 免交罚金,如果你在规定的字数里没有说出什么有震撼力的话,那老兄你 可就惨了,交钱吧。 J 这个程序比原来的英文程序有了几点不同,第一,由于用到的是双字 节中文的中文,所以对于检测中文字符和英文有很大不同,第二,原来的 英文程序不管你说多少, 警察依然是依法从事, 本例中给了犯规者 10%的免 罚机会(有点无聊??L ,不过也是为了学一些东东嘛)。下面就跟我来 设计窗体吧。(如图 6-6) 三个图片框 Picture1-3的 Picture 属性分别为绿灯,黄灯和红灯, 这些图标在 VB 目录下的 Graphics\Icons\Traffic下(VB5),或是 VB 目 录下的 Icons\Traffic下(VB4、 VB3),你还可以为 Label1在 Font 属性 里选一个合适的字体和字重。下面我们来看代码: 首先初始化程序: Private Sub Form_Load() ' 把 Command1放在水平的中央 Command1.Top = Label2.Top+200 Command1.Left = (Form1.Width - Command1.Width) / 2 ' 重叠三个图片框 Picture2.Left = Picture1.Left Picture2.Top = Picture1.Top Picture3.Left = Picture1.Left Picture3.Top = Picture1.Top End Sub 下面我来讲一讲程序是怎样运行的,我们将用到 Text 的 Change 事件, 每当字符串改变一次就对它进行一次检查,算出已经说的字数,当字数超 过 10时,下面的红绿灯会变成黄色,并且在这时随机抽取一个数,它在一 个范围内出现的可能是 10%, 如果在这个范围内就可以免交罚金, 如果不在 范围则继续,当文字超过 20的时候,红绿灯会变成红色,再一次抽取随机 数字,步骤同上,如果 30个字已满,再进行一次检查,如果你真的那么不 幸就该罚款了。 程序的步骤清楚了,我们在来看看程序的要点。由于中文是双字节字 符,也就是说一个汉字占两个 ASC 码的位置,而 VB 显然是为英语国家设计 的用 Len 函数无法返回汉字字节,也就是说一个汉字和和一个 ASC 字符在 Len 函数中得到的值是一样的,这就需要特殊处理。用 Asc ()函数,在括 号内放入一个 ASC 字符或字符串,它会把第一个 ASC 码转化为 0-255的数 值,而把一个汉字放入,它的值必然不在 0-255,这也就可以作为判定汉 字的基础。我们可以把英文算作半个汉字。 第六章 输入(二) 下面我们来看看代码: 在 General 里声明窗体级变量: Dim Level As Integer Private Sub Command1_Click() Unload Me End Sub Private Sub Text1_Change() Dim StrLength As Integer’字符串长度 Dim RandomNum As Single’随机数 Dim Str1 As String Dim a As String Dim i, Temp StrLength = 0’每次开始时把字符串长度还原为 0 a = Text1.Text For i = 1 To Len(a)’ Len(a)代表字符串的长度 Temp = Asc(Mid$(a, i, 1))’挨个取字符 If Temp > 255 Or Temp < 0="" then’不是="" asc="" 码="" strlength="StrLength" +=""> Else StrLength = StrLength + 1 End If Next i StrLength = StrLength / 2 Select Case StrLength Case 0 To 9 Picture1.Visible = True Picture2.Visible = False Picture3.Visible = False Label2.Caption = Case 10 To 19 If Level = 1 Then RandomNum = Rnd * 10’得 到随机数 If RandomNum <= 10="">=> RandomNum > 9 Then Text1.Enabled = False Label2.Caption = Command1.Visible = True Command1.Caption = End If Level = 2 Else Picture1.Visible = False Picture2.Visible = True Picture3.Visible = False Str1 = End If Case 20 To 29 If Level = 2 Then RandomNum = Rnd * 10 If RandomNum <= 10="" and="" randomnum=""> 9 Then Text1.Enabled = False Label2.Caption = Command1.Visible = True Command1.Caption = End If Level = 3 Else Picture1.Visible = False Picture2.Visible = False Picture3.Visible = True Str1 = Label2.Caption = Str1 & 你还有 StrLength) & End If Case Else Text1.Enabled = False Label2.Caption = Command1.Visible = True Command1.Caption = End Select End Sub 中间有几个函数需要解释一下: Mid 可以从字符串中取出一部分,返回字符型,格式 : Mid(字符串 , 从第几个字符开始 , 取字符的长度 ) Asc 可以把字符转换为 ASCII 码,格式: Asc(字符串 ) Rnd ,取得大于 0但小于 1 的数值,可以没有参数。 怎么样,十分简单吧,我们将在下一次继续讨论 VB 的输入机制! 在继续上面的内容时,我想再回顾和强调几个在字符串操作中经常函 数: 先是几个已经接触过的, Mid(), Asc(), Len(),它们的语法分别是: Mid(字符型,起始字符,长度 ) 返回子字符串,如果从字符串的第一个字符取起, 起始字符为 1, 依此 类推。 Asc(字符型 ) 返回数值,如果参数不是一个字符,而是字符串(多个字符),将返 回参数的第一个字符 ASCII 值。 Len(字符型 ) 返回字符串的长度。 下面我再为你解释几个新的函数: Left(字符串,长度 ) 将返回字符型,从字符串的第一个字符向左取字符串,与之相对应的 是 Right(),它将从字符串的最后一个字符向右取字符串。 Chr(数值型 ) 该数值范围从 0-255,返回字符型,如 Chr(65)可返回字符“ A ”,这 样可以输入一些用键盘无法输入的字符。 Str(数值型 ) 该函数把数值型转换为字符型, 也许你觉得数值 “ 123” 和字符串 “ 123” 没什么区别,但在内存中一个 ASCII 字符是占一个字节,也就是说字符串 “ 123”占 3个字节,而当数值“ 123”是整型时,它占两个字符,当它是 一、打开程序: 点击桌面上的 Visual Basic 图标,在弹出的如图一的窗口中选择“创建标准 EXE”按钮。 图一 确定后的状态如图二 图二 这就是创建了一个新的“标准 EXE”文件了。 二、工作界面简介: 默认的 VB 工作界面由标题栏(1)、菜单栏(2)、工具栏(3)、工具箱面板(4)、程序设计区(5)、项目窗口(6)、属性窗口(7)、布局窗口(8)组成,至于它们具体有什么作用,我们将在以后的实例学习中接触,这里就不予以说明。 三、编写我的第一个应用程序: 、应用程序要产生的效果: 创建的应用程序要有什么样的功能?这是开发每一个应用程序必须最先想到的。 我们的第一个应用程序非常简单,使用者只需点击程序上的一个按钮,程序界面上就会显现“跟我来学 VB 神童教程”字样。 、开发思路: 根据应用程序要实现的功能,那么我们至少需要制作一个按钮、一个程序界面,为了让应用程序更规范,我们还需要创建一个用来显示“跟我来学 VB 神童教程”字样的容器。 、具体制作过程: 1、创建一个新的“标准 EXE”文件,如第一步所做。 需要指出的是,这个以 Form1 为标题栏的程序界面就是我们需要的“程序界面”,也是用户首先看到的对象,所以尽可能将其做得美观一点。 当然,对应用界面的美化问题我们将在以后探讨。 2、根据开发思路,现在我们来制作按钮。 双击工具箱面板上的命令按钮(Command Button)图标,如图三: 图三 然后你会发现程序界面上多了一个命令按钮,如图四: 图四 用鼠标拖动新建的按钮到适当位置,如图五: 图五 再创建一个标签按钮,双击如图六的图标: 图六 完成后程序界面如图七: 图七 用鼠标拖动标签按钮到合适位置,如图八: 图八 将鼠标放在标签按钮左右边缘任意一处,当鼠标呈左右键头时横向拖动,把标签按钮拖长,最后的程序界面如图九: 图九 3、对按钮属性进行设置: 开发任何应用程序,在完成界面布局后,应该就每一个元素进行属性设置以达到自己的要求。 当然,也可以在元素布局的过程中进行属性设置。 首先点选箭头状的“选择”图标以便进行选择,如图十: 图十 选中程序界面上的命令按钮,然后找到属性面板,如图十一: 图十一 其中,“名称:Command1”是此按钮的名称,主要用于程序引用,所以不要用中文名字。 此处,可以不修改按钮的名字,但为了程序更规范,我们将其名字改成“CmdShow”,如图十二: 图十二 “Caption:Command1”是命令按钮的标题,也就是显示在命令按钮上的字样, 我们将其改成“显示”,如图十三: 图十三 用上面的方法,我们将标签按钮的名字改为“LblShow”,如图十四: 图十四 将标签按钮的标题改成空字符串,也就是没有任何文字,如图十五: 图十五 4、输入程序代码: 我们前面讲到的元素布局、属性设置只不过是对应用程序操作界面的定制,要让程序实现功能,关键还得输入程序代码。 选中命令按钮 CmdShow ,然后双击它,弹出如图十六的程序代码输入窗口: 图十六 在光标闪烁处输入代码:LblShow.Caption = 图十七 输入完毕,点击右上角的 “X” 回到对象窗口,然后点击工具栏上的“启动”按钮(快捷键:F5),可以看最终结果了! 四、知识点: 1、我们的第一个程序确实非常简单,但它道出了程序设计的基本方法:首先,应用程序要用来做什么?也就是开发应用程序的目的;其次,应用程序大体上由哪些元素组成?也就是应用程序的操作界面如何,如果可能,最好先用笔把程序界面画出来;然后是对程序界面中每一个元素的属性进行设置;最后输入程序代码和调试。 2、前面我们所谈到的“命令按钮”、“标签按钮”,其实它们准确的说法是“命令按钮控件”、“标签按钮控件”,无论是这些控件,还是刚才作为应用程序界面的“窗体”,都是“对象”,因此, VB 是一门面向对象的编程语言,每一个对象都具有很多属性,如大小、位置、标题等等。属性的设置通过属性窗口完成。 3、这一点的内容不需强记,在以后的控件讲述中将会涉及。 除了“命令控钮控件”、“标签按钮控件”,默认的工具箱面板上还有“指针”工具(用来选择程序设计窗口中的对象)、图片控件(在界面上添加图片)、文本框控件(在界面上显示文本或用来输入文本)、选项框控件(主要用来作为区域划分的控件,一般把相同类型的控件放置在一个选项框中,把其他类型的控件放在其他选项框中)、复选控件(用来制作复选按钮)、单选控件(制作单选按钮)、组合框控件(用来制作功能更为强大的列表框,既有文本框控件的功能,还有列表框控件的功能)、列表框控件(制作各种列表)、滚动条控件(共有横向与竖直两种)、时钟控件(一般用来添加时间触发)、文件操作控件(共有磁盘列表框控件、文件夹列表框、文件列表框三种),另外,还有绘图控件、图像框控件、日期控件。 4、VB 提供了丰富的控件选择,除了默认的工具箱面板上的控件外,还有很多控件没有罗列出来,我们可以通过“工程‖部件”命令或在工具箱面板上单击鼠标右键,在弹出的快捷菜单中选择“部件”命令,弹出如图十八的窗口: 图十八 本窗口罗列了当前系统中所有的控件,只需选中所需控件前面对应的复选框就行了。5、编写程序应该养成好习惯,在给每一个对象命名时首先要保证规范,其次要能“望文生义”,也就是看见一个对象的名字就能知道它是做什么的,如前面我们给命令按钮控件起名为“CmdShow”,一看就知道是用来 Show 的 Command 类型控件。6、我们最初进入的程序设计界面是对象界面,进入代码界面的办法很简单,前面用到的双击控件是一种办法,另外还可以通过点击项目窗口中的“查看代码”按钮进入,如果点按旁边的“查看对象”按钮就会又回到原来的对象界面。如图十九: 图十九 7、在前面的例子:LblShow.Caption = 另外如:X = X+6 ,在数学中,这种表达式不存立,而在 VB 中,是指在 X 本来的基础上加 6 ,然后把结果重新赋给 X ,这时 X 的值不再是原来的数字,而是加上 6 后的值。 8、程序的保存: 在 VB 中进行保存,常常用“保存工程”命令,而在保存过程中,必须保存两次,一次是以 .frm 为扩展名的文件保存,另一次是以 .VBP 为扩展名的文件保存。前者是保存应用程序的窗体文件,后者是保存应用程序的工程文件。如图二十与图二十一: 图二十 图二十一 第一节——Label 控件 在第一章,我们已经知道,任何一个 VB 程序都是由操作界面及与之相应的程序代码组成,而操作界面则是由诸如“命令按钮控件”、“标签控件”等控件以及窗体共同组成。从本章开始,我们进入控件的学习过程。 Label(标签控件)是图形控件,主要作用在于显示文字信息,如大家比较熟悉的程序安装界面:在某个软件安装过程中,常常会显示一些帮助信息或与产品相关的介绍信息,而这些,大多是用标签控件制成的。 与以后我们要学到的文本框控件(TextBox)不同的是,标签控件显示的文字不能直接进行修改,要修改的话只能在设计阶段进行;文本框既可以用来显示文本,还能够在文本框中输入文本。 在 Visual Basic 工具箱中,标签控件的图标如图一所示。标签的默认名称(Name)和标题(Caption)为 LabelX(X为1、2、3,等等),规范的命名方式为:LblX(X为自己定义的詞,如 LblShow 、LblRed ,等等) 图一 一、标签控件的主要属性: 1、Caption(标题)属性: 此属性用来设置在标签上显示的文本信息,可以在创建界面时设置,也可以在程序中改变文本信息,如第一章的例子中,通过点击按钮改变标签显示的字样。 如果要在程序中修改标题属性,代码规则如下: 标签名称.Caption = 如第一章在程序中改变标签 LblShow 的 Caption 属性: LblShow.Caption = 但是请大家注意,上面的代码应该写入供触发的控件对应的程序代码区,如第一章中,是在命令按钮的程序代码区输入的代码,而不是标签本身的代码区哟。 这也是初学者常常大惑不解的地方,为什么我要让标签改变字样,却要在其他控件中输入代码?这是因为,我们是通过触发其他控件这个事件来让标签改变 Caption 属性的。 当然,你也可以让标签本身来触发 Caption 属性改变事件,如用鼠标点击标签,这时你就需要在标签对应的程序代码区输入代码了,但在实际编写中,这种情况非常罕见。毕竟,标签控件用于显示信息的本意远远超过了响应鼠标点击的意图。 2、BorderStyle(边框)属性: 本属性用来设置标签的边框类型,有两种值可选:0,代表标签无边框;1,代表标签有边框,并且具有三维效果,如图二显示的两个标签: 图二 BorderStyle 属性可以在设计界面时指定,如图三: 图三 也可以在程序中改变(但这种应用不多见),程序代码规则: 标签名.BorderStyle = 0/1(0或1,两者取一) 习题一:创建一个标签(LblShow)、两个按钮(CmdChange1、CmdChange2),点按 CmdChange1 ,标签有边框;点按 CmdChange2 ,标签无边框。 联想:在完成本题后,你可能会想到,有没有办法用一个按钮来完成本题的功能?即鼠标点击一下,标签有边框,再点一下,标签边框消除,再点一下,边框又出现,以此类推。回答是肯定的,不过,这是在以后的学习中要讲的。 答案:见本节最后的答案区。 3、Font(字体)属性: 本属性用来设置标签显示的字体,既可以在创建界面时设定,也可以在程序中改变。 在创建界面时设定,如图四: 图四 在图四的设置界面中,除了可以选择字体,还可以设置显示文字是否为粗体、斜体、下划线等。 在程序中改变 Font 属性,程序代码书写规则如下: 字体改变:标签名.FontName = 字体大小改变:标签名.FontSize = X ,其中,X 是阿拉伯数字,代表字体是几号字。如:LblShow.FontSize = 11 。 粗体(FontBold)、斜体(FontItalic)、下划线(FontUnderline)、删除线(FontStrikethru)属性的设置值是代表真/假的逻辑判断值 True/False ,如下: LblShow.FontBold = True/False LblShow.FontItalic = True/False 习题二:一个标签(LblShow)用于显示文本;按钮1(Cmd1)可以让标签显示的字体变成隶书;按钮2(Cmd2)可以让标签显示的字体变成 13 号字;按钮3(Cmd3)可以让字体变成粗体。 答案:见本节最后的答案区。 4、Alignment(对齐)属性: 此属性用来设置标签上显示的文本的对齐方式,分别是:左对齐,0;右对齐,1;居中显示,2。可以在界面设置时设定,如图五: 图五 也可以在程序中改变,代码如下: 标签名.Alignment = 0/1/2 5、Visible(可见)属性: 本属性在大多数控件中都有,它能设定该控件是否可见。当值为 True ,控件可见;当值为 False ,控件隐藏。 控件的可见属性可以在界面设置时设定,如图六: 图六 也可以在程序中改变,代码如下: 标签名.Visible = True/False 习题三:一个标签(LblShow),在界面设置时为可见;按钮1(Cmd1),能够让标签隐藏;按钮2(Cmd2),能够让标签显现。 答案:见本节最后的答案区 二、标签控件(Label)的主要事件: 所谓的事件,其实就是用户对应用程序的操作,如第一章中用鼠标点击命令按钮触发的 Click 事件。 事件的作用在于触发程序的执行,如第一章中的 Click 事件改变了标签控件的 Caption 属性。 标签控件的主要作用在于显示文本信息,但也支持一些为数不多的事件。 1、Click 事件(鼠标单击): 用鼠标点击标签时触发的事件,如改变标签的字体属性: Private Sub LblShow_Click() LblShow.FontName = 2、DbClick 事件(鼠标双击): 鼠标双击引发的事件,如改变标签的可见性: Private Sub LblShow_DbClick() LblShow.Visible = False End Sub 三、知识点: 1、用 VB 编写程序犹如搭积木,把每块“积木”(控件或其他对象)放在合理的位置,然后以某种机制(程序)将这些“积木”们运用起来,最后就搭成了我们需要的东西。所以,掌握每一种控件,包括它们的属性与主要事件,是我们学习编程的基础! 2、某些属性是大多数控件所共有的,如 Name 、FontBold、FontItalic、Visible ,等等;但也有些属性是某个控件所独有的,如标签控件的 WordWrap (标签的标题显示方式)。本节中我们只是讲述了部分标签控件的属性,其他属性可以在 VB 的帮助文件中查找到。 3、大家在学习过程中一定会疑惑,为什么在属性设置时,“=” 右边有时使用 4、字符的大小写问题:初学者还常常疑惑,字母什么时候应该大写,什么时候应该小写?其实,大写小写在 VB 程序中都是一样的,但为了让程序编写得更为规范,程序可读性更高,英文单词的第一个字母一般都要大写,如 Visible 、Name ,等等; 控件的命名也遵循以上原则,不同的是,命名都是由“控件类型名+具体名字”组成的,控件类型名的第一个字母要大写,具体名字的第一个字母要大写,如 LblShow 、CmdShow 、LblChange ,等等。 5、程序代码的规范:上面有这样的例子: Private Sub CmdShow_Click() LblShow.Caption = Private Sub CmdShow_Click()代表一个过程,共由两部分组成,CmdShow 代表 CmdShow 这个按钮,Click 代表这个按钮的触发事件。 以此类推,Private Sub LblShow_DbClick ()也代表一个过程,LblShow 是个标签,DbClick 是双击事件。 另外,Private 意为“私有”,表明这个事件过程的类型;此外还有 Public 即“公有”事件。 Sub 表明这个过程是“子程序”,若干个“子程序”共同组成最终的应用程序。 ()里面是用来装参数的,关于参数,我们以后讲述,如果没有参数,()里面为空。 四、答案区: 第一题: 第一个按钮的点击事件: Private Sub CmdChange1_Click() LblShow.BorderStyle = 1 End Sub 第二个按钮的点击事件: Private Sub CmdChange2_Click() LblShow.BorderStyle = 0 End Sub 第二题: 按钮1: Private Sub Cmd1_Click() LblShow.FontName = Private Sub Cmd2_Click() LblShow.FontSize = 13 End Sub 按钮3: Private Sub Cmd3_Click() LblShow.FontBold = True End Sub 第三题: 按钮1: Private Sub Cmd1_Click() LblShow.Visible = False End Sub 按钮2: Private Sub Cmd2_Click() LblShow.Visible = True End Sub 第二节——TextBox控件 在 Visual Basic 操作界面中,TextBox(文本框)控件所代表的图标如图一: 图一 TextBox 控件主要用来显示文本或用来输入文本,如 Windows 登陆时的“口令”窗口,或者记事本的整个编辑区域。 双击工具箱中的文本框控件或者单击文本控件,然后用鼠标在 VB 的工作区域拖拉,就可以创建文本框了。如图二: 图二 文本框控件的默认名称为 TextX(X为 1、2、3,等等),命名规则为 TxtX(X为用户自定义的名字,如 TxtShow、TxtFont、TxtColor ,等等) 一、文本框控件的主要属性: 1、Text(文本)属性: 本控件最重要的属性,用来显示文本框中的文本内容,可以在界面设置时指定,如图三: 图三 也可以在程序中动态修改,程序代码规则: 文本框控件名.Text = 如要在一个名为 TxtFont 的文本框控件中显示“隶书”字样,那么输入代码: TxtFont.Text = 习题一:创建一个文本框(TxtContent)用来显示文本;按钮一(Cmd1),点击时文本框内容变为“跟我来学VB神童教程”;按钮二(Cmd2),点击时文本框内容清空(也就是没有内容)。 答案:见答案区。 2、SelText(选中文本)属性: 本属性返回或设置当前所选文本的字符串,如果没有选中的字符,那么返回值为空字符串即 请注意,本属性的结果是个返回值,或为空,或为选中的文本。 一般来说,选中文本属性跟文件复制、剪切等剪贴板(在 VB 中,剪贴板用 Clipboard 表示)操作有关,如要将文本框选中的文本拷贝到剪贴板上: Clipboard.SetText 文本框名称.SelText(注意,本行没有表示赋值的等号。) 要将剪贴板上的文本粘贴到文本框内: 文本框名称.SelText = Clipboard.GetText(注意,本行有表示赋值的等号。) 例:一个文本框(TxtContent),按钮一(CmdCopy)用于复制文本框中的选中文本;按钮二(CmdPaste)用于将剪贴板上的内容粘贴到文本框内。 按钮一: Private Sub CmdCopy_Click() Clipboard.SetText TxtContent.SelText End Sub 按钮二: Private Sub CmdPaste_Click() TxtContent.SelText = Clipboard.GetText End Sub 3、SelStart 与 SelLength 属性: SelStart ,选中文本的起始位置,返回的是选中文本的第一个字符的位置。 SelLength ,选中文本的长度,返回的是选中文本的字符串个数。 例如:文本框 TxtContent 中有内容如下: 跟我一起学习 VB 神童教程 假设选中“一起学习”四个字,那么,SelStart 为 3 ,SelLength 为 4 。 4、MaxLength(最大长度)属性: 本属性限制了文本框中可以输入字符个数的最大限度,默认为 0 ,表示在文本框所能容纳的字符数之内没有限制,文本框所能容纳的字符个数是 64K ,如果超过这个范围,则应该用其他控件来代替文本框控件。 这跟 Windows 中用记事本打开文件一样,当文件过大,系统会自动调用写字板来打开文件,而不是用记事本。 文本框控件 MaxLength 属性既可以在界面设置过程中予以指定,如图四: 图四 也可以在设计时予以改变,代码如下: 文本框控件名.Maxlength = X(X为阿拉伯数字,如 10、20、57,等等)。 5、MultiLine(多行)属性: 本属性决定了文本框是否可以显示或输入多行文本,当值为 True ,文本框可以容纳多行文本;当值为 False ,文本框则只能容纳单行文本。 本属性只能在界面设置时指定,程序运行时不能加以改变。如图五: 图五 6、PasswordChar(密码)属性: 本属性主要用来作为口令功能进行使用。例如,若希望在密码框中显示星号,则可在“属性”窗口中将 PasswordChar 属性指定为 “*” 。这时,无论用户输入什么字符,文本框中都显示星号。如图六: 图六 在 VB 中,PasswordChar 属性的默认符号是星号,但你也可以指定为其他符号。但请注意,如果文本框控件的 MultiLine(多行)属性为 True ,那么文本框控件的 PasswordChar 属性将不起作用。 习题二:一个文本框(TxtPassword),PasswordChar 属性指定为星号“*”;一个按钮(CmdShow);另外还有一个标签(LblShow),在初始状态下,Caption 为空。程序目的在于,点击 CmdShow 按钮,LblShow 能显示文本框控件中输入的密码。 答案:见本节后面的答案区。 7、ScrollBars(滚动条)属性: 本属性可以设置文本框是否有滚动条。当值为 0 ,文本框无滚动条;值为 1 ,只有横向滚动条;值为 2 ,只有纵向滚动条;值为 3 ,文本框的横竖滚动条都具有。如图七: 图七 8、Locked(锁定)属性: 当值为 False ,文本框中的内容可以编辑;当值为 True ,文本框中的内容不能编辑,只能查看或进行滚动操作。 二、文本框控件的事件: 除了 Click、DbClick 这些不常用的事件外,与文本框相关的主要事件是 Change、GotFocus、LostFocus 事件。 1、Change 事件: 当用户向文本框中输入新内容,或当程序把文本框控件的 Text 属性设置为新值时,触发 Change 事件。 2、GotFocus 事件: 本事件又名“获得焦点事件”。所谓获得焦点,其实就是指处于活动状态。在电脑日常操作中,我们常常用 Alt+Tab 键在各个程序中切换,处于活动中的程序获得了焦点,不处于活动的程序则失去了焦点(LostFocus)。 3、LostFocus 事件: 失去焦点,详情如上。 例子:一个文本框(TxtContent),默认状态下内容为空;当获得焦点时,文本框内容显示————“大家好,课程还难吗”字样;当失去焦点,文本框回到初始状态。另外再创建一个标签(LblShow),当用户试图向文本框输入文本或改变文本框本来的文本时,标签显示“标签的作用大家还清楚吗”字样。 界面如图八: 图八 程序如下: 文本框: Private Sub TxtContent_GotFocus() TxtContent.Text = Private Sub TxtContent_LostFocus() TxtContent.Text = Private Sub TxtContent_Change() LblShow.Caption = 1、请记住,Clipboard 指的是 Windows 剪贴板,剪贴板最常用的操作是所选文本的拷贝与粘贴。 拷贝: Clipboard.SetText 文本框名称.SelText 粘贴: 文本框名称.SelText = Clipboard.GetText 2、Multiline 属性为 True 时,文本框控件的 PasswrodChar 属性不起作用。 3、如果要让文本框的内容自动换行,只需取消文本框的横向滚动条就行了。 四、答案区: 习题一: 按钮一: Private Sub Cmd1_Click() TxtContent.Text = Private Sub Cmd2_Click() TxtContent.Text = Private Sub CmdShow_Click() LblShow.Caption = TxtPassword.Text End Sub VB 神童教程第二章第三节——综合示例一 在前面两节里,我们学到了 VB 的操作方法,以及 Label 与 TextBox 控件的使用方法,现在我们用这两节学到的知识来做一个简单的文本编辑器。 一、程序最终目的: 用户可以在程序的编辑窗口输入文本;对输入的文本可以进行复制、粘贴、清除操作;另外,还能在两个标签上分别显示选中文本的起始位置、选中文本的长度。 二、界面设置: 根据程序的要求,我们需要制作一个文本框控件(TxtContent),它将做为程序的输入窗口;另外还有四个按钮,分别是复制按钮(CmdCopy)、粘贴按钮(CmdPaste)、清除按钮(CmdClear)、退出程序按钮(CmdQuit);此外,还需要两个用来显示所选文本起始位置的标签一(LblStart)和显示所选文本长度的标签二(LblLength)。 最终界面如图一: 图一 请大家仿照图一制作。 三、属性设置: 如图一所示,但请注意,文本框控件的 Multiline(多行)属性要设置为 True ,这样,文本框才能自动换行。如图二: 图二 四、程序书写: 1、文本框(TxtContent)的鼠标事件: 对文本的选择,可以理解为这样的过程:先在欲选择的文本前点击鼠标,按下左键不放,拖动鼠标直到选择文本的结束处,最后松开鼠标。这说明,松开鼠标代表着文本选择的结束,从而应该在文本框的鼠标弹起事件(MouseUp)中书写代码,以改变两个标签的标题。 具体代码如下: 注意:这个 “&”符号表示将两个字符串连接起来。另外如: A & B ,结果是 AB ;ABC & EFG ,结果是 ABCEFG ,等等。 2、复制按钮的点击事件: 3、粘贴按钮的点击事件: 4、清空按钮的点击事件: 5、退出程序按钮的点击事件: 五、运行调试: 按 F5 键,或者点按运行按钮,这个简单的文本编辑器可以用了吗? 六、控件的一些基本操作: 在 VB “菜单栏”中有一个“格式”命令,通过它提供的一些功能可以让我们的工作事半功倍。 1、对齐: 分别是纵向对齐的“左对齐”、“居中对齐”、“右对齐”;横向对齐的“顶端”、“中间”、“底端”对齐;以及面向网格的“网格对齐”。它们的功能非常简单,你只需随意绘制几个控件,然后选择它们,再试着使用相关命令就能掌握了。如图三是随意绘制的程序界面: 图三 全部选中后,使用“左对齐”的结果如图四: 图四 也许你要问,这个对齐是以哪一个控件做为参照物的?再仔细看看图三,那个 Command1 按钮四周是八个实心的黑色小点,而其他控件则是白色的小点,现在你知道了吧,正是以 Command1 按钮为参照物进行对齐的,也就是说你最后选择的那一个控件。 2、统一尺寸: 以某个控件为参照物,统一其他控件的大小尺寸。 3、水平间距与垂直间距: 调整某几个控件的水平间距或垂直间距。 活用上面几个操作,将使你的工作事半功倍! VB 神童教程第二章第四节——CommandButton 控件 在 Visual Basic 操作界面中,CommandButton(命令按钮)控件所代表的图标如图一: 图一 CommandButton 控件在程序中主要作为按钮进行使用。默认的名称为 CommandX(X为 1、2、3,等等),命名规则为 CmdX(X为用户自定义的名字,如 CmdCopy、CmdPaste ,等等)。 一、CommandButton 的主要属性: 1、Cancel(取消)属性: 当一个按钮的 Cancel 属性设置为 True 时,按 ESC 键与单击此命令按钮的作用相同,因此,这个命令按钮被称为取消按钮。 在一个窗体中,只允许一个命令按钮的 Cancel 属性为 True 。如图二: 图二 2、Default(默认)属性: 当一个按钮的 Default 属性设置为 True 时,按回车键与单击此命令按钮的作用相同,因此,这个命令按钮被称为默认按钮。 与 Cancel 的设置一样,在一个窗体中,只允许一个命令按钮的 Default 属性设置为 True ,如图三: 图三 3、Caption(标题)属性: 跟其他控件的 Caption 属性一样,都用来显示控件标题的属性。这里要强调的是,作为按钮控件,用户可以给按钮控件的 Caption 指定快捷方式。 方法是在按钮 Caption 属性中欲作为快捷键的字母前加上一个 “&” 符号,程序运行时,该字母的下面会自带一条下划线,同时按下 Alt 键和带有下划线的字母,功效相当于用鼠标点击该按钮。如图四: 图四 4、Enabled(可用)属性: 本属性决定了控件是否可用的问题。当值为 False ,按钮在程序运行时呈灰色,不能响应用户的鼠标动作;只有当值为 True ,按钮才能使用。 本属性可以在设置界面时予以指定,如图五: 图五 也可以在程序中修改,代码如下: 按钮控件名称.Enabled = True/False 例一: 两个命令按钮,按钮一(CmdEnable)初始状态为可用,按钮二(CmdFalse)初始状态不可用。点击按钮一,按钮二变为可用,按钮一变为不可用;点击按钮二,按钮一变为可用,按钮二变为不可用。 程序界面如图六: 图六 程序代码如下: 按钮一: 按钮二: 5、Style(类型)与 Picture(图片)属性: 也许你想让应用程序的操作界面更美观一点,也许你想在某个按钮上添加幅小图片,那么,你就得使用到本控件的 Style 与 Picture 属性。 铵钮控件共有两种 Style ,一种是标准型(Standard),VB 中用 VbButtonStandard ,或者 0 表示;另外一种是图形型(Graphical),VB 中用 VbButtonGraphical ,或者 1 表示。 Style 属性可以在界面设置过程中予以指定,如图七: 图七 也可以在程序中改变,代码如下: 按钮名称.Style = VbButtonStandard/VbButtonGraphical 或者:按钮名称.Style = 0/1 只有当按钮的 Style 设置为 Graphical 类型时,按钮的 Picture 属性才起作用。本属性能在指定的按钮上添加图片。 可以在界面设置过程中为按钮指定图片,如图八: 图八 也可以在程序中进行指定,代码如下: 按钮名称.Picture = 二、CommandButton 的事件: 命令按钮最常用的事件是鼠标点击(Click)事件,当点击按钮时,犹如发出了一道命令,而这也正是“命令按钮”这个说法的由来。 VB 神童教程第二章第五节——单选与复选控件 在 Visual Basic 中,单选与复选按钮控件主要作为选项提供给用户选择。不同的是,在一组选择按钮中,单选控件只能选择一个,其他单选控件自动变为未被选中状态;而在一组复选按钮中,可以选定任意数量的按钮。 一、单选控件(OptionButton)与复选控件(CheckBox)的主要属性: 单选控件默认名称为 OptionX(X为阿拉伯数字 1、2、3,等等),起名规则为 OptX(X为用户自定义名字,如 OptRed、OptArial,等等);复选控件默认名称为 CheckX(X为 1、2、3,等等),起名规则为 ChkX(X为用户自定义名字,如 ChkName、ChkRed ,等等)。 在 VB 操作界面中,单选控件与复选控件的图标如图一所示: 图一 以前讲到的大多数属性都适用于单选与复选控件,包括:Caption、Enabled、Font(FontBold、FontItalic、FontName,等等)、Name、Height ,等等,此处不再赘述。 Value 属性是单选与复选控件最主要的属性,但单选与复选控件的 Value 值有些微的差别。 单选控件: 选中时,Value 值为 True ;未被选中,Value 值为 False 。 复选控件: 选中时,Value 值为 1 ;未被选中,Value 值为 0 ;禁止对该按钮进行选择, Value 值为 2 。 请大家注意,单选控件与复选控件的 Value 值是不同的,而这是初学者最容易混淆的。 二、单选按钮与复选按钮的事件: 这两种控件最主要的事件是 Click 事件,当选中时,Value 值变为 True 或者 1 ,控件也自动变为选中状态。 三、单选按钮程序举例: 有如图二这样一个程序: 图二 文本框(TxtContent)显示预设的字样;单选按钮一(OptArial),单击此按钮可以将文本框里显示的字样改变成 Arial 字体;单选按钮二(OptModern),单击此按钮能将文本框里显示的字样改变成 Modern 字体。 1、单选按钮一: Private Sub OptArial_Click() TxtContent.FontName = End Sub 2、单选按钮二: Private Sub OptModern_Click() TxtContent.FontName = End Sub 四、复选按钮的判断过程: 复选按钮的使用跟单选按钮相似,但由于一次可以选择多个复选按钮,所以复选按钮的选择比单选按钮多了一个判断过程。 这个判断过程在 VB 中可以用 If···Then···ElseIf···End If 语句完成。 If···Then···ElseIf···End If 是 VB 中的块结构条件语句,主要用来针对不同的情况,让应用程序做出不同的反应。 语句功能如下: If 假设情况一 Then 假设情况一成立时执行的语句块一 [ElseIF 假设情况二 Then 假设情况二成立时执行的语句块二] [ElseIf 假设情况三 Then 假设情况三成立时执行的语句块三] ······ [Else 所有条件都不成立时要执行的语句块] End If 上面的语句块含义为:如果“情况一”成立,则执行“语句块一”;否则如果“情况二”成立,则执行“语句块二”······;如果所有情况都不成立,则执行 Else 之后的语句块并最后跳出判断过程。 例: 假设输入学生成绩(Score),如果分数小于 60 ,标签(LblShow)显示“成绩不及格”;如果分数大于 90 ,标签显示“成绩优秀”;如果分数介于两者之间,标签显示“成绩优良”。 If Score LblShow.Caption = ElseIf Score > 90 Then LblShow.Caption = Else LblShow.Caption = End If 有几点必须加以注意: (1)、在上面的语句块中,ElseIf 之间没有空格,如果有空格即 Else If ,块结构则不成立。Else If 这种形式只能在单行结构条件语句中成立,而不能在块结构条件中成立。 (2)、执行语句块的程序代码不能紧跟 Then ,必须放到下一行中,这是块状结构的规定。 (3)、在块结构判断语句中,ElseIf 子句的数量没有限制,可以根据需要加入任意多个 ElseIf 子句。 (4)、ElseIf 与 Else 都是可选的,最简单的判断语句块形式如下: If 条件 Then 要执行的语句块 End If 如:If Score LblShow.Caption = End If (5)、块结构语句必须以 If 开始,以 End If 结束。 五、复选按钮举例: 上面我们学习了复选按钮的判断过程,现在进入实例学习。 有如图三这样一个应用程序: 图三 文本框(TxtContent)显示预设的字样;复选按钮一(ChkBold)可以将文本框里面的字变为粗体;复选按钮二(ChkItalic)可以将文本框里面的字变为斜体;复选按钮三(ChkUnderline)可以给文本框里面的文字加上下划线。 复选按钮一: Private Sub ChkBold_Click() If ChkBold.Value = 1 Then TxtContent.FontBold = True Else TxtContent.FontBold = False End Sub 复选按钮二: Private Sub ChkItalic_Click() If ChkItalic.Value = 1 Then TxtContent.FontItalic = True Else TxtContent.FontItalic = False End Sub 复选按钮三: Private Sub ChkUnderline_Click() If ChkUnderline.Value = 1 Then TxtContent.FontUnderline = True Else TxtContent.FontUnderline = False End Sub 联想: 复选按钮是不是非得经过这种选择判断?能不能如单选按钮那样直接使用呢?这是许多初学者,包括笔者自己,曾经感到疑惑的地方。(虽然现在看来它们的区别是如此之大) 还是上面这个例子,假设复选按钮一不经过判断,而直接在点击事件中输入代码: Private Sub ChkBold_Click() TxtContent.FontBold = True End Sub 那么你会发现,复选按钮一经点击就不能取消字体加粗的效果了;而实际上,复选按钮一的功能是,点击一次即选中时,字体加粗;点击第二次即取消选择,字体不再加粗;以此类推。 六:知识点: 1、切记,单选按钮与复选按钮的 Value 值是不同的。 单选按钮: 选中时,Value 值为 True ;未被选中时,Value 值为 False 。 复选按钮: 选中时,Value 值为 1 ;未被选中时,Value 值为 0 ;禁止选择,Value 值为 2 。 你可以试验一下,将复选按钮的 Value 值分别用 True/False 代替,看一下会出现什么问题。 2、两种选择按钮都针对 Click 事件做出反应,但单选按钮比较简单,只需直接输入代码即可;复选按钮比较复杂,需经过条件判断后再做出反应。切记! 3、 If···Then···ElseIf···End If ,只是条件判断方法的一种,以后我们还会学到其他的方法。 VB 神童教程第二章第六节——综合示例二 在前面两节中,我们学习了命令按钮(CommandButton)、单选按钮(OptionButton)、复选按钮(CheckBox)的使用,本节将就前两节的知识做个总结。 一、程序目的: 通过选项按钮的选择,对所选文本进行定制。 二、程序界面: 程序界面如图一: 图一 一个文本框(TxtContent),显示“Learning Visual Basic”字样;三个单选按钮:按钮一(OptArial)让文本字体变为 Arial 类型;按钮二(OptModern)让文本字体变为 Modern 类型;按钮三(OptRoman)让文本字体变为 Times New Roman 类型;三个复选按钮:按钮一(ChkBold),让文本字体变为黑体;按钮二(ChkItalic),让文本字体变为斜体字;按钮三(ChkUnderline),给文本增加下划线。另外,还有一个退出按钮(CmdQuit),作用在于退出程序。 三、属性设置: 根据图一进行属性设置。 四、书写程序: Else TxtContent.FontBold = False End Sub ChkItalic 按钮: Private Sub ChkItalic_Click() If ChkItalic.Value = 1 Then TxtContent.FontItalic = True Else TxtContent.FontItalic = False End Sub ChkUnderline 按钮: Private Sub ChkUnderline_Click() If ChkUnderline.Value = 1 Then TxtContent.FontUnderline = True Else TxtContent.FontUnderline = False End Sub CmdQuit 按钮: Private Sub CmdQuit_Click() End End Sub 五、分组控件(Frame)的学习: 从前面学到的知识我们知道,单选按钮只能多选一,那么,下面这种分组选项的选择又该如何制作呢?如图二: 图二 在图二中,既可以选择性别,又可以选择年级,它们是通过选项框分组控件(Frame)得以实现的。 简单地说,选项框控件是将不同的选项分类,在某一类里只能多选一,但多个类别的交叉使用,可以完成比较复杂的多项选择。 不仅仅如此,我们还可以将单选按钮、多选按钮分组,不同组内的操作不会影响其他组的操作。如图三: 图三 分组控件的制作方法: 先在窗体上绘制合适大小的框架,然后点选单选控件或多选控件,最后将鼠标移到框架内并拖拉出选项按钮。 注意:请不要使用双击选择按钮控件然后将其拖动到分组框内的办法,否则,分组会失败。 VB 神童教程第二章第七节——列表框控件 Visual Basic 提供了列表框控件(ListBox)以供用户进行多个项目的选择。在工具箱面板上,列表框控件的图标如图一所示: 图一 默认的列表框控件名为 ListX(X为阿拉伯数字 1、2、3,等等),规则的命名方式为:LstX(X为用户自定义的名字,如 LstName、LstUser,等等)。 一、列表框控件的主要属性: 列表框中可以有多个项目供选择,用户通过单击某一项选择自己所需要的项目,如果项目太多,超出了列表框设计时的长度,则自动增加竖向滚动条,如图二: 图二 除了一些常见的诸如 Font 、Height、Left、Width、Enabled、Name 等属性外,列表框还有一些特殊的属性: 1、List(列表)属性: List 是列表框最重要的属性之一,其作用是罗列或设置表项中的内容。可以在界面设置时直接输入内容,如图三: 图三 在程序运行时,列表框中所有的选项,都可以通过 List(下标值) 的形式表示。比如列表框中的第一项,用 List(0)表示,列表框中的第二项,用 List(1)表示,列表框中的第十项,用 List(9)表示,以此类推。 大家注意,列表框中的第一项,是 List(0) ,而不是 List(1) 。 、List() 属性的使用是非常灵活的,比如我们要从如图二的列表框(Lst1)中取出第三项内容,可以用下面的代码做到:A$ = Lst1.List(2) 其中,A 是一个变量;$ 指明了这个变量的类型:字符串型;这句话的意思是:将 Lst1 列表框中第三项(List(2))取出来然后赋值给字符串变量 A 。 象上面这种赋值办法,在 VB 中是非常普遍的,又如以前我们学到的: LblShow.Caption = 紧接上面的内容,假设我们用一个标签显示出刚才取出的表项: LblShow.Caption = A$ 那么显示的结果正是我们取出的选项。 可见,取出某个列表框中的某一表项并将其赋值给某个变量,代码如下: 字符串变量 = 列表框名称.List(X) ,其中,X 是下标。 、通过 List() 改变原有表项:假设我们要将如图二的列表框中第三项内容改为“跟我学 VB”,只需输入下面的代码即可: Lst1.List(2) = 上句话的意思是将“跟我学 VB”字符串赋值给 Lst1 并作为其第三项的内容。 结果如图四: 图四 可见,要修改某个列表框中某一选项: 列表框名称.List(X) = 2、ListCount 属性: 本属性返回列表框表项数量的数值,只能在程序运行时起作用。比如:一个有着四种选项的列表框,那么 ListCount 就为 4 ;一个列表框有五个选项,那么 ListCount 就为 5 。 返回一个列表框的表项数量值并将其赋值给某个变量,代码如下: 数值型变量 = 列表框名称.ListCount 比如要返回图二列表框的 ListCount: X% = Lst1.ListCount ,其中,X 是变量,% 表示X是整数类型的变量。 3、ListIndex(索引)属性: 本属性用来返回或设置控件中当前选择项目的索引号,只能在程序运行时使用。第一个选项的索引号是 0 ,第二个选项的索引号是 1 ,第三个选项的索引号是 2 ,依此类推,List Count 始终比最大的 ListIndex 值大 1 。当列表框没有选择项目时, ListIndex 值为 -1 。 在程序中设置 ListIndex 后,被选中的项目呈反相显示,如图五: 图五 在列表框控件的所有属性中,本属性是非常重要的,因为一个列表,事先你并不知道用户将要选择哪一条项目,这时,只有根据 ListIndex 返回的数值,我们才能让程序针对用户的选择做出适当的反应。 返回 ListIndex 的代码如下: X% = 列表框名称.ListIndex 联想:根据前面的知识我们知道,要取出第三项内容,代码如下: A$ = Lst1.List(2) 假设现在选中的是第三项,但我们事先不知道用户要选择这一项,那么又应该如何访问这第三项呢? 代码如下:A$ = Lst1.List(Lst1.ListIndex) 此时,Lst1.ListIndex 等同于 2 。 仔细想一想,为何要如此书写? 4、Columns(列)属性: 本属性用来确定列表框的列数,当值为 0 时,所有项目呈单列显示;当值为 1 或者大于 1 ,项目呈多列显示。Columns 属性只能在界面设置时指定。如图六: 图六 默认状态时,如果项目的总高度大于列表框的高度,那么列表框右边会自动增加一个垂直滚动条,用来上下移动列表框。 5、MultiSelect(多重选择)属性: 本属性决定了选项框中的内容是否可以进行多重选择,只能在界面设置时指定,程序运行时不能予以修改。如图七: 图七 MultiSelect 共有三个值:0 ,不允许多项选择,如果选择了一项就不能选择其他项;1 ,允许多重选择,但功能不如 2 ,可以用鼠标或空格选择;2 ,功能最强大的多重选择,可以结合 Shift 键或 Ctrl 键完成多个表项的多重选择。方法是:单击所要选择的范围的第一项,然后按住 Shift 键,再单击选择范围最后一项。 6、Style(类型)属性: 本属性决定了列表框的外观,共有两个值:1 ,Standard ,即为标准型,如图八: 图八 2 ,CheckBox ,复选框型,如图九: 图九 本属性只能在界面设置时确定。 7、Selected(选中)属性: 本属性返回或设置在列表框控件中某项目是否选中的状态。选中时,值为 True ;未被选中,值为 False 。 代码规则如下: 列表框名称.Selected(索引值) = True/False 注意,索引号其实是项目的下标值,如果是第三项,那么索引值是 2 ,如果是第十项,那么索引值是 9 ,以此类推。 例一: 有如图十这样一个应用程序: 图十 列表框(LstName)中是人物的名称,用户选择不同的名字,下面的标签(LblShow)自动显示此人的相关信息。 源代码如下: 本程序是根据用户选择的不同,在标签按件中显示不同的信息;另外,我们用到了前面学到的 If ···Then··· ElseIf··· End If 语法。 8、SelCount(选中项目数量): 只有当 MultiSelect 属性值为 1 或 2 时,本属性才起作用,用来读取列表框中所选项目的数目,通常与 Selected 一起使用,以处理控件中的所选项目。 二、列表框控件的主要事件: 列表框控件主要接收 Click 与 DblClick ,如例一。 三、列表框控件的方法: 1、增加项目:AddItem 用 AddItem 可以为列表框增加项目,代码规则如下: 列表框名称.AddItem 欲增项目[,索引值] 其中,索引值是可选项,是指欲增项目放到原列表框中的第几项,如放在第三项,那么索引值是 2 ,放在第五项,索引值则是 4 。 假设我们要在如图十这样的程序中增加项目:LstName.AddItem 用 Clear 可以清除列表框中所有的内容,代码如下: 列表框名称.Clear 3、删除选项:RemoveItem 此方法可以删除列表框中指定的项目,代码如下: 列表框名称.RemoveItem 索引值 其中,索引值是必须的,表示欲删除哪一个项目。 同样如图十的程序,假设我们要删除第三个项目,代码如下: LstName.RemoveItem 2 联想:对于任意一个列表框,要删除已经选中的项目,代码如下: 列表框名称.RemoveItem 列表框名称.ListIndex 比如:LstName.RemoveItem LstName.ListIndex 为什么这样写?请大家仔细想想。 四、知识点: 1、本节的难点在于 List() 、ListIndex ,请大家一定要把它们吃透。 2、本节提到了变量,关于它们的详细情况,我们将在以后学习,目前大家只需要知道,这里的变量只是个临时工,主要用来储存一些临时数据。 VB 神童教程第二章第八节——组合框控件 组合框控件(ComboBox)将文本框控件(TextBox)与列表框控件(ListBox)的特性结合为一体,兼具文本框控件与列表框控件两者的特性。它可以如同列表框一样,让用户选择所需项目;又可以如文本框一样通过输入文本来选择表项。 组合框默认的名称是 ComboX(X为阿拉伯数字 1、2、3 ,等等),规则的命名方式为:CboX(X为用户自定义的名字,如 CboName、CboColor ,等等)。组合框在 VB 工具箱面板中的图标如图一: 图一 一、组合框控件的主要属性: 列表框控件的大部分属性同样适合于组合框,此外,组合框还有一些自己的一些属性: 1、Style(类型)属性 组合框共有三种 Style : 当值为 0 ,组合框是“下拉式组合框”(DropDown Combo),与下拉式列表框相似,但不同的是,下拉式组合框可以通过输入文本的方法在表项中进行选择,可识别 Dropdown 、Click、Change 事件,如图二: 图二 当值为 1 ,组合框称为“简单组合框”(Simple Combo),由可以输入文本的编辑区与一个标准列表框组成,可识别 Change 、DblClick 事件,如图三: 图三 当值为 2 ,组合框称为“下拉式列表框”(Dropdown ListBox),它的右边有个箭头,可供“拉下”或“收起”操作。它不能识别 DblClick 及 Change 事件,但可识别 Dropdown 、Click 事件,如图四: 图四 综上所述,如果你想让用户能够输入项目,则应将组合框设置成 0 或 1 ,如果只想让用户对已有项目进行选择,则应将组合框设置成 2 。 2、Text(文本)属性: 本属性值返回用户选择的文本或直接在编辑区域输入的文本,可以在界面设置时直接输入,如图五: 图五 但要显示多个选项,不能简单地用 Text 属性指定,因为后一选项会覆盖前面的选项,这时,常常要用到窗体的载入事件。(Form_Load) Form_Load 的意思是,在打开窗口的同时,将指定的内容载入。详细情况见后面的窗体篇。 二、组合框的事件: 根据组合框的类型,它们所响应的事件是不同的。 例如,当组合框的 Style 属性为 1 时,能接收 DblClick 事件,而其他两种组合框能够接收 Click 与 Dropdown 事件;当 Style 属性为 0 或 1 时,文本框可以接收 Change 事件。 三、组合框的方法: 跟列表框一样,组合框也适用 AddItem 、Clear 、RemoveItem 方法。 四、组合框举例: 有如图六这样一个应用程序: 图六 在名为 CboChoose 的下拉组合框中任意选择一种机型,自动会在名为 LblShow 的标签上显示出来。 程序代码如下: 窗体: Private Sub Form_Load() CboChoose.AddItem 下拉式组合框的 Click 事件: Private Sub CboChoose_Click() LblShow.Caption = VB 神童教程第二章第九节——综合示例三 前面我们学了列表框控件(ListBox)与组合框控件(ComboBox),本节将就它们制作一个简单的应用程序。 一、程序界面:界面如图一 图一 二、程序目的: 两个列表框,左列表框(LstLeft)罗列了一些歌手名字,右列表框(LstRight)初始状态为空;点击向右按钮(CmdRight),可以将左列表框中的指定选项移动到右边列表框;点击全部向右按钮(CmdAllRight),可以将左列表框中所有的内容搬到右列表框中;点击向左按钮(CmdLeft),可以将右列表框中选定的表项移动到左列表框中;点击全部向左按钮(CmdAllLeft),可以将右列表框中的所有内容移动到左列表框中。 三、属性设置: 见图一,注意,列表框的 Style 都为 0 即标准类型。 四、程序代码: 1、窗体的载入事件(Form_Load) Private Sub Form_Load() LstLeft.AddItem LstLeft.AddItem 2、向右按钮的点击事件(CmdRight_Click) Private Sub CmdRight_Click() LstRight.AddItem LstLeft.List(LstLeft.ListIndex) LstLeft.RemoveItem LstLeft.ListIndex End Sub 3、全部向右按钮的点击事件(CmdAllRight_Click) Private Sub CmdAllRight_Click() LstRight.AddItem 4、向左按钮的点击事件(CmdLeft_Click) Private Sub CmdLeft_Click() LstLeft.AddItem LstRight.List(LstRight.ListIndex) LstRight.RemoveItem LstRight.ListIndex End Sub 5、全部向左按钮的点击事件:(CmdAllLeft_Click) Private Sub CmdAllLeft_Click() LstLeft.AddItem 五、注意事项: 1、窗体载入事件: 就是窗体打开时自动加载的信息,也可以在界面设置时通过左列表框的 List 属性设定。如图二: 图二 2、无论是部分转移,还是全部移动,都要记着将本已移动的表项在原有列表框中清除,如代码: LstLeft.RemoveItem LstLeft.ListIndex 如果不清除,那么表项移动后,原先的表项还在原处,用户可能对同一表项多次选择。如图三 图三 3、第一个应用程序还没编写完,仔细看一下,哪里还需要再编写? 没错,就是向左按钮与向右按钮的点击事件还没完善,按照上面的程序,如果在初始状态下(也就是没有选中任何表项),点击向左或向右按钮会产生程序错误。 所以我们得在原来向左或向右按钮的事件中增加判断过程,修改后的代码如下: 素描中的成角透视 正六面体的成角透视: 当正六面体的一个面与地面平行,其左右各竖立饿侧面与画面成角时就叫“成角透视”(它有两个消失点)。 正六面体三组边线的透视方向是:有四条边线与画面垂直,有四条边线消失于左余点,有四条边线消失于右余点。(如下图所示) 素描教程:素描几何方体的基本步骤 我们研究三维空间形态关系,就要借助透视原理,着重研究形态的本质规律,这种形态本质规律包含在几何形体之中。几何形体属于最单纯的形态,有利于我们了解形的构造、比例、空间等关系。 从而明白形体的立体感与空间感是如何表现出来的,在透彻地了解形态关系的基础上,我们还有所侧重的进行形态的增减训练,强化对形态空间关系的认识。我们选用的几何形体是常见的同时又具有较强个性的形体:立方体、球体、锥体和圆柱体。 我们采用的表现手段主要是以线为主,用线条来表现形态的立体感、空间感、质感与量感。要表现出形态的这些关系,用线就要讲究粗与细、浓与淡、虚与实等等变化。在前面我们已经谈到了透视的基本规律是近大远小,同时还存在着近粗远细、近实远虚、近浓远淡的关系。当然在进行艺术表现时,以上这些说法并非是绝对的,但作为视觉规律,在空间表现上还是要遵循的。 在形体表现时,我们注重辅助线的运用,同时在对称的形体中还要充分利用中心线。以利于观察和表现形体。 辅助线:是辅佐形体描绘的线,有利于帮助我们观察、分析和表现形体的各种关系。尤其是形体表现之初。我们会运用它进行标记、推理等,从而画出准确而生动的形体关系。 几何形体单线描绘 立方体的描绘 立方体形态是我们所见到的许多直线形中最典型的形态,许多物象均可概括成立方体特征。例如山石、楼宇、家具等等。 在进行立方体描绘时,我们采用最理想的角度,便于我们对立方体的认识,(图1) 图1 立方体 首先我们来认识一下立方体的形体结构,(图2)。立方体的结构关系其实很单纯,如图所示,这是一个正方形的透视图垂直和水平方向的排列。立方体在成角的情况下,其结构关系可以分解为无数条如图所示的透视线。只有了解立方体的结构关系,表现时就会变得容易了。 图2 立方体的形体结构 素描方体时的基本步骤: 1.画平行透视时: 2.画成角透视时: 注意:起步时用线要轻,铅笔可稍倒一点,可用软一点的铅笔起大形,画大形的线可比实际需要的长一些,再根据需用截取! 立方体绘画步骤详解 我们选择一个观察角度,以图1为例,首先要画出一条垂直线,(步骤图一),这条线就是这个立方体的近角棱线。画时应注意他在画面上的位置,一般应处于画面中部略偏一点。 步骤图一 步骤图 二 步骤图三 图1 立方体描绘的步骤图 在这条垂直线上截取它的上端点和下端点,(步骤图二)。这两点间的距离就是这个立方体的高度,由于透视原因,其它任何线的长度都小于这条垂直线。 ③ 根据所取的上下两个端点,画出向远处延伸的透视线,先画右侧的线,再画出左侧的线,注意这四条线与垂直线所呈的角度,或者与水平线形成的倾斜度。由于角度关系,我们所看到的立方体两个面的大小是有差别的,所以这四条线所呈现的倾斜度也是不一样的。左侧的线与水平线所成的角度大,右侧的线要小些。如果我们看到的立方体右侧的形比左侧的形大的话,以上的情形就会相反,(步骤图三、四)。 ④ 根据所确定的高度,用辅助线定出左右两个面的大体位置。左侧面与右侧面的比例关系通过比较是可以确定的。其方法是先在下面的水平线上找出这两个面的比例线段,再以这两点做垂直线,立方体的两个侧面便画出来了,(步骤图五)。 ⑤ 画出立方体上方两条线时,透视关系要非常注意。这样我们所画的立方体的外观形态即三大面,面与面之间形成的九条棱线就全部画出来了,(步骤图六、七)。 步骤图四 步骤图五 图2 立方体描绘的步骤图 ⑥实际上立方体概括了自然界中的一切方体形态的特征,包括三棱锥、四棱锥、多棱锥、多面体等。立方体由六个面组成,面和面之间又形成了十二条棱角线。除特殊视角造成的几个特殊形体外,如视线垂直观察立方体的一个面时,我们只能看到一个正方形形态,视角稍做水平方向或垂直向上移动时,立方体就会呈现两个面的形态,面和面之间的棱角线也只能看到一条。而两个面情况下的立方体,三维空间感是非常不明显,因此,在表现时近量避免在这种视角下观察立方体。 步骤图六步骤图七 图3 立方体描绘的步骤图 画立方体上面时要特别注意两条线的透视关系,不然的话就容易把上面画得翻过来了。反之,透视关系画过头了也是不行的,如图4所示,这是描绘立方体时常见的错误。 透视关系画反了 透视关系画过头了 图4 画立方体透视关系时的常见错误 虽然我们有三个面和三条线看不到。但是要透彻了解立方体的形态、结构关系,我们还是要把看不到的线和面都画出来。过立方体最高的交点作垂线,然后再过立方体下方两端点向内作倾斜线与这条垂线相交,这样立方体的十二条线、六个面就都画出来了。其中四条线是垂直关系。四条线向左侧形成透视关系,另四条线向右侧形成透视关系如图5所示。 四条向左侧形成透视关系的线 四条向右侧形成透视关系的线 图5 立方体线的透视关系 这八条线并非是平行的关系,而是向远处越来越靠近的关系,最终相交于视平线两侧的灭点上。 ⑦整体调整,注意用线要讲究虚实关系,体现空间感与立体感。图6是立方体的完成图。 图6 立方体的完成图 从不同角度观察立方体,衡量每一个角度下立方体各个面的比例关系,并尝试描绘在不同视角下立方体的形体结构,反复研究立方体的比例、结构和透视关系,直到研究透彻为止。 素描几何物体的明暗规律 在学习素描的过程中,应该如何把握物体的明暗规律呢?今天,我们将通过下面几个例子来向大家展示光与明度的关系和介绍素描常见的五调子又是什么。 光与明度的关系: 1、物体靠近光源近,亮的更亮,暗的更暗,对比强烈:反之光源越远,亮面越弱,暗面也越灰。(下图所示的亮、灰、暗也就是我们经常所说的素描三大面) 2、物体离画者越近,明暗对比越强,越远明暗对比越弱,其实就是近实远虚。(如下图所示) 物体离画者越近,明暗对比越强,越远明暗对比越弱,其实就是近实远虚。(如下图所示) 素描写生中的五调子: 1、受光面(亮面):是物体受光线90度直射的地方,这部分受光最大,调子淡,亮部的受光焦点叫“高光”,一般只有光滑的物体才能出现。 2、中间色(灰面):是物体受光侧射的部分,是明暗交界线的过渡地带,色阶接近,层次丰富。 3、明暗交界线:由于它受到环境光的影响,但又受不到主要光源的照射,因此对比强烈,给人的感觉调子最深! 4、反光部:暗部由于受周围物体的反射作用,会产生反光。反光作为暗部的一部分,一般要比亮部最深的中间颜色要深。 5、投影:就是物体本身影子的部分。它作为一个大的色块出现,也算五调子之 一。投影的边沿近处清楚,渐远的模糊!(如下图所示) 为了更加明确地理解明暗调子,根据光源和物体的体面形成的角度,我们以1–6的调子变化说明明暗调子在物体上所呈现的形式(如下图所示) 1、直接受光面(高光) 2、光源侧射部分(中间色) 3、背景(亮面偏暗,暗面偏亮) 4、暗面部分 5、反光部分 6、明暗交界线和投影部分 11 素描教程:结构素描的画法 1、观察对象,在画面上定好构图形式:三角形。 2、定出形体的大的比例,画出物体的内部结构,通过此来检查物体的形体和透视准确性。 12 3、保留起稿时的线条,作为辅助线,琢步地画出物体的形体起伏变化。 4、用粗线条来示物体的空间位置,注意线条的虚实变化。画面主要的地方,可画得实一点,次要的地方可画得虚一点。 13 5、反复地用线表现你的形体,直到近似为止,注意线条在空间上比较,以加强空间感。 6、从整体出发,调整画面。 素描教程:单个球体素描方法 素描入门通常的是由几何体开始的,如正方体、长方体和圆柱体,球体等。画几何体的目的为的是能更好得掌握透视、明暗和空间的关系。 今天我们来学习一下素描中如何画好球体,一起来看一下球体的素描写生步骤。 单个圆球体素描写生步骤范图: 14 (照片) 单个球体的素描写生步骤(一) 1:以正方体入手,十字线用来初步判断圆球体的中心。边缘线不宜画得过死,大致画出基本轮廓,注意不要画得过大或过小! 单个球体的素描写生步骤(二) 2:树立体积概念,不要停留在圆球体的轮廓线上,整体观察,找出暗部,阴影及衬布的大体位置。 15 单个球体的素描写生步骤(三) 3:调整圆球体的准确度,注意明暗交界线向灰面的过渡变化及暗部的反光阴影处理。背景以衬托圆球体并表现其空间关系,不宜画得过实! 单个球体的素描写生步骤(四) 4:加强体积感,进一步区分黑、灰、白,使画面更加完整。 16 转载请注明出处范文大全网 » Win32汇编基础教程(整理范文二:origin基础教程
范文三:vb基础教程
范文四:VBde基础教程
范文五:素描基础教程