顯示具有 VB 標籤的文章。 顯示所有文章
顯示具有 VB 標籤的文章。 顯示所有文章

2019/05/28

二進位陣列串接 合併

字串串接 A$ = A$ + B$ 方式簡單

但是陣列就不使用上列方式

使用API方式串接陣列


' 使用API

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Dest As Any, Src As Any, ByVal cb&)


If (Not AllBytes) = -1 Then                                         ' 判斷陣列是否有初始化

     AllBytes = buf

Else

     NewBytesLength = UBound(buf()) + 1                              ' 新資料個數

     AllBytesLength = UBound(AllBytes())                             ' 原資料個數

     ReDim Preserve AllBytes(0 To AllBytesLength + NewBytesLength)     ' 重新定義陣列,並保留資料

     CopyMemory AllBytes(AllBytesLength + 1), buf(0), NewBytesLength  ' 資料串接合併

End If



其中 If (Not AllBytes) = -1 Then , 為判斷陣列裡面是否有資料

2009/01/08

VB6 動態新增控制項物件

【方法一】增加動態物件陣列

新增方法:
Laod ObjectArray(Index),如 Load Text1(10)。

    《注意事項》
        1.最初物件陣列必須先存在,如 Text1(0)。
        2.引數Index不可以重複。
    優點:
        Load 新增的控制項物件會繼承(Inheritance)原先控制項物件的屬性設定,
        如 Text1(10). MultiLine = True 會自動設定,這個屬性在執行時期無法動態更改。

刪除方法:
Unload ObjectArray(Index) ,如 Unload Text1(10)。

事件觸發:
Private Sub Text1_Change(Index As Integer)
    Select Case Index
    Case 1
        '..... 觸發的控制項
    End Select
End Sub


【方法二】控制項集合(Controls collection)

新增方法:
Set ControlRef=Controls.Add(ProgID,Name [,Container])

    說明:
        1.ProgID是指控制項的類別名稱,它是 Libraryname.controlname 的格式。
        2.Name 是您給控制項的名稱, (這就是控制項Name屬性所傳回名稱) 。
            Name 必需為唯一的(unique),假如在集合中有其它的控制項具有同樣
            的名稱,就會產生
            Error 727 "There is already a control with the name 'ctrlname'" 。
        3.Container 為選擇性參數,是一個對收納器控制項(如PictureBox 或
            是Frame控制項)的引用,如果沒有指定或為 NULL,預設值
            為Controls 集合物件所屬的收納器。
        4.ControlRef 為物件變數,是一個對該控制項的引用,透過此變數可
            使用控制項的屬性,方法及事件,由底下的程式碼您可以發現要在
            表單右下角,動態新增一個控制項,是非常容易的一件事。

範例:
Private Sub Command1_Click()
    Set textCtrl1 = Controls.Add("vb.textbox", "textCtrl1")
    textCtrl1.Text = "textCtrl1"
    textCtrl1.Visible = True
    Set textCtrl2 = Controls.Add("vb.textbox", "textCtrl2")
    textCtrl2.Top = 500
    textCtrl2.Text = "textCtrl2"
    textCtrl2.Visible = True
End Sub

優點:
無須最初物件陣列 textCtrl(0),便可以無中生有來動態新增控制項。


刪除方法:
Controls.Remove Control

範例:
Private Sub Command3_Click()
    UnLoadCtrl "textCtrl1"
End Sub

Private Sub UnLoadCtrl(ByVal ctrlName As String)
    Dim Ctrls As Control
    For Each Ctrls In Controls
        If Ctrls.Name = ctrlName Then Controls.Remove Ctrls
    Next
End Sub


    《注意事項》
        Controls.Remove Control 只能刪除Controls.Add 所建立之物件,不然會發生執行階段錯誤 729。

事件觸發:
使用到 WithEvents 變數可以讓您對它的事件作處理。
Option Explicit
'--- textCtrl 先設定 Events
Dim WithEvents textCtrl1 As TextBox
Dim WithEvents textCtrl2 As TextBox

Private Sub textCtrl1_Change()
    Me.Caption = "textCtrl1_Change"
End Sub
Private Sub textCtrl1_GotFocus()
    Me.Caption = "textCtrl1_GotFocus"
End Sub
Private Sub textCtrl2_Change()
    Me.Caption = "textCtrl2_Change"
End Sub
Private Sub textCtrl2_GotFocus()
    Me.Caption = "textCtrl2_GotFocus"
End Sub

《問題》每一次新增控制項就要先設定 WithEvents,使用上非常不方便。

