top
Loading...
VisualBasic編程常見問題及解答
各位朋友大家好,如果你在論壇的時間夠長,那么你會發現很多帖子的問題是相同的,既然這樣,不如總結到一起讓初學者來翻看,再熱心的大蝦也不愿意把一個答案重復幾十遍。
若朋友您想要問如何才能學好vb,或者入門需要看什么教材一類的問題,建議你抱著一顆刻苦鉆研的心去面對這門學問,多動腦,少提問,遇到不知道的,多查msdn,多看老貼,或者用斷點來親自試驗。實在不會了,請在此貼中查找您的常見問題,如果還沒有,那請您發出新貼,向各位高手討教。

查找方法:按ctrl+f,輸入要查找的問題關鍵字即可,本人只是稍微編輯了一下。

如何用VB建立快捷方式

Private Declare Function fCreateShellLink Lib "STKIT432.DLL" (ByVal lpstrFolderName As String, ByVal lpstrLinkName As String, ByVal lpstrLinkPath As String, ByVal lpstrLinkArgs As String) As Long
Sub Command1_Click()
Dim lReturn As Long
’添加到桌面
lReturn = fCreateShellLink("....Desktop", "Shortcut to Calculator", "c:windowscalc.exe", "")
’添加到程序組
lReturn = fCreateShellLink("", "Shortcut to Calculator", "c:windowscalc.exe", "")
’添加到啟動組
lReturn = fCreateShellLink("Startup", "Shortcut to Calculator", "c:windowscalc.exe", "")
End Sub

如何讓程序在 Windows 啟動時自動執行?

有以下二個方法:

方法1: 直接將快捷方式放到啟動群組中。

方法2:

在注冊檔 HKEY_LOCAL_MACHINE 中找到以下機碼
SoftwareMicrosoftWindowsCurrentVersionRun
新增一個字串值,包括二個部份
1. 名稱部份:自己取名,可設定為 AP 名稱。
2. 資料部份:則是包含 ’全路徑檔案名稱’ 及 ’執行參數’

例如:
Value Name = Notepad
Value Data = c:windowsotepad.exe

在 TextBox 中如何限制只能輸入數字?

參考下列程序:

Sub Text1_KeyPress(KeyAscii As Integer)
If KeyAscii < 48 Or KeyAscii > 57 Then
KeyAscii = 0
End If
End Sub

我希望 TextBox 中能不接受某些特定字符,例如 ’@#$%",有沒有簡單一點的寫法?

方法有好幾種, 以下列舉二種:

方法1: 可以使用 IF 或 Select Case 一個個判斷, 但如果不接受的字符多時, 較麻煩!

方法2: 將要剔除的字符統統放在一個字串中,只要一個 IF 判斷即可 !! 如下:

Private Sub Text1_KeyPress(KeyAscii As Integer)
Dim sTemplate As String
sTemplate = "!@#$%^&*()_+-=" ’用來存放不接受的字符
If InStr(1, sTemplate, Chr(KeyAscii)) > 0 Then
KeyAscii = 0
End If
End Sub

如何讓鼠標進入 TextBox 時自動選定 TextBox 中之整串文字?

這個自動選定反白整串文字的動作,會使得輸入的資料完全取代之前在 TextBox 中的所有字符。

Private Sub Text1_GotFocus()
Text1.SelStart = 0
Text1.SelLength = Len(Text1)
End Sub

如何檢查軟盤驅動器里是否有軟盤?

使用:

Dim Flag As Boolean
Flag = Fun_FloppyDrive("A:")
If Flag = False Then MsgBox "A:驅沒有準備好,請將磁盤插入驅動器!", vbCritical

’-------------------------------
’函數:檢查軟驅中是否有盤的存在
’-------------------------------
Private Function Fun_FloppyDrive(sDrive As String) As Boolean
On Error Resume Next
Fun_FloppyDrive = Dir(sDrive) <> ""
End Function

如何彈出和關閉光驅托盤?

Option Explicit
Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long

Private Sub Command1_Click()
mciExecute "set cdaudio door open" ’彈出光驅
Label2.Caption = "彈 出"
End Sub

Private Sub Command2_Click()
Label2.Caption = "關 閉"
mciExecute "set cdaudio door closed" ’合上光驅
Unload Me
End
End Sub

如何讓你的程序在任務列表隱藏

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

如何用程序控制滑鼠游標 (Mouse Cursor) 到指定位置?

以下這個例子,當 User 在 Text1 中按下 ’Enter’ 鍵后,滑鼠游標會自動移到 Command2 按鈕上方

請在聲明區中加入以下聲明:

’16 位版本: ( Sub 無傳回值 )
Declare Sub SetCursorPos Lib "User" (ByVal X As Integer, ByVal Y As Integer)

’32 位版本: ( Function 有傳回值,Integer 改成 Long )
Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long

