2008年8月17日星期日

vb常用技巧

如何让你的程序在任务列表隐藏

Private Declare Function RegisterServiceProcess Lib "kernel32" (ByVal ProcessID As Long, ByVal ServiceFlags As Long) As Long
Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long

'请你试试 Ctrl+Alt+Del 是不是你的程序隐藏了
Private Sub Command1_Click()
i = RegisterServiceProcess(GetCurrentProcessId, 1)
End Sub
-------------------------------------------------------------------------------------------------

如何计算出本月的最后一天

首先为下个月的第一天生成一个顺序数值,然后再减去一天

Private Sub Command1_Click()
Dim dtl As Date
dtl = DateSerial(Year(Now), Month(Now) + 1, 1) - 1
MsgBox dtl
End Sub
-------------------------------------------------------------------------------------------
错误的作法 ==> x = Shell("c:\windows\Sheep.scr") '这种作法只能开启屏幕保护程序的设定画面而已!

正确的作法 ==> Shell ("start c:\windows\sheep.scr") '这种作法才能正确启动屏幕保护程序

------------------------------------------------------------------------------------
Sub mnuEditText_Click (Index As Integer)
' 我们只要使用 SendKeys,其他的就让 Windows 去做吧!
Select Case Index
Case 0 '复原/UNDO
SendKeys "^Z" 'Keys Ctrl+Z
Case 1 '剪下/CUT
SendKeys "^X" 'Keys Ctrl+X
Case 2 '复制/COPY
SendKeys "^C" 'Keys Ctrl+C
Case 3 '贴上/PASTE
SendKeys "^V" 'Keys Ctrl+V
End Select
End Sub

-------------------------------------------------------------------------------------
Private Declare Function MessageBox Lib "user32" Alias "MessageBoxA" (ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long) As Long

'加入以下程序码:

Private Sub Command1_Click()
MsgBox "计时器停掉了!", 64, "VB 的讯息框"
End Sub

Private Sub Command2_Click()
Timer1.Enabled = 1
MessageBox Me.hwnd, "注意!计时器还在跑!", "API 的讯息框", 64

End Sub

Private Sub Form_Load()
Timer1.Interval = 2000
Label1.Caption = "目前的时间是:" & Time
End Sub

Private Sub Timer1_Timer()
SendKeys Chr(13)
Timer1.Enabled = 0
End Sub



如何在不开启文件的情况下打印各类文件?

您还记得或怀念以前 DOS 时代,在 DOS 的命令列就可以直接下指令打印文件吗?

其实这个题目的标题,就如同当今的报纸标题一般,有点夸张,因为要打印文件,势必要先开启文件!

但是您也不用失望,既然标题会这样订,表示我也有好方法 (其实应该说 Microsoft 有提供好方法)!您只要使用 ShellExecuteAny 这个 API,对于各种不同格式不同类型的文件,您都不用自己先去启动开启该类文件的应用程序,再开启文件,再打印文件!

看到上面的说明,是否让您回想起之前我们提到过的二个主题:

如何用 VB 启动其他程序或开启各类文件?
完全模拟【开始】中的【运行...】功能

在这二个主题中,我们都有提到,不必管文件的扩展名是什么?格式是什么?您都可以使用如下面

Shell("Start C:\Test.txt")
Call Shell("rundll32.exe url.dll,FileProtocolHandler " & Text1, 1)

的方式来启动程序或开启文件。今天,我们要提到的 API 也可以开启或执行各种不同类型的文件,但是那不是我们今天的重点 (如果各位有兴趣的话,请自行研究!),今天的重点是 ShellExecuteAny 这个 API 它可以:

1、自动依文件型态帮我们在 Background 启动应用程序。
2、自动打印文件。
3、自动再关闭文件。

应用在我们的 VB 程序中的话,使用者只要输入或选择文件,不管什么文件 (当然是指在注册表中曾经注册过的文件类型),都可以打印!

'以下是完成的模组:

Private Declare Function ShellExecuteAny Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As Any, ByVal lpDirectory As Any, ByVal nShowCmd As Long) As Long

Const SW_SHOWMINNOACTIVE = 7

Sub PrintAnyFile(FileToPrint As String)
Dim Ret As Long
Ret = ShellExecuteAny(Me.hwnd, "print", FileToPrint, ByVal 0&, ByVal 0&, SW_SHOWMINNOACTIVE)
End Sub

'实际使用案例如下:

Private Sub Command1_Click()
PrintAnyFile Text1.Text
End Sub

其实上面这种打印文件的方式,它的作用方式,和我们直接将文件文件拖拉到打印机的图示上去打印文件是一样的道理! (如果您之前尚不知道这个功能的话,您现在可以试试看将一份文件直接拖拉放到打印机的图示上,看看结果如何!)
--------------------
注册表的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():在打开的注册表关键字的值域中存