Visual Basic编程疑难问题解一二.docx
- 文档编号:11926783
- 上传时间:2023-06-03
- 格式:DOCX
- 页数:43
- 大小:32.40KB
Visual Basic编程疑难问题解一二.docx
《Visual Basic编程疑难问题解一二.docx》由会员分享,可在线阅读,更多相关《Visual Basic编程疑难问题解一二.docx(43页珍藏版)》请在冰点文库上搜索。
VisualBasic编程疑难问题解一二
VisualBasic编程疑难问题解
(一)
(二)
[前言:
]在这个专题中我收集了一些在VisualBasic编程中的常见问题,这些问题均来自论坛,本专题以解决实际问题主要目的。
问:
VB中如何使用C++类?
答:
把vc的类编译成dll文件,这样的话就可以使用,最好是作为组件com来使用。
VB调用DLL的方法和调用WindowsAPI的方法是一样的,一般在VB的书中有介绍。
对于上面一个例子,先要声明VC函数:
DeclareFunctionsampleLib"mydll.dll"(ByValnLenAsInteger,bufferAsInteger)AsInteger
这里mydll.dll是你的dll的名字。
你可能已经注意到了两个参数的声明有所不同,第一个参数加上了ByVal。
规则是这样的:
如果在VC中某个参数声明为指针和数组,就不加ByVal,否则都要加上ByVal。
在VB中调用这个函数采用这样的语法:
sample10,a(0)
这里的a()数组是用来存放数据的,10为数组长度,这里的第二个参数不能是a(),而必须是要传递的数据中的第一个。
这是VB编程的关键。
下面在说几个可能遇到的问题。
一个问题是VB可能报告找不到dll,你可以把dll放到system目录下,并确保VB的Declare语句正确。
另一个问题是VB报告找不到需要的函数,这通常是因为在VC中*.def文件没设置。
第三种情况是VB告诉不能进行转换,这可能是在VC中没有加上__stdcall关键字,也可能是VB和VC的参数类型不一致,注意在VC中int是4个字节(相当于VB的Long),而VB的Integer只有2个字节。
必须保证VB和VC的参数个数相同,所占字节数也一致。
最后一个要注意的问题是VC中绝对不能出现数组越界的情况,否则会导致VB程序崩溃。
问:
怎样用编程方式在窗体上创建一个label或textbox?
答:
代码如下:
'声明
PrivateWithEventsNewButtonAsComandButton
'1,添加
SetNewButton=Controls.Add("VB.CommandButton","cmdNew",Me)
NewButton.Move0,0,Width,Height
NewButton.Visible=True
'2,删除
Controls.RemoveNewButton
SetNewButton=Nothing
问:
如何把一个已编译的EXE程序打包到VB中再编译呢?
答:
你需要先编写一个程序B,并将其编译为EXE。
如果你希望今后允许程序A定制程序B的某个文本框,可以先将该文本框的Caption属性设置为“ChangeMe!
ChangeMe!
”之类首先定义好的字符串。
然后程序A以二进制方式打开程序B,然后在其中查找“ChangeMe!
ChangeMe!
”字符串,并将其改变为程序A中设置的文字。
但这种方法有几个缺点:
1、字符串长度有限;
2、对于VB来说,编译后有的中文字符串编译后格式有些办法,不好处理。
也可以采用另一种办法。
程序A将设置信息保存在程序B文件的尾部。
用程序B以二进制方式打开其自己的EXE文件,利用Seek命令移动到指定位置读出设置信息。
如:
DimsAsString*100
OnErrorGoToErrHandler
OpenApp.Path+"\"+App.EXEName+".EXE"ForBinaryAs#1
Seek1,20480'这里是EXE文件的长度
Get1,,s
Label1.Caption=s
Close#1
ExitSub
问:
如何确定EXE文件的长度的具体数值呢?
答:
先编译程序B,看看程序B的EXE文件的长度,例如17234。
然后将上面的20480改为17234,再编译一次程序B。
问:
关于程序热键公用问题?
如果两个程序都用到了相同的热键比如说ctrl+enter当这2个程序同时运行起来的时候,怎么才能让只有一个程序接受热键,换句话说就是谁在前台(前面激活状态)谁就使用这个热键,谁在后台或者最小化等非激活状态那么就不使用这个热键!
怎么能做到呢?
答:
代码如下:
PrivateSubText2_KeyDown(KeyCodeAsInteger,ShiftAsInteger)
IfShift=2Then
IfKeyCode=vbKeyReturnThen
Text1.Text=Text2.Text
Text2.Text=""
EndIf
EndIf
EndSub
问:
在用二进制binary,写入一个字串时(比如"你好")后,如何用get读出来?
答:
在VB读和写有专用的语法,或者直接使用FSO,如:
Open文件所在路径ForOutputAs#1
Write#1,"你好"
Close
(1)
'这是写文件操作
读的话类同,用lineinput读出来就可以了。
问:
怎样让Listbox中的滚动条的颜色与Listbox的背景颜色一致?
答:
其实要看每个控件是否可以设置颜色,一般检查一下控件的backcorlor和forecolor属性就可以了,有的话,自己设置吧。
问:
怎么让form时刻处于最上方,formName.show不能做到这一点?
答:
代码如下:
PrivateDeclareFunctionSetWindowPosLib"user32"(ByValhwndAsLong,ByValhWndInsertAfterAsLong,ByValxAsLong,ByValyAsLong,ByValcxAsLong,ByValcyAsLong,ByValwFlagsAsLong)AsLong
PrivateConstHWND_TOPMOST=-1
PrivateConstSWP_NOMOVE=&H2
PrivateConstSWP_NOSIZE=&H1
PrivateSubForm_Load()
SetWindowPosMe.hwnd,HWND_TOPMOST,0,0,Me.Width,Me.Height,SWP_NOMOVEOrSWP_NOSIZE
EndSub
问:
定义在类中的Procedure和Function有什么区别?
他们是不是都可以单独存在?
答:
procedure是声明一个过程,没有返回值.
function是声明一个函数,有返回值的.
问:
VB中在textbox中查找单个的字符或字符串有什么好方法?
如:
在textbox中查找:
如textbox.text="12345678"查找"78"或"8"代码怎么写?
答:
用instr函数
例:
DimiAsInteger
Text1.Text="12345678"
i=instr(text1.text,"78"
i的值就是在textBox中找到的字符串"78"的第一次出现的位置.
问:
怎样判断程序是否在运行,如果运行怎样关闭他呢?
答:
先用findwindow得到你要查的窗口的hwnd,然后用sendmessgeyourform.hwnd,wm_close,0
Privatebutton1_click()
DimtmpAsLong
tmp=findwindow(vbNullString,"程序的窗口名VB中FORM的NAME属性值")
Iftmp>0Then
SendMessagetmp,wm_close,0
Else
MsgBox"Sorry!
Don'tfindformname"
EndIf
EndSub
问:
如何用vb实现真正的多线程而不是多进程?
答:
1.最好把代码放在ActiveDll里,编译时使用p代码方式,至少要装vbsp3以上
2.线程函数里不能有VB的内置函数,比如left,trim等
3.创建线程CreateThread的参数不要使用ByVal&0,使用变量
主程序退出时要使用TerminateProcess(GetCurrentProcess,ByVal0&)强行结束当前进程,否则有可能出错,这是两个API函数,请查相关资料
问:
局域网点对点传输,如何数据加密?
怎样实现?
答:
在text1中输入你要加密的数据(16进制)
将它和4E进行异或
再按就把数据还原了
PrivateSubCommand1_Click()
tmp=Hex(Val("&H"&Text1.Text)XorVal("&H"&"4E"))
Text1.Text=tmp
EndSub
问:
如何实现鼠标取词?
'所要用到的函数、常量、类型
PrivateDeclareFunctionSendMessageLib"user32"Alias"SendMessageA"(ByValhwndAsLong,ByValwMsgAsLong,ByValwParamAsLong,lParamAsAny)AsLong
PrivateDeclareFunctionWindowFromPointLib"user32"(ByValxAsLong,ByValyAsLong)AsLong
PrivateDeclareFunctionGetCursorPosLib"user32"(lpPointAsPOINTAPI)AsLong
PrivateConstWM_GETTEXT=&HD
PrivateConstWM_SETTEXT=&HC
PrivateTypePOINTAPI
xAsLong
yAsLong
EndType
PrivateSubForm_Load()
EndSub
PrivateSubTimer1_Timer()
'
'代码就是这么简单,你好好研究一下吧。
'
'
DimShuAsPOINTAPI
DimstrAsString*300
GetCursorPosShu
SendMessageWindowFromPoint(Shu.x,Shu.y),WM_GETTEXT,299,ByValstr
Label1.Caption=str
EndSub
根据代码加入相应控件,timer1的interval的属性为100再加入把当前窗口置顶就是一个完美的简单的取词工具了!
问:
VB调DLL时,如何传Structure?
答:
在DLL里定义时应该用指针作参数,在VB里面,只要把结构变量定义成Long类型就可以了,调用的时候传入地址,就是在调用的时候,在参数前面加ByVal。
问:
如何可以在VB中实现对整个系统鼠标和键盘的屏蔽
答:
我们常见一些导览系统或教学系统,会自动移动Mouse与Keyin字,而那个时候,我们不管Keyin或动Mouse都没有效,直到完成了导览系统的某个动作後才让使用者可以移动Mouse与做Keyin的动作;想做到这个,要借重JournalPlayBackHook。
JournalPlayBackHook,它和JournalRecordHook合称JournalHook,它们作用范围是整个System,也就是挂上这个Hook後,影响的层面不单是这个Process,而是有的Process,而这两Hook又不用写在Dll之中,所以很好用。
首先我们要知道由键盘和Mouse输入等的硬体讯息,会存到一个SystemQueue而後OS会该SystemQueue看有没有讯息在其中,若有则撷取出来,看目前Active的Window是谁将讯息Post给它。
而挂上JournalRecordHook时,当有讯息被撷取出来时,会先执行他们所设定的HookFunction(在vb中,一定要放在.BAS档之中)。
这可以做什麽事呢?
例如我们可以Check整个系统是否有按了键盘或有没有移动Mouse(一般来说,KeyUp,KeyDown,MouseMove等Event只有Form在Active时才收得到,挂上JournalRecordhook後,执行Hook的thread便能收到所有这些讯息)。
再如,它既然能收到Keyboard、Mouse的讯息,那便可以将收到的讯息记录起来(记录於Memory或Disk都可以),之後再依方才的顺序重新将讯息放送出来,可重新执行方才的动作(这不就是巨集的作法吗),或许它叫JournalRecord便是这个原因。
再来便是播放记录讯息的问题了,如果一面播放,一面有其他讯息插队(如移动Mouse),那就不对了,所以JournalPlayBack这个Hook它会让Mouse、Keyboard都失效,当OS要求读SystemQueue时,便会启动这个Hook,就在此时,我们可以把方才记录起来的讯息丢出一个出来,OS再要求读SystemQueue时,再丢下一个讯息,如此达重播的效果(所以才叫JournalPlayBack),正因它会让键盘、Mouse失效,拿它来做导览、教学系统的自动MoveMouse或文字显示是最适合的了。
Mouse的自动导引系统制作方式,可叁考如何自动移动Mouse
'以下在.Bas中
DeclareSubSleepLib"kernel32"(ByValdwMillisecondsAsLong)
ConstWM_MOUSELAST=&H209
ConstWM_MOUSEFIRST=&H200
PublicConstWM_KEYLAST=&H108
PublicConstWM_KEYFIRST=&H100
PublicConstWH_JOURNALRECORD=0
PublicConstWH_JOURNALPLAYBACK=1
TypeEVENTMSG
messageAsLong
paramLAsLong
paramHAsLong
timeAsLong
hwndAsLong
EndType
DeclareFunctionSetWindowsHookExLib"user32"Alias_
"SetWindowsHookExA"(ByValidHookAsLong,ByVallpfnAsLong,_
ByValhmodAsLong,ByValdwThreadIdAsLong)AsLong
DeclareFunctionUnhookWindowsHookExLib"user32"_
(ByValhHookAsLong)AsLong
DeclareFunctionCallNextHookExLib"user32"(ByValhHookAsLong,_
ByValnCodeAsLong,ByValwParamAsLong,lParamAsAny)AsLong
PublichNxtHookAsLong'handleofHookProcedure
PublicmsgAsEVENTMSG
SubEnableHook()
hNxtHook=SetWindowsHookEx(WH_JOURNALPLAYBACK,AddressOfHookProc,App.hInstance,0)
EndSub
SubFreeHook()
DimretAsLong
ret=UnhookWindowsHookEx(hNxtHook)
EndSub
FunctionHookProc(ByValcodeAsLong,ByValwParamAsLong,_
ByVallParamAsLong)AsLong
HookProc=CallNextHookEx(hNxtHook,code,wParam,lParam)
EndFunction
'以下在Form中,需求:
一个Command1,一个text1
PrivateSubCommand1_Click()
Dimstr5AsString,len5AsLong,iAsLong
CallEnableHook
str5="这是一个测试JournalPlayBackHook的程式"
len5=Len(str5)
Fori=1Tolen5
Text1.Text=Mid(str5,1,i)
Text1.Refresh
Sleep(200)
Next
CallFreeHook
EndSub
问:
如何把picture控件中图形数据写成“流”?
答:
可以使用adodb.stream对象?
上传图片或显示SWF的时候都希望得到它的高度和宽度,基本原理使用Adodb.Stream读二进制文件然后进行解析,然后返回一数组:
第一个元素为类型(BMPJPGPNGGIFSWF)
第二个元素为宽度{width}
第三个元素为高度{height}
第四个元素为width={width},height={height}式字符串
ClassqswhImg
Dimaso
PrivateSubClass_Initialize()
Setaso=CreateObject("Adodb.Stream")
aso.Mode=3
aso.Type=1
aso.Open
EndSub
PrivateSubClass_Terminate()
Setaso=Nothing
EndSub
PrivateFunctionBin2Str(bin)
Dimi,str
Fori=1ToLenB(bin)
clow=MidB(bin,i,1)
IfAscB(clow)<128Then
str=str&Chr(AscB(clow))
Else
i=i+1
Ifi<=LenB(bin)Thenstr=str&Chr(AscW(MidB(bin,i,1)&clow))
EndIf
Next
Bin2Str=str
EndFunction
PrivateFunctionNum2Str(num,base,lens)
'qiushuiwuhen(2002-8-12)
Dimret
ret=""
While(num>=base)
ret=(numModbase)&ret
num=(num-numModbase)/base
Wend
Num2Str=Right(String(lens,"0")&num&ret,lens)
EndFunction
PrivateFunctionStr2Num(str,base)
'qiushuiwuhen(2002-8-12)
Dimret
ret=0
Fori=1ToLen(str)
ret=ret*base+CInt(Mid(str,i,1))
Next
Str2Num=ret
EndFunction
PrivateFunctionBinVal(bin)
'qiushuiwuhen(2002-8-12)
Dimret
ret=0
Fori=LenB(bin)To1Step-1
ret=ret*256+AscB(MidB(bin,i,1))
Next
BinVal=ret
EndFunction
PrivateFunctionBinVal2(bin)
'qiushuiwuhen(2002-8-12)
Dimret
ret=0
Fori=1ToLenB(bin)
ret=ret*256+AscB(MidB(bin,i,1))
Next
BinVal2=ret
EndFunction
FunctiongetImageSize(filespec)
'qiushuiwuhen(2002-9-3)
Dimret(3)
aso.LoadFromFile(filespec)
bFlag=aso.Read(3)
SelectCaseHex(BinVal(bFlag))
Case"4E5089":
aso.Read(15)
ret(0)="PNG"
ret
(1)=BinVal2(aso.Read
(2))
aso.Read
(2)
ret
(2)=BinVal2(aso.Read
(2))
Case"464947":
aso.Read(3)
ret(0)="GIF"
ret
(1)=BinVal(aso.Read
(2))
ret
(2)=BinVal(aso.Read
(2))
Case"535746":
aso.Read(5)
binData=aso.Read
(1)
sConv=Num2Str(AscB(binData),2,8)
nBits=Str2Num(Left(sConv,5),2)
sConv=Mid(sConv,6)
while(len(sConv)binData=aso.Read
(1)
sConv=sConv&Num2Str(ascb(binData),2,8)
Wend
ret(0)="SWF"
ret
(1)=Int(Abs(Str2Num(Mid(sConv,1*nBits+1,nBits),2)-Str2Num(Mid(sConv,0*nBits+1,nBits),2))/20)
ret
(2)=Int(Abs(Str2Num(Mid(sConv,3*nBits+1,nBits),2)-Str2Num(Mid(sConv,2*nBits+1,nBits),2))/20)
Case"FFD8FF":
Do
Do:
p1=BinVal(aso.Read
(1)):
LoopWhilep1=255AndNotaso.EOS
Ifp1>191Andp1<196ThenExitDoElseaso.Read(BinVal2(aso.Read
(2))-2)
Do:
p1=BinVal(aso.Read
(1)):
LoopWhilep1<255AndNotaso.EOS
L
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Visual Basic编程疑难问题解一二 Basic 编程 疑难 题解 一二
![提示](https://static.bingdoc.com/images/bang_tan.gif)