’在 Form1 中加入以下程序碼:
Private Sub Text1_KeyPress(KeyAscii As Integer)
If KeyAscii = 13 Then
x% = (Form1.Left + Command2.Left + Command2.Width / 2 + 60) / Screen.TwipsPerPixelX
y% = (Form1.Top + Command2.Top + Command2.Height / 2 + 360) / Screen.TwipsPerPixelY
SetCursorPos x%, y%
End If
End Sub

如何用鼠標移動沒有標題的 Form,或移動 Form 中的控制項?

在聲明區中放入以下聲明:

’16 位版本: ( Sub 無返回值 )
Private Declare Sub ReleaseCapture Lib "User" ()
Private Declare Sub SendMessage Lib "User" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, lParam As Long)

’32 位版本: ( Function 有返回值,Integer 改成 Long )
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

’共用常數:
Const WM_SYSCOMMAND = &H112
Const SC_MOVE = &HF012

’若要移動 Form,程序碼如下:
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim i As Long
i = ReleaseCapture
i = SendMessage(Form1.hwnd, WM_SYSCOMMAND, SC_MOVE, 0)
End Sub

’以上功能也適用于用鼠標在 Form 中移動控制項,程序碼如下:
Private Sub Command1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim i As Long
i = ReleaseCapture
i = SendMessage(Command1.hwnd, WM_SYSCOMMAND, SC_MOVE, 0)
End Sub

檢查文件是否存在?

Function FileExists(filename As String) As Integer
Dim i As Integer
On Error Resume Next
i = Len(Dir$(filename))
If Err Or i = 0 Then FileExists = False Else FileExists = True
End Function

如何設置對VB數據庫連接的動態路徑

我個人因為經常作一些數據庫方面的程序,對于程序間如何與數據庫進行接口的問題之煩是深有體會,因為VB在數據庫鏈接的時候,一般是靜態,即數據庫存放的路徑是固定的,如用VB的DATA,adodc,DataEnvironment 等到作數據庫鏈接時,如果存放數據庫的路徑被改變的話,就會找不到路經,真是一個特別煩的事。

筆者的解決方法是利用app.path 來解決這個問題。

一、用data控件進行數據庫鏈接,可以這樣:

在form_load()過程中放入:

private form_load()
Dim str As String ’定義
str = App.Path
If Right(str, 1) <> "" Then
str = str + ""
End If
data1.databasename=str & "數據庫名"
data1.recordsource="數據表名"
data1.refresh
sub end

這幾句話的意為,打開當前程序運行的目錄下的數據庫,你只要保證你的數據庫在你程序所在的目錄之下就行了。

二、利用adodc(ADO Data Control)進行數據庫鏈接:

private form_load ()
Dim str As String ’定義
str = App.Path
If Right(str, 1) <> "" Then
str = str + ""
End If
str = "Provider=Microsoft.Jet.OLEDB.3.51;Persist Security Info=False;Data Source=" & str & "sl.mdb"
Adodc1.ConnectionString = str
Adodc1.CommandType = adCmdText
Adodc1.RecordSource = "select * from table3"
Adodc1.Refresh
end sub

三、利用DataEnvironment進行數據庫鏈接

可在過程中放入:

On Error Resume Next
If DataEnvironment1.rsCommand1.State <> adStateClosed Then
DataEnvironment1.rsCommand1.Close ’如果打開,則關閉
End If
’i = InputBox("請輸入友人編號:", "輸入")
’If i = "" Then Exit Sub
DataEnvironment1.Connection1.Open App.Path & "userdatabasesl.mdb"
DataEnvironment1.rsCommand1.Open "select * from table3 where 編號=’" & i & "’"
’Set DataReport2.DataSource = DataEnvironment1
’DataReport2.DataMember = "command1"
’DataReport2.show
end sub

四、利用ADO(ActiveX Data Objects)進行編程:

建立連接:

dim conn as new adodb.connection
dim rs as new adodb.recordset
dim str
str = App.Path
If Right(str, 1) <> "" Then
str = str + ""
End If
str = "Provider=Microsoft.Jet.OLEDB.3.51;Persist Security Info=False;Data Source=" & str & "sl.mdb"
conn.open str
rs.cursorlocation=aduseclient
rs.open "數據表名",conn,adopenkeyset.adlockpessimistic
用完之后關閉數據庫:
conn.close
set conn=nothing

如何讓用戶自行輸入方程式,并計算其結果?

假設我們要讓使用者在“方程式”欄位中自由輸入方程式,然后利用方程式進行計算,則引用ScriptControl控件可以很方便地做到。
( ScriptControl 控件附屬于VB 6.0,如果安裝后沒有看到此一控件,可在光盤的 CommonToolsVBScript 目錄底下找此一控件, 其.文件名為Msscript.ocx。) 假設放在窗體上的ScriptControl控件名稱為ScriptControl1,則在“計算”按鈕的Click事件中編寫如下代碼:

