一、sp2、sp3、企业版有何区别 问 请问vb中的sp2、sp3、企业版这三种,各代表什么含义? 答 sp是service pack的缩写。微软每推出一个软件后,都会不定期地推出一些补丁程序,依时间先后称为sp1、sp2等等。后一个sp版本包括前一个版本的全部内容,所以如果你安装了sp3就用不着安装sp2了。sp可以从微软的站点免费下载。vb 5.0的sp下载地址:http://msdn.microsoft.com/vstudio/sp/vs97/。vb 6.0的sp下载地址:http://msdn.microsoft.com/vstudio/sp/default.asp。在service pack的readme文件中介绍了该service pack修改了哪些错误。vb有三个主要版本:学习版、专业版、企业版。企业版是功能最全的版本,当然也是最贵的版本。 ------------------------------------ 二、api的意义是什么 问 编程中经常碰到api。请问api的意义是什么?如何知道编程中经常用到的窗口句柄、窗口类名等? 答:api是application programming interface(应用编程接口)的缩写,也就是应用程序调用系统功能的接口。windows api主要包括由windows系统定义的函数、消息及与之相关的数据类型。我们使用各种开发工具归根结底都是和api打交道。但是api本身比较难掌握,所以visual basic提供了可视的面向对象的控件,使初学者即使不太了解api,也可以编写windows程序。但是visual basic提供的控件毕竟是有限的,不可能包括api的所有方面,所以一些复杂的功能仍然需要调用api来实现。 ------------------------------------ 三、api定义中的&h是什么含义 问 现在我看到一些用api函数做的例程,其中有一个语句:public const lvm_first = &h1000 ,该语句中&h1000代表的是什么含义? 答:&h是16进制的表示,比如&h10等于十进制的16。 ------------------------------------ 四、为何总提示“变量未定义” 问 下面是一个关闭windows的小程序: option explicit private declare function exitwindowsex lib “user32” (byval uflags as long, byval dwreserved as long) as long private sub form_load() exitwindowsex ewx_force or ewx_logoff or ewx_shutdown, 0 end sub 但编译的时候,总是提示:ewx_force 变量未定义,但ewx_force 是一个参数。这是为何? 答:ewx_force和其他几个参数都是windows api中定义的常数。你使用了option explicit(这是个好习惯,便于发现错误),所以vb发现未定义的符号都会进行提示,这有助于发现拼写错误和遗漏参数定义。你应该从vb的win32api.txt中复制这几个参数的定义。 ------------------------------------ 五、如何保存图片 问 我在vb的主窗体要装入一幅事先选好的图片,程序运行后我可以在图片上进行修改并保存它,以备以后调用。请问怎样办? 答 你可以把form或picturebox的autodraw属性设为true,进行修改后使用vb的savepicture语句进行存盘。如: savepicture picture1.picture, “c:\test.bmp” 这种存盘的文件为.bmp文件,颜色数与当前屏幕的色彩数相同。如果你的存盘要求很高,希望控制存盘格式,只能借助于其他控件,比如imageman(http://www.data-tech.com下载)、lead tools(http://www.leadtools.com下载)等等。 ------------------------------------ 六、“实时错误9下标越界”错误 问 我在为一数组赋值时出现如下错误:“实时错误9——下标越界”。出错的代码如下: dim inputdata() as single inputdata(0) = text2(0).text / text2(1).text '入学率 请问为何会出现这种错误? 答 vb在使用数组前必须指定数组的大小。一种办法是在定义时确定大小,如:dim inputdata(10) as single,另一种是采用动态数组。对于你的程序,数组声明部分可以不用修改,而在出错语句前加一句:redim inputdata(10) as single。 ------------------------------------ 七、如何打开光盘上的数据库 问 我在编一个vb 程序,当程序刻到光盘以后,不能使用,经过检查发现是因为.mdb文件为只读,程序出错:“该数据库文件已经被另外的一个用户以独占的方式打开,您不能访问”。请问各位高手怎么办?可是我用access却可以阅读该数据库(只读)。 答 如果你用data控件使用该数据库,将data控件的readonly属性设为true,将exclusive属性设为true。如果readonly属性为false,则就出现你所见到错误信息。如果不将exclusive属性设为true,将出现can't lock file的错误信息。如果你是使用openrecordset语句打开数据库,exclusive属性对应着dbdenywrite和dbdenyread参数。 ------------------------------------ 八、怎样避免当前窗口被关闭 问 在按下右上角的关闭键后,怎样避免当前窗口被关闭? 答 在按下关闭键后,会发生form_unload和form_queryunload事件。这两个事件都有个cancel参数,如果在事件处理过程中将其设为true就可以避免窗口被关闭。对于你的问题,form_queryunload事件可能更好些,因为它有一个unloadmode参数可以区分关闭窗口的指令是用户做出的,还是系统做出的,或者是本程序代码产生的。 ------------------------------------ 九、dll的编程格式问题 问 我是第一次编写activex dll程序,在dll中,我只在类模块中写了一个函数card,编译成dll后,在另外一个程序中调用,在模块中声明: public declare function card_config lib "c:\test\card.dll" (byval address as integer, byval intermit as integer) 在一个按钮中写如下代码: c = card_config(12,12) 运行后出现错误:编译activex dll后,调用时出现错误:“实时错误453,找不到dll入口点”望指教。如有可能:请详细告之dll的编程格式。 答 declare语句只能用来调用标准dll,而不能用于调用activex dll,这是你程序出错的原因。vb无法生成标准dll,只能生成activex dll。要调用activex dll,一般通过createobject语句调用,或在集成环境中选择菜单“工程/引用”,在对话框中选择你要调用的activex dll。这样你就可以在程序中使用activex dll中定义的对象或函数。 ------------------------------------ 十、怎样启动其他应用程序 问 怎样在vb中启动其他windows应用程序,例如记事本? 答 你可以使用vb的shell函数调用其他应用程序。如: shell“notepad.exe c:\autoexec.bat” ------------------------------------ 十一、如何打印 mschart 问 如何打印 mschart 控件中的内容? 答 mschart本身没有打印功能,所以必须先用editcopy将图像放在剪贴板中,然后再打印,如: mschart1.editcopy printer.print ″ ″ printer.paintpicture clipboard.getdata(), 0, 0 printer.enddoc ------------------------------------ 十二、“can′t find dll entry point”是指什么 问 出现以下错误信息是什么意思?“run-time error '453' can't find dll entry point openprocess in kernel 32 ”,(我有一个定义private declare function openprocess lib “kernel32" (byval dwdesireaccess as long, byval binherithandle as long, byval dwprocessid as long) as long) 答 把openprocess改为openprocess。因为在win 32下,dll中的函数名是区分大小写的。在kernel32中只有openprocess函数,没有openprocess函数。 十三、“对象不支持该属性或方法”错误 问 为什么执行data1.recordset.findfirst “pubid=” & dbcombo1.boundtext时出现“对象不支持该属性或方法”错误? 答 这是因为findfirst、findnext、findlast等方法不支持table类的记录集,但可以使用seek方法进行查找工作。但你必须对pubid字段建立索引。如果想使用findfirst方法,请修改data1的recordsettype属性为dynaset。 ------------------------------------ 十四、问题:如何编程使文本框中文本的某一特定字符或字符串同时高亮显示? 答:由于普通textbox控件不支持不连续字符串的同时高亮显示,所以我们选择richtextbox控件。单击工程(project)选单项,在弹出的下拉选单中单击组件(components)选单项,从弹出的对话框中选择microsoft rich textbox control 5.0复选框,确定加载richtextbox控件。 新建(new)一个工程,在窗体(form)上添加一个richtextbox控件和两个command(按钮)控件,都采用系统默认的name属性值;设置richtextbox的text属性值为空,command1和command2的caption属性值分别设为“输入文本”和“选择字符串”。最后,添加如下vb代码: private sub command1—click() dim str as string dim text as string str=″输入文本″ text=inputbox(str) richtextbox1.text=text end sub private sub command2—click() dim str as string dim text as string dim position as integer dim lenth as integer str=″输入要高亮显示的字符串″ text=inputbox(str) if text 〈〉 ″″ then position=instr(richtextbox1.text, text)-1 lenth=len(text) richtextbox1.selstart=position richtextbox1.sellength=lenth richtextbox1.selcolor=rgb(255,0,0) do while instr(position+lenth+1, richtextbox1.text, text) 〈〉 0 position=instr(position+lenth+1, richtextbox1.text, text)-1 richtextbox1.selstart=position richtextbox1.sellength=lenth richtextbox1.selcolor=rgb(255,0,0) loop end if end sub 按f5执行程序,单击“输入文本”按钮,在弹出的对话框中输入一些文本,确定后,刚刚输入的文本将显示在richtextbox中;再单击“选择字符串”按钮,在弹出的对话框中输入你希望高亮显示的字符串,确定后,richtextbox中相应的字符串将以红色高亮显示。 ------------------------------------ 十五、问题:如何利用vb编写程序实现windows 95操作系统的热启动? 答:要利用程序实现系统的重新启动,可以在你的程序中调用api函数来实现。建一个子函数:(以vb为例) declare function systemparametersinfo lib ″user32″ alias — ″systemparametersinfo″ (byval uaction as long, byval uparam as long, byval lpvparam as any, byval fuwinini as long) as long sub disablectrlaltdelete(bdisabled as boolean) dim x as long x=systemparametersinfo(97, bdisabled, cstr(1), 0) end sub call disablectrlaltdelete(true) ′禁止热启 call disablectrlaltdelete(false) ′允许热启 ------------------------------------ 十六、问题:如何把数据文件输出到text控件中?如果数据量比较大,窗体满屏也不够大,怎么解决? 答:有一个比较简单的方法,就是把数据放到一个文本框(text)里,并在其中加上水平和垂直滚动条。具体实现步骤为:先在窗体(form)里加入一个文本框,采用默认名text1;然后,设置文本框text1的属性:text属性设置为空,multiline属性设置为true,scrollbars属性设置为3-both;接着添加如下vb代码: private sub form—load() dim handle as integer dim filename as string on error goto errexit begin: ′输入要显示的数据文件的名称 filename=inputbox$(″input filename″, ″open file″) on error goto fileerr handle=freefile open filename for input as #handle ′把数据文件中的数据输出到文本框中 text1.text=input$(lof(handle), handle) close #handle exit sub fileerr: dim errnum as integer if err.number=53 then errnum=msgbox(″file not exist″, vbokcancel, ″error information″) if errnum=1 then goto begin else exit sub end if end if msgbox err.description, , ″file open failed″ errexit: exit sub end sub ′使文本框充满整个窗体 private sub form—resize() text1.left=0 text1.top=0 text1.width=form1.width-100 text1.height=form1.height-400 end sub 通过这样的处理,不仅能解决问题,而且用户还可以在文本框中对数据进行编辑。 ------------------------------------ 十七、问题:怎样把文件列表框、目录列表框和驱动器列表框相互关联起来? 想做一个对话窗体,包含驱动器列表框、目录列表框和文件列表框,并能实现三者的同步操作,怎么做? 答:在实际应用中,经常会遇到上述问题,在vb中解决这个问题非常简单,可以通过path属性的改变引发change事件来实现。例如: sub dir1—change() file1.path=dir1.path end sub 该事件过程使窗体上的目录列表框dir1和文件列表框file1产生同步。因为目录列表框path属性的改变将产生change事件,所以在dir1—change事件过程中,把dir1.path赋给file1.path,就可以产生同步效果。 类似地,增加下面的事件过程,就可以使三种列表框同步操作: sub drive1—change() dir1.path=drive1.drive end sub 该过程使驱动器列表框和目录列表框同步,前面的过程使目录列表框和文件列表框同步,从而使三种列表框同步,问题即可解决。 ------------------------------------ 十八、问题:如何在windows 95或windows 98启动后自动启动程序? 答:我们都知道在windows 95和windows 98的“开始”→“程序”选单下有一“启动”选单项,当每次启动windows 95或windows 98时,系统都会自动启动放在“启动”选单栏里的可执行程序。 但目前有好多软件,像解霸五、icq,以及大部分实时侦测病毒的软件等等,安装后,并没有放在“启动”选单里,也能在启动操作系统时自动启动。怎么实现的呢? 其实只要知道windows注册表的一些知识,这个问题就不能称之为问题了。用鼠标单击“开始”,打开开始选单,再单击“运行”,出现一对话框,然后输入“regedit”,确定后,会打开系统注册表编辑器,找到hkey—local—machine? software?microsoft?windows?currentversion?run,加入你的程序的入口,就可以了。如果不知道怎么加,就参考一下已经存在的键值。 ------------------------------------ 十九、问题:如何用vb在窗体上点鼠标右键产生一个弹出式选单(popup menu)? 答:大家都知道,在windows95的桌面和许多流行软件的视窗中,当我们点鼠标右键时,会在鼠标的当前位置弹出一个快捷选单。许多爱好编程的朋友是不是也希望能在自己的程序里有类似的功能呢?其实,这并不困难。笔者经过一番努力,在vb下找出一个通用的方法,供大家分享。 要实现上述功能,需分两个步骤: (1) 利用vb的选单编辑器(menu editor)编辑你希望弹出的选单及子选单,注意,要将选单的visible属性设置为:false。 (2) 在窗体(form1)的mousedown事件中编写程序,来激发编辑好的选单,假设选单名为popmenu,程序源码如下: private sub form—mousedown(button as integer, shift as integer, x as single, y as single) if button = vbrightbutton then popmenu.visible = true popupmenu popmenu end if end sub 上述方法是针对窗体的,我们也可以针对任意控件,用鼠标右键点击控件时,也弹出一个快捷选单。方法也很简单,只要把上述代码放到相应控件的mousedown事件中,就可以了。 二十、问题:怎样动态在窗体上判断某区域内是否有控件存在? 答:最近编一小程序,想在窗体的某个区域输出数据,这就要求在这个区域内不能有其他控件存在,那么,怎么才能知道在窗体的某个区域内,是否有控件存在呢? 为了判断在窗体的某个区域中,是否含有控件,我们可以利用以下vb程序来实现: function getcontrol(x1 as single, y1 as single, x2 as single, y2 as single) as control dim control as control for each control in form1 with control if (x1 〈= .left) and (x2 〉= .left) and _ (y1 〈= .top) and (y2 〉= .top) or _ (x1 〈=.left + width) and (x2 〉= .left + width) and _ (y1 〈= .top) and (y2 〉= .top) or _ (x1 〈= .left) and (x2 〉= left) and _ (y1 〈= .top + height) and (y2 〉= .top + height) or _ (x1 〈= . left + width) and (x2 〉= .left + width) and _ (y1 〈= .top + height) and (y2 〉= .top + height) then set getcontrol = control exit function end if end with next set getcontrol = nothing end function 注:(x1, y1)和(x2, y2)分别为选定矩形区域的左上角和右下角点的坐标值。 该程序通过计算窗体上所有控件的四个角的位置来判断控件是否与选定区域相交,并返回相交的控件。 ------------------------------------ 二十一、问题:如何给vb控件picturebox加滚动条? 答:用过picturebox控件的朋友都知道,在其中我们可以加载图片。当图片不是很大时,可能还不会有什么问题,但是,如果所加载的图片比picturebox大时,我们只能看到图片的一部分,那么,怎么才能看到其他的部分呢? 为了解决上述问题,我们可以在图片框(picturebox)内部加上水平和垂直滚动条,利用滚动条来显示看不到的图片。具体方法如下: 首先给工程(project)添加一个ocx控件,单击选单上的工程(project)选单项,在弹出的下拉选单中点击组件(components),选中其中的“microsoft common dialog control 5.0”,确定完成加载工作;然后画一个picturebox,采用vb提供的默认名字picture1, 再在picture1上面画一个picturebox,默认名字为picture2,注意别忘了设置:picture2.autosize=true;接着,加上水平和垂直滚动条,默认名字分别为:hscroll1,vscroll1;以后加载图形到picture2上,就可以了;最后,在窗体中引入其它控件:一个按钮(command),默认名为command1和一个“microsoft common dialog control”,默认名为commondialog1。具体vb代码如下: private sub form—load() picture2.left = 0 picture2.top = 0 picture2.width = picture1.width picture2.height = picture1.height vscroll1.min = 0 hscroll1.min = 0 hscroll1.min = 0 vscroll1.max = picture2.height - picture1.height hscroll1.max = picture2.width - picture1.width if hscroll1.max 〈 0 then hscroll1.enabled = false if vscroll1.max 〈 0 then vscroll1.enabled = false end sub private sub command—click() on error goto errexit commondialog1.filter = "bitmap file(*.bmp)|*.bmp|all file(*.*)|*.*" commondialog1.filterindex = 1 commondialog1.showopen picture2.picture = loadpicture(commondialog1.filename) vscroll1.min = 0 hscroll1.min = 0 vscroll1.max = picture2.height - picture1.height hscroll1.max = picture2.width - picture1.width if hscroll1.max 〈 0 then hscroll1.enabled = false if vscroll1.max 〈 0 then vscroll1.enabled = false errexit: end sub private sub hscroll1—change() picture2.left = -hscroll1.value end sub private sub vscroll1—change() picture2.top = -vscroll1.value end sub 该程序通过点击command1按钮,在弹出的对话框中选择一个图形文件加载到picture2中,利用水平和垂直滚动条就可以实现图片的滚动。 ------------------------------------ 二十二、问题:如何用vb做一个聊天的程序? 答:所谓“聊天”是指两个程序能够发送数据给对方。这个程序涉及到数据通讯的知识,仿佛很复杂,不过,由于vb给我们提供了一个winsock控件,问题就变得很简单了。 首先编写“聊天(主机)”程序。在窗体里添加winsock控件,并设置其protocol属性为1-sckudpprotocol,其他属性为缺省值。接着添加两个标签和两个文本框,设置两个标签的标题属性分别为“接收窗”和“发送窗”;两个文本框的标题属性为空。最后编写代码: (1)“聊天(主机)” private sub form—load() ′设置网络地址 winsock1.localport=1024 winsock1.remotehost="202.96.6.1" winsock1.remoteport=1999 end sub private sub text1—change() ′发送用户输入的内容 winsock1.senddata text1.text end sub private sub winsock1—dataarrival(byval bytestotal as long) dim rec as string ′接收对方数据并在文本框内显示 winsock1.getdata rec, vb string text2.text=rec end sub (2)“聊天(副机)” private sub form_load() ′设置网络地址 winsock1.localport=1999 winsock1.remotehost="202.96.6.1" winsock1.remoteport=1024 其他部分程序与(主机)相同。最后将两个程序存盘,并编译成执行(.exe)文件。现在就可以使用这个程序进行对话了。 ------------------------------------ 二十三、让窗口一直在最上方 很多软件都有这样一个选项“always on top”。它可以让窗口始终在最上面,别的窗口不能覆盖它。在 vb 中可以用下面的方法来实现: 声明: private const swp-nosize = &h1 private const swp-nomove = &h2 private const hwnd-topmost = -1 private const hwnd-notopmost = -2 private declare function setwindowpos lib ″user32″ (byval hwnd as long, byval hwndinsertafter as long, byval x as long, byval y as long, byval cx as long, byval cy as long, byval wflags as long) as long private sub form-load() setwindowpos hwnd, hwnd-topmost, 0, 0, 0, 0, swp-nomove or swp-nosize ′这条语句可使窗口一直在最上方 …… setwindowpos hwnd,hwnd- notopmost,0, 0, 0, 0, swp-nomove or swp-nosize ′这条语句可使窗口恢复原状态 end sub ------------------------------------ 二十四、禁用ctrl+del+alt键 有时候编制的程序需要禁用“ctrl+del+alt”键,可以通过以下代码实现: 声明: const spi-screensaverrunning = 97 private declare function systemparametersinfo lib ″user32″alias ″systemparametersinfoa″ (byval uaction as long, byval uparam as long, lpvparam as any, byval fuwinini as long) as long private sub form-load() dim pold as boolean call systemparametersinfo(spi-screen- saverrunning, true, pold, 0) ′禁用“ctrl+del+alt”键 …… call systemparametersinfo(spi-screen- saverrunning, false, pold, 0) ′恢复使用“ctrl+del+alt”键 end sub ------------------------------------ 二十五、鼠标的隐藏 在大多数场合下,鼠标都是可见的。但有些场合需要隐藏鼠标,使之不可见,以免影响屏幕画面的整体效果,如屏幕保护程序。在vb中可通过调用windows api函数showcursor()来轻松地实现鼠标的隐藏。首先在全局模块中声明函数: declare function showcursor lib ″user32″(byval bshow asinterger) as interger sub form-load() temp = showcursor(0) ′隐藏鼠标 …… temp = showcursor(1) ′显示鼠标 end sub ------------------------------------ 二十六、关闭窗口时确认 像“空当接龙”游戏一样,退出时先确认。 private sub form_queryunload(cancel as integer, unloadmode as integer) dim flag as integer flag = msgbox(″确定退出吗?″, vbokcancel, ″退出″) select case flag case vbok cancel = false case else cancel = true end select end sub 二十七、检查软驱中是否有盘 如果要从软盘读取资料或向软盘写资料,在读写之前先检查一下软驱中是否有盘是十分重要的。下面是一个这样的函数: public function floppydrive(sdrive as string) as boolean on error resume next ′设置错误处理 floppydrive = dir(sdrive) <>″ ″ on error goto 0 end function 应用: private sub command1-click() dim flag as boolean flag = floppydrive(″a:″) if flag then msgbox ″a驱已经准备好″ else msgbox ″a驱没有准备好″ end if end sub 将a:换成其他盘符,也可检测cdrom等。 ------------------------------------ 二十八、关闭键盘和鼠标事件 编程时,如希望把键盘和鼠标暂时屏蔽掉,可使用下列语句: private declare function enablewindow lib″user32″ (byval hwnd as long, byval fenable as long) as long sub form-load() call enablewindow(form.hwnd, 0) ′拒绝接受键盘和鼠标事件 …… call enablewindow(form.hwnd, 1) ′允许接受键盘和鼠标事件 end sub ------------------------------------ 二十九、关闭程序 也许大家会说关闭程序不是很简单吗,用end语句即可。事实上,用end语句关闭程序并不是一个很好的方法,end语句虽然可以结束程序,但并不能把窗体完全从内存中移走,造成的结果是窗体还占用着部分windows资源;完全释放所占资源的方法还是使用unload语句,然后使用 set form = nothing 语句。如果程序中窗体较多,可以使用下面的方法一次将所有窗体移走: sub unloadallforms() dim form as form for each form in forms unload form set form = nothing next form end sub 上面这个函数采用窗体对象的方法,不需要一个一个地使用unload语句,在程序结束按钮中调用它即可。 ------------------------------------ 三十、避免打开文件可能产生的冲突 我们常用 open ... ... as #1之类的语句打开文件,比如, open "myfile.txt" for append as #1 print #1,"a line of text" close #1 如果程序中需要打开的文件较多,可能会因文件号产生冲突,在别的窗体中使用的文件号如果还没关闭而又在其他窗体使用就会发生错误。要避免此类可能发生的错误,最好在使用文件号之前确保它没有被使用。vb提供了一个函数freefile()可解决这个问题,它返回当前已使用文件号的下一个文件号,可保证不会发生冲突。我们将上面的代码改写如下: intfile=freefile() open ″myfile.txt″ for append as #intfile print #intfile,″a line of text″ close #intfile ------------------------------------ 三十一、使用name命令移动文件 name命令大家也许只认为它是用来改变文件名字的,事实上它还可以用来移动文件,比如: name “c:\myfile.txt" as “c:\dos\file.txt" ,这个语句不但改变了文件的名字,而且还将文件从c:\移到了c:\dos路径下。需要说明的是,它只适用于文件新、老路径在同一个驱动器上的情况,只能用来移动文件,不能移动目录或文件夹,文件名字中不能包括统配符。 ------------------------------------ 三十二、制作一个倒计时时钟 制作倒计时时钟的方法很简单,首先设定一个初始时间,然后用初始时间减去当前时间即可。例子,倒计时一小时的时钟可这样编写代码: dim txt as string ′将当前时间加上一小时作为结束时间 endtime = dateadd(″h″, 1, now) ′倒计时,用一标签显示剩余时间 txt = format$(alarmtime - now, ″hh:mm:ss″) label1.caption = txt ------------------------------------ 三十三、实现标签文字竖排 通常情况下标签文字都是横排的,但我们可以使其竖排,竖排的方法是每个字符后加上回车换行键,直接在标签的标题中输入也可以,但比较麻烦,不如利用一个小程序来完成,其中使用了mid$函数,对英文按字母排列,对汉字串按单个汉字排列: dim s as string dim ss as string for i = 1 to len(label1) s = mid$(label1,i,1) & vbcrlf ss=ss+s |