フォームを最小化した状態で、KeyDownイベントの発生
投稿者 (削除されました)  ()
投稿日時
2009/3/1 21:26:17
(削除されました)
投稿者 るきお  (社会人)
投稿日時
2009/3/1 21:26:17
フォームが最小化されているときにKeyDownイベントを受け取ることはできません。純粋なVBには最小化されているといきにキーボード入力に反応する方法はありません。
どうしても実現したい場合は、Windowsの機能と連携して実現可能です。
つまり、Windowsはどのキーが押されたかいつでも把握しているので、Windowsからキーボード入力を通知してもらうようにするのです。
VB(をはじめてするほとんどのプログラミング言語)はWindowsの機能を使用しようとするととたんに面倒になります。これだけのことを実現するために信じられないようなコードを書いて、綿密にテストする必要があります。
以下にサンプルを紹介します。
このサンプルは標準モジュールとフォームを使用します。Module1に以下のコードを記述してください。
実行するとフォームを最小化しているときに[Ctrl] + [N]を押すと、フォームを標準の大きさに戻せます。
サンプルが長いので投稿を分けます。
どうしても実現したい場合は、Windowsの機能と連携して実現可能です。
つまり、Windowsはどのキーが押されたかいつでも把握しているので、Windowsからキーボード入力を通知してもらうようにするのです。
VB(をはじめてするほとんどのプログラミング言語)はWindowsの機能を使用しようとするととたんに面倒になります。これだけのことを実現するために信じられないようなコードを書いて、綿密にテストする必要があります。
以下にサンプルを紹介します。
このサンプルは標準モジュールとフォームを使用します。Module1に以下のコードを記述してください。
実行するとフォームを最小化しているときに[Ctrl] + [N]を押すと、フォームを標準の大きさに戻せます。
サンプルが長いので投稿を分けます。
投稿者 るきお  (社会人)
投稿日時
2009/3/1 21:27:35
Option Explicit
Private Declare Function RegisterHotKey Lib "user32" (ByVal hwnd As Long, ByVal id As Long, ByVal fsModifiers As Long, ByVal vk As Long) As Long
Private Declare Function UnregisterHotKey Lib "user32" (ByVal hwnd As Long, ByVal id As Long) As Long
Private Declare Function GlobalAddAtom Lib "kernel32" Alias "GlobalAddAtomA" (ByVal lpString As String) As Integer
Private Declare Function GlobalDeleteAtom Lib "kernel32" (ByVal nAtom As Integer) As Integer
Private Const MOD_ALT = &H1
Private Const MOD_CONTROL = &H2
Private Const MOD_SHIFT = &H4
'□API関数
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
'□SetWindowLongで使用
Private Const GWL_WNDPROC = -4
'□メッセージ
Private Const WM_CONTEXTMENU = &H7B '右クリック
Private Const WM_HOTKEY = &H312
'□コレクション すべてウィンドウハンドルがキー
Dim colDProc As Collection '現在サブクラス化されているコントロールの元のWindowsProcのアドレス
Dim HotKeyID As Long
Dim m_BaseForm As Form
'■WindowProc
'■機能:メッセージを横取りする。
'■備考:この関数はコールバック関数なので定義を変えてはいけない!
Public Function HotKeyProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim DefaultProc As Long
Select Case uMsg
Case WM_HOTKEY
m_BaseForm.GotHotkey
End Select
CONTINUE:
'引当のWindowProcへメッセージを回す。
DefaultProc = colDProc(CStr(hwnd))
HotKeyProc = CallWindowProc(DefaultProc, hwnd, uMsg, wParam, lParam)
End Function
'■BeginSubClass
'■機能:サブクラス化を開始する。
Private Sub BeginHotKeyWatch(oControl As Object)
Static bAlready As Boolean
Dim DefaultProc As Long
If Not bAlready Then
Set colDProc = New Collection
bAlready = True
End If
'サブクラス化実行
DefaultProc = SetWindowLong(oControl.hwnd, GWL_WNDPROC, AddressOf HotKeyProc)
'元のWindowProcのアドレスを保存
colDProc.Add DefaultProc, CStr(oControl.hwnd)
End Sub
'■EndSubClass
'■機能:サブクラス化を終了します。
Private Sub EndHotKeyWatch(oControl As Object)
Dim ret As Long
Dim DefaultProc As Long
'WindowProcのアドレスを元に戻す。
DefaultProc = colDProc(CStr(oControl.hwnd))
ret = SetWindowLong(oControl.hwnd, GWL_WNDPROC, DefaultProc)
colDProc.Remove CStr(oControl.hwnd)
End Sub
Public Function CreateHotKey(BaseForm As Form, ByVal HotKeyName As String, ByVal Shift As Integer, ByVal lVKey As Long) As Long
Dim nID As Long
Dim IsShift As Boolean
Dim IsCtrl As Boolean
Dim IsAlt As Boolean
Dim fsModifiers As Long
IsShift = Shift And vbShiftMask
IsCtrl = Shift And vbCtrlMask
IsAlt = Shift And vbAltMask
fsModifiers = IIf(IsShift, MOD_SHIFT, 0) + IIf(IsCtrl, MOD_CONTROL, 0) + IIf(IsAlt, MOD_ALT, 0)
HotKeyID = GlobalAddAtom(HotKeyName)
Call RegisterHotKey(BaseForm.hwnd, nID, fsModifiers, lVKey)
CreateHotKey = HotKeyID
Set m_BaseForm = BaseForm
Call BeginHotKeyWatch(BaseForm)
End Function
Public Sub DeleteHotKey(BaseForm As Form)
Call EndHotKeyWatch(BaseForm)
Call UnregisterHotKey(BaseForm.hwnd, HotKeyID)
Call GlobalDeleteAtom(HotKeyID)
End Sub
次にフォームに以下のコードを追加します。
Private Sub Form_Load()
'Ctrl + N が押されたらGotHotKeyプロシージャを呼び出すように設定する
CreateHotKey Me, "MyHoykey", vbCtrlMask, vbKeyN
End Sub
Public Sub GotHotkey()
Me.WindowState = vbNormal
End Sub
Private Sub Form_Unload(Cancel As Integer)
DeleteHotKey Me
End Sub
投稿者 じょにー  (社会人)
投稿日時
2009/3/3 19:20:29
るきお様、回答ありがとうございました
標準機能での実現は、不可能なのですね、参考コードまで、書いていただき、ありがとうございます
教えていただいた、コードを参考に、色々、試行錯誤やってみます、どうも、ありがとうございました
標準機能での実現は、不可能なのですね、参考コードまで、書いていただき、ありがとうございます
教えていただいた、コードを参考に、色々、試行錯誤やってみます、どうも、ありがとうございました
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2009/3/3 19:33:09
API を使う以外の方法として、DirectInput を使う方法があります。
下記は、マウスとキーボードの入力をとらえるサンプルです。
http://www.geocities.co.jp/SiliconValley/7406/tips/mouse/mouse2.html
下記は、マウスとキーボードの入力をとらえるサンプルです。
http://www.geocities.co.jp/SiliconValley/7406/tips/mouse/mouse2.html
例えば、コマンドボタンを、押したら、フォームを最小化させて、ファンクションキーが、押されたら、元のサイズに、戻すと、言う事をやりたいのですが、可能でしょうか?アドバイス、お願いいたします