简体   繁体   中英

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?

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);

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM