Отправка определенных клавиш на цифровой клавиатуре, например +, -, / или Enter (имитация нажатия клавиши)

Я работаю над проектом, где необходимо имитировать нажатия клавиш, чтобы вызвать определенное поведение в другом приложении.

все работает хорошо и хорошо, используя импортируемую функцию keybd_event (могут быть лучшие способы, но она работает нормально).

теперь я хочу добавить поддержку всех в тупик.

просмотр электронной. г. здесь http://msdn.microsoft.com/en-us/library/dd375731(в=против.85).аспн или в Система.Окна.Вход.Пространство имен ключей, я могу легко найти ключи для Num0..Num9, а также для NumLock. Но.. Я не могу найти ничего для Num/, Num+, NumEnter и т. д.

Я написал приложение quick froms, чтобы поймать событие keydown, выводя параметры события, и получил интересные результаты:

e.KeyCode NumLock e.KeyData NumLock e.KeyValue 144 e.Modifiers None  
e.KeyCode Divide e.KeyData Divide e.KeyValue 111 e.Modifiers None  
e.KeyCode Multiply e.KeyData Multiply e.KeyValue 106 e.Modifiers None  
e.KeyCode Subtract e.KeyData Subtract e.KeyValue 109 e.Modifiers None  
e.KeyCode Add e.KeyData Add e.KeyValue 107 e.Modifiers None  
e.KeyCode NumLock e.KeyData NumLock e.KeyValue 144 e.Modifiers None  
e.KeyCode NumLock e.KeyData NumLock e.KeyValue 144 e.Modifiers None  
e.KeyCode Divide e.KeyData Divide e.KeyValue 111 e.Modifiers None  
e.KeyCode Multiply e.KeyData Multiply e.KeyValue 106 e.Modifiers None  
e.KeyCode Subtract e.KeyData Subtract e.KeyValue 109 e.Modifiers None  
e.KeyCode Add e.KeyData Add e.KeyValue 107 e.Modifiers None  
e.KeyCode Return e.KeyData Return e.KeyValue 13 e.Modifiers None

клавиша Num+ (и так далее) кажется клавишами, которые Windows вызывает функциональные клавиши (например, F18 для клавиши Num+). Так.. это странно, но ладно.

но.. Я не могу различить клавиша Enter от клавиши NumEnter. Они отличаются для моего приложения, поэтому я должен отправить определенные коды ключей для обоих.

и это мой вопрос: как я могу отправить обычный ключ ввода и как я могу отправить ключ нумерации?

(Я не знаю, имеет ли это значение, я нахожусь на немецкой раскладке клавиатуры.)

Thx для любых идей!

3 ответов


Я нашел это здесь работает для меня !

protected override void WndProc(ref Message m)
{
     if (m.Msg == 256 && m.WParam.ToInt32() == 13)
     {   // WM_KEYDOWN == 256, Enter == 13
         if ((m.LParam.ToInt32() >> 24) == 0)
         {
             MessageBox.Show("main enter pressed!");
         }
         else
         {
             MessageBox.Show("numpad enter pressed!");
         }
      }
      else
      {
         base.WndProc(ref m);
      }
}

спасибо andreas за предоставление начала решения. вот более полная версия:

[DllImport("user32.dll")]
private static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll")]
private static extern bool GetGUIThreadInfo(uint idThread, out GUITHREADINFO lpgui);

public struct GUITHREADINFO
{
    public int cbSize;
    public int flags;
    public int hwndActive;
    public int hwndFocus;
    public int hwndCapture;
    public int hwndMenuOwner;
    public int hwndMoveSize;
    public int hwndCaret;
    public System.Drawing.Rectangle rcCaret;
}

private void sendNumpadEnter()
{
    bool keyDown = true; // true = down, false = up
    const uint WM_KEYDOWN = 0x0100;
    const uint WM_KEYUP = 0x0101;
    const int VK_RETURN = 0x0D;

    IntPtr handle = IntPtr.Zero;
    // Obtain the handle of the foreground window (active window and focus window are only relative to our own thread!!)
    IntPtr foreGroundWindow = GetForegroundWindow();
    // now get process id of foreground window
    uint processID;
    uint threadID = GetWindowThreadProcessId(foreGroundWindow, out processID);
    if (processID != 0)
    {
        // now get element with (keyboard) focus from process
        GUITHREADINFO threadInfo = new GUITHREADINFO();
        threadInfo.cbSize = Marshal.SizeOf(threadInfo);
        GetGUIThreadInfo(threadID, out threadInfo);
        handle = (IntPtr)threadInfo.hwndFocus;
    }

    int lParam = 1 << 24; // this specifies NumPad key (extended key)
    lParam |= (keyDown) ? 0 : (1 << 30 | 1 << 31); // mark key as pressed if we use keyup message

    PostMessage(handle, (keyDown) ? WM_KEYDOWN : WM_KEYUP, VK_RETURN, lParam); // send enter
}

поскольку вы говорите о решении с обратной стороны, обнаруживая событие, и я хочу его поднять, мне даже не нужно переопределять WndProc. Я могу просто отправлять свои сообщения.

из вашего решения я посмотрел на SendMessage / PostMessage, а затем WM_KEYDOWN и WM_KEYUP. Документация на самом деле дает вам информацию (если вы действительно смотрите трудный.)

http://msdn.microsoft.com/en-us/library/ms646280(v=vs. 85).aspx
http://msdn.microsoft.com/en-us/library/ms646281(v=vs. 85).aspx

Итак, мое решение (компилируется и теперь с поиском правильного окна (где ввести текст)) выглядит так:

 bool keyDown = true; // true = down, false = up
 const uint WM_KEYDOWN = 0x0100;
 const uint WM_KEYUP = 0x0101;
 const int VK_RETURN = 0x0D;

 IntPtr handle = IntPtr.Zero;
 // Obtain the handle of the foreground window (active window and focus window are only relative to our own thread!!)
 IntPtr foreGroundWindow = GetForegroundWindow();
 // now get process id of foreground window
 uint processID;
 uint threadID = GetWindowThreadProcessId(foreGroundWindow, out processID);
 if (processID != 0)
 {
 // now get element with (keyboard) focus from process
 GUITHREADINFO threadInfo = new GUITHREADINFO();
 threadInfo.cbSize = Marshal.SizeOf(threadInfo);
 GetGUIThreadInfo(threadID, out threadInfo);
 handle = (IntPtr)threadInfo.hwndFocus;
 }

 int lParam = 1 << 24; // this specifies NumPad key (extended key)
 lParam |= (keyDown) ? 0 : (1 << 30 | 1 << 31); // mark key as pressed if we use keyup message
 PostMessage(handle, (keyDown) ? WM_KEYDOWN : WM_KEYUP, VK_RETURN, lParam); // send enter

надеюсь, что это полезно для кого-то другого. Как и Совет вендетты.

а.. если у вас есть лучшее решение, пожалуйста, так сказать!