【以下範例可改良上面 WithEvents 的不方便,使用 SubClassing 方法】
Command2_Click 動態新增物件的手法

' 於表單
Option Explicit
'--- textCtrl 設定 Events
Dim WithEvents textCtrl1 As TextBox
Dim WithEvents textCtrl2 As TextBox

Private Sub Command1_Click()
    Set textCtrl1 = Controls.Add("vb.textbox", "textCtrl1")
    textCtrl1.Text = "textCtrl1"
    textCtrl1.Visible = True
    Set textCtrl2 = Controls.Add("vb.textbox", "textCtrl2")
    textCtrl2.Top = 500
    textCtrl2.Text = "textCtrl2"
    textCtrl2.Visible = True
End Sub

'----- 新增10個 TextBox 控制項 ( Controls.Add )
Private Sub Command2_Click()
    Dim txtArray As Object
    Dim Index As Long
    Dim str As String
    '新增10個 TextBox
    Index = 10
    ReDim CtrlhWnd(Index - 1)
    For Index = 0 To Index - 1
        str = "txtArray" & Index
        Set txtArray = Controls.Add("vb.textbox", str)
        With txtArray
            .Top = Index * 300
            .Left = 1300
            .Height = 280
            .Width = 1000
            .Text = str
            .Visible = True
            CtrlhWnd(Index) = .hwnd
        End With
    Next
    '--- txtArray 設定 Events
    MeProc = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub

Private Sub Command3_Click()
    UnLoadCtrl "textCtrl1"
End Sub
Private Sub UnLoadCtrl(ByVal ctrlName As String)
    Dim Ctrls As Control
    For Each Ctrls In Controls
        If Ctrls.Name = ctrlName Then Controls.Remove Ctrls
    Next
End Sub

Private Sub Form_Unload(Cancel As Integer)
    SetWindowLong Me.hwnd, GWL_WNDPROC, MeProc
End Sub

'---------- ALL Events()
Private Sub textCtrl1_Change()
    Me.Caption = "textCtrl1_Change"
End Sub
Private Sub textCtrl1_GotFocus()
    Me.Caption = "textCtrl1_GotFocus"
End Sub

Private Sub textCtrl2_Change()
    Me.Caption = "textCtrl2_Change"
End Sub
Private Sub textCtrl2_GotFocus()
    Me.Caption = "textCtrl2_GotFocus"
End Sub

Public Sub txtArray_Change(Index As Integer)
    Me.Caption = "txtArray" & Index & "_Change"
End Sub
Public Sub txtArray_GotFocus(Index As Integer)
    Me.Caption = "txtArray" & Index & "_GotFocus"
End Sub


' 於模組
Option Explicit
Public Type LongToByte
    B0 As Byte
    B1 As Byte
    B2 As Byte
    B3 As Byte
End Type
Public bLong As LongToByte
Public Const WM_COMMAND = &H111
Public Const GWL_WNDPROC = (-4)
Public MeProc As Long
Public CtrlhWnd() As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Select Case uMsg
    Case WM_COMMAND
        Dim Index As Integer
        For Index = 0 To UBound(CtrlhWnd)
            If lParam = CtrlhWnd(Index) Then
                CopyMemory bLong, wParam, 4
                Select Case bLong.B3
                Case &H3
                    Form1.txtArray_Change (Index)
                Case &H1
                    Form1.txtArray_GotFocus (Index)
                End Select
            End If
        Next
    End Select
    WindowProc = CallWindowProc(MeProc, hwnd, uMsg, wParam, lParam)
End Function




2007/10/30

別讓 MsgBox 中斷了一些 Background 的處理作業


在 VB 中,一旦您呼叫了 MsgBox,您正在執行的一些 Background 的處理作業,例如計數器或時鐘...等,都會停下來,直到您回應了 MsgBox 之后,一切才會恢复正常!或許您并不希望如此,這也有可能造成一些不必要的錯誤!

要解決這個問題,您必須使用 Windows API 去呼叫 MessageBox Function,它的使用方法、外觀和 MsgBox 的結果完全相同,但是它卻不會中斷一些 Background 的處理作業!

在以下的范例中,您要在 Form 中加入一個 Label、二個 CommandButton 及一個 Timer,不更改任何屬性。

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

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()
MessageBox Me.hwnd, "注意!計時器還在跑!", "API 的訊息框", 64
End Sub

Private Sub Form_Load()
Timer1.Interval = 1000
Label1.Caption = "目前的時間是:" & Time
End Sub

Private Sub Timer1_Timer()
Label1.Caption = "目前的時間是:" & Time
End Sub

2007/10/25

VB程式中跳下一個駐點的方法

