Click here to Skip to main content
15,897,371 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I try to use PostMasseg to send VK to inactive application i want to sent (Space+1)

but it always send only (1)

here what spy++ read whine i press (space+1)

<000001> 000702FC P WM_KEYDOWN nVirtKey:VK_SPACE cRepeat:1 ScanCode:39 fExtended:0 fAltDown:0 fRepeat:0 fUp:0<br />
<br />
<000002> 000702FC P WM_CHAR chCharCode:'32' (32) cRepeat:1 ScanCode:39 fExtended:0 fAltDown:0 fRepeat:0 fUp:0<br />
<br />
<000003> 000702FC P WM_KEYDOWN nVirtKey:'1' cRepeat:1 ScanCode:02 fExtended:0 fAltDown:0 fRepeat:0 fUp:0<br />
<br />
<000004> 000702FC P WM_CHAR chCharCode:'49' (49) cRepeat:1 ScanCode:02 fExtended:0 fAltDown:0 fRepeat:0 fUp:0<br />
<br />
<000005> 000702FC P WM_KEYUP nVirtKey:VK_SPACE cRepeat:1 ScanCode:39 fExtended:0 fAltDown:0 fRepeat:1 fUp:1<br />
<br />
<000006> 000702FC P WM_KEYUP nVirtKey:'1' cRepeat:1 ScanCode:02 fExtended:0 fAltDown:0 fRepeat:1 fUp:1<br />
<br />
<000007> 000702FC P WM_SYSKEYDOWN nVirtKey:VK_MENU cRepeat:1 ScanCode:38 fExtended:0 fAltDown:1 fRepeat:0 fUp:0


how to simulate this?

now i have something else i didn't under stand i didn't get what i need with this code


C#
public static void sendKey(IntPtr hwnd, Keys keyCode)
    {
        uint scanCode = MapVirtualKey((uint)keyCode, 0);
        uint lParam;
        // 
        //KEY DOWN
        lParam = (0x00000001 | (scanCode << 16));
        //if (extended)
        //{
        //    lParam |= 0x01000000;
        //}
        PostMessage(hwnd, (UInt32)WM_KEYDOWN, (IntPtr)keyCode, (IntPtr)lParam);
        Thread.Sleep(100);

        uint scanCode1 = MapVirtualKey((uint)Keys.D1, 0);
        uint lParam1;
        // 
        //KEY DOWN
        lParam1 = (0x00000001 | (scanCode1 << 16));

        PostMessage(hwnd, (UInt32)WM_KEYDOWN, (IntPtr)Keys.D1, (IntPtr)lParam1);

        Thread.Sleep(50);
        //KEY UP
        //lParam |= 0xC0000000;  // set previous key and transition states (bits 30 and 31)
        PostMessage(hwnd, WM_KEYUP, (IntPtr)Keys.D1, (IntPtr)(0xC0020001));
        PostMessage(hwnd, WM_KEYUP, (IntPtr)keyCode, (IntPtr)(0xC0390001));

    }


and spy++ read this from my app when i press the command button

<000001> 000401BA P WM_KEYDOWN nVirtKey:VK_SPACE cRepeat:1 ScanCode:39 fExtended:0 fAltDown:0 fRepeat:0 fUp:0

<000002> 000401BA P WM_CHAR chCharCode:'32' (32) cRepeat:1 ScanCode:39 fExtended:0 fAltDown:0 fRepeat:0 fUp:0

<000003> 000401BA P WM_KEYDOWN nVirtKey:'1' cRepeat:1 ScanCode:02 fExtended:0 fAltDown:0 fRepeat:0 fUp:0

<000004> 000401BA P WM_CHAR chCharCode:'49' (49) cRepeat:1 ScanCode:02 fExtended:0 fAltDown:0 fRepeat:0 fUp:0

<000005> 000401BA P WM_KEYUP nVirtKey:'1' cRepeat:1 ScanCode:02 fExtended:0 fAltDown:0 fRepeat:1 fUp:1

<000006> 000401BA P WM_KEYUP nVirtKey:VK_SPACE cRepeat:1 ScanCode:39 fExtended:0 fAltDown:0 fRepeat:1 fUp:1

but it didn't do what i need ?

can any one tell me where's the error

i don it with this code

