Johnny Bueti
Johnny Bueti

Reputation: 648

Setting WM_KEYDOWN lParam parameters

public class sendKeys {
    [DllImport("user32.dll")]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [DllImport("user32.dll")]
    public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr, lParam);

    public static void sendKeystroke(ushort k)
        {
            const uint WM_KEYDOWN = 0x0100;
            const uint WM_SYSCOMMAND = 0x018;
            const uint SC_CLOSE = 0x053;

            IntPtr WindowToFind = FindWindow(null, "processname");

            IntPtr result3 = SendMessage(WindowToFind, WM_KEYDOWN, ((IntPtr)k), (IntPtr)0);
        }
}

http://msdn.microsoft.com/en-us/library/windows/desktop/ms646280%28v=vs.85%29.aspx I can read in the page above, that the lParam argument should contain all the parameters I want to send, in bits. If, for example, I wanted to send a "0x2D" value for the ScanCode, how should I do it?

Upvotes: 2

Views: 4268

Answers (2)

Beeeaaar
Beeeaaar

Reputation: 1035

Here's more complete example using TypeIA's answer to help those with the overflow issue. I'm adding this because his answer is one of the most correct and down into the necessary nitty-gritty of any I've seen on SO to actually make this work.


TypeIA's and Fehniix's with conversions:

The MSDN page tells you what bits of lParam to use for each of the parameters. All you need to do is some bit shifting to assemble lParam:

const uint WM_KEYDOWN = 0x0100;
const uint WM_SYSCOMMAND = 0x018;
const uint SC_CLOSE = 0x053;

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

uint repeatCount = 0;
uint scanCode = k;
uint extended = 0;
uint context = 0;
uint previousState = 0;
uint transition = 0;

// combine the parameters above according to the bit
// fields described in the MSDN page for WM_KEYDOWN

uint lParamDown = repeatCount
    | (scanCode << 16)
    | (extended << 24)
    | (context << 29)
    | (previousState << 30)
    | (transition << 31);

previousState = 1;
transition = 1;

uint lParamUp = repeatCount
    | (scanCode << 16)
    | (extended << 24)
    | (context << 29)
    | (previousState << 30)
    | (transition << 31);

var ipKey = (IntPtr)(int)k;
var ipLParamDown = unchecked((IntPtr)(int)lParamDown);
var ipLParamUp = unchecked((IntPtr)(int)lParamUp);

IntPtr WindowToFind = FindWindow(null, "processname");

IntPtr result3 = SendMessage(WindowToFind, WM_KEYDOWN, ipKey, ipLParamDown);
IntPtr result4 = SendMessage(WindowToFind, WM_KEYUP, ipKey, ipLParamUp);

Upvotes: 3

TypeIA
TypeIA

Reputation: 17250

The MSDN page tells you what bits of lParam to use for each of the parameters. All you need to do is some bit shifting to assemble lParam:

uint repeatCount = 0;
uint scanCode = 0x2D;
uint extended = 0;
uint context = 0;
uint previousState = 0;
uint transition = 0;

// combine the parameters above according to the bit
// fields described in the MSDN page for WM_KEYDOWN

uint lParam = repeatCount
    | (scanCode << 16)
    | (extended << 24)
    | (context << 29)
    | (previousState << 30)
    | (transition << 31);

Upvotes: 5

Related Questions