问题描述
我想编写一个虚拟键盘,例如用于触摸屏电脑的 Windows 屏幕键盘.但是我的虚拟键盘从正在使用的应用程序中窃取焦点时遇到问题.即使用户单击它,Windows 屏幕键盘也会将焦点保持在当前应用程序上.有没有办法在 C# 中对 windows 窗体做同样的事情?
I'm wanting to write a virtual keyboard, like windows onscreen keyboard for touchscreen pcs. But I'm having problem with my virtual keyboard stealing the focus from the application being used. The windows onscreen keyboard mantains the focus on the current application even when the user clicks on it. Is there a way to do the same with windows forms in C#?
我现在唯一能做的就是将键盘事件发送到特定的应用程序,例如以下代码中的记事本.如果我可以使表单不可聚焦,我可以使用 GetForegroundWindow 获得当前聚焦的窗口.
The only thing I can do for now is to send a keyboard event to an especific application, like notepad in the following code. If I could make the form not focusable, I could get the current focused window with GetForegroundWindow.
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName,string lpWindowName);
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
private void button1_Click(object sender, EventArgs e)
{
IntPtr calculatorHandle = FindWindow("notepad", null);
SetForegroundWindow(calculatorHandle);
SendKeys.SendWait("111");
}
有没有办法做到这一点?有什么更好的方式让表单向正在使用的应用程序发送键盘事件的建议吗?
Is there a way this can be done? Any suggestions of a better way to have the form sending keyboard events to the application being used?
谢谢!!
推荐答案
与其在你的窗口被点击后尝试重置活动窗口,我宁愿尝试阻止你的窗口接收焦点/被激活.
Instead of trying to reset the active window after your one has been clicked, I would rather try to prevent your window from receiving focus/being activated.
查看这篇文章.最后,作者简要说明了如何做到这一点:
Have a look at this article. At the end, the author briefly explains how this can be done:
如何防止我的窗口在显示时获得激活和焦点?
在 Windows Forms 2.0 中,有一个名为的新属性ShowWithoutActivation - 您需要在表单上覆盖它.在本机应用程序中,您可以将 SetWindowPos 与SWP_NOACTIVATE 标志或带有 SW_SHOWNA 标志的 ShowWindow.
In Windows Forms 2.0 there is a new property called ShowWithoutActivation – which you would need to override on the Form. In native applications you can use SetWindowPos with the SWP_NOACTIVATE flag or the ShowWindow with the SW_SHOWNA flag.
此外,在这篇文章中,他提供Windows 窗体的代码示例:
Furthermore, in this article he provides a code example for Windows Forms:
如果您想要一个完整的表单,您现在可以覆盖一个名为ShowWithoutActivation
:
If you want a full-on form, you can now override a property called
ShowWithoutActivation
:
public class NoActivateForm : Form
{
protected override bool ShowWithoutActivation => true;
}
请记住,这不会一直阻止"激活 - 您可以仍然通过调用Activate()
、Focus()
…等方法激活.如果您想防止点击客户区激活窗口,您可以处理 WM_MOUSEACTIVATE
消息.
Keep in mind this does not "prevent" activation all the time – you can
still activate by calling the Activate()
, Focus()
… etc methods. If
you want to prevent clicks on the client area from activating the
window, you can handle the WM_MOUSEACTIVATE
message.
private const int WM_MOUSEACTIVATE = 0x0021, MA_NOACTIVATE = 0x0003;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_MOUSEACTIVATE)
{
m.Result = (IntPtr)MA_NOACTIVATE;
return;
}
base.WndProc(ref m);
}
这篇关于在 C# 中使表单不可聚焦的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!