-1

I'm trying to send uppercase letters or symbols (!@# etc), using the PostMessage() function:

[DllImport("user32.dll")]
public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

I tried sending both shift and the letter I want to send in upper case but it doesn't seem to work:

        public const uint WM_KEYUP = 0x0101;
        public const uint WM_KEYDOWN = 0x100;

        void function()
        {
            Keys key = Keys.A;
            Keys shift = Keys.ShiftKey;

            PostMessage(process.MainWindowHandle, WM_KEYDOWN, (IntPtr)shift, IntPtr.Zero);
            PostMessage(process.MainWindowHandle, WM_KEYDOWN, (IntPtr)key, IntPtr.Zero);
            PostMessage(process.MainWindowHandle, WM_KEYUP, (IntPtr)shift, IntPtr.Zero);
            PostMessage(process.MainWindowHandle, WM_KEYUP, (IntPtr)key, IntPtr.Zero);
        }

Edit: for those wondering: I ended up using SendInput() to send the shift key press, because apparently many games don't detect the shift key press the same way they detect other key presses that's why it didn't detect the shift key press when I tried sending it with PostMessage(), you can also use keybd_event() and SendKeys(). Note: that these methods don't send the keys to a specific process.

  • Have you looked into `SendKeys`? It has .NET support in Windows Forms, but you can use P/Invoke otherwise – Flydog57 Jun 01 '20 at 22:03
  • Yea, I looked into SendKeys, but I need to use specifically PostMessage() and SendMessage() because I want to send the input to a specific process.Can you give an example of how to use the invoke please. –  Jun 02 '20 at 07:12
  • You have a problem here because your modifier keys are stacked on top of whatever the physical keyboard state was. You send "SHIFT (keyup)". What if the SHIFT key actually is down? Now you confused the program. Or what if the CTRL key (which you generate no events for) is down? Now the program thinks that "SHIFT+CTRL+A" was typed. – Ben Voigt Jun 02 '20 at 18:05
  • Also, `IntPtr.Zero` is not correct for *lParam*. Read [the documentation](https://learn.microsoft.com/en-us/windows/win32/inputdev/wm-keyup) to see what must be sent. – Ben Voigt Jun 02 '20 at 18:06

1 Answers1

1

Try this instead of using WM_KEYDOWN and WM_KEYUP:

        public const uint WM_CHAR = 0x0102;

            ...

            PostMessage(process.MainWindowHandle, WM_CHAR, (IntPtr)'A', IntPtr.Zero);

Full Solution: Create a C# Console App (Mine was .NET Framework 4.7.2)

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace PostMessageTest
{
    class Program
    {
        [DllImport("user32.dll")]
        public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
        public const uint WM_CHAR = 0x0102;

        public static void function()
        {
            IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
            Console.WriteLine("Sending Keys...");
            PostMessage(handle, WM_CHAR, (IntPtr)'A', IntPtr.Zero); // 0x41
        }

        static void Main(string[] args)
        {
            function();
            Console.Read();
        }
    }
}

Tam Bui
  • 2,940
  • 2
  • 18
  • 27
  • It should work. I've updated my answer with the full solution, which I ran before giving you my answer. Try it out. – Tam Bui Jun 02 '20 at 19:23