Sending specific keys on the Numpad like +, -, / or Enter (simulating a keypress)

后端 未结 3 1025
离开以前
离开以前 2021-01-12 20:56

I am working on a project where it is necessary to simulate key-presses to cause specific behaviours in a different application.

All is running well and fine, using

相关标签:
3条回答
  • 2021-01-12 21:40

    Since you are talking about a the-other-way-round solution, detecting the event, and I want to raise it, I don't even have to override the WndProc. I can simply send my own messages.

    From your solution, I had a look at SendMessage/PostMessage, and then WM_KEYDOWN and WM_KEYUP. The documentation actually gives you the info (if you look really really hard).

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

    So my solution (compiles and now with finding the right window (where to enter the text)) is like this:

     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
    

    Hope it is useful to someone else as well. As was Vendetta's tip to me.

    And.. if you do have a better solution, please say so!

    0 讨论(0)
  • 2021-01-12 21:44

    I found this here works for me !

    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);
          }
    }
    
    0 讨论(0)
  • 2021-01-12 21:58

    thanks to andreas for providing the beginning of a solution. here's a more complete version:

    [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
    }
    
    0 讨论(0)
提交回复
热议问题