微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

发送键盘到应用程序在c#sendkeys,postmessage,sendmessage都不工作

我正在尝试执行以下操作之一1.打开所需的程序并以编程方式按下一个键2.find打开的程序窗口并以编程方式按下一个键(或者很好)

我尝试了SendKeys.SendWait(),PostMessage()和SendMessage()的许多实现失败。 以下是我的代码片段

//included all these for attempts [DllImport("User32.dll")] static extern IntPtr FindWindow(string lpClassName,string lpWindowName); [DllImport("User32.dll")] static extern int SetForegroundWindow(IntPtr hWnd); [DllImport("User32.Dll",EntryPoint = "PostMessageA")] static extern bool PostMessage(IntPtr hWnd,uint msg,int wParam,int lParam); [DllImport("user32.dll")] static extern byte VkKeyScan(char ch); [DllImport("user32.dll",CharSet = CharSet.Auto)] static extern IntPtr SendMessage(IntPtr hWnd,UInt32 Msg,IntPtr wParam,IntPtr lParam);

获取窗口句柄,sendmessage / postmessage / sendkeys使用的variables

IntPtr ptrOBS = proc.Handle;//this works properly,proc is instantiated properly //IntPtr ptrOBS = FindWindow(null,"Open broadcaster Software v0.472b"); SetForegroundWindow(ptrOBS); const UInt32 WM_CHAR = 0x0102; const uint WM_KEYDOWN = 0x100; const int VK_R = 0x52; // taken from http://msdn.microsoft.com/en-us/library/dd375731(v=vs.85).aspx const int VK_S = 0x53;

SendMessage尝试:

如何使我的应用程序被视为Windows中的通信程序

从windows服务中杀死一个进程

哪个.NET框架版本将被包含在Windows 7中?

如何阅读设备和驱动程序版本

sql Server Compact Edition数据库部署策略

SendMessage(ptrOBS,WM_KEYDOWN,(IntPtr)VK_R,(IntPtr)1);//tried both WM_CHAR and WM_KEYDOWN

PostMessage尝试:

string message = "rs"; bool sent = PostMessage(ptrOBS,VkKeyScan(message[0]),0);

SendKeys尝试:

SendKeys.SendWait("{r}");

在父窗口(应用程序)和子窗口(通过按键im试图发送触发的button)尝试SetFocus:

static void SetFocus(IntPtr hwndTarget,string childClassName) { // hwndTarget is the other app's main window // ... IntPtr targetThreadID = GetwindowThreadProcessId(hwndTarget,IntPtr.Zero); //target thread id IntPtr myThreadID = GetCurrentThread(); // calling thread id,our thread id try { bool lRet = AttachThreadInput(myThreadID,targetThreadID,-1); // attach current thread id to target window // if it's not already in the foreground... lRet = BringWindowToTop(hwndTarget); SetForegroundWindow(hwndTarget); // if you kNow the child win class name do something like this (enumerate windows using Win API again)... IntPtr hwndChild = (IntPtr)1183492;//(IntPtr)EnumAllWindows(hwndTarget,childClassName).FirstOrDefault(); if (hwndChild == IntPtr.Zero) { // or use keyboard etc. to focus,ie send keys/input... // sendinput (...); return; } // you can use also the edit control's hwnd or some child window (of target) here SetFocus(hwndChild); // hwndTarget); SendKeys.SendWait("{r}"); } finally { SendKeys.SendWait("{r}"); bool lRet = AttachThreadInput(myThreadID,0); //detach from foreground window SendKeys.SendWait("{r}"); } }

对于NSGaga:

string windowName = "Open broadcaster Software v0.472b"; IntPtr outerPtr = FindWindow(null,windowName); IntPtr ptrOBS = (IntPtr)527814;//button that im trying to trigger keypress on SetForegroundWindow(outerPtr); SetForegroundWindow(ptrOBS); SetFocus(outerPtr,"OBSWindowClass");//SetFocus(ptrOBS,"Button"); const UInt32 WM_CHAR = 0x0102; const int VK_R = 0x52; // taken from http://msdn.microsoft.com/en-us/library/dd375731(v=vs.85).aspx const int VK_S = 0x53; //SetForegroundWindow(ptrOBS); System.Threading.Thread.Sleep(3000); SendKeys.SendWait("{r}"); SendMessage(outerPtr,(IntPtr)1); PostMessage(outerPtr,VkKeyScan('r'),0);

Windows如何区分常规EXE和.NET EXE?

发布版本包含额外的文件,我需要这些?

.NET位图类无法打开LinkedIn的个人资料图像 – 关于如何打开任何build议?

我如何以编程方式find我的MEGAsync文件夹?

从Windows服务获取用户根目录

有很多的试验和错误,以得到它的工作

这里是我之前发布的一些代码,你可能想尝试一下(还有一些更多的信息)。

Pinvoke SetFocus到一个特定的控制

先尝试设置焦点(使用提到的机制) – 然后使用SendKeys或sendinput

这里是一些sendinput详细代码

如何将字符串发送到包括Microsoft Word在内的其他应用程序

您无法可靠地使用SendMessage和PostMessage来合成键盘输入 。 他们不是为此而设计的。 这些消息( WM_CHAR , WM_KEYDOWN等)是当键盘输入已被接收,处理并转发给适当的接收者时由较低级子系统引发的通知 。 自己发送或发布这些消息就像恶作剧 – 呼唤某人。

SendKeys (像所有其他输入合成器方法包括显式设计用于合成键盘输入的sendinput函数,以及至少在一些实现中SendKeys实际使用的内容)仅在希望接收键盘输入的窗口具有焦点。 在Windows中,只有聚焦(活动)窗口才能接收输入事件。

所以SendKeys可能是如果你打算让这个工作(或者P /调用sendinput及其所有关联的结构)的方式,但是你需要尊重接收者窗口必须具有的警告焦点。 否则,它不会得到任何东西。

它看起来像你的示例代码,你正在尝试使用SetForegroundWindow函数来满足这个先决条件。 不幸的是,你传递一个无效的值,而不是做任何错误检查,可能会提醒你这个错误。 具体来说,这个代码错误的:

IntPtr ptrOBS = proc.Handle;//this works properly,proc is instantiated properly SetForegroundWindow(ptrOBS); // WRONG,ptrOBS is not a window handle

即使我相信你正确地初始化了ptrOBS ,这也使得它成为一个有效的进程句柄,这与一个有效的窗口句柄是非常不同的。 除了显而易见的名义差异,进程可以有多个窗口,只有一个窗口可以有焦点(即“在前台”)。

调用SetForegroundWindow之前,您需要获取特定窗口的句柄,并且我们知道一个进程可以有多个窗口,这可能会非常棘手。 你需要一些可靠的方法来确定你想要的窗口。 许多人通过将窗口的名字硬编码为一个字符串来实现这一点,这很好的工作,直到目标应用程序被重新编译并且这个实现细节改变。 我能想到的唯一的防弹方法是让用户单击目标窗口和代码来检索当前在鼠标指针下的窗口的句柄。

当然,所有这一切都假定您已经观察到使用SetForegroundWindow的限制,在链接的SDK文档的“备注”部分中枚举。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