今天需要用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

完整代码如下:

public partial class Form2 : Form

{

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;
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 = "大写";
}
}
}
}

调用代码如下:

private void btnKeybord_Click(object sender, EventArgs e)
{
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实现屏幕小键盘相关推荐

  1. winform 自适应屏幕分辨率具体操作和注意事项

    第一步:先借助一个类文件 AutoSizeFormClass.cs class AutoSizeFormClass { public struct controlRect { public int L ...

  2. iwork11旗舰版 linux,苹果 iWork 11 套件来了,Pages/Numbers/Keynote iOS/macOS 版大升级

    IT之家3月24日消息 苹果今天专为 iOS 和 macOS 设备设计的 iWork 应用套件更新到了版本 11,引入了许多新功能和调整,以改善其功能. IT之家获悉,在 iOS 系统上,Pages. ...

  3. Windows Mobile 5.0 认知篇

    (本文只作为本人学习用途) 1.什么是微软Windows Mobile 5.0? 最新的Windows Mobile 5.0不叫Windows Mobile 5.0 2005,而是Windows Mo ...

  4. UR机器人PolyScope使用入门教程

    PolyScope 是一个图形用户界面 (GUI),可用于操作机器人手臂和控制箱,执行机器人程序,以 及轻松创建新程序.使用 PolyScope 之前,必须先安装机器人手臂和控制箱,将控制箱接通电源. ...

  5. 计算机房英语单词,计算机与网络英语词汇(O1)

    News 计算机与网络英语词汇(O1) Source: 2008-07-14 我要投稿 论坛   Favorite OA, office automation 办公室自动化 object 物件 obj ...

  6. web服务器读取客户端设备信息,人机界面与组态.ppt

    人机界面与组态.ppt 工业控制人机界面和组态软件 工业自动化生产的监视和控制 第一章 绪论 什么是工业控制人机界面通过计算机和设备的接口,实现对设备工作状态的观察和操作控制. 组态软件的概念在计算机 ...

  7. Windows Mobile 5.0 的探讨

    1.什么是微软Windows Mobile 5.0? 最新的Windows Mobile 5.0不叫Windows Mobile 5.0 2005,而是Windows Mobile 5.0.此次微软推 ...

  8. ubuntu16.04+xfce4截图、终端调出、锁屏的快捷键设置、去掉Alt+鼠标移动屏幕的功能、安装thunar、小键盘问题、设置终端背景

    首先 apt-get install xfce4-screenshooter 然后 Applications=>Settings=>Keyboard=>Application Sho ...

  9. 使用C# winform 制作一个按钮可自适应屏幕大小的 简易加减乘除计算器

    一:成果物     不多展示,,,我们开始吧.. 二: 窗体包含内容 2.1 显示屏部分组成 显示屏部分由两个组件组成,一个是方便操作的panel控件位于顶部,且为了使其显示屏在改变窗体大小时一直位于 ...

  10. C# WinForm如何截取屏幕并保存图片到本地

    C# WinForm如何截取屏幕并保存图片到本地 static void toScreen()//截屏并存储到D盘Screen文件夹中 {//设置显示屏幕为主屏(windows主屏)Screen sc ...

最新文章

  1. 震精!Spring Boot内存泄露,排查竟这么难!
  2. 推荐10个毕业3年,月入5万技术大神的公众号!
  3. CSS3 flexbox 布局 ---- flex项目属性介绍
  4. Linux socket 网络编程常用函数总结
  5. NYOJ 330 一个简单的数学题
  6. Apollo创建项目
  7. 收集bug开源框架_划重点 | 小程序框架全面测评
  8. linux php pdo server,linux服务器用PHP的PDO链接myql方法(php pdo)
  9. 翻译自 RedHat 文章:What is middleware? (什么是中间件?)
  10. 个人支付源码_[5G时代投资风口源码修复版] 投资区块链+订制UI完美版+对接免签支付+自带发圈推广任务奖励+视频教程...
  11. 使用PO+跨平台改造Macaca示例(APP端)
  12. Awake OnEnable Start Update LateUpdate FixedUpdate
  13. 基于.NET Compact Framework的应用程序和库汇总
  14. 亚马逊测评自养号IP重要性
  15. java基于ssm的高速公路收费管理系统
  16. Oracle 官网登录账户 下载资源
  17. Ubuntu 16.10 解决 DNS 解析失败
  18. BeanUtils的populate方法之日期处理
  19. NGFW防火墙的ASPF实现原理
  20. 高斯公式(三重积分和第二类曲面积分互相转换)

热门文章

  1. Java基础Lambda表达式【四】
  2. ASP.NET中Dictionary的基本用法
  3. element做树形下拉_Element input树型下拉框的实现代码
  4. #笔记2021-08
  5. 数据结构——>线索化二叉树
  6. c语言自动化课题设计,自动化专业C语言程序设计课堂教学方案设计和实践.doc
  7. python房价预测_Python实战:使用线性回归预测房价
  8. 《计算机操作系统》练习题
  9. java 任务栏程序_如何为Java Swing程序动态启用或禁用任务栏图标
  10. TypeScript:函数进阶