Private Sub Text3_KeyDown(Index As Integer, KeyCode As Integer, Shift As Integer)
        '檢查是否為數值 and 檢查是否按下"Enter" 
        If IsNumeric(Text3(Index).Text) = False And KeyCode = 13 Then
                a = MsgBox("Input Error", , "Error")
        Else
                If KeyCode = 13 Then
                        SendKeys "{TAB}" '傳送"Tab"鍵值
                End If
        End If
End Sub
 

VB程式中使用滑鼠滾倫


 說明

由於VB自訂的事件中,並沒有這項訊息,於是只好自己攔截WM_MOUSEWHEEL這個訊息了

程式

'以下在.Bas
Option Explicit

'用以告訴系統當這個視窗的msg事件發生時 執行lpPrevWndFunc
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
'lpPrevWndFunc執行函數的位址
'hwnd 就是視窗的hwnd屬性
'Msg就是訊息 例如按下滑鼠右鍵 最大化....
'wParam,lParam會因Msg不同而有不同的用途

'用以設定視窗的程序
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" ( _
ByVal hwnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
'hwnd 就是所要設定視窗的hwnd屬性
'nIndex 是要設定的程序
'dwNewLong  所指定的程序(nIndex)所要執行的動作

Public Const GWL_WNDPROC = (-4)
Public Const WM_MOUSEWHEEL = &H20A
Public PrevWndProc As Long

Function WndProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim t(0 To 1) As Integer
If uMsg = WM_MOUSEWHEEL Then '如果是滾輪
    If wParam < 0 Then 'backward
        Form1.Top = Form1.Top + 10
    Else 'forforward
        Form1.Top = Form1.Top - 10
    End If
Else
    WndProc = CallWindowProc(PrevWndProc, hwnd, uMsg, wParam, lParam)
    '其他訊息用原來的回呼函數處理
End If
End Function

'以下在Form1中
Option Explicit
Private Sub Form_Load()
PrevWndProc = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf WndProc)
'設定新的回呼函式 以攔截訊息
'note: 傳回值PrevWndProc是原來視窗的回呼函數
'WndProc函數放在模組 因為AddressOf只能取得模組下函數的位址
End Sub

Private Sub Form_Unload(Cancel As Integer)
Dim lResult As Long
lResult = SetWindowLong(Me.hwnd, GWL_WNDPROC, PrevWndProc)
'結束時歸還原來的回呼函數 不然會當機
End Sub

相關資訊

  WM_MOUSEWHEEL

  SetWindowLong

  CallWindowProc

文件出處

  Honey  

2007/03/13

VB中各種進制的轉換

'-------------------------------------------

' 用途:將十進制轉化為二進制
' 輸入:Dec(十進制數)
' 輸入數據類型:Long
' 輸出:DEC_to_BIN(二進制數)
' 輸出數據類型:String
' 輸入的最大數為2147483647,輸出最大數為1111111111111111111111111111111(31個1)
'-------------------------------------------
Public Function DEC_to_BIN(Dec As Long) As String
DEC_to_BIN = ""
Do While Dec > 0
DEC_to_BIN = Dec Mod 2 & DEC_to_BIN
Dec = Dec \ 2
Loop
End Function
'-------------------------------------------
' 用途:將二進制轉化為十進制
' 輸入:Bin(二進制數)
' 輸入數據類型:String
' 輸出:BIN_to_DEC(十進制數)
' 輸出數據類型:Long
' 輸入的最大數為1111111111111111111111111111111(31個1),輸出最大數為2147483647
'-------------------------------------------
Public Function BIN_to_DEC(ByVal Bin As String) As Long
Dim i As Long
For i = 1 To Len(Bin)
BIN_to_DEC = BIN_to_DEC * 2 + Val(Mid(Bin, i, 1))
Next i
End Function
'-------------------------------------------
' 用途:將十六進制轉化為二進制
' 輸入:Hex(十六進制數)
' 輸入數據類型:String
' 輸出:HEX_to_BIN(二進制數)
' 輸出數據類型:String
' 輸入的最大數為2147483647個字符
'-------------------------------------------
Public Function HEX_to_BIN(ByVal Hex As String) As String
Dim i As Long
Dim B As String

