简体   繁体   English

C# - 将键盘事件发送到(最后)所选窗口

[英]C# - Sending keyboard events to (last) selected window

I want to use virtual keyboard assembly found here http://www.codeproject.com/KB/miscctrl/touchscreenkeyboard.aspx like on screen keyboard (OSK.exe) in Windows. 我想在Windows中使用虚拟键盘组件http://www.codeproject.com/KB/miscctrl/touchscreenkeyboard.aspx,就像在Windows上的屏幕键盘(OSK.exe)。 Can someone please tell me how can I use it so that it always stays on top and yet for user to be able to select other windows on dekstop for keyboard input, just like "on screen keyboard" in Windows, specifically I don't know how to select last selected window (can't use GetForegroundWindow or GetFocus only, because when user clicks on virtual keyboard it gets focused and I get handle of keyboard window itself)? 有人可以告诉我如何使用它,以便它始终保持在顶部,但用户可以在dekstop上选择其他窗口进行键盘输入,就像Windows中的“屏幕键盘”,具体我不知道如何选择最后选择的窗口(不能只使用GetForegroundWindow或GetFocus,因为当用户点击虚拟键盘时它会聚焦并且我自己处理键盘窗口)? This is very urgent to me so any advice would be greatly appreciated. 这对我来说非常紧迫,所以任何建议都会受到高度赞赏。

Thanks in advance. 提前致谢。

What you need to do is make your window that it cannot be activated. 你需要做的是让你的窗口无法激活。 This is quite easily done by overriding CreataParams . 通过重写CreataParams可以轻松完成此操作。 Then you can use SendKey.Send to send key presses to the currently active window, your window will never become active. 然后,您可以使用SendKey.Send将按键发送到当前活动的窗口,您的窗口将永远不会变为活动状态。

Here is a simple example 这是一个简单的例子

  public partial class Form1 : Form
  {
    const int WS_EX_NOACTIVATE = 0x08000000;

    public Form1()
    {      
      InitializeComponent();      
    }

    protected override CreateParams CreateParams
    {
      get
      {
        CreateParams param = base.CreateParams;
        param.ExStyle |= WS_EX_NOACTIVATE;
        return param;
      }
    }

    private void button1_Click(object sender, EventArgs e)
    {
      SendKeys.Send("A");
    }
  }

One strange thing you will notice is that since your window never becomes active it does react rather strang when you drag the window. 您会注意到一个奇怪的事情是,由于您的窗口永远不会变为活动状态,因此当您拖动窗口时它会做出相反的反应。 Basically the dragging works, it just does not give the visual feedback during the drag. 基本上拖动工作,它只是在拖动过程中不提供视觉反馈。 You can address this by overriding WndProc and handling the WM_NCLBUTTONDOWN and WM_MOUSEMOVE messages. 您可以通过覆盖WndProc并处理WM_NCLBUTTONDOWN和WM_MOUSEMOVE消息来解决此问题。

When you get the input focus, the windows message WM_SETFOCUS is sent to your window, and .net converts this into the Forms events that you receive. 当您获得输入焦点时,Windows消息WM_SETFOCUS将发送到您的窗口,.net将其转换为您收到的Forms事件。 The windows message contains the handle of the previous input-focus window. Windows消息包含上一个输入焦点窗口的句柄。

If this information isn't available in your C# Form.Activated or Control.Enter/Control.GotFocus event, then you may need to override Form.WndProc to catch the raw windows message and retrieve the handle - which you can then use to activate or send WM_KEYDOWN messages to the previous input-focus window. 如果您的C#Form.Activated或Control.Enter / Control.GotFocus事件中没有此信息,则您可能需要覆盖Form.WndProc以捕获原始Windows消息并检索句柄 - 然后您可以使用该句柄激活或将WM_KEYDOWN消息发送到上一个输入焦点窗口。

Sending Keystrokes to another Application in C# 在C#中向另一个应用程序发送击键
http://www.codeproject.com/KB/cs/SendKeys.aspx http://www.codeproject.com/KB/cs/SendKeys.aspx

Then, all you would need is a way to select another window from the virtual keyboard. 然后,您只需要从虚拟键盘中选择另一个窗口。 To do that, you just need the target window's title. 要做到这一点,你只需要目标窗口的标题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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