您现在的位置是: 软件 > 开发者网络 > 程序方舟 > 开发专栏 > VB开发 > 正文
·速成电脑精英(包分配)白领高薪一族从这里开始



-与“蠕虫王”战斗到底
-三款资源访问辅助工具使用
-五款即时通讯软件横向比较
-天极贺卡大赛新春贺卡精选

Visual Basic编程疑难问题解(一)
2003-02-03· ···yesky

上一页  1 2 3 4  


  问:如何可以在VB中实现对整个系统鼠标和键盘的屏蔽

  答:我们常见一些导览系统或教学系统,会自动移动Mouse与Keyin字,而那个时候,我们不管Keyin或动Mouse都没有效,直到完成了导览系统的某个动作後才让使用者可以移动Mouse与做Keyin的动作;想做到这个,要借重JournalPlayBack Hook。

  JournalPlayBack Hook,它和JournalRecord Hook合称Journal Hook,它们作用范围是整个System,也就是挂上这个Hook後,影响的层面不单是这个Process,而是有的Process,而这两Hook又不用写在Dll之中,所以很好用。

  首先我们要知道由键盘和Mouse输入等的硬体讯息,会存到一个System Queue而後OS会该System Queue看有没有讯息在其中,若有则撷取出来,看目前Active的Window是谁将讯息Post给它。而挂上JournalRecord Hook时,当有讯息被撷取出来时,会先执行他们所设定的Hook Function(在vb中,一定要放在.BAS档之中)。这可以做什麽事呢?

  例如我们可以Check整个系统是否有按了键盘或有没有移动Mouse(一般来说,KeyUp,KeyDown, MouseMove等Event只有Form在Active 时才收得到,挂上JournalRecord hook後,执行Hook的thread便能收到所有这些讯息)。再如,它既然能收到Keyboard、Mouse的讯息,那便可以将收到的讯息记录起来(记录於Memory或Disk都可以),之後再依方才的顺序重新将讯息放送出来,可重新执行方才的动作(这不就是巨集的作法吗),或许它叫JournalRecord便是这个原因。再来便是播放记录讯息的问题了,如果一面播放,一面有其他讯息插队(如移动Mouse),那就不对了,所以JournalPlayBack这个Hook它会让Mouse、Keyboard都失效,当OS 要求读System Queue时,便会启动这个Hook,就在此时,我们可以把方才记录起来的讯息丢出一个出来,OS再要求读System Queue时,再丢下一个讯息,如此达重播的效果(所以才叫JournalPlayBack),正因它会让键盘、Mouse失效,拿它来做导览、教学系统的自动Move Mouse或文字显示是最适合的了。

  Mouse的自动导引系统制作方式,可叁考如何自动移动Mouse

'以下在.Bas中
Declare Sub Sleep Lib "KERNEL32" (ByVal dwMilliseconds As Long)
Const WM_MOUSELAST = &H209
Const WM_MOUSEFIRST = &H200
Public Const WM_KEYLAST = &H108
Public Const WM_KEYFIRST = &H100
Public Const WH_JOURNALRECORD = 0
Public Const WH_JOURNALPLAYBACK = 1

Type EVENTMSG
message As Long
paramL As Long
paramH As Long
time As Long
hwnd As Long
End Type
Declare Function SetWindowsHookEx Lib "user32" Alias _
"SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, _
ByVal hmod As Long, ByVal dwThreadId As Long) As Long
Declare Function UnhookWindowsHookEx Lib "user32" _
(ByVal hHook As Long) As Long
Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _
ByVal nCode As Long, ByVal wParam As Long, lParam As Any) As Long
Public hNxtHook As Long ' handle of Hook Procedure
Public msg As EVENTMSG

Sub EnableHook()
hNxtHook = SetWindowsHookEx(WH_JOURNALPLAYBACK, AddressOf HookProc, App.hInstance, 0)
End Sub
Sub FreeHook()
Dim ret As Long
ret = UnhookWindowsHookEx(hNxtHook)
End Sub
Function HookProc(ByVal code As Long, ByVal wParam As Long, _
ByVal lParam As Long) As Long
HookProc = CallNextHookEx(hNxtHook, code, wParam, lParam)
End Function

'以下在Form中,需求:一个Command1, 一个text1
Private Sub Command1_Click()
Dim str5 As String, len5 As Long, i As Long