C#
<pre>using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {

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

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern uint MapVirtualKey(uint uCode, uint uMapType);

        [DllImport("user32.dll", SetLastError = true)]
        static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);

        const uint WM_KEYDOWN = 0x0100;
        const uint WM_KEYUP = 0x0101;
        const int WM_SYSKEYDOWN = 0x0104;
        const int KEYEVENTF_EXTENDEDKEY = 0x0001; //Key down flag
        const int KEYEVENTF_KEYUP = 0x0002; //Key up flag

        public Form1()
        {
            InitializeComponent();
            LoadProcess();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Process p = (Process)comboBox1.SelectedItem;
            keybd_event((byte)Keys.Space, (byte)0x02, (int)WM_KEYDOWN, 0);
            sendKeyUp(p.MainWindowHandle, Keys.D1);
            sendKeyDown(p.MainWindowHandle, Keys.D1);
            keybd_event((byte)Keys.Space, (byte)0x82, KEYEVENTF_KEYUP, 0);
        }

        private void LoadProcess()
        {
            comboBox1.Items.Clear();
            comboBox1.DisplayMember = "MainWindowTitle";
            foreach (Process item in Process.GetProcesses())
            {
                try
                {
                    comboBox1.Items.Add(item);
                }
                catch { }
            }
        }

        public static void sendKeyDown(IntPtr hwnd, Keys keyCode)
        {
            uint scanCode = MapVirtualKey((uint)keyCode, 0);
            uint lParam;
            // 
            //KEY DOWN
            lParam = (0x00000001 | (scanCode << 16));
            //if (extended)
            //{
            //    lParam |= 0x01000000;
            //}
            PostMessage(hwnd, (UInt32)WM_SYSKEYDOWN, (IntPtr)keyCode, (IntPtr)lParam);
        }

        public static void sendKeyUp(IntPtr hwnd, Keys keyCode)
        {
            uint scanCode = MapVirtualKey((uint)keyCode, 0);
            uint lParam;
            // 
            //KEY DOWN
            lParam = (0xC0000001 | (scanCode << 16));
            //KEY UP
            //lParam |= 0xC0000001;  // set previous key and transition states (bits 30 and 31)
            PostMessage(hwnd, WM_KEYUP, (IntPtr)keyCode, (IntPtr)lParam);
        }
    }
}


but still there is error

the app didn't stop it keep repeat the key pressing

What I have tried:

C#
const uint WM_KEYDOWN = 0x100;
const uint WM_KEYUP = 0x0101;

PostMessage(p.MainWindowHandle, WM_KEYDOWN, (IntPtr)Keys.Space, (IntPtr)0x0);
PostMessage(p.MainWindowHandle, WM_KEYDOWN, (IntPtr)Keys.D1, (IntPtr)0x0);
PostMessage(p.MainWindowHandle, WM_KEYUP, (IntPtr)Keys.Space, (IntPtr)0x0);
PostMessage(p.MainWindowHandle, WM_KEYUP, (IntPtr)Keys.D1, (IntPtr)0x0);
Posted
Updated 5-Feb-18 7:18am
v6

i find way to solve it

C#
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace SendKeysWithModefire
{
   public class KeysTest
    {
        [DllImport("user32.dll", SetLastError = true)]
        static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);

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

        const uint WM_KEYDOWN = 0x100;
        const uint WM_KEYUP = 0x101;
        const uint Key_Down = 0x0001;
        const uint Key_Up = 0x0002;
        private volatile bool _shouldStop;
        private Process _sroProcess;
        private Keys _modefirKey;
        private Keys _pressKey;

        public KeysTest(Process targetSro,Keys modKey,Keys pressKey)
        {
            _sroProcess = targetSro;
            _modefirKey = modKey;
            _pressKey = pressKey;
        }

        public void SendKeys()
        {
            SendKeyWithModefir(_sroProcess, (byte)_modefirKey, (byte)_pressKey);
        }

        public void SendKeyWithModefir(Process _p, byte ModKey, byte PressKey)
        {
            while (!_shouldStop)
            {
                keybd_event(ModKey, 0, Key_Down, 0);
                Thread.Sleep(50);
                PostMessage(_p.MainWindowHandle, WM_KEYDOWN, (IntPtr)(PressKey), (IntPtr)(0));
                PostMessage(_p.MainWindowHandle, WM_KEYUP, (IntPtr)(PressKey), (IntPtr)(0));
                Thread.Sleep(50);
                keybd_event(ModKey, 0, Key_Up, 0);
            }
        }

        public void RequestStop()
        {
            _shouldStop = true;
        }

        ~KeysTest()
        {
            GC.Collect();
        }
    }
}