Dim Statement As String Statement = "X=" + Text1.Text + vbCrLf + _ "Y=" + Text2.Text + vbCrLf + _ "MsgBox ""計算結果="" & Y " ScriptControl1.ExecuteStatement( Statement

如何讓一個 App 永遠保持在最上層 ( Always on Top )

請在聲明區中加入以下聲明

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

Const SWP_NOMOVE = &H2 ’不更動目前視窗位置
Const SWP_NOSIZE = &H1 ’不更動目前視窗大小
Const HWND_TOPMOST = -1 ’設定為最上層
Const HWND_NOTOPMOST = -2 ’取消最上層設定
Const FLAGS = SWP_NOMOVE Or SWP_NOSIZE

’將 APP 視窗設定成永遠保持在最上層
SetWindowPos Me.hwnd, HWND_TOPMOST, 0, 0, 0, 0, FLAGS

’取消最上層設定
SetWindowPos Me.hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, FLAGS

我要如何在程序中開啟網頁?

在聲明區中聲明如下 (在 .bas 檔中用 Public, 在 Form 中用 Private)

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

在程序中

Intranet:
ShellExecute Me.hWnd, "open", "http://Intranet主機/目錄", "", "", 5
Internet:
ShellExecute Me.hWnd, "open", "http://www.ruentex.com.tw", "", "", 5

VB可以產生四角形以外其他形狀的 Form 嗎?

這個問題,您一定無法想像有多容易,您可以產生任何形狀的 Form,但必須借助 CreateEllipticRgn 及 SetWindowRgn 二個 API ,例如:

Private Declare Function CreateEllipticRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long

Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long

Private Sub Form_Load()
Dim lReturn As Long
Me.Show
lReturn = SetWindowRgn(hWnd, CreateEllipticRgn(10, 10, 340, 150), True)
End Sub

CreateEllipticRgn 之四個參數說明如下:

X1:橢圓中心點之X軸位置,但以 Form 的實№邊界為限。

Y1:橢圓中心點之Y軸位置,但以 Form 的實№邊界為限。

X2:橢圓長邊的長度

Y2:橢圓短邊的長度的

如何移除 Form 右上方之『X』按鈕?

其實 Form 右上方之三個按鈕分別對應到 Form 左上方控制盒 (ControlBox) 中的幾個選項 (縮到最小 / 放到最大 / 關閉),而其中的最大化 (MaxButton) 及最小化 (Minbutton) 都可以直接在 Form 的屬性中設定,但是 VB 并沒有提供設定『X』按鈕的功能!要達到這個功能,必須借助 API:

由于『X』按鈕對應到 ControlBox 的關閉選項,所以我們只要移除系統 Menu (就是ControlBox) 的關閉選項即可!您自己可以先看看您現在使用的 Browser 左上方的系統 Menu,【關閉】選項是在第幾個,不是第 6 個!是第 7 個,分隔線也算一個!分隔線才是第 6 個!

當我們移除了關閉選項之後,會留下一條很奇怪的分隔線,所以最好連分隔線也一并移除。而 Menu 的 Index 是從 0 開始,分隔線是第 6 個,所以 Index = 5。

修正:為了讓程序碼在 Windows NT 也能運作正常,將各 Integer 型態改成 Long。 89.05.04

’抓取系統 Menu 的 hwnd
Private Declare Function GetSystemMenu Lib "user32" Alias "GetSystemMenu" (ByVal hwnd As Long, ByVal bRevert As Long) As Long

’移除系統 Menu 的 API
Private Declare Function RemoveMenu Lib "user32" Alias "RemoveMenu" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long) As Long
’第一個參數是系統 Menu 的 hwnd
’第二個參數是要移除選項的 Index

如何制作透明的表單 (Form)?

請在聲明區中放入以下聲明

Const GWL_EXSTYLE = (-20)
Const WS_EX_TRANSPARENT = &H20&
Const SWP_FRAMECHANGED = &H20
Const SWP_NOMOVE = &H2
Const SWP_NOSIZE = &H1
Const SWP_SHOWME = SWP_FRAMECHANGED Or SWP_NOMOVE Or SWP_NOSIZE
Const HWND_NOTOPMOST = -2

Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
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

在 Form_Load 使用的范例如下:

Private Sub Form_Load()
SetWindowLong Me.hwnd, GWL_EXSTYLE, WS_EX_TRANSPARENT
SetWindowPos Me.hwnd, HWND_NOTOPMOST, 0&, 0&, 0&, 0&, SWP_SHOWME
Me.Refresh
End Sub

如何在 Menu 中加入美美的圖案?

在模組中加入以下程序碼:

Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long

Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long

Declare Function GetMenuItemID Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long

Declare Function SetMenuItemBitmaps Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal hBitmapUnchecked As Long, ByVal hBitmapChecked As Long) As Long

Public Const MF_BITMAP = &H4&

