C# 里的sendkeys.send的实现原理

yjcpu 2009-04-12 10:34:31
C# 里的sendkeys.send是如何实现的,我试过postmessage,用过 wm_keydown,wm_char都达不到同样的效果。
而且这个sendkeys只能发送到当前窗口中,所以我试图作一个可以向任何一般窗口发送key的过程时遇到上述问题。
...全文
1697 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
huwei001982 2009-04-13
  • 打赏
  • 举报
回复
SendKeys 类使用两种机制来发送按键

一种是使用API SendInput

一种是使用JournalHook
yjcpu 2009-04-13
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 wartim 的回复:]
网上一段话
注意
SendKeys 类已针对 .NET Framework 3.0 进行了更新,能够用于在 Windows Vista 上运行的应用程序中。Windows Vista 增强的安全性(称为用户账户控件或 UAC)使以前的实现无法按预期方式工作。

SendKeys 类容易出现计时问题,有些开发人员必须解决这个问题。更新的实现仍然容易发生计时问题,但速度略有提高,并且可能要求更改解决方法。SendKeys 类首先会尝试使用以前的实现,失败后再使用新的实现。因此…
[/Quote]

谢谢指教

SendInput 一样是全局的
wartim 2009-04-13
  • 打赏
  • 举报
回复
网上一段话
注意
SendKeys 类已针对 .NET Framework 3.0 进行了更新,能够用于在 Windows Vista 上运行的应用程序中。Windows Vista 增强的安全性(称为用户账户控件或 UAC)使以前的实现无法按预期方式工作。

SendKeys 类容易出现计时问题,有些开发人员必须解决这个问题。更新的实现仍然容易发生计时问题,但速度略有提高,并且可能要求更改解决方法。SendKeys 类首先会尝试使用以前的实现,失败后再使用新的实现。因此,SendKeys 类的行为可能因操作系统的不同而有所差异。此外,当 SendKeys 类使用新的实现时,SendWait 方法在消息被发送到另一进程时不会等待消息的处理。

如果您的应用程序依赖于不受操作系统影响的一致性行为,则可通过向 app.config 文件添加以下应用程序设置,强制 SendKeys 类使用新的实现。

<appSettings>

<add key="SendKeys" value="SendInput"/>

</appSettings>

要强制 SendKeys 类使用以前的实现,请改用值 "JournalHook"。

http://blog.csdn.net/menglingjun/archive/2007/09/18/1789788.aspx
十八道胡同 2009-04-13
  • 打赏
  • 举报
回复
不懂,帮顶
yjcpu 2009-04-13
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 wartim 的回复:]
它实现原理嘛最终肯定也是消息机制咯
利用IMessageFilter接口可以监视应用程序的一切消息

C# code
namespace WindowsApplication20
{
public partial class Form1 : Form, IMessageFilter
{
public Form1()
{
InitializeComponent();

Application.AddMessageFilter(this);
}

public bool PreFilterMessage(ref Message m)

[/Quote]

很可恶的一点是:它还就是不用消息
yjcpu 2009-04-13
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 zgke 的回复:]
使用API

SendMessage
[/Quote]

试过,不行,我是向窗体内的一个有flash控件的窗体发送的消息,然后处理了窗体的wm_keydown,和keypress消息
给你看下结果:
1)使用sendkeys.send(先将窗体置前) 结果:flash控件-反应正常 消息拦截-没有反应
2)使用sendmessage,postmessage 结果:flash控件-没反应 消息拦截-反应正常
这个样子很让人不解
wartim 2009-04-13
  • 打赏
  • 举报
回复
它实现原理嘛最终肯定也是消息机制咯
利用IMessageFilter接口可以监视应用程序的一切消息

namespace WindowsApplication20
{
public partial class Form1 : Form, IMessageFilter
{
public Form1()
{
InitializeComponent();

Application.AddMessageFilter(this);
}

public bool PreFilterMessage(ref Message m)
{
if (m.Msg == 0x201) // 左键
return true; // 过滤掉所有左键信息
return false;
}
}
}
zgke 2009-04-13
  • 打赏
  • 举报
回复
使用API

SendMessage
yjcpu 2009-04-13
  • 打赏
  • 举报
回复
我找到了个DELPHI版的sendkeys源码,原来如此,很无语啊:
Procedure SendKeyDown(VKey: Byte; NumTimes : Word; GenUpMsg : Boolean);
var
Cnt : Word;
ScanCode : Byte;
NumState : Boolean;
KeyBoardState : TKeyboardState;
begin
If (VKey=VK_NUMLOCK) then begin
NumState:=ByteBool(GetKeyState(VK_NUMLOCK) and 1);
GetKeyBoardState(KeyBoardState);
If NumState then KeyBoardState[VK_NUMLOCK]:=(KeyBoardState[VK_NUMLOCK] and not 1)
else KeyBoardState[VK_NUMLOCK]:=(KeyBoardState[VK_NUMLOCK] or 1);
SetKeyBoardState(KeyBoardState);
exit;
end;

ScanCode:=Lo(MapVirtualKey(VKey,0));
For Cnt:=1 to NumTimes do
If (VKey in ExtendedVKeys)then begin
KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY);
If (GenUpMsg) then
KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP)
end else begin
KeyboardEvent(VKey, ScanCode, 0);
If (GenUpMsg) then KeyboardEvent(VKey, ScanCode, KEYEVENTF_KEYUP);
end;
end;

怪不得只能发到活动窗口。。。只接发键盘消息,很暴力的样子
对于有些com控件,比如flash控件,是接收不到windows sendmessage消息的?还是根本就不理会,直接底层处理键盘的哦?
yjcpu 2009-04-13
  • 打赏
  • 举报
回复
那个不灵活,不喜欢用啊,有没有可以指定窗体的例程?
kkun_3yue3 2009-04-13
  • 打赏
  • 举报
回复
你想办法使接收按键信息的窗口成为当前活动窗口,此时你的程序再发送按键信息,那就相当于发到活动窗口上去了
kkun_3yue3 2009-04-13
  • 打赏
  • 举报
回复
Process.Start("打开你要发送按键信息的程序");
SendKeys.Send("发送你的按键信息,注意要等待接收程序的窗口打开后,自然会成为ActiveForm");

110,565

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