程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> VB實現窗體注冊快捷鍵

VB實現窗體注冊快捷鍵

編輯:.NET實例教程

在VB的菜單編輯器中,快捷鍵很少,如果想要實現Ctrl+Shift+O這樣的快捷鍵,都無法解決。後來利用API以及鉤子,實現了代碼,代碼如下

 



‘模塊代碼

Option Explicit
''
'' Copyright ?1997-1999 Brad Martinez, http://www.mvps.org
''
'' A general purpose subclassing module w/ debugging code
''
'' - Code was developed using, and is formatted for, 8pt. MS Sans Serif font
'' ==============================================

Public Declare Function GetProp Lib "user32" Alias "GetPropA" (ByVal hwnd As Long, ByVal lpString As Any) As Long
Public Declare Function SetProp Lib "user32" Alias "SetPropA" (ByVal hwnd As Long, ByVal lpString As String, ByVal hData As Long) As Long
Public Declare Function RemoveProp Lib "user32" Alias "RemovePropA" (ByVal hwnd As Long, ByVal lpString As String) As Long

Public Const WS_BORDER = &H800000
Public Const WS_CLIPCHILDREN = &H2000000

Public Enum GWL_nIndex
  GWL_WNDPROC = (-4)
''  GWL_HWNDPARENT = (-8)
  GWL_ID = (-12)
  GWL_STYLE = (-16)
  GWL_EXSTYLE = (-20)
''  GWL_USERDATA = (-21)
End Enum

Public Const WM_HOTKEY = &H312
Public Declare Function RegisterHotKey Lib "user32" (ByVal hwnd As Long, ByVal id As Long, ByVal fsModifIErs As Long, ByVal vk As Long) As Long
Public Declare Function UnregisterHotKey Lib "user32" (ByVal hwnd As Long, ByVal id As Long) As Long


Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As GWL_nIndex) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As GWL_nIndex, ByVal dwNewLong As Long) As Long

Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function DefWindowProc Lib "user32" Alias "DefWindowProcA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Const LMEM_FIXED = &H0
Private Const LMEM_ZEROINIT = &H40
Private Const LPTR = (LMEM_FIXED Or LMEM_ZEROINIT)
Private Declare Function LocalAlloc Lib "kernel32" (ByVal uFlags As Long, ByVal uBytes As Long) As Long
Private Declare Function LocalFree Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function lstrcpyA Lib "kernel32" (lpString1 As Any, lpString2 As Any) As Long

Private Const OLDWNDPROC = "OldWndProc"
Private Const OBJECTPTR = "ObjectPtr"

'' Allocated string pointer filled with OLDWNDPROC string and used with all
'' CallWindowProc(GetProp(hwnd, m_lpszOldWndProc), ...) calls.
Private m_lpszOldWndProc As Long

#If DEBUGWINDOWPROC Then
  '' maintains a WindowProcHook reference for each subclassed window.
  '' the window''s handle is the collection item''s key string.
  Private m_colWPHooks As New Collection
#End If
''

'' On first window subclass, allocates a memory buffer and copIEs the
'' "OldWndProc" string to the buffer. On last unsubclass, frees and
'' zeros the allocated buffer. The pointer to the buffer is passed directly
'' to GetProp when retrIEing the subclassed window''s original window
'' procedure pointer, eliminating VB''s Unicode to ANSI string conversion
'' in our window procedures.

Private Sub SetWndProcPropertyBuffer(hwnd As Long, fAdd As Boolean)
  Static colhWnds As New Collection
  
  '' Collection holds the handles of all subclassed Windows,
  '' ensuring an accurate count of unique handles.
  On Error Resume Next
  If fAdd Then
    colhWnds.Add hwnd, CStr(hwnd)
  Else
    colhWnds.Remove CStr(hwnd)
  End If
  On Error GoTo 0
  
  '' If adding a window handle and the buffer is not yet
  '' allocated, allocate it.
  If fAdd Then
    If (m_lpszOldWndProc = 0) Then
      m_lpszOldWndProc = LocalAlloc(LPTR, Len(OLDWNDPROC))
      If m_lpszOldWndProc Then
        Call lstrcpyA(ByVal m_lpszOldWndProc, ByVal OLDWNDPROC)