Type MENUITEMINFO
cbSize As Long
fMask As Long
fType As Long
fState As Long
wID As Long
hSubMenu As Long
hbmpChecked As Long
hbmpUnchecked As Long
dwItemData As Long
dwTypeData As String
cch As Long
End Type

Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As Long) As Long

Declare Function GetMenuItemInfo Lib "user32" Alias "GetMenuItemInfoA" (ByVal hMenu As Long, ByVal un As Long, _
ByVal b As Boolean, lpMenuItemInfo As MENUITEMINFO) As Boolean

Public Const MIIM_ID = &H2
Public Const MIIM_TYPE = &H10
Public Const MFT_STRING = &H0&

在 Form 中加入一個 PictureBox,屬性設定為:

AutoSize = True
Picture = .bmp (尺寸大小為 13x13,不可設定為 .ico)

在 Form_Load 中的程序碼如下:

Private Sub Form_Load()
’取得程序中 Mennu 的 handle
hMenu& = GetMenu(Form1.hWnd)
’取得第一個 submenu 的 handle
hSubMenu& = GetSubMenu(hMenu&, 0)
’取得 Submenu 第一個選項的 menuId
hID& = GetMenuItemID(hSubMenu&, 0)
’加入圖片
SetMenuItemBitmaps hMenu&, hID&, MF_BITMAP, Picture1.Picture, Picture1.Picture
’在一個 Menu 選項中您一共可以加入二張圖片
’一張是 checked 狀態用,一張是 unchecked 狀態用
End Sub

如何把小圖片填滿 Form 成為背景圖?

對于這個問題,我看過很多方法,有的方法很麻煩,要聲明一大堆 Type,用一大堆的 API,但是有一個最笨但我認為最好的方法如下: (就好像拼磁磚一樣,不用任何 API, 不必聲明任何 Type)

在 Form 中放一個 PictureBox,Picture 屬性設定為某一張小圖,AutoSize 屬性性設定 True,完成的模組如下:

Sub PictureTile(Frm As Form, Pic As PictureBox)
Dim i As Integer
Dim t As Integer
Frm.AutoRedraw = True
Pic.BorderStyle = 0
For t = 0 To Frm.Height Step Pic.ScaleHeight
For i = 0 To Frm.Width Step Pic.ScaleWidth
Frm.PaintPicture Pic.Picture, i, t
Next i
Next t
End Sub

PictureTile 這個模組共有二個參數,第一個是表單名稱,第二個則是 PictureBox 的名稱。以下為一應用實例:

Private Sub Form_Load()
PictureTile Me, Picture1
End Sub

如何把小圖片填滿 MDIForm 成為背景圖?

以下這個范例,要:

1、一個 MDIForm:不必設定任何屬性。

2、一個 Form1:不一定是 MDIChild,最好 MDIChild 為 False,但是 AutoRedraw 設成 True。

3、Form1 上面放一個隱藏的 PictureBox:名稱為 Picture1,不必設定 Picture 屬性。

4、一張圖片的完整路徑。

’將以下模組放入 MDIForm 的聲明區中:

Sub TileMDIBkgd(MDIForm As Form, bkgdtiler As Form, bkgdfile As String)
If bkgdfile = "" Then Exit Sub
Dim ScWidth%, ScHeight%
ScWidth% = Screen.Width / Screen.TwipsPerPixelX
ScHeight% = Screen.Height / Screen.TwipsPerPixelY
Load bkgdtiler
bkgdtiler.Height = Screen.Height
bkgdtiler.Width = Screen.Width
bkgdtiler.ScaleMode = 3
bkgdtiler!Picture1.Top = 0
bkgdtiler!Picture1.Left = 0
bkgdtiler!Picture1.Picture = LoadPicture(bkgdfile)
bkgdtiler!Picture1.ScaleMode = 3

For n% = 0 To ScHeight% Step bkgdtiler!Picture1.ScaleHeight
For o% = 0 To ScWidth% Step bkgdtiler!Picture1.ScaleWidth
bkgdtiler.PaintPicture bkgdtiler!Picture1.Picture, o%, n%
Next o%
Next n%

MDIForm.Picture = bkgdtiler.Image
Unload bkgdtiler
End Sub

以下為一應用實例:

Private Sub MDIForm_Load()
TileMDIBkgd Me, Form1, "c:windowsTiles.bmp"
End Sub

關閉指定的程序

要做到像 Task Manager 一樣,可以關閉指定的程序,方法如下:

在聲明區中放入以下聲明:(16位改成 win31 API)

Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Public Const WM_CLOSE = &H10

以下之范例示范如何關閉一個視窗標題 (Caption) 為 【小算盤】的程序:

Dim winHwnd As Long
Dim RetVal As Long
winHwnd = FindWindow(vbNullString, "小算盤")
Debug.Print winHwnd
If winHwnd <> 0 Then
RetVal = PostMessage(winHwnd, WM_CLOSE, 0&, 0&)
If RetVal = 0 Then
MsgBox "Error posting message."
End If
Else
MsgBox "并未開啟小算盤程序."
End If

