C# sendmessage详解,键盘 鼠标 求给力 拜托

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# sendmessage详解,键盘 鼠标 求给力 拜托相关的知识,希望对你有一定的参考价值。

sendmessage有几个参数 用来发键盘消息 鼠标消息,我现在不太明白的有这些
虚拟键值、按下松开、怎么区分是键盘还是鼠标、数字跟字母按键是不是不仅仅是键值的差别 还是有其他参数的区别,暂且抛开组合键, 实际点说是帮我搞定几个
发送数字键,发送字母键,发送左键,右键,当然这个都包括按下和松开,
另外
///模拟鼠标左键点击 x表示横坐标,y表示纵坐标
public void SendMsg(IntPtr hWnd, int x, int y)

///发送左键消息
SendMessage(hWnd, 0x0201, (IntPtr)1, (IntPtr)(y * 65536 + x));
Thread.Sleep(50);
SendMessage(hWnd, 0x0202, (IntPtr)1, (IntPtr)(y * 65536 + x));

这段代码是否有误?
很需要满意答案 加分

这本身是win32API 级别的东西,你咋放在C#里面问呢?虽然是在C#里面用.NET语言,但本身这还是Win32API的东西。。。。比较底层了啊。


【疑点-1】你的代码有没有问题,要看 0x0201 和 0x0202 到底是什么:

     我不清楚键盘鼠标的事件码,你自己明白发的这2消息201和202是什么吗?



【疑点-2】后两个参数:(IntPtr)1, (IntPtr)(y * 65536 + x)

    你确定目标窗口(hWnd) 会处理这俩参数吗?而且为什么一定要转换成IntPtr的地址指针类型?


    如果目标窗口(hWnd)和你的程序不是一个主进程启动的,对方是不能访问你的内存地址的啊。。。(现在都有进程隔离)。。。


这个函数的底层(原始C)是这么定义的:

LRESULT WINAPI SendMessage(
  _In_  HWND hWnd,
  _In_  UINT Msg,
  _In_  WPARAM wParam,
  _In_  LPARAM lParam
);


如你所见,第一个参数是接收你的消息的目标窗口句柄是个数字ID,第二个参数是所要发送的消息,最后俩参数是可选的参数,一般是特殊数据才需要用的。你传过去2个地址指针,不是很明白你要干什么。。。或者 0x0201 在对方程序里是什么特殊意思吗?


【疑点-3】 对于IntPtr的使用。。。

    你确定你的程序将运行在64位的机器上吗?因为IntPtr在32位机器上运行就是32位整数,64位机器就是64位整数。。。。


    如果在32位机器上【(IntPtr)(y * 65536 + x)】 这可能就是个负数……无论是地址还是鼠标坐标应该都没有负数这么一说吧。



【疑点-4】关于 “y * 65536 + x” 的目的。。。

    我实在不能理解你这是想干什么,目测最大可能是:你想把x/y坐标系转成一个数字参数传递过去?  但你这样算出一个值z,你怎么能从结果z推导出原始的x和y呢???


    如果是屏幕坐标,一般是不超过8192的吧。。。(就算是8K分辨率),所以8192是:2的13次方。。。那么你混合坐标应该这么算: z = (y << 13 |  x );

     逆推就是: x = z & 8191 ; y = z >>> 13;


顺便一问:

你这是要做外挂么。。。

追问

那个方法是用模拟鼠标点击,是操作一些日常工作的软件,IntPtr是因定义函数用的是这个,那个什么65536是网上弄来的 我也不知道什么意思
发送数字按键,字母按键 鼠标 咋个弄?
SendMessage(hWnd, 256, (IntPtr)49, IntPtr.Zero);
SendMessage(hWnd, 257, (IntPtr)49, IntPtr.Zero);
没法发出按键呀 咋搞

追答

