VB2005にて、Enterキーのテンキーと、キーボードを判定したく、以下の方法を試しましたが、同じ結果が返ってきて、判断できませんでした。
【KeyDownイベント】
If e.KeyCode = Keys.Return Then
ElseIf e.KeyCode = Keys.Enter Then
【KeyPressイベント】
If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Return) Then
ElseIf e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Enter) Then
いろいろ調べてみて、Ms-ACCESS2000では、判断できるソースがありましたので、
そちらを参考にVB2005に書き換えようと試みていますが、MyMSG に値が入って来ないため、判断にも至りません。
Enterキーの判断方法をご存知の方いらっしゃいますか?
Public Structure POINTAPI
Dim X As Integer
Dim Y As Integer
End Structure
Public Structure MSG
Dim hWnd As Long
Dim message As Long 'メッセージ情報
Dim wParam As Long
Dim lParam As Long
Dim time As Long
Dim pt As POINTAPI
End Structure
Private Declare Function PeekMessage Lib "user32" _
Alias "PeekMessageA" (ByVal lpMsg As MSG, ByVal hWnd As IntPtr, _
ByVal wMsgFilterMin As Integer, ByVal wMsgFilterMax As Integer, _
ByVal wRemoveMsg As Integer) As Long
Private Declare Function TranslateMessage Lib "user32" (ByVal lpMsg As MSG) As Integer
Private Declare Function DispatchMessage Lib "user32" Alias "DispatchMessageA" (ByVal lpMsg As MSG) As Integer
Const PM_NOREMOVE As Long = &H0
Const WM_KEYFIRST As Long = &H100
Const WM_KEYLAST As Long = &H108
【KeyPressイベント】
Dim MyMsg As MSG, RetVal As Long
RetVal = PeekMessage(MyMsg, Me.Handle, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE)
If RetVal <> 0 Then
If MyMsg.wParam = CDbl(vbNewLine) Then
If CBool(MyMsg.lParam And &H1000000) Then
MsgBox("テンキー")
Else
MsgBox("キーボード")
End If
End If
else
TranslateMessage(MyMsg)
DispatchMessage(MyMsg)
End If
因みにMs-ACCESS2000で、確認できましたソースは、以下になります
Private Declare Function PeekMessage Lib "user32" _
Alias "PeekMessageA" (lpMsg As Msg, ByVal hwnd As Long, _
ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long, _
ByVal wRemoveMsg As Long) As Long
Private Declare Function TranslateMessage Lib "user32" (lpMsg As Msg) As Long
Private Declare Function DispatchMessage Lib "user32" Alias "DispatchMessageA" (lpMsg As Msg) As Long
Private Type POINTAPI
x As Long
y As Long
End Type
Private Type Msg
hwnd As Long
message As Long
wParam As Long
lParam As Long
time As Long
pt As POINTAPI
End Type
Const PM_NOREMOVE = &H0
Const WM_KEYFIRST = &H100
Const WM_KEYLAST = &H108
Const VK_RETURN = &HD
Private Sub Form_Load()
Me.KeyPreview = True
End Sub
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Dim MyMsg As Msg, RetVal As Long
If KeyCode = vbKeyReturn Then
Do
RetVal = PeekMessage(MyMsg, Me.hwnd, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE)
If RetVal <> 0 Then
If MyMsg.wParam = VK_RETURN Then
If MyMsg.lParam And &H1000000 Then
MsgBox "Enter from Keypad pressed"
Else
MsgBox "Enter from Keyboard pressed"
End If
Exit Do
End If
Else
TranslateMessage MyMsg
DispatchMessage MyMsg
End If
Loop
End If
End Sub
WndProc をオーバーライドすれば、OnKeyDown に渡る前の WM_KEYDOWN を拾えます。
> If e.KeyCode = Keys.Return Then
> ElseIf e.KeyCode = Keys.Enter Then
上記では判定できません。そもそも
If Keys.Enter = Keys.Return Then
は True となってしまうはずですし。
(Return と Enter は、どちらも数値としては「13」です)
> Ms-ACCESS2000では、判断できるソースがありましたので、
これかな?
http://support.microsoft.com/kb/188550/en-us
> MyMSG に値が入って来ないため、判断にも至りません。
こうかな。
Public Class Form1
Public Event EnterKeyPress(ByVal IsKeyPad As Boolean)
Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
Debug.WriteLine(keyData.ToString() & ":" & msg.ToString())
Const WM_KEYDOWN As Integer = &H100
If msg.Msg = WM_KEYDOWN AndAlso keyData = Keys.Return Then
If IntPtr.Size = 4 Then
RaiseEvent EnterKeyPress(CBool(msg.LParam.ToInt32() And &H1000000I))
Else
RaiseEvent EnterKeyPress(CBool(msg.LParam.ToInt64() And &H1000000L))
End If
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
Private Sub Form1_EnterKeyPress(ByVal IsKeyPad As Boolean) Handles Me.EnterKeyPress
ListBox1.Items.Add(IsKeyPad)
End Sub
End Class
動作しました
ご回答、ありがとうございました
VB2005使用しはじめ、日が浅い初心者事もあり、伝わりにくい表現にも関わらず、ありがとうございました。
APIを使わずとも、ProcessCmdKey・Overrides により、取得できるのですね。
教えていただいたソースの完全理解に励みます
どうもありがとうございました。
ツイート | ![]() |