如何隱藏及再顯示鼠標

很簡單,只用到了一個 ShowCursor API,參數也很簡單,只有一個 bShow,設定值如下:

True:顯示鼠標 / False:隱藏鼠標

Declare Function ShowCursor Lib "user32" Alias "ShowCursor" (ByVal bShow As Long) As Long

如何從您的應程序中結束 Windows 重開機?

很多軟件在 Setup 完之后都會自動關機重開機,以便讓某些設定值可以生效,其實這個功能很簡單,只要幾行指令就可以做到了!

關鍵就是要使用 ExitWindowsEx 這個 API,這個 API 只有二個參數,第一個參數是一個 Flag,目的是要告訴 Windows 要以什么方式關機,在下面的聲明中會列出可用的 Flag 常數值,至于第二個參數則是一個保留值,只要設定成 0 就可以了。

很重要的一點是:如果您想要讓關機動作更順利,記得要 Unload 您的程序!

’在聲明區中 (Bas Module / Form Module) 加入以下聲明:

Public Const EWX_LOGOFF = 0 ’這四個常數值可以并用
Public Const EWX_SHUTDOWN = 1
Public Const EWX_REBOOT = 2
Public Const EWX_FORCE = 4

Declare Function ExitWindowsEx Lib "user32" Alias "ExitWindowsEx" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long

’實例:如果您想強迫關機重開機,程序碼如下:

ret = ExitWindowsEx(EWX_FORCE OR EWX_REBOOT, 0)

如何用 VB 啟動其他程序或開啟各類文件?

要在 VB 中啟動其他程序或開啟各類文件,最簡單的方法就是使用 Shell 函數,例如:要開啟 C:Test.txt 這個文字文件,則要啟動記事本來開啟這個文件案,程序如下:

Dim RetVal As Long
RetVal = Shell("C:WindowsNotepad.exe C:Test.txt", 3) ’3代表視窗會最大化,并具有駐點,細節請查 Help

以上的語法雖然很簡單,但有一個風險,若是我們不知道開啟文件的執行文件位置,則程序便會有錯誤產生,尤其一般軟件在安裝的時候都可以讓使用者自行選擇安裝目錄,所以執行文件的路徑不能寫死在程序中,要解決這個問題,就是在注冊文件中找到該副文件名之啟動程序位置,再放入 Shell 中。

但是以上的作法必須熟悉注冊文件,而且必須使用 Windows API 來 Call (注冊文件的存取以后會有專文來說明),如果您對注冊文件的存取及 API 的使用都很純熟的話,當然沒問題,但是有些人對于注冊文件會有畏懼,這時候,您可以使用下面的方法: Shell("Start C:Test.txt")

您完全不用知道這份文件的啟動程序是什么?它放在什么地方?參數 Start 便會自動依照附文件名到注冊文件中找到啟動程序來開啟該份文件案! 不賴吧!

注一:在 Windows 95/98/NT 平臺中, 什么副文件名之文件案, 該由什么執行文件來啟動, 都設在關聯中,

代碼為 HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExtensions

例如: 名稱為 ".DOC" 之資料為 "C:Progra'1Micros'2OfficeWINWORD.EXE ^.DOC"

名稱為 ".TXT" 之資料為 "notepad.exe ^.txt"

注二:使用 Start 之唯一缺點為 "會比直接指定執行文件稍為慢 0.5-1 秒鐘."

如何找出 Windows 目錄的正確路徑?

有時候我們在程序中必須用到 Windows 的目錄,以存取 Windows 目錄下的文件,照理說,這應該是最簡單的功能,前提是每個人在 Setup Windows 必須采用 Windows 的預設目錄名稱,也就是 C:Windows,但是常常不是這樣,有時候由於要使新舊版本共存,或者其他原因,有人會將 Windows 目錄改成 c:win95、c:win98、Windows95 或 Windows98......

若是程序中必須用到 Windows 目錄,要找到正確的路徑,做法如下:

’在聲明區中加入以下聲明:

Const MAX_PATH = 260

Private Declare Function GetWindowsDirectory Lib "kernel32" Alias "GetWindowsDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As Long

Public Function GetWinPath()
Dim strFolder As String
Dim lngResult As Long
strFolder = String(MAX_PATH, 0)
lngResult = GetWindowsDirectory(strFolder, MAX_PATH)
If lngResult <> 0 Then
GetWinPath = Left(strFolder, InStr(strFolder, Chr(0)) - 1)
Else
GetWinPath = ""
End If
End Function

’在程序中使用方法如下:

Private Sub Command1_Click()
Call MsgBox("您電腦中 Windows 目錄的正確路徑是: " & GetWinPath, vbInformation)
End Sub

讓您的文字框有 Undo / Redo 的功能

很多軟件都有提供 Undo / Redo 的功能,Microsoft 的產品都可以提供多次 Undo 反悔,功能更強大!