Call EnableHook
str5 = "这是一个测试JournalPlayBackHook的程式"
len5 = Len(str5)
For i = 1 To len5
Text1.Text = Mid(str5, 1, i)
Text1.Refresh
Sleep (200)
Next
Call FreeHook
End Sub

  问:如何把picture控件中图形数据写成“流”?

  答:可以使用adodb.stream对象。
  上传图片或显示SWF的时候都希望得到它的高度和宽度,基本原理使用Adodb.Stream读二进制文件然后进行解析,然后返回一数组:

  第一个元素为类型(BMP JPG PNG GIF SWF)

  第二个元素为宽度{width}

  第三个元素为高度{height}

  第四个元素为width={width},height={height}式字符串


Class qswhImg
dim aso
Private Sub Class_Initialize
set aso=CreateObject("Adodb.Stream")
aso.Mode=3
aso.Type=1
aso.Open
End Sub
Private Sub Class_Terminate
set aso=nothing
End Sub

Private Function Bin2Str(Bin)
Dim I, Str
For I=1 to LenB(Bin)
clow=MidB(Bin,I,1)
if ASCB(clow)<128 then
Str = Str & Chr(ASCB(clow))
else
I=I+1
if I <= LenB(Bin) then Str = Str & Chr(ASCW(MidB(Bin,I,1)&clow))
end if
Next
Bin2Str = Str
End Function

Private Function Num2Str(num,base,lens)
'qiushuiwuhen (2002-8-12)
dim ret
ret = ""
while(num>=base)
ret = (num mod base) & ret
num = (num - num mod base)/base
wend
Num2Str = right(string(lens,"0") & num & ret,lens)
End Function

Private Function Str2Num(str,base)
'qiushuiwuhen (2002-8-12)
dim ret
ret = 0
for i=1 to len(str)
ret = ret *base + cint(mid(str,i,1))
next
Str2Num=ret
End Function

Private Function BinVal(bin)
'qiushuiwuhen (2002-8-12)
dim ret
ret = 0
for i = lenb(bin) to 1 step -1
ret = ret *256 + ascb(midb(bin,i,1))
next
BinVal=ret
End Function

Private Function BinVal2(bin)
'qiushuiwuhen (2002-8-12)
dim ret
ret = 0
for i = 1 to lenb(bin)
ret = ret *256 + ascb(midb(bin,i,1))
next
BinVal2=ret
End Function

Function getImageSize(filespec)
'qiushuiwuhen (2002-9-3)
dim ret(3)
aso.LoadFromFile(filespec)
bFlag=aso.read(3)
select case hex(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)): loop while p1=255 and not aso.EOS
if p1>191 and p1<196 then exit do else aso.read(binval2(aso.Read(2))-2)
do:p1=binVal(aso.Read(1)):loop while p1<255 and not aso.EOS
loop while true
aso.Read(3)
ret(0)="JPG"
ret(2)=binval2(aso.Read(2))
ret(1)=binval2(aso.Read(2))
case else:
if left(Bin2Str(bFlag),2)="BM" then
aso.Read(15)
ret(0)="BMP"
ret(1)=binval(aso.Read(4))
ret(2)=binval(aso.Read(4))
else
ret(0)=""
end if
end select
ret(3)="width=""" & ret(1) &""" height=""" & ret(2) &""""
getimagesize=ret
End Function
End Class

  使用范例(读某目录下所有图片的宽度):


set qswh=new qswhImg

Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFolder(server.mappath("."))
Set fc = f.Files
For Each f1 in fc
ext=fso.GetExtensionName(f1.path)
select case ext
case "gif","bmp","jpg","png":
arr=qswh.getImageSize(f1.path)
response.write "
" & arr(0) & " " & arr(3) & ":" & f1.name & " width:" & arr(1) & " height:" & arr(2)
case "swf"
arr=qswh.getimagesize(f1.path)
response.write "
" & arr(0) & " " & arr(3) & ":" & f1.name & " width:" & arr(1) & " height:" & arr(2)
end select

Next
Set fc=nothing
Set f=nothing
Set fso=nothing
Set qswh=nothing





上一页  1 2 3 4  

【责任编辑:方舟】
【发表评论】【关闭窗口】
■ 相关内容
 实战Visual Basic条形码编程
 FSO对象模型在VB中的应用
 如何编写高质量的VB代码
 运用VB.net创建Web服务访问程序
 VB多类图片数据库存取技巧
 用VB6设计有趣的动画场景
 用VB设计有安全认证服务的Email
 VB串口使用心得两则
 VB.NET实现超级ptm查看器
 VB.NET注册表编程
 VB中利用OpenGL绘制三维地质构造图
 如何在VB例程中接收自定义消息
 怎样实现在VB窗体中有Html页面
 如何用VB.Net创建一个三层的数据库应用程序
 Visual Studio使可编程Web语言的革新发生在VB.NET中
感谢 访问天极网,如果您觉得该文章涉及版权问题,请看这里!