vba - 将 PostMessage WM_KEYDOWN/UP 发送到记事本编辑控件适用于 VK_F5 但不适用于普通字母

标签 vba winapi keyboard-events

我正在尝试将 WM_KEYDOWN 和 WM_KEYUP 发送到记事本的编辑控件。如果我发送 VK_F5,则以下示例有效:记事本插入当前日期和时间。但是,如果我尝试发送一个简单的 h,记事本不会停止一个接一个地插入 h,因此我必须使用任务管理器终止记事本。

我不明白为什么它只适用于一个键而不适用于另一个键,我想知道我必须更改什么才能发送一封简单的信件。

option explicit

const WM_KEYDOWN     = &h0100
const WM_KEYUP       = &h0101
const VK_F5          = &h074

declare function FindWindow          lib "user32"  alias "FindWindowA" ( _
     byVal lpClassName  as string, _
     byVal lpWindowName as string) as long

declare function FindWindowEx        lib "user32"  alias "FindWindowExA"      ( _
     byVal hWnd           as long  , _
     byVal hWndChildAfter as long  , _
     byVal lpClassName    as string, _
     byVal lpWindowName   as string) as long

declare function MapVirtualKey       lib "user32"       alias "MapVirtualKeyA"        ( _
     byVal wCode          as long,   _
     byVal wMapType       as long) as long

declare function PostMessage         lib "user32"       alias "PostMessageA" ( _
     byVal hwnd   as long, _
     byVal wMsg   as long, _
     byVal wParam as long, _
           lParam as any) as long

declare function ShellExecute Lib "shell32.dll"         alias "ShellExecuteA"     ( _
     byVal hwnd         as long  , _
     byVal lpOperation  as string, _
     byVal lpFile       as string, _
     byVal lpParameters as string, _
     byVal lpDirectory  as string, _
     byval lpShowCmd    as long)      as long

declare sub      Sleep               lib "kernel32" (byVal dwMilliseconds as long   )

sub main()

    dim hWndNotepad     as long
    dim hWndNotepadEdit as long

  '
  ' Start notepad
  '
    ShellExecute 0, "Open", "notepad.exe", "", "", 1
  '
  ' Find the window handle for notepad
  '
    hWndNotepad = FindWindow("notepad", vbNullString)
    while hWndNotepad = 0
    '
    ' Wait a while if notepad window not yet initialized:
    '
      Sleep 100 
      hWndNotepad = FindWindow("notepad", vbNullString)
    wend

  '
  ' Find the window handle of the edit control
  ' in notepad:
  '
    hWndNotepadEdit = FindWindowEx(hWndNotepad, 0, "Edit", vbNullString)

    dim vkCode as long
  ' This works:
  ' ----------
  '
  ' vkCode = VK_F5
  '
  ' This doesn't:
  ' ------------
    vkCode = asc("H")

    dim lParam as long
    lParam = 1 + MapVirtualKey(vkCode, 0) * 2^16

    PostMessage hWndNotepadEdit, WM_KEYDOWN, vkCode, lParam
    Sleep 100
    PostMessage hWndNotepadEdit, WM_KEYUP  , vkCode, lParam or &hc0000000

end sub

最佳答案

你在 PostMessage 函数的声明中有一个错误(lParam as Any) 正确的是 ByVal lParam as Long

Option Explicit

Const WM_KEYDOWN = &H100
Const WM_CHAR = &H102
Const WM_KEYUP = &H101
Const VK_F5 = &H74

Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _
     ByVal lpClassName As String, _
     ByVal lpWindowName As String) As Long

Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" ( _
     ByVal hwnd As Long, _
     ByVal hWndChildAfter As Long, _
     ByVal lpClassName As String, _
     ByVal lpWindowName As String) As Long

Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" ( _
     ByVal wCode As Long, _
     ByVal wMapType As Long) As Long

Declare Function PostMessage Lib "user32" Alias "PostMessageA" ( _
     ByVal hwnd As Long, _
     ByVal wMsg As Long, _
     ByVal wParam As Long, _
     ByVal lParam As Long) As Long

Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" ( _
     ByVal hwnd As Long, _
     ByVal lpOperation As String, _
     ByVal lpFile As String, _
     ByVal lpParameters As String, _
     ByVal lpDirectory As String, _
     ByVal lpShowCmd As Long) As Long

Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Sub main()

    Dim hWndNotepad     As Long
    Dim hWndNotepadEdit As Long

  '
  ' Start notepad
  '
    ShellExecute 0, "Open", "notepad.exe", "", "", 1
  '
  ' Find the window handle for notepad
  '
    hWndNotepad = FindWindow(vbNullString, "Bez názvu – Poznámkový blok")
    While hWndNotepad = 0
    '
    ' Wait a while if notepad window not yet initialized:
    '
      Sleep 100
      hWndNotepad = FindWindow(vbNullString, "Bez názvu – Poznámkový blok")
    Wend

  '
  ' Find the window handle of the edit control
  ' in notepad:
  '
    hWndNotepadEdit = FindWindowEx(hWndNotepad, 0, "Edit", vbNullString)

    Dim vkCode As Long
  ' This works:
  ' ----------
  '
  ' vkCode = VK_F5
  '
  ' This doesn't:
  ' ------------
    vkCode = Asc("H")

    Dim lParam As Long
    lParam = 1 + MapVirtualKey(vkCode, 0) * (2 ^ 16)
    Debug.Print Hex(vkCode), Hex(lParam)

    PostMessage hWndNotepadEdit, WM_KEYDOWN, vkCode, lParam  
'    PostMessage hWndNotepadEdit, WM_KEYUP, vkCode, lParam Or &HC0000000

End Sub

关于vba - 将 PostMessage WM_KEYDOWN/UP 发送到记事本编辑控件适用于 VK_F5 但不适用于普通字母,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51007808/

相关文章:

vba - Excel VBA : Animating Visibility of a Range w/RowHeight loop

vba - Range.Find 在隐藏且属于过滤器的范围上失败

c++ - 在 Windows 8.1 中查找触摸数字化仪的物理尺寸

blackberry - 如何检测 Field 子类中的 'delete' 键?

html - Angular 6 - 移动设备上的按键空间

excel - 工作表名称显然不存在

excel - 在Excel VBA中更改饼图的切片颜色

c++ - WINAPI 消息循环让我抓狂

c++ - 路径不存在时的 SHParseDisplayName

javascript - Draft js中如何处理按键事件