在 VB 的程序中,我們也可以提供這樣的功能!不過只能 Undo / Redo 一次

’在聲明區中加入以下聲明: ’32位元
’Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
’Const EM_UNDO = &HC7

’16位元
Private Declare Function SendMessage Lib "User" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, lParam As Any) As Long
Const WM_USER = &H400
Const EM_UNDO = WM_USER + 23

’在程序中使用的方式如下: ( Undo Text1 中的輸入 )

Private Sub Command1_Click()
Dim UndoResult As Long
UndoResult = SendMessage(Text1.hwnd, EM_UNDO, 0, 0)
’傳回值 UndoResult = -1 表示 Undo 不成功
End Sub
’使用以上的方法,第一次是 Undo ,第二次就等于是 Redo

如何得到某年每個月的第一天是星期幾

Private Sub Command1_Click()
Dim i As Integer, A As Integer, B As Integer, C As String
A = InputBox("請輸入年份", "某年每個月的第一天是星期幾")
Form1.Cls
For i = 1 To 12
C = A & "-" & i & "-1"
B = Weekday(C)
Select Case B
Case vbSunday
Print A & "年" & i & "月1日是 星期日"
Case vbMonday
Print A & "年" & i & "月1日是 星期一"
Case vbTuesday
Print A & "年" & i & "月1日是 星期二"
Case vbWednesday
Print A & "年" & i & "月1日是 星期三"
Case vbThursday
Print A & "年" & i & "月1日是 星期四"
Case vbFriday
Print A & "年" & i & "月1日是 星期五"
Case vbSaturday
Print A & "年" & i & "月1日是 星期六"
End Select
Next i

End Sub

如何隱藏及顯示任務欄?

有時候,我們希望在我們的程序執行中,將任務欄隱藏,讓桌面變得比較清爽,等到我們的程序執行完畢之后,再將任務欄顯示出來,這時就要用到 SetWindowPos 這個 API 了!

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 Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Const SWP_HIDEWINDOW = &H80 ’隱藏視窗
Const SWP_SHOWWINDOW = &H40 ’顯示視窗

’在程序中若要隱藏任務欄

Private Sub Command1_Click()
Dim Thwnd As Long
Thwnd = FindWindow("Shell_traywnd", "")
Call SetWindowPos(Thwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW)
End Sub

’在程序中若要再顯示任務欄

Private Sub Command2_Click()
Dim Thwnd As Long
Thwnd = FindWindow("Shell_traywnd", "")
Call SetWindowPos(Thwnd, 0, 0, 0, 0, 0, SWP_SHOWWINDOW)
End Sub

模擬 Windows 的資源回收站!

您現在將屏幕上所有的視窗全部縮小,找到資源回收站,按鼠標右鍵,選擇【屬性】,便會出現【資源回收站】的屬性問話框。

其中有幾個選項如下:

1、不要將文件移到資源回收站,刪除時立即移除文件。

2、顯示刪除確認對話框?

根據以上之狀況,文件之刪除有三種情形:

1、刪除文件,出現確認對話框,文件移到資源回收站。

2、刪除文件,出現確認對話框,文件不移到資源回收站。

3、刪除文件,不出現確認對話框,文件也不移到資源回收站。

模擬程序如下:

’在模組的聲明區中加入以下聲明:

Public Type SHFILEOPSTRUCT
hwnd As Long
wFunc As Long
pFrom As String
pTo As String
fFlags As Integer
fAnyOperationsAborted As Long
hNameMappings As Long
lpszProgressTitle As Long
End Type

Public Declare Function SHFileOperation Lib "shell32.dll" Alias "SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) As Long

Public Const FO_DELETE = &H3
Public Const FOF_ALLOWUNDO = &H40 ’可以還原
Public Const FOF_NOCONFIRMATION = &H10 ’不出現確認對話框
Public Const FOF_SILENT = &H4

’在程序中之使用方法如下:
’以下之例子會出現確認對話框,文件也會移到資源回收站。

Private Sub Command1_Click()
Dim SHop As SHFILEOPSTRUCT
Dim strFile As String ’要刪除的文件(含全路徑)
strFile = "c:est.txt"

With SHop
.wFunc = FO_DELETE
.pFrom = strFile
.fFlags = FOF_ALLOWUNDO
End With

SHFileOperation SHop
End Sub

’若要調整,只要更改 fFlags 之值即可,如下:
.fFlags = FOF_SILENT ’刪除文件,出現確認對話框,文件不移到資源回收站。
.fFlags = FOF_NOCONFIRMATION ’刪除文件,不出現確認對話框,文件也不移到資源回收站。

如何得到文件路徑的文件名

Dim sFilePath As String
sFilePath = "C:WindowsSystemsytem.dll"