Hex = UCase(Hex)
For i = 1 To Len(Hex)
Select Case Mid(Hex, i, 1)
Case "0": B = B & "0000"
Case "1": B = B & "0001"
Case "2": B = B & "0010"
Case "3": B = B & "0011"
Case "4": B = B & "0100"
Case "5": B = B & "0101"
Case "6": B = B & "0110"
Case "7": B = B & "0111"
Case "8": B = B & "1000"
Case "9": B = B & "1001"
Case "A": B = B & "1010"
Case "B": B = B & "1011"
Case "C": B = B & "1100"
Case "D": B = B & "1101"
Case "E": B = B & "1110"
Case "F": B = B & "1111"
End Select
Next i
While Left(B, 1) = "0"
B = Right(B, Len(B) - 1)
Wend
HEX_to_BIN = B
End Function
'-------------------------------------------
' 用途:將二進制轉化為十六進制
' 輸入:Bin(二進制數)
' 輸入數據類型:String
' 輸出:BIN_to_HEX(十六進制數)
' 輸出數據類型:String
' 輸入的最大數為2147483647個字符
'-------------------------------------------
Public Function BIN_to_HEX(ByVal Bin As String) As String
Dim i As Long
Dim H As String
If Len(Bin) Mod 4 <> 0 Then
Bin = String(4 - Len(Bin) Mod 4, "0") & Bin
End If

For i = 1 To Len(Bin) Step 4
Select Case Mid(Bin, i, 4)
Case "0000": H = H & "0"
Case "0001": H = H & "1"
Case "0010": H = H & "2"
Case "0011": H = H & "3"
Case "0100": H = H & "4"
Case "0101": H = H & "5"
Case "0110": H = H & "6"
Case "0111": H = H & "7"
Case "1000": H = H & "8"
Case "1001": H = H & "9"
Case "1010": H = H & "A"
Case "1011": H = H & "B"
Case "1100": H = H & "C"
Case "1101": H = H & "D"
Case "1110": H = H & "E"
Case "1111": H = H & "F"
End Select
Next i
While Left(H, 1) = "0"
H = Right(H, Len(H) - 1)
Wend
BIN_to_HEX = H
End Function
'-------------------------------------------
' 用途:將十六進制轉化為十進制
' 輸入:Hex(十六進制數)
' 輸入數據類型:String
' 輸出:HEX_to_DEC(十進制數)
' 輸出數據類型:Long
' 輸入的最大數為7FFFFFFF,輸出的最大數為2147483647
'-------------------------------------------
Public Function HEX_to_DEC(ByVal Hex As String) As Long
Dim i As Long
Dim B As Long

Hex = UCase(Hex)
For i = 1 To Len(Hex)
Select Case Mid(Hex, Len(Hex) - i + 1, 1)
Case "0": B = B + 16 ^ (i - 1) * 0
Case "1": B = B + 16 ^ (i - 1) * 1
Case "2": B = B + 16 ^ (i - 1) * 2
Case "3": B = B + 16 ^ (i - 1) * 3
Case "4": B = B + 16 ^ (i - 1) * 4
Case "5": B = B + 16 ^ (i - 1) * 5
Case "6": B = B + 16 ^ (i - 1) * 6
Case "7": B = B + 16 ^ (i - 1) * 7
Case "8": B = B + 16 ^ (i - 1) * 8
Case "9": B = B + 16 ^ (i - 1) * 9
Case "A": B = B + 16 ^ (i - 1) * 10
Case "B": B = B + 16 ^ (i - 1) * 11
Case "C": B = B + 16 ^ (i - 1) * 12
Case "D": B = B + 16 ^ (i - 1) * 13
Case "E": B = B + 16 ^ (i - 1) * 14
Case "F": B = B + 16 ^ (i - 1) * 15
End Select
Next i
HEX_to_DEC = B
End Function
'-------------------------------------------
' 用途:將十進制轉化為十六進制
' 輸入:Dec(十進制數)
' 輸入數據類型:Long
' 輸出:DEC_to_HEX(十六進制數)
' 輸出數據類型:String
' 輸入的最大數為2147483647,輸出最大數為7FFFFFFF
'-------------------------------------------
Public Function DEC_to_HEX(Dec As Long) As String
Dim a As String
DEC_to_HEX = ""
Do While Dec > 0
a = CStr(Dec Mod 16)
Select Case a
Case "10": a = "A"
Case "11": a = "B"
Case "12": a = "C"
Case "13": a = "D"
Case "14": a = "E"
Case "15": a = "F"
End Select
DEC_to_HEX = a & DEC_to_HEX
Dec = Dec \ 16
Loop
End Function
'-------------------------------------------
' 用途:將十進制轉化為八進制
' 輸入:Dec(十進制數)
' 輸入數據類型:Long
' 輸出:DEC_to_OCT(八進制數)
' 輸出數據類型:String
' 輸入的最大數為2147483647,輸出最大數為17777777777
'-------------------------------------------
Public Function DEC_to_OCT(Dec As Long) As String
DEC_to_OCT = ""
Do While Dec > 0
DEC_to_OCT = Dec Mod 8 & DEC_to_OCT
Dec = Dec \ 8
Loop
End Function
'-------------------------------------------
' 用途:將八進制轉化為十進制
' 輸入:Oct(八進制數)
' 輸入數據類型:String
' 輸出:OCT_to_DEC(十進制數)
' 輸出數據類型:Long
' 輸入的最大數為17777777777,輸出的最大數為2147483647
'-------------------------------------------
Public Function OCT_to_DEC(ByVal Oct As String) As Long
Dim i As Long
Dim B As Long

For i = 1 To Len(Oct)
Select Case Mid(Oct, Len(Oct) - i + 1, 1)
Case "0": B = B + 8 ^ (i - 1) * 0
Case "1": B = B + 8 ^ (i - 1) * 1
Case "2": B = B + 8 ^ (i - 1) * 2
Case "3": B = B + 8 ^ (i - 1) * 3
Case "4": B = B + 8 ^ (i - 1) * 4
Case "5": B = B + 8 ^ (i - 1) * 5
Case "6": B = B + 8 ^ (i - 1) * 6
Case "7": B = B + 8 ^ (i - 1) * 7
End Select
Next i
OCT_to_DEC = B
End Function
'-------------------------------------------
' 用途:將二進制轉化為八進制
' 輸入:Bin(二進制數)
' 輸入數據類型:String
' 輸出:BIN_to_OCT(八進制數)
' 輸出數據類型:String
' 輸入的最大數為2147483647個字符
'-------------------------------------------
Public Function BIN_to_OCT(ByVal Bin As String) As String
Dim i As Long
Dim H As String
If Len(Bin) Mod 3 <> 0 Then
Bin = String(3 - Len(Bin) Mod 3, "0") & Bin
End If

For i = 1 To Len(Bin) Step 3
Select Case Mid(Bin, i, 3)
Case "000": H = H & "0"
Case "001": H = H & "1"
Case "010": H = H & "2"
Case "011": H = H & "3"
Case "100": H = H & "4"
Case "101": H = H & "5"
Case "110": H = H & "6"
Case "111": H = H & "7"
End Select
Next i
While Left(H, 1) = "0"
H = Right(H, Len(H) - 1)
Wend
BIN_to_OCT = H
End Function
'-------------------------------------------
' 用途:將八進制轉化為二進制
' 輸入:Oct(八進制數)
' 輸入數據類型:String
' 輸出:OCT_to_BIN(二進制數)
' 輸出數據類型:String
' 輸入的最大數為2147483647個字符
'-------------------------------------------
Public Function OCT_to_BIN(ByVal Oct As String) As String
Dim i As Long
Dim B As String

For i = 1 To Len(Oct)
Select Case Mid(Oct, i, 1)
Case "0": B = B & "000"
Case "1": B = B & "001"
Case "2": B = B & "010"
Case "3": B = B & "011"
Case "4": B = B & "100"
Case "5": B = B & "101"
Case "6": B = B & "110"
Case "7": B = B & "111"
End Select
Next i
While Left(B, 1) = "0"
B = Right(B, Len(B) - 1)
Wend
OCT_to_BIN = B
End Function
'-------------------------------------------
' 用途:將八進制轉化為十六進制
' 輸入:Oct(八進制數)
' 輸入數據類型:String
' 輸出:OCT_to_HEX(十六進制數)
' 輸出數據類型:String
' 輸入的最大數為2147483647個字符
'-------------------------------------------
Public Function OCT_to_HEX(ByVal Oct As String) As String
Dim Bin As String
Bin = OCT_to_BIN(Oct)
OCT_to_HEX = BIN_to_HEX(Bin)
End Function
'-------------------------------------------
' 用途:將十六進制轉化為八進制
' 輸入:Hex(十六進制數)
' 輸入數據類型:String
' 輸出:HEX_to_OCT(八進制數)
' 輸出數據類型:String
' 輸入的最大數為2147483647個字符
'-------------------------------------------
Public Function HEX_to_OCT(ByVal Hex As String) As String
Dim Bin As String
Hex = UCase(Hex)
Bin = HEX_to_BIN(Hex)
HEX_to_OCT = BIN_to_OCT(Bin)
End Function


VB自帶函數:
十進制轉八進制:Oct(num)
十六進制轉八進制:oct("&H" &amp; num)
十進制轉十六進制:hex(num)
八進制轉十六進制:hex("&O" & num)

十六進制轉換為十進制
Dim str As String
str = Text2.Text
Text10.Text = CLng("&H" & str)