''Debug.Print "wndproc buffer allocated"
      End If
    End If
  
  '' If removing a window handle, the collection count is zero, and the
  '' buffer is allocated, deallocate the buffer memory and zero the variable
  ElseIf (fAdd = False) And (colhWnds.Count = 0) Then
    If m_lpszOldWndProc Then
      Call LocalFree(m_lpszOldWndProc)
      m_lpszOldWndProc = 0
''Debug.Print "wndproc buffer freed"
    End If
  End If   '' fAdd

End Sub

Public Function SubClass(hwnd As Long, _
                                         lpfnNew As Long, _
                                         Optional objNotify As Object = Nothing) As Boolean
  Dim lpfnOld As Long
  Dim fSuccess As Boolean
  On Error GoTo Out

  If GetProp(hwnd, OLDWNDPROC) Then
    SubClass = True
    Exit Function
  End If
  
  Call SetWndProcPropertyBuffer(hwnd, True)
  
#If (DEBUGWINDOWPROC = 0) Then
    lpfnOld = SetWindowLong(hwnd, GWL_WNDPROC, lpfnNew)

#Else
    Dim objWPHook As WindowProcHook
    
    Set objWPHook = CreateWindowProcHook
    m_colWPHooks.Add objWPHook, CStr(hwnd)
    
    With objWPHook
      Call .SetMainProc(lpfnNew)
      lpfnOld = SetWindowLong(hwnd, GWL_WNDPROC, .ProcAddress)
      Call .SetDebugProc(lpfnOld)
    End With

#End If
  
  If lpfnOld Then
    fSuccess = SetProp(hwnd, OLDWNDPROC, lpfnOld)
    If (objNotify Is Nothing) = False Then
      fSuccess = fSuccess And SetProp(hwnd,OBJECTPTR, ObjPtr(objNotify))
    End If
  End If
  
Out:
  If fSuccess Then
    SubClass = True
  
  Else
    If lpfnOld Then Call SetWindowLong(hwnd, GWL_WNDPROC, lpfnOld)
    MsgBox "Error subclassing window &H" & Hex(hwnd) & vbCrLf & vbCrLf & _
                  "Err# " & Err.Number & ": " & Err.Description, vbExclamation
  End If
  
End Function

Public Function UnSubClass(hwnd As Long) As Boolean
  Dim lpfnOld As Long
  
  lpfnOld = GetProp(hwnd, OLDWNDPROC)
  If lpfnOld Then
    
    If SetWindowLong(hwnd, GWL_WNDPROC, lpfnOld) Then
      Call RemoveProp(hwnd, OLDWNDPROC)
      Call RemoveProp(hwnd, OBJECTPTR)

#If DEBUGWINDOWPROC Then
      '' remove the WindowProcHook reference from the collection
      m_colWPHooks.Remove CStr(hwnd)
#End If
      
      Call SetWndProcPropertyBuffer(hwnd, False)
      UnSubClass = True
    
    End If   '' SetWindowLong
  End If   '' lpfnOld

End Function

Public Function WndProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

    Select Case uMsg
        Case WM_HOTKEY
            Select Case wParam
                Case 100
                    Form1.ExecuteMenuCommand 100
                    Exit Function
            End Select
    
    End Select
    
    WndProc = CallWindowProc(GetProp(hwnd, m_lpszOldWndProc), hwnd, uMsg, wParam, lParam)

End Function

 



''窗體代碼
Private Const MOD_ALT = &H1
Private Const MOD_CONTROL = &H2
Private Const MOD_SHIFT = &H4

Private Sub Form_Load()
    Me.mnuFile_Open.Caption = "打開(&O)" & vbTab & "Ctrl+Shift+O"
    
    RegisterHotKey Me.hwnd, 100, MOD_CONTROL + MOD_SHIFT, vbKeyO
    
    SubClass Me.hwnd, AddressOf WndProc
    
    
End Sub

Private Sub Form_Unload(Cancel As Integer)
    UnregisterHotKey Me.hwnd, 100
    UnSubClass Me.hwnd
    
End Sub

Public Sub ExecuteMenuCommand(ByVal id As Long)
    Select Case id
        Case 100
            mnuFile_Open_Click
    End Select
    
End Sub

Private Sub mnuFile_Open_Click()
    MsgBox mnuFile_Open.Caption
    
End Sub

Private Sub mnuFile_Save_Click()
    MsgBox mnuFile_Save.Caption
    
End Sub

 

所顯示的菜單圖片:

[圖片信息]


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved