如何設定 熱鍵 (Hot Key) 叫起視窗

如何設定 熱鍵 (Hot Key) 叫起視窗

如何設定 熱鍵 (Hot Key) 叫起視窗

<< VB.Net >>

如何處理 當視窗最小化於工作列時,或縮小於工作匣 (Tray) 或 Focus 在其他視窗操作中時

能夠按 Hot Key ( 快速 / 組合) 鍵 叫起特定視窗

方法1 :

使用API SendMessage 傳送 WM_SETHOTKEY 訊息, 讓 Windows Call Back 叫起應用程式視窗

' Imports 陳述式

' 匯入在所參考的專案和組件中定義的命名空間 ( Namespace ) 或程式設計項目。

' System.Runtime.InteropServices 命名空間

' 提供各種支援COM Interop 和平台叫用服務的成員。與 Unmanaged 程式碼互通。

Imports System.Runtime.InteropServices

Public Class Form1

' 宣告SendMessage API

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _

(ByVal hwnd As Integer, ByVal wMsg As Integer, _

ByVal wParam As Integer, ByRef lParam As Integer) As Integer

' Enum 陳述式: 宣告列舉型別並定義其成員值。

Private Enum HotKey

Shift = 1

Ctrl = 2

Alt = 4

End Enum

' Structure 陳述式: 宣告結構的名稱,並引入組成結構之變數、屬性 (Property) 的定義。

Private Structure TpInt

Dim aint As Short

End Structure

' Structure 陳述式: 宣告結構的名稱,並引入組成結構之變數、屬性 (Property) 的定義。

Private Structure Tp2Bt

Dim lByte As Byte

Dim hByte As Byte

End Structure

' 在Form_Load 事件設定 快速 ( 組合 ) 鍵 ( 用Hot Key 將Form 叫起 )

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

SetHotKey(HotKey.Ctrl Or HotKey.Alt Or HotKey.Shift, Keys.U) ' 指定 Ctrl + Alt + Shift + U 為HotKey

' 可自行設定 HotKey , 參考如下:

' SetHotKey(HotKey.Ctrl, Keys.U) ' 指定 Ctrl + U 為 HotKey

' SetHotKey(HotKey.Shift, Keys.U) ' 指定 Shift + U 為 HotKey

' SetHotKey(HotKey.Alt, Keys.U) ' 指定 Alt + U 為 HotKey

' SetHotKey(HotKey.Ctrl Or HotKey.Shift, Keys.U) ' 指定 Alt + U 為 HotKey

' PS : U 可為其他按鍵, 注意不可跟其他應用程式的 HotKey 衝突( 重複)

End Sub

' 設定快速鍵的副程式 ( Subroutine )

Private Sub SetHotKey(ByVal hk As HotKey, ByVal k As Keys)

' 宣告自訂結構變數

Dim ti As TpInt

Dim tb As Tp2Bt

' 宣告常數

Const WM_SETHOTKEY As Short = 50

' WM_SETHOTKEY 訊息說明:

' 應用程式傳送 WM_SETHOTKEY 訊息給 Windows ( 並指定 HotKey 參數)

' Windows 會將所設定之快速鍵與應用程式視窗設定關聯

' 往後,當使用者按下快速鍵, 則 Windows 訊息系統就會發訊息叫起該應用程式視窗

tb.hByte = hk ' 高位元組( 可為 1 或 多個值)

tb.lByte = k ' 低位元組( Virtual-Key code )

' 將一使用者自訂型態變數複製到另一使用者自訂型態變數。

LSet(tb, ti)

' PS : VB6 有 LSet 陳述式 , 但 VB.Net 未提供

Dim wParam As Integer = CInt(ti.aint) ' 參數

' Call API SendMessage 送出 WM_SETHOTKEY 訊息

Select Case SendMessage(Handle.ToInt32, WM_SETHOTKEY, wParam, 0)

' Handle.ToInt32 = Me.Handle.ToInt32() , Me. 省略了

Case 1

Debug.WriteLine("指定 HotKey 成功!")

Case 2

Debug.WriteLine("跟其它視窗 HotKey 重複!")

Case Else

Debug.WriteLine("指定 HotKey 失敗!")

End Select

' SendMessage 回傳值:

' -1 : 失敗, HotKey 設定有誤

' 0 : 失敗, 視窗 Handle 值指定有誤

' 1 : 成功指定 HotKey

' 2 : 成功指定 HotKey, 但與其他視窗 HotKey 相同

End Sub

' LSet 副程式( Subroutine ) : 將變數的 二元資料 複製到 記憶體 給其他變數

Private Sub LSet(ByRef Src As Object, ByRef Dst As Object)

' GCHandle 提供從 Unmanaged 記憶體存取 Managed 物件的方法。

' Alloc 多載。配置指定物件的控制代碼。

' GCHandle.Alloc 方法(Object, GCHandleType) : 配置指定型別的控制代碼給指定的物件。

' 擷取在 Pinned 控制代碼中的物件位址。表示 GCHandle 類別可以配置的控制代碼的型別

Dim GChnd As GCHandle = GCHandle.Alloc(Src, GCHandleType.Pinned)

' 從 Unmanaged 記憶體區塊封送處理資料到 Managed 物件。

Dst = Marshal.PtrToStructure(GChnd.AddrOfPinnedObject, Dst.GetType)

' GCHandle.Free 方法: 釋放 GCHandle ( 釋放 Unmanaged 記憶體)。

GChnd.Free()

End Sub

End Class

相關主題連結:

WM_SETHOTKEY Message :

http://windowssdk.msdn.microsoft.com/en-us/library/ms646284(VS.80).aspx

RegisterHotKey Function :

http://windowssdk.msdn.microsoft.com/en-us/library/ms646309(VS.80).aspx

================================================================

方法2 :

使用API GetAsyncKeyState 去取得鍵盤狀態, 於特定鍵值時叫起應用程式視窗

Public Class Form3

' 宣告 API GetAsyncKeyState

Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Integer) As Short

' 宣告 Timer 類別, 實作一個在使用者定義的間隔引發事件的計時器。

Private WithEvents tmr As New Timer ' 個體( 建立實體) 化記時器

' WithEvents 關鍵字 : 指定宣告的成員變數, 參考可引發事件之類別的執行個體。

' 於表單載入事件設定啟動計時器

Private Sub Form3_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

' Timer.Interval 屬性 : 取得或設定計時器刻度之間的時間,以毫秒為單位。

tmr.Interval = 200 ' 設定 Interval 為 1/5 秒( 可自行調整)

' Timer.Start 方法 : 啟動計時器。

tmr.Start()

End Sub

' Timer.Tick 事件: 發生在指定的計時器間隔已耗用,且計時器被啟用時。

Private Sub tmr_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles tmr.Tick

' GetAsyncKeyState 取得非同步鍵盤(值) 狀態

' The GetAsyncKeyState function determines whether a key is up or down at the time the function is called,

' and whether the key was pressed after a previous call to GetAsyncKeyState.

' GetAsyncKeyState 參數 vKey : 1 ~ 256 之間 Virtual-Key codes

If GetAsyncKeyState(Keys.ControlKey) And GetAsyncKeyState(Keys.U) Then WindowState = 0

' 設定 Ctrl + U 為 HotKey 叫起視窗

' 0 = FormWindowState.Normal

End Sub

End Class

================================================================

<< VB6 >>

方法1 :

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

Private Const WM_SetHotKey = &H32

Private Const HotKey_Shift = &H1

Private Const HotKey_Control = &H2

Private Const HotKey_Alt = &H4

Private Const HotKey_Ext = &H8

Private Type TpInt

aint As Integer

End Type

Private Type Tp2Bt

lByte As Byte

hByte As Byte

End Type

Private ti As TpInt

Private tb As Tp2Bt

Private Sub Form_Load() ' 表單載入時 , 設定 Ctrl + O 會叫起本視窗表單

Dim wParam As Long

tb.hByte = HotKey_Control ' 高位元組( 可為或多個值)

tb.lByte = vbKeyO ' 低位元組( Virtual-Key code )

LSet ti = tb

' LSet 陳述式 : 將一使用者自訂型態變數複製到另一使用者自訂型態變數。

wParam = CLng(ti.aint) ' 參數

Select Case SendMessage(hwnd, WM_SetHotKey, wParam, 0) ' hwnd = Me.hwnd , Me. 省略了

Case 1

Debug.Print "指定 HotKey 成功!"

Case 2

Debug.Print "跟其它視窗 HotKey 重複!"

Case Else

Debug.Print "指定 HotKey 失敗!"

End Select

End Sub

================================================================

方法2 :

放個 Timer

Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer

Private Sub Form_Load()

Timer1.Interval = 200

Timer1.Enabled = True

End Sub

Private Sub Timer1_Timer()

' 設定 Ctrl + O 會叫起 視窗表單

If GetAsyncKeyState(vbKeyControl) And GetAsyncKeyState(vbKeyO) Then WindowState = 0

End Sub