转:用Winform实现屏幕小键盘
今天需要用winform实现小键盘,因为车载电脑没有键盘,所以自己就做一个. 这里参考了这两篇文章,并小记一下.
http://www.cnblogs.com/killmyday/archive/2009/09/11/1564673.html
http://www.pin5i.com/showtopic-27071.html
非常感谢以上两位,这里作下整理.
首先引用一段话:
屏幕小键盘的实现方式很简单,无非就是在窗体上加上几个按钮,然后在鼠标的点击事件里使用SendKeys.Send函数将按钮代表的字符输入到当前激活的窗口里面。
因此如何保证小键盘窗口永远不会获取鼠标焦点,是实现屏幕小键盘的关键。一般的窗口如果有鼠标在它上面操作的话,那么这个窗口默认就处于激活(Activated)状态,所有的键盘鼠标输入都是被操作系统重定向到桌面上激活(Activated)状态的窗体上。这样就会产生类似下面描述的矛盾:
1. 打开一个Windows程序,比如说notepad.exe。
2. 启动屏幕小键盘程序keyboard.exe。
3. 在keyboard.exe上面点击按钮,这时keyboard.exe处于激活状态—因为它获取到了鼠标焦点。
4. SendKeys.Send函数没有办法把对应的字符输入到notepad.exe里面,因为notepad.exe不能获取鼠标焦点—它不是桌面上处于激活状态的窗口。
为了解决上面的矛盾,Win32 API里面,CreateWindowEx的第一个参数dwExStyle如果设置为WS_EX_NOACTIVATE,那么创建的窗口则不会被操作系统设置为激活状态。因此如果我们能够在创建keyboard.exe的时候,通知Winform函数库将其创建成一个WS_EX_NOACTIVATE就可以了,这就是为什么Winform函数库里面有一个Form.CreateParams这个属性,在从Form类继承下来的窗体中重载这个属性,就可以在Winform创建窗口之前,修改创建参数了。
下面是keyboard.exe小键盘窗口的源代码, 当然在创建这个窗口的时候,最好将窗口的Topmost属性设置为true。
代码第一部分:
但是发现这个时候并不能用,我们需要的是像输入法那种没有焦点的窗体.
这个时候点击button1焦点又回到了新的窗体上.
(后来将Form1的FormBorderStyle设置为 System.Windows.Forms.FormBorderStyle.FixedToolWindow后证实了这一点。焦点的确移到Form1 上)
后来想想,在启动Form1后,强制将焦点切回来后能不能好一点呢,于是,降打开窗体的代码改为.
Form1.Show()
this.Activate()
焦点回来了,当作为第二个页面打开的时候,第一个页面还是保留有焦点,但是当打开第二个页面,再点一次,焦点还是被当前窗体获取到了.
所以需要继续.将当前窗体获取焦点事件取消掉.
添加了一段修改Form的WndProc代码,拦截WM_MOUSEACTIVATE消息,改为MA_NOACTIVATE
完整代码如下:
{
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= (int)0x08000000L;
return cp;
}
}
public Form2()
{
InitializeComponent();
}
// 屏幕小键盘上的一个按钮“A”
private void button1_Click(object sender, EventArgs e)
{
SendKeys.Send("A");
}
}
但是发现这个时候并不能用,我们需要的是像输入法那种没有焦点的窗体.
这个时候点击button1焦点又回到了新的窗体上.
(后来将Form1的FormBorderStyle设置为 System.Windows.Forms.FormBorderStyle.FixedToolWindow后证实了这一点。焦点的确移到Form1 上)
后来想想,在启动Form1后,强制将焦点切回来后能不能好一点呢,于是,降打开窗体的代码改为.
Form1.Show()
this.Activate()
焦点回来了,当作为第二个页面打开的时候,第一个页面还是保留有焦点,但是当打开第二个页面,再点一次,焦点还是被当前窗体获取到了.
所以需要继续.将当前窗体获取焦点事件取消掉.
添加了一段修改Form的WndProc代码,拦截WM_MOUSEACTIVATE消息,改为MA_NOACTIVATE
完整代码如下:
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
//download by http://www.codefans.net
namespace TouchKey
{
public partial class Form1 : Form
{
private const int WS_EX_NOACTIVATE = 0x08000000;
private const int WM_MOUSEACTIVATE = 0x0021;
private const int MA_NOACTIVATE = 0x0003;
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= WS_EX_NOACTIVATE;
return cp;
}
}
protected override void WndProc(ref Message m)
{
//If we're being activated because the mouse clicked on us...
if (m.Msg == WM_MOUSEACTIVATE)
{
//Then refuse to be activated, but allow the click event to pass through (don't use MA_NOACTIVATEEAT)
m.Result = (IntPtr)MA_NOACTIVATE;
}
else
{
base.WndProc(ref m);
}
}
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
lbl_0.Click += new EventHandler(lbl_Click);
lbl_1.Click += new EventHandler(lbl_Click);
lbl_2.Click += new EventHandler(lbl_Click);
lbl_3.Click += new EventHandler(lbl_Click);
lbl_4.Click += new EventHandler(lbl_Click);
lbl_5.Click += new EventHandler(lbl_Click);
lbl_6.Click += new EventHandler(lbl_Click);
lbl_7.Click += new EventHandler(lbl_Click);
lbl_8.Click += new EventHandler(lbl_Click);
lbl_9.Click += new EventHandler(lbl_Click);
lbl_Q.Click += new EventHandler(lbl_Click);
lbl_W.Click += new EventHandler(lbl_Click);
lbl_R.Click += new EventHandler(lbl_Click);
lbl_E.Click += new EventHandler(lbl_Click);
lbl_T.Click += new EventHandler(lbl_Click);
lbl_Y.Click += new EventHandler(lbl_Click);
lbl_U.Click += new EventHandler(lbl_Click);
lbl_I.Click += new EventHandler(lbl_Click);
lbl_O.Click += new EventHandler(lbl_Click);
lbl_P.Click += new EventHandler(lbl_Click);
lbl_A.Click += new EventHandler(lbl_Click);
lbl_S.Click += new EventHandler(lbl_Click);
lbl_D.Click += new EventHandler(lbl_Click);
lbl_F.Click += new EventHandler(lbl_Click);
lbl_G.Click += new EventHandler(lbl_Click);
lbl_H.Click += new EventHandler(lbl_Click);
lbl_J.Click += new EventHandler(lbl_Click);
lbl_K.Click += new EventHandler(lbl_Click);
lbl_L.Click += new EventHandler(lbl_Click);
lbl_Z.Click += new EventHandler(lbl_Click);
lbl_X.Click += new EventHandler(lbl_Click);
lbl_C.Click += new EventHandler(lbl_Click);
lbl_V.Click += new EventHandler(lbl_Click);
lbl_B.Click += new EventHandler(lbl_Click);
lbl_N.Click += new EventHandler(lbl_Click);
lbl_M.Click += new EventHandler(lbl_Click);
lbl_BACKSPACE.Click +=new EventHandler(lbl_Click);
}
void lbl_Click(object sender, EventArgs e)
{
Label l = (Label)sender;
string strkey = l.Name.Substring(4);
if (label9.Text == "大写")
{
strkey = strkey.ToUpper();
}
else
{
strkey = strkey.ToLower();
}
SendKeys.Send("{" + strkey + "}");
}
private void label1_Click(object sender, EventArgs e)
{
Close();
}
private void label9_Click(object sender, EventArgs e)
{
if (label9.Text =="大写")
{
label9.Text = "小写";
}
else
{
label9.Text = "大写";
}
}
}
}
调用代码如下:
{
Form1 f = new Form1();
tbcontent.Focus();
f.Show();
this.Activate();
}
再做了若干测试,发现上面的代码效果,如果要成功,还必不可少的是Form上没有能接受焦点的控件(Button,TextBox等),而且还不能有标题栏。解决的办法,就是去掉Form的标题栏,不使用能接受焦点的控件(或者是改写控件的WndProc过程,拦截接受焦点的消息,使之不能接受焦点)。虽然Form不能接受焦点,但是经过测试,控件还是能接受其他的事件(例如:Click,DoubleClick,MouseHover,MouseLeave 等事件),合理运用的话,还是能产生不错的效果。
概括一下就是 去掉标题栏 this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.TopMost = true;
感谢上述两位的奉献.提供源码下载:http://files.cnblogs.com/cyrix/TouchKey.rar
转载于:https://www.cnblogs.com/starxp/articles/1888050.html
转:用Winform实现屏幕小键盘相关推荐
- winform 自适应屏幕分辨率具体操作和注意事项
第一步:先借助一个类文件 AutoSizeFormClass.cs class AutoSizeFormClass { public struct controlRect { public int L ...
- iwork11旗舰版 linux,苹果 iWork 11 套件来了,Pages/Numbers/Keynote iOS/macOS 版大升级
IT之家3月24日消息 苹果今天专为 iOS 和 macOS 设备设计的 iWork 应用套件更新到了版本 11,引入了许多新功能和调整,以改善其功能. IT之家获悉,在 iOS 系统上,Pages. ...
- Windows Mobile 5.0 认知篇
(本文只作为本人学习用途) 1.什么是微软Windows Mobile 5.0? 最新的Windows Mobile 5.0不叫Windows Mobile 5.0 2005,而是Windows Mo ...
- UR机器人PolyScope使用入门教程
PolyScope 是一个图形用户界面 (GUI),可用于操作机器人手臂和控制箱,执行机器人程序,以 及轻松创建新程序.使用 PolyScope 之前,必须先安装机器人手臂和控制箱,将控制箱接通电源. ...
- 计算机房英语单词,计算机与网络英语词汇(O1)
News 计算机与网络英语词汇(O1) Source: 2008-07-14 我要投稿 论坛 Favorite OA, office automation 办公室自动化 object 物件 obj ...
- web服务器读取客户端设备信息,人机界面与组态.ppt
人机界面与组态.ppt 工业控制人机界面和组态软件 工业自动化生产的监视和控制 第一章 绪论 什么是工业控制人机界面通过计算机和设备的接口,实现对设备工作状态的观察和操作控制. 组态软件的概念在计算机 ...
- Windows Mobile 5.0 的探讨
1.什么是微软Windows Mobile 5.0? 最新的Windows Mobile 5.0不叫Windows Mobile 5.0 2005,而是Windows Mobile 5.0.此次微软推 ...
- ubuntu16.04+xfce4截图、终端调出、锁屏的快捷键设置、去掉Alt+鼠标移动屏幕的功能、安装thunar、小键盘问题、设置终端背景
首先 apt-get install xfce4-screenshooter 然后 Applications=>Settings=>Keyboard=>Application Sho ...
- 使用C# winform 制作一个按钮可自适应屏幕大小的 简易加减乘除计算器
一:成果物 不多展示,,,我们开始吧.. 二: 窗体包含内容 2.1 显示屏部分组成 显示屏部分由两个组件组成,一个是方便操作的panel控件位于顶部,且为了使其显示屏在改变窗体大小时一直位于 ...
- C# WinForm如何截取屏幕并保存图片到本地
C# WinForm如何截取屏幕并保存图片到本地 static void toScreen()//截屏并存储到D盘Screen文件夹中 {//设置显示屏幕为主屏(windows主屏)Screen sc ...
最新文章
- 震精!Spring Boot内存泄露,排查竟这么难!
- 推荐10个毕业3年,月入5万技术大神的公众号!
- CSS3 flexbox 布局 ---- flex项目属性介绍
- Linux socket 网络编程常用函数总结
- NYOJ 330 一个简单的数学题
- Apollo创建项目
- 收集bug开源框架_划重点 | 小程序框架全面测评
- linux php pdo server,linux服务器用PHP的PDO链接myql方法(php pdo)
- 翻译自 RedHat 文章:What is middleware? (什么是中间件?)
- 个人支付源码_[5G时代投资风口源码修复版] 投资区块链+订制UI完美版+对接免签支付+自带发圈推广任务奖励+视频教程...
- 使用PO+跨平台改造Macaca示例(APP端)
- Awake OnEnable Start Update LateUpdate FixedUpdate
- 基于.NET Compact Framework的应用程序和库汇总
- 亚马逊测评自养号IP重要性
- java基于ssm的高速公路收费管理系统
- Oracle 官网登录账户 下载资源
- Ubuntu 16.10 解决 DNS 解析失败
- BeanUtils的populate方法之日期处理
- NGFW防火墙的ASPF实现原理
- 高斯公式(三重积分和第二类曲面积分互相转换)