首先: 要确保 hWnd 是你希望操作的”日常工作软件“的主窗口句柄的ID号码 —— 这是很古老的Win32API的概念,每个桌面上的窗口(包括不可见的),甚至一个按钮,都对应一个唯一的hWnd句柄ID。。。。 如果不能获取或者获取的不对,你就趁早放弃吧。。。

其次:在现在Windows的UAC的管制之下,以及各种安全机制、沙箱隔离的现代防恶意软件的保护机制的呵护下,你要确定你的程序有系统管理员级别的权限,能够给其他”日常工作软件“的窗体发送消息才可以

最后:如其他楼层回复所述,如果是要发送键盘,那第二个参数应该是个类似于:WM_KEYDOWN 这样的值,你可以查查对应的事件数字是多少,也可以找找C#里面对应的枚举类型之类的(实在是不能帮你找了)

额外的:发送键盘(WM_KEYDOWN, WM_KEYUP)事件和发送鼠标事件(WM_MOUSEDOWN, WM_MOUSEUP)时候,最后两个参数的用途是不一样的。。。。还是你需要去看Win32API方面的知识才可以。。。。问C#是问不出个所以然的。你可以搜搜SendMessage关于发送键盘消息的用法(应该是用了第三个参数传递的消息码,如86对应回车什么的),再查查SendMessage发送鼠标消息……

有楼层帮你查到MSDN了,你又省事了一步。。。温馨提醒这个坐标系的clientArea转化是相对于目标窗体的。。。

回答满意且牛B的话,请加分

参考技术A 楼主您好:
先看SendMessage,从百科就可以查询到
SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);
第一个参数HWND hWnd
故名思议是窗体句柄,你这儿作为参数传递进来了
第二个参数UINT Msg
是windows消息常量,这里使用到两个0x201,0x202,还是百科就可以找到,如下:
WM_LBUTTONDOWN = $0201;//按下鼠标左键
WM_LBUTTONUP = $0202;//释放鼠标左键
第三个参数WPARAM wParam
MSDN里头有这么一段
WM_LBUTTONDOWN
WPARAM wParam
LPARAM lParam;
Parameters
wParam
Indicates whether various virtual keys are down. This parameter can be one or more of the following values.
MK_CONTROL
The CTRL key is down.
MK_LBUTTON
The left mouse button is down.//这句是重点了,而后我查找MK_LBUTTON的值,就是定义为 0x01.也就是为什么是(IntPtr)1。
第四个参数LPARAM IParam
MSDN里说到
lParam
The low-order word specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.
The high-order word specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.
这里说到低位代表X坐标,指向左上角,高位则代表Y坐标。从代码中的(IntPtr)(y * 65536 + x)参数不难分析到,y * 65536相当于<<16。65536代表16位数据的数据量,这个是属于位的运算。比如0-65535是个16位unsigned int类型的数据范围,一共能取到的数就是65536.这个数据是个32位的数据,前16位代表了X坐标值,后16位为Y值,所以按照这个写法应该是正确的。

希望对你有帮助,望采纳。
参考技术B SendMessage 第二个参数,指定发送的消息类型, 如鼠标消息WM_LBUTTONDOWN,WM_MOUSEMOVE等。键盘消息:WM_KEYDOWN,WM_KEYUP

没问题,最后2个参数也不必转成句柄。

C#用windows Api Hooks 控制鼠标键盘在一个窗体内

其实功能很简单,我也做了一半,现在问题是语言是C#
获取一个窗体的句柄,让后把鼠标控制在此窗体里面(也就是不可以离开此窗体),键盘也一样,最好可以控制ctrl+alt+delete的组合键,我做了下,有难度、、、

源码也行,理论也行。谢谢各位

主要是第一个窗体类.其他的2个类是我封装的WINDOWS API

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace HookDemo

public partial class Form1 : Form

private System.Windows.Forms.Timer monitorTimer = null;
private Kits.Hook.WinHook mouseHook = null;
private IntPtr HWND = IntPtr.Zero;

public Form1()