and that's the call for it

C#
private KeysTest sendingKeys;
private Thread startSending;

...............

//that code send Left Control + 1
//s is the target process
sendingKeys = new KeysTest(s, Keys.LControlKey, Keys.D1);
startSending = new Thread(sendingKeys.SendKeys); 
startSending.Start();
while (!startSending.IsAlive) ;
Thread.Sleep(2000);
sendingKeys.RequestStop();
startSending.Join();
startSending.Abort();
 
Share this answer
 
v2
Comments
wt1682 6-Dec-22 23:10pm    
Two key combinations such as Ctrl+A worked, but how can I do three or more key combinations such as Ctrl+Shift+I?
Thank you.

[Use Google Translate]
wt1682 6-Dec-22 23:16pm    
I tried rewriting the code as below, but as far as I tried, it didn't work.

....
public void SendKeys()
{
SendKeyWithModefir(_sroProcess, (byte)_modefirKey1, (byte)_modefirKey2, (byte)_modefirKey3, (byte)_modefirKey4, (byte)_pressKey);
}

public void SendKeyWithModefir(Process _p, byte ModKey1, byte ModKey2, byte ModKey3, byte ModKey4, byte PressKey)
{
while (!_shouldStop)
{
int interval = 50;
if (_modefirKey1 != Keys.None)
{
keybd_event(ModKey1, 0, Key_Down, 0);
Thread.Sleep(interval);
}
if (_modefirKey2 != Keys.None)
{
keybd_event(ModKey2, 0, Key_Down, 1);
Thread.Sleep(interval);
}
if (_modefirKey3 != Keys.None)
{
keybd_event(ModKey3, 0, Key_Down, 2);
Thread.Sleep(interval);
}
if (_modefirKey4 != Keys.None)
{
keybd_event(ModKey4, 0, Key_Down, 3);
Thread.Sleep(interval);
}
PostMessage(_p.MainWindowHandle, WM_KEYDOWN, (IntPtr)(PressKey), (IntPtr)(0));
PostMessage(_p.MainWindowHandle, WM_KEYUP, (IntPtr)(PressKey), (IntPtr)(0));
if (_modefirKey1 != Keys.None)
{
Thread.Sleep(interval);
keybd_event(ModKey1, 0, Key_Up, 0);
}
if (_modefirKey2 != Keys.None)
{
Thread.Sleep(interval);
keybd_event(ModKey2, 0, Key_Up, 1);
}
if (_modefirKey3 != Keys.None)
{
Thread.Sleep(interval);
keybd_event(ModKey3, 0, Key_Up, 2);
}
if (_modefirKey4 != Keys.None)
{
Thread.Sleep(interval);
keybd_event(ModKey4, 0, Key_Up, 3);
}
}
}
....
Try sending the WM_KEYUP before the next WM_KEYDOWN:
C++
PostMessage(p.MainWindowHandle, WM_KEYDOWN, (IntPtr)Keys.Space, (IntPtr)0x0);
PostMessage(p.MainWindowHandle, WM_KEYUP, (IntPtr)Keys.Space, (IntPtr)0x0);
PostMessage(p.MainWindowHandle, WM_KEYDOWN, (IntPtr)Keys.D1, (IntPtr)0x0);
PostMessage(p.MainWindowHandle, WM_KEYUP, (IntPtr)Keys.D1, (IntPtr)0x0);
 
Share this answer
 
Comments
Member 7912784 1-Feb-18 12:49pm    
i try it but not work i need it to press (Space + 1)
Richard MacCutchan 2-Feb-18 8:42am    
What does "not work" mean? As far as I can see from your Spy++ trace the keys are all being sent correctly.
Member 7912784 2-Feb-18 9:03am    
yes but it didn't do the effect as when i press them manual
Richard MacCutchan 2-Feb-18 9:24am    
It might help if you actually explained what you expect it to do, and what result it does produce.
Member 7912784 2-Feb-18 9:36am    
i try to create key presser for game

one of game commands is (Space + number)

i try to simulate this with code

but when i do that the result with code is just as i press the number only not as i press (Space + number)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900