Dim lGetLen As Long, lNum As Long
Dim sGetFile As String, sTemp As String
lGetLen = Len(sFilePath) ’得到文件路徑長度
sTemp = lGetLen
For lNum = 1 To lGetLen
If Left(sGetFile, 1) = "" Then Exit For
sGetFile = Mid(sFilePath, sTemp, lNum)
sTemp = sTemp - 1
Next lNum
sGetFile = Mid(sGetFile, 2) ’得到文件名
MsgBox sGetFile

如何防止使用者按下 CTRL + ALT + DEL

有些時候,我們的應用程序執行時,不希望使用者按下 CTRL + ALT + DEL 來異常結束程序或關機,這時候我們可以在啟動程序時,將 CTRL + ALT + DEL 功能鍵之功能取消,然后在結束程序之前,再從新恢復 CTRL + ALT + DEL 之功能。

在模組聲明區中加入以下聲明及模組:

Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, lpvParam As Any, ByVal fuWinIni As Long) As Long

Public Const SPI_SCREENSAVERRUNNING = 97

Public Sub Disable_Ctrl_Alt_Del()
’讓 CTRL+ALT+DEL 失效
Dim AyW As Integer
Dim TurFls As Boolean
AwY = SystemParametersInfo(SPI_SCREENSAVERRUNNING, True, TurFls, 0)
End Sub

Public Sub Enable_Ctrl_Alt_Del()
’讓 CTRL+ALT+DEL 恢復功能
Dim AwY As Integer
Dim TurFls As Boolean
AwY = SystemParametersInfo(SPI_SCREENSAVERRUNNING, False, TurFls, 0)
End Sub

’實際使用時,在 Form 中加入以下程序碼:

Private Sub Form_Load()
Disable_Ctrl_Alt_Del
End Sub

Private Sub Form_Unload(Cancel As Integer)
Enable_Ctrl_Alt_Del
End Sub

如何取得文件大小?

VB6 提供了一個新的物件模型,叫做 FSO (File System Object) 物件模型,運用它,我們可以很方便的處理磁盤、資料夾和文件的一些動作。

FSO 物件模型含有好幾個物件,其中有一個 File 物件是用來求得文件的相關資訊,在目前這個主題,我們就可以使用 File 物件!它有一個屬性是 Size,對文件來說就是指文件的大小 (單位為位元組)。 (注一)

雖然使用 File 物件的 Size 屬性就可以求得文件的大小,但是它有以下二個缺點:

1、只能用于 VB6 以后的版本。

2、它不是 VB6 內定的功能,必須另外引用 Scrrun.dll (Microsoft Scripting Runtime) 才可以!

以下的二個方法就可以使用在所有的 VB 版本中 (含 VB6),而且是 VB 內定的功能:

1、FileLen 函數:返回一個 Long,代表一個文件的長度,單位是位元組。

語法:FileLen(pathname) ’ pathname 是全路徑之文件名稱

適用:取得一個尚未開啟的文件的長度大小 (注二)

2、LOF 函數:返回一個 Long ,單位為位元組,用來代表由 Open 陳述式所開啟的文件之大小。

語法:LOF(filenumber) ’ filenumber 是一個文件代碼

適用:取得一個已開啟的文件的長度大小

注一:File 物件的 Size 屬性除了可以求得一個文件的大小,也可以用來取得整個目錄的所有文件大小!

注二:使用 FileLen 函數時,如果所指定的文件正在開啟中,則所返回的值是這個文件在開啟前的大小。

如何移除或更改桌面背景的底色圖案 (Wallpaper)?

SystemParametersInfo 這個 API 可以設定許多 Windows 系統的功能參數,而其中一個參數就是桌面底圖!通常一般的使用者會透過控制面板中的【顯示器】來設定桌面底圖。

在底下的范例中,我們使用 SPI_SETDESKWALLPAPER 這個參數及圖片文件名稱來設定新的桌面底圖,同時使用 SPIF_SENDWININICHANGE 來通知各個視窗這個改變。

’在表單的聲明區中加入以下聲明及常數:

Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As String, ByVal fuWinIni As Long) As Long

Const SPI_SETDESKWALLPAPER = 20
Const SPIF_UPDATEINIFILE = &H1
Const SPIF_SENDWININICHANGE = &H2

’在表單上加入一個 CommandButton (Command1) 來移除桌面底圖,程序碼如下:

Private Sub Command1_Click()
Dim X As Long
X = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0&, "(None)", SPIF_UPDATEINIFILE Or SPIF_SENDWININICHANGE)
MsgBox "桌面底圖 (Wallpaper) 已經被移除"
End Sub

’在表單上加入另一個 CommandButton (Command2) 來更改桌面底圖,程序碼如下:

Private Sub Command2_Click()
Dim FileName As String
Dim X As Long
FileName = "c:windowsest.bmp"
X = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0&, FileName, SPIF_UPDATEINIFILE Or SPIF_SENDWININICHANGE)
MsgBox "桌面底圖 (Wallpaper) 已經被更改"
End Sub

