C# 设置WM_键控LPRAM参数

C# 设置WM_键控LPRAM参数,c#,winapi,C#,Winapi,我可以在上面的页面中看到,lParam参数应该包含我想要发送的所有参数,以位为单位。例如,如果我想为扫描码发送一个“0x2D”值,我应该怎么做?MSDN页面会告诉您每个参数要使用的lParam位。您只需进行一些位移位即可组装lParam: public class sendKeys { [DllImport("user32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWind


我可以在上面的页面中看到,lParam参数应该包含我想要发送的所有参数,以位为单位。例如,如果我想为扫描码发送一个“0x2D”值,我应该怎么做?

MSDN页面会告诉您每个参数要使用的
lParam
位。您只需进行一些位移位即可组装
lParam

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);
        }
}
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);
uint repeatCount=0;
uint扫描代码=0x2D;
uint扩展=0;
uint上下文=0;
uint-previousState=0;
uint跃迁=0;
//根据钻头组合上述参数
//WM_KEYDOWN的MSDN页面中描述的字段
uint lParam=重复计数

|(scanCode这里有一个更完整的例子,使用TypeIA的答案来帮助那些解决溢出问题的人。我之所以添加这个,是因为他的答案是我所见过的所有问题中最正确、最深入的一个,所以要真正做到这一点


带转换的TypeIA和Fehniix:


MSDN页面会告诉您每个参数要使用的
lParam
位。您只需进行一些位移位即可组装
lParam

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);
        }
}
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);
consuint WM_KEYDOWN=0x0100;
const uint WM_SYSCOMMAND=0x018;
consuint SC_CLOSE=0x053;
[DllImport(“user32.dll”)]
公共静态外部IntPtr SendMessage(IntPtr hWnd、uint Msg、IntPtr wParam、IntPtr lParam);
uint repeatCount=0;
uint扫描代码=k;
uint扩展=0;
uint上下文=0;
uint-previousState=0;
uint跃迁=0;
//根据钻头组合上述参数
//WM_KEYDOWN的MSDN页面中描述的字段
uint lParamDown=重复计数

|(扫描代码,因为您不是真正发送指针,而是实际的int值,所以也可以使用:[DllImport(“user32.dll”)]静态外部IntPtr SendMessage(IntPtr hWnd,UInt32 Msg,Int32 wParam,Int32 lParam);在这种情况下,您不需要强制转换为IntPtr。这看起来不是您问题的正确解决方案,但我们无法告诉您正确的解决方案,因为您没有告诉我们该问题对于WM_KEYDOWN消息非常有效,但对于该消息,我应该将previousState和transition设置为1,作为算术OverflowException是thrown@Phoenìx我无法复制此代码(它对我来说工作正常,不会引发异常)。您是否使用我在上面发布的确切代码(只需将
previousState
transition
设置为
1
)?@dvnrss是的,我使用的代码与您发布的代码相同。顺便说一句,如果我按照csgero的建议在函数声明中用Int32替换IntPtr,问题似乎已经解决了,但是为什么呢?@Phoenìx为了64位兼容性,确实应该是
IntPtr
;如果链接到64位Windows API,使用
UInt32
将失败。
IntPtr
是32位或64位,以匹配目标环境(在
sendmages()定义中使用的
LPARAM
也是如此).至于你的溢出错误,我真的不知道;我发布的代码对我来说很好。Necro helper消息面向未来旅行者。你可以使用此代码,它也可以工作,但你需要在IntPtr之前执行从'uint'到'int'的未经检查的转换。你肯定应该使用IntPtr或学习使用它,现在已经有64位了。所以:var iplParam=unchecked((IntPtr)(int)lParam);然后在winapi调用中使用ipLParam。