InitializeComponent();
this.monitorTimer = new Timer();
this.monitorTimer.Tick += new EventHandler(this.TimeProc);
this.monitorTimer.Interval = 1000;
mouseHook = new Kits.Hook.WinHook(Kits.Win32API.HookType.WH_MOUSE_LL);


private void Form1_Load(object sender, EventArgs e)

this.WindowState = FormWindowState.Minimized;
this.monitorTimer.Enabled = true;


private void TimeProc(object sender, EventArgs e)

HWND = Kits.Win32API.WinAPI.FindWindow("Notepad", null);
if (HWND != IntPtr.Zero)

//Kits.Win32API.CSharpRect rect = new Kits.Win32API.CSharpRect();
//Kits.Win32API.WinAPI.GetWindowRect(HWND, ref rect);
//this.Text = string.Format("0,1,2,3",rect.top,rect.left,rect.width,rect.height);
if (HWND == Kits.Win32API.WinAPI.GetForegroundWindow())

mouseHook.SetWindowsHookEx(new Kits.Win32API.HookProc(this.MouseHookProc));

else

if (mouseHook.HHook != 0)

mouseHook.UnhookWindowsHookEx();





private int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)

if (wParam == new IntPtr((int)Kits.Win32API.WindowsMessages.WM_MOUSEMOVE))

bool isOut = false;
Kits.Win32API.MouseHookStruct MyMouseHookStruct = (Kits.Win32API.MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(Kits.Win32API.MouseHookStruct));
Kits.Win32API.CSharpRect rect = new Kits.Win32API.CSharpRect();
Kits.Win32API.WinAPI.GetWindowRect(HWND, ref rect);
if (MyMouseHookStruct.pt.x >= rect.right)
isOut = true;
if (MyMouseHookStruct.pt.x <= rect.left)
isOut = true;
if (MyMouseHookStruct.pt.y <= rect.top)
isOut = true;
if (MyMouseHookStruct.pt.y >= rect.bottom)
isOut = true;

//Cursor.Position = new Point(MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y);
if (isOut)
return -1;

return Kits.Win32API.WinAPI.CallNextHookEx(mouseHook.HHook, nCode, wParam, lParam);




using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace Kits.Win32API

public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);

public class WinAPI

[DllImport("User32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

[DllImport("User32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);

[DllImport("User32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr GetModuleHandle(string lpModuleName);

[DllImport("User32.dll")]
public static extern IntPtr FindWindow(string lpClassName,string lpWindowName);

[DllImport("User32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("User32.dll")]
public static extern void keybd_event(Byte bVk, Byte bScan, Int32 dwFlags, Int32 dwExtraInfo);

[DllImport("user32")]
public static extern IntPtr GetActiveWindow();

[DllImport("user32")]
public static extern IntPtr GetForegroundWindow();

[DllImport("user32")]
public static extern int GetWindowRect(IntPtr hwnd, ref CSharpRect lpRect);

[DllImport("user32")]
public static extern int SetCaretPos(int x, int y);

[DllImport("user32")]
public static extern int ScreenToClient(IntPtr hwnd, ref POINTAPI lpPoint);

[DllImport("user32")]
public static extern int ClientToScreen(IntPtr hwnd, ref POINTAPI lpPoint);

[DllImport("user32")]
public static extern int SetCursorPos(int x, int y);


public struct POINTAPI

public int x;
public int y;


public struct RECT

public long left;
public long top;
public long right;
public long bottom;


public struct CSharpRect

public int top;
public int left;
public int right;
public int bottom;


public enum HookType : int

WH_JOURNALRECORD = 0,
WH_JOURNALPLAYBACK = 1,
WH_KEYBOARD = 2,
WH_GETMESSAGE = 3,
WH_CALLWNDPROC = 4,
WH_CBT = 5,
WH_SYSMSGFILTER = 6,
WH_MOUSE = 7,
WH_HARDWARE = 8,
WH_DEBUG = 9,
WH_SHELL = 10,
WH_FOREGROUNDIDLE = 11,
WH_CALLWNDPROCRET = 12,
WH_KEYBOARD_LL = 13,
WH_MOUSE_LL = 14


[StructLayout(LayoutKind.Sequential)]
public class POINT

public int x;
public int y;


[StructLayout(LayoutKind.Sequential)]
public class MouseHookStruct

public POINT pt;
public int wHitTestCode;
public int dwExtraInfo;


[StructLayout(LayoutKind.Sequential)]
public class MouseLLHookStruct

public POINT pt;
public int mouseData;
public int flags;
public int time;
public int dwExtraInfo;


[StructLayout(LayoutKind.Sequential)]
public class KeyboardHookStruct

public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;


public enum WindowsMessages:int

WM_ACTIVATE = 0x6,
WM_ACTIVATEAPP = 0x1C,
WM_AFXFIRST = 0x360,
WM_AFXLAST = 0x37F,
WM_APP = 0x8000,
WM_ASKCBFORMATNAME = 0x30C,
WM_CANCELJOURNAL = 0x4B,
WM_CANCELMODE = 0x1F,
WM_CAPTURECHANGED = 0x215,
WM_CHANGECBCHAIN = 0x30D,
WM_CHAR = 0x102,
WM_CHARTOITEM = 0x2F,
WM_CHILDACTIVATE = 0x22,
WM_CLEAR = 0x303,
WM_CLOSE = 0x10,
WM_COMMAND = 0x111,
WM_COMPACTING = 0x41,
WM_COMPAREITEM = 0x39,
WM_CONTEXTMENU = 0x7B,
WM_COPY = 0x301,
WM_COPYDATA = 0x4A,
WM_CREATE = 0x1,
WM_CTLCOLORBTN = 0x135,
WM_CTLCOLORDLG = 0x136,
WM_CTLCOLOREDIT = 0x133,
WM_CTLCOLORLISTBOX = 0x134,
WM_CTLCOLORMSGBOX = 0x132,
WM_CTLCOLORSCROLLBAR = 0x137,
WM_CTLCOLORSTATIC = 0x138,
WM_CUT = 0x300,
WM_DEADCHAR = 0x103,
WM_DELETEITEM = 0x2D,
WM_DESTROY = 0x2,
WM_DESTROYCLIPBOARD = 0x307,
WM_DEVICECHANGE = 0x219,
WM_DEVMODECHANGE = 0x1B,
WM_DISPLAYCHANGE = 0x7E,
WM_DRAWCLIPBOARD = 0x308,
WM_DRAWITEM = 0x2B,
WM_DROPFILES = 0x233,
WM_ENABLE = 0xA,
WM_ENDSESSION = 0x16,
WM_ENTERIDLE = 0x121,
WM_ENTERMENULOOP = 0x211,
WM_ENTERSIZEMOVE = 0x231,
WM_ERASEBKGND = 0x14,
WM_EXITMENULOOP = 0x212,
WM_EXITSIZEMOVE = 0x232,
WM_FONTCHANGE = 0x1D,
WM_GETDLGCODE = 0x87,
WM_GETFONT = 0x31,
WM_GETHOTKEY = 0x33,
WM_GETICON = 0x7F,
WM_GETMINMAXINFO = 0x24,
WM_GETOBJECT = 0x3D,
WM_GETTEXT = 0xD,
WM_GETTEXTLENGTH = 0xE,
WM_HANDHELDFIRST = 0x358,
WM_HANDHELDLAST = 0x35F,
WM_HELP = 0x53,
WM_HOTKEY = 0x312,
WM_HSCROLL = 0x114,
WM_HSCROLLCLIPBOARD = 0x30E,
WM_ICONERASEBKGND = 0x27,
WM_IME_CHAR = 0x286,
WM_IME_COMPOSITION = 0x10F,
WM_IME_COMPOSITIONFULL = 0x284,
WM_IME_CONTROL = 0x283,
WM_IME_ENDCOMPOSITION = 0x10E,
WM_IME_KEYDOWN = 0x290,
WM_IME_KEYLAST = 0x10F,
WM_IME_KEYUP = 0x291,
WM_IME_NOTIFY = 0x282,
WM_IME_REQUEST = 0x288,
WM_IME_SELECT = 0x285,
WM_IME_SETCONTEXT = 0x281,
WM_IME_STARTCOMPOSITION = 0x10D,
WM_INITDIALOG = 0x110,
WM_INITMENU = 0x116,
WM_INITMENUPOPUP = 0x117,
WM_INPUTLANGCHANGE = 0x51,
WM_INPUTLANGCHANGEREQUEST = 0x50,
WM_KEYDOWN = 0x100,
WM_KEYFIRST = 0x100,
WM_KEYLAST = 0x108,
WM_KEYUP = 0x101,
WM_KILLFOCUS = 0x8,
WM_LBUTTONDBLCLK = 0x203,
WM_LBUTTONDOWN = 0x201,
WM_LBUTTONUP = 0x202,
WM_MBUTTONDBLCLK = 0x209,
WM_MBUTTONDOWN = 0x207,
WM_MBUTTONUP = 0x208,
WM_MDIACTIVATE = 0x222,
WM_MDICASCADE = 0x227,
WM_MDICREATE = 0x220,
WM_MDIDESTROY = 0x221,
WM_MDIGETACTIVE = 0x229,
WM_MDIICONARRANGE = 0x228,
WM_MDIMAXIMIZE = 0x225,
WM_MDINEXT = 0x224,
WM_MDIREFRESHMENU = 0x234,
WM_MDIRESTORE = 0x223,
WM_MDISETMENU = 0x230,
WM_MDITILE = 0x226,
WM_MEASUREITEM = 0x2C,
WM_MENUCHAR = 0x120,
WM_MENUCOMMAND = 0x126,
WM_MENUDRAG = 0x123,
WM_MENUGETOBJECT = 0x124,
WM_MENURBUTTONUP = 0x122,
WM_MENUSELECT = 0x11F,
WM_MOUSEACTIVATE = 0x21,
WM_MOUSEFIRST = 0x200,
WM_MOUSEHOVER = 0x2A1,
WM_MOUSELAST = 0x20A,
WM_MOUSELEAVE = 0x2A3,
WM_MOUSEMOVE = 0x200,
WM_MOUSEWHEEL = 0x20A,
WM_MOVE = 0x3,
WM_MOVING = 0x216,
WM_NCACTIVATE = 0x86,
WM_NCCALCSIZE = 0x83,
WM_NCCREATE = 0x81,
WM_NCDESTROY = 0x82,
WM_NCHITTEST = 0x84,
WM_NCLBUTTONDBLCLK = 0xA3,
WM_NCLBUTTONDOWN = 0xA1,
WM_NCLBUTTONUP = 0xA2,
WM_NCMBUTTONDBLCLK = 0xA9,
WM_NCMBUTTONDOWN = 0xA7,
WM_NCMBUTTONUP = 0xA8,
WM_NCMOUSEHOVER = 0x2A0,
WM_NCMOUSELEAVE = 0x2A2,
WM_NCMOUSEMOVE = 0xA0,
WM_NCPAINT = 0x85,
WM_NCRBUTTONDBLCLK = 0xA6,
WM_NCRBUTTONDOWN = 0xA4,
WM_NCRBUTTONUP = 0xA5,
WM_NEXTDLGCTL = 0x28,
WM_NEXTMENU = 0x213,
WM_NOTIFY = 0x4E,
WM_NOTIFYFORMAT = 0x55,
WM_NULL = 0x0,
WM_PAINT = 0xF,
WM_PAINTCLIPBOARD = 0x309,
WM_PAINTICON = 0x26,
WM_PALETTECHANGED = 0x311,
WM_PALETTEISCHANGING = 0x310,
WM_PARENTNOTIFY = 0x210,
WM_PASTE = 0x302,
WM_PENWINFIRST = 0x380,
WM_PENWINLAST = 0x38F,
WM_POWER = 0x48,
WM_PRINT = 0x317,
WM_PRINTCLIENT = 0x318,
WM_QUERYDRAGICON = 0x37,
WM_QUERYENDSESSION = 0x11,
WM_QUERYNEWPALETTE = 0x30F,
WM_QUERYOPEN = 0x13,
WM_QUEUESYNC = 0x23,
WM_QUIT = 0x12,
WM_RBUTTONDBLCLK = 0x206,
WM_RBUTTONDOWN = 0x204,
WM_RBUTTONUP = 0x205,
WM_RENDERALLFORMATS = 0x306,
WM_RENDERFORMAT = 0x305,
WM_SETCURSOR = 0x20,
WM_SETFOCUS = 0x7,
WM_SETFONT = 0x30,
WM_SETHOTKEY = 0x32,
WM_SETICON = 0x80,
WM_SETREDRAW = 0xB,
WM_SETTEXT = 0xC,
WM_SETTINGCHANGE = 0x1A,
WM_SHOWWINDOW = 0x18,
WM_SIZE = 0x5,
WM_SIZECLIPBOARD = 0x30B,
WM_SIZING = 0x214,
WM_SPOOLERSTATUS = 0x2A,
WM_STYLECHANGED = 0x7D,
WM_STYLECHANGING = 0x7C,
WM_SYNCPAINT = 0x88,
WM_SYSCHAR = 0x106,
WM_SYSCOLORCHANGE = 0x15,
WM_SYSCOMMAND = 0x112,
WM_SYSDEADCHAR = 0x107,
WM_SYSKEYDOWN = 0x104,
WM_SYSKEYUP = 0x105,
WM_TCARD = 0x52,
WM_TIMECHANGE = 0x1E,
WM_TIMER = 0x113,
WM_UNDO = 0x304,
WM_UNINITMENUPOPUP = 0x125,
WM_USER = 0x400,
WM_USERCHANGED = 0x54,
WM_VKEYTOITEM = 0x2E,
WM_VSCROLL = 0x115,
WM_VSCROLLCLIPBOARD = 0x30A,
WM_WINDOWPOSCHANGED = 0x47,
WM_WINDOWPOSCHANGING = 0x46,
WM_WININICHANGE = 0x1A



using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Kits.Win32API;

namespace Kits.Hook

public class WinHook

private int _hookType = 0;
public int HookType get return this._hookType;

private HookProc _hookProc = null;
public HookProc HookProc get return this._hookProc;

private int _hHook = 0;
public int HHook get return this._hHook;

public WinHook(HookType type)
this._hookType = (int)type;


public bool SetWindowsHookEx(HookProc Proc)
bool Success = false;
if (this._hHook == 0)
this._hookProc = Proc;
_hHook = WinAPI.SetWindowsHookEx(this._hookType, this._hookProc, Process.GetCurrentProcess().MainModule.BaseAddress, 0);
if (this._hHook != 0)
Success = true;

return Success;


public bool UnhookWindowsHookEx()
bool Success = false;
if (this._hHook != 0)

Success = WinAPI.UnhookWindowsHookEx(this._hHook);

return Success;


参考技术A 关注

以上是关于C# sendmessage详解,键盘 鼠标 求给力 拜托的主要内容,如果未能解决你的问题,请参考以下文章

winform用SendMessage怎么发送一个鼠标消息,指定鼠标在某个窗口(32,32)处按下,指定坐标在sendmess

C#用windows Api Hooks 控制鼠标键盘在一个窗体内

如何用 sendmessage 发送键盘按键消息

delphi中有模拟发送鼠标按键sendmessage的疑问

DirectX 游戏挂钩

如何在 C# 中模拟鼠标按钮按下并按住