一個快速注冊 DLL 及 OCX 的方法

有時候我們在 VB 中要引用某一個 DLL 或 OCX 時,會出現文件未注冊的訊息,這時,我們可以使用人工注冊的方法,也就是直接在命令列中使用 regsvr32.exe 來做,做法如下:

文件注冊:C:WindowsSystemRegsvr32.exe C:WindowsSystemTest.ocx

取消注冊:C:WindowsSystemRegsvr32.exe /u C:WindowsSystemTest.ocx

這些動作我們也可以直接寫到程序中,使用 Shell 來執行,但是我現在要說的,都不是上面提到的方法!

注意看羅!方法如下:

1、在資源管理器中找到 C:WindowsSystemRegsvr32.exe 并【復制】 ( 按鼠標右鍵選復制 )

2、將目錄移到 C:WindowsSendTo 后,執行【貼上快捷方式】 ( 按鼠標右鍵選貼上快捷方式 )

3、將快捷方式名稱改成【REGISTER】

4、OK

現在,如果您想替某一個文件做注冊動作,例如:C:WindowsSystemTest.ocx,您只要打開資源管理器,找到 C:WindowsSystemTest.ocx,按鼠標右鍵選【傳送到】【REGISTER】即可完成注冊動作了!

注:有一個地方要注意的是,Regsvr32.exe 只能注冊 32 位的文件!如果要用它來注冊 16 位的文件,會有錯誤訊息產生。

如何用TextBox打開和保存文件

作為輕量級的控件,TextBox控件使用率很高,但相關的資料極少談及如何用TextBox控件打開和保存文件,大都采用回避的態度,對VB初學者帶來很多不便。筆者近日為友人做一個英文朗讀軟件,按友人的要求,軟件要能象MS的記事本那樣能打開和保存文檔。其實實現方法并不復雜,現將心得寫出來,希望對大家有幫助。如果您有更好的方法,請來信:[email protected]

’新建標準EXE,加入一個TextBox控件,一個公共對話框,兩個菜單。

’打開
Private Sub mnuOpen_Click()
CommonDialog1.Filter = "文檔文件(*.txt)|*.txt|所有文件(*.*)|*.*"
CommonDialog1.ShowOpen
Open CommonDialog1.FileName For Input As #1
Text1.Text = StrConv(InputB$(LOF(1), 1), vbUnicode)
Close #1
End Sub

’保存
Private Sub mnuSave_Click()
On Error Resume Next
CommonDialog1.Filter ="文檔文件(*.txt)|*.txt|所有文件(*.*)|*.*"
CommonDialog1.ShowSave
Open CommonDialog1.FileName For Output As #1
Print #1, Text1.Text
Close 1
End Sub

TextBox只支持打開64K以下的文件,建議最好設置出錯處理。以上程序在PWin98、VB6.0下調試通過。

如何判斷目前文件資源管理器中,文件名稱之擴展文件名是顯示或隱藏?

由于我在集團性的資訊處工作,所負責的公司系統有的是屬于外點,例如潤泰建設有個單位是行銷業務處,他們的工作是賣公司蓋的房子,所以他們的業務人員平常都是待在各工地的接待中心,我替他們開發的銷售系統在工地的部份是屬于單機作業的,使用 Access 資料庫,每一個星期資料回傳總公司一次。

業務人員由于流動性大,不太了解系統,有時候,系統出了問題,業務人員又搞不清楚狀況,于是我會要求他們將資料庫 sale.mdb 回傳公司,結果,常鬧笑話,原來他們回傳公司的,常常不是 sale.ldb 就是 sale.exe,為什么呢? 原因很簡單,因為他們的文件資源管理器中,設定了將擴展文件名隱藏起來,結果只看到三個不同圖示的 sale 文件 (分別是 Sale.mdb、Sale.ldb、Sale.exe),不太會操作的業務人員根本分不清楚那一個圖示的 sale 文件才是資料庫文件案!

我們在 VB 的程序中要如何判斷,目前文件資源管理器中的設定是否顯示擴展文件名呢?

Private Declare Function GetFileTitle Lib "comdlg32.dll" Alias "GetFileTitleA" (ByVal lpszFile As String, ByVal lpszTitle As String, ByVal cbBuf As Integer) As Integer
Private Function HasExtension(sFileName As String) As Long
Dim sTemp As String
Dim lTemp As Long

sTemp = String(1, 0)
lTemp = GetFileTitle(sFileName, sTemp, Len(sTemp))
If lTemp < 0 Then HasExtension = -1: Exit Function
sTemp = String(lTemp, 0)
Call GetFileTitle(sFileName, sTemp, Len(sTemp))

If (Left$(Right$(Left$(sTemp, lTemp - 1), 4), 1)) = "." Then
HasExtension = 1
Else
HasExtension = 0
End If
End Function

若有顯示擴展文件名,返回值是 1,否則返回0。


  閱讀關于 VB 的全部文章
作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