`
ljl_xyf
  • 浏览: 634583 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

自己制作软键盘的几个关键技术解析

    博客分类:
  • c#
阅读更多

在嵌入式应用和一些安全软件中经常需要不通过物理键盘输入,虽然微软提供了也一个软键盘,但这个软件盘不能定制界面不能自动感应当前光标是否处于输入状态,所以有时候我们还是需要自己来实现这个软键盘。本文将讲解自己实现软键盘时涉及到的几个关键技术。

一、浮动窗体的实现

软键盘的窗体和普通窗体不一样,这个窗体在成为当前窗体时,不会影响其它进程的窗体的光标焦点。也就是说虽然这个窗体现在为当前激活的前台窗体,但光标仍然停在其他进程的窗体上。


如上图所示,虽然软键盘在记事本的前面,但光标仍然在记事本上。

要实现这个技术,我们必须要把当前窗体设置为浮动工具条才行。这里我给出 C# Winform 的实现方法:

        private
 const
 int
 WS_EX_TOOLWINDOW = 0x00000080;
        private
 const
 int
 WS_EX_NOACTIVATE = 0x08000000;

        protected
 override
 CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base
.CreateParams;
                cp.ExStyle |= (WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW);
                cp.Parent = IntPtr.Zero; // Keep this line only if you used UserControl

                return
 cp;

                //return base.CreateParams;

            }
        } 

.csharpcode pre { margin: 0em; }.csharpcode .rem { color: rgb(0, 128, 0); }.csharpcode .kwrd { color: rgb(0, 0, 255); }.csharpcode .str { color: rgb(0, 96, 128); }.csharpcode .op { color: rgb(0, 0, 192); }.csharpcode .preproc { color: rgb(204, 102, 51); }.csharpcode .asp { background-color: rgb(255, 255, 0); }.csharpcode .html { color: rgb(128, 0, 0); }.csharpcode .attr { color: rgb(255, 0, 0); }.csharpcode .alt { background-color: rgb(244, 244, 244); width: 100%; margin: 0em; }.csharpcode .lnum { color: rgb(96, 96, 96); }

如上代码就是将 Winform 指定为浮动工具条窗体。只要在winform 的类中重载 CreateParams 函数,并按上述代码编写就可以了。

二、如何检测当前处于输入状态

在一些嵌入式设备中,我们没有物理键盘,所有的输入都是通过触摸屏和软键盘输入。那么这个时候,我们必须要做到只有处于输入状态时才弹出软键盘,否则如果软键盘一直在界面上,既不美观也妨碍其他程序的正常使用。

要实现这个功能,我们能想到的最直接的方法是 windows 是否会在当前处于输入状态下时发一个什么事件,或者通过什么钩子程序来实现。但我研究了很久,没有找到这种方法。如果哪位知道这种方法,不妨在回复中告诉我。

我目前找到的方法是定时询问 windows 的当前窗体是否处于输入状态(http://www.my400800.cn )。

            IntPtr hWnd = GetForegroundWindow();

            uint
 processId;
            uint
 threadid = GetWindowThreadProcessId(hWnd, out
 processId);

            GUITHREADINFO lpgui = new
 GUITHREADINFO();
            lpgui.cbSize = Marshal.SizeOf(lpgui);

            if
 (GetGUIThreadInfo(threadid, ref
 lpgui))
            {
                if
 (lpgui.hwndCaret != 0)
                {
                    return
 hWnd;
                }
            }
.csharpcode pre { margin: 0em; }.csharpcode .rem { color: rgb(0, 128, 0); }.csharpcode .kwrd { color: rgb(0, 0, 255); }.csharpcode .str { color: rgb(0, 96, 128); }.csharpcode .op { color: rgb(0, 0, 192); }.csharpcode .preproc { color: rgb(204, 102, 51); }.csharpcode .asp { background-color: rgb(255, 255, 0); }.csharpcode .html { color: rgb(128, 0, 0); }.csharpcode .attr { color: rgb(255, 0, 0); }.csharpcode .alt { background-color: rgb(244, 244, 244); width: 100%; margin: 0em; }.csharpcode .lnum { color: rgb(96, 96, 96); }

如上面代码所示

首先我们通过  GetForegroundWindows API 得到当前窗体的句柄。然后我们再通过 GetGUIThreadInfo 得到当前窗体的一些属性。这些属性在 GUITHREADINFO 中定义

        public
 struct
 GUITHREADINFO
        {
            public
 int
 cbSize;
            public
 int
 flags;
            public
 int
 hwndActive;
            public
 int
 hwndFocus;
            public
 int
 hwndCapture;
            public
 int
 hwndMenuOwner;
            public
 int
 hwndMoveSize;
            public
 int
 hwndCaret;
            public
 System.Drawing.Rectangle rcCaret;
        }

.csharpcode pre { margin: 0em; }.csharpcode .rem { color: rgb(0, 128, 0); }.csharpcode .kwrd { color: rgb(0, 0, 255); }.csharpcode .str { color: rgb(0, 96, 128); }.csharpcode .op { color: rgb(0, 0, 192); }.csharpcode .preproc { color: rgb(204, 102, 51); }.csharpcode .asp { background-color: rgb(255, 255, 0); }.csharpcode .html { color: rgb(128, 0, 0); }.csharpcode .attr { color: rgb(255, 0, 0); }.csharpcode .alt { background-color: rgb(244, 244, 244); width: 100%; margin: 0em; }.csharpcode .lnum { color: rgb(96, 96, 96); } 上面是  GUITHREADINFO  结构。我们可以通过这个信息得到当前窗体中当前焦点的子窗口句柄,当前获得光标的子窗口句柄,当前正激活的子窗体句柄等等。这里我们只要用到当前获得光标 的子窗口句柄,就是 hwndCaret 。如果hwndCaret 不为0,则表示当前窗体处于可输入状态。

相关API函数的 C# 定义如下:

        [DllImport("user32.dll"
)]
        [return
: MarshalAs(UnmanagedType.Bool)]
        public
 static
 extern
 bool
 GetGUIThreadInfo(uint
 idThread, ref
 GUITHREADINFO lpgui);
        [DllImport("user32.dll"
)]
        public
 static
 extern
 IntPtr GetForegroundWindow();
        [DllImport("user32.dll"
, SetLastError = true
)]
        static
 extern
 uint
 GetWindowThreadProcessId(IntPtr hWnd, out
 uint
 lpdwProcessId);
.csharpcode pre { margin: 0em; }.csharpcode .rem { color: rgb(0, 128, 0); }.csharpcode .kwrd { color: rgb(0, 0, 255); }.csharpcode .str { color: rgb(0, 96, 128); }.csharpcode .op { color: rgb(0, 0, 192); }.csharpcode .preproc { color: rgb(204, 102, 51); }.csharpcode .asp { background-color: rgb(255, 255, 0); }.csharpcode .html { color: rgb(128, 0, 0); }.csharpcode .attr { color: rgb(255, 0, 0); }.csharpcode .alt { background-color: rgb(244, 244, 244); width: 100%; margin: 0em; }.csharpcode .lnum { color: rgb(96, 96, 96); }

三、模拟键盘输入

模拟键盘输入比较简单,.Net 提供了一个静态函数来模拟键盘输入

System.Windows.Forms.SendKeys.Send

这个函数很简单,而且微软的帮助也很全面了,我这里就不多说了。

另外我们还可以用更加底层的 API 函数来模拟键盘的输入

        [DllImport("user32.dll"
)]
        static
 extern
 void
 keybd_event(byte
 bVk, byte
 bScan, uint
 dwFlags,
           int
 dwExtraInfo);
.csharpcode pre { margin: 0em; }.csharpcode .rem { color: rgb(0, 128, 0); }.csharpcode .kwrd { color: rgb(0, 0, 255); }.csharpcode .str { color: rgb(0, 96, 128); }.csharpcode .op { color: rgb(0, 0, 192); }.csharpcode .preproc { color: rgb(204, 102, 51); }.csharpcode .asp { background-color: rgb(255, 255, 0); }.csharpcode .html { color: rgb(128, 0, 0); }.csharpcode .attr { color: rgb(255, 0, 0); }.csharpcode .alt { background-color: rgb(244, 244, 244); width: 100%; margin: 0em; }.csharpcode .lnum { color: rgb(96, 96, 96); }

这个函数是 keybd_event,关于这个函数的使用,微软的帮助也写的很清楚,这里也不重述了。



分享到:
评论

相关推荐

    软键盘设计

    在实际开发软键盘时,开发者需要注意几个技术要点:一是要考虑触摸输入的精度和延迟问题,优化用户体验;二是要确保软键盘与应用程序的交互流畅,避免输入延迟或数据丢失;三是要处理好键盘的布局和自适应性,确保在...

    emWin 数字软键盘

    在开发软键盘时,有以下几个关键知识点: 1. **窗口对象和控件**:emWin支持多种窗口对象和控件,如按钮、文本框和滚动条。软键盘的每个数字键可以视为一个按钮控件,需要定义其外观、大小、位置和响应事件。 2. *...

    在网页中使用软键盘的方法

    网页软键盘的实现通常涉及到以下几个关键步骤: - **HTML布局**:定义键盘的基本结构,包括按键的排列方式等。 - **CSS样式**:美化键盘外观,使其更加接近真实的键盘视觉效果。 - **JavaScript逻辑**:处理用户的...

    Qt中英文软键盘

    Qt中英文软键盘的实现可能包括以下几个关键部分: 1. 字符集:为了支持中英文输入,键盘需要包含完整的ASCII码表以及常见的中文字符。这通常意味着要包含GB2312、GBK、UTF-8等编码中的字符。 2. 图形界面:Qt的...

    comt.rar_软键盘

    6. **源代码分析**:如果"comt"是源代码,可以对其进行分析,解释关键函数和逻辑,以理解如何实现软键盘密码的获取或保护。 这些知识点对于网络安全专业人员、软件开发者以及对在线隐私和安全感兴趣的普通用户都...

    易语言画板软键盘

    易语言画板软键盘的系统结构可以分为以下几个关键组成部分: 1. 用户界面(UI):这是用户与程序交互的窗口,包括画板区域和软键盘区域。易语言提供了丰富的控件和布局管理器,用于创建直观且易于操作的界面。 2. ...

    STM32F767 EMWIN实现软键盘实验【支持STM32F7系列单片机-EMWIN GUI可视化】.zip

    为了实现软键盘功能,实验可能包含以下几个关键步骤: 1. 初始化EMWIN库:设置显示设备(如LCD控制器)、颜色模式、分辨率等,并启动EMWIN。这通常通过调用`GUI_Init()`函数来完成。 2. 创建窗口和控件:使用EMWIN...

    qt-使用qt开发的虚拟键盘-项目源码.zip

    虚拟键盘的开发主要包括以下几个关键部分: 1. **设计键盘布局**:虚拟键盘的设计需要考虑不同操作场景下的键位排列,包括字母、数字、符号键以及常用快捷键。在Qt中,可以使用QLayout类来组织和管理控件的位置,...

    soft_key_board.rar_Soft!_soft key board

    在开发屏幕软键盘时,有几个关键知识点值得深入探讨: 1. **用户界面设计**:软键盘的界面设计需考虑到易用性和效率。它应该有常见的字符布局,如QWERTY布局,以及特殊符号和功能键。同时,设计应适应不同屏幕尺寸...

    高仿微信表情自定义键盘支持emoji,自定义表情

    综合以上信息,这个项目的核心技术涉及以下几个方面: 1. **Android/iOS开发**:由于提到的是高仿微信表情键盘,所以很可能是针对移动端的应用开发。 2. **自定义键盘(Custom Keyboard)**:开发者需要实现一个自定义...

    基于51单片机的矩阵键盘c源码.zip

    在51单片机的应用中,矩阵键盘的实现主要涉及以下几个关键技术点: 1. **硬件连接**:矩阵键盘的行线连接到51单片机的输入引脚,列线连接到输出引脚。通过设置列线为低电平并读取行线状态,可以确定按键位置。 2. ...

    Android仿QQ,微信表情源码

    在Android中,实现表情功能需要考虑以下几个关键技术点: 1. **表情解析**:表情解析是将用户输入的文字转换为对应的图像的关键步骤。这通常涉及到创建一个表情映射表,将特定的文字序列(如`:joy:`或`[偷笑]`)...

    解析开题报告书软件基于单片机的温度控制器设计.doc

    总结来说,这篇开题报告涉及了以下几个关键知识点: 1. **89S51单片机**:一种常见的微控制器,用于处理温度控制系统的数据处理和决策。 2. **DS18B20温度传感器**:提供精确的温度测量,直接数字输出,简化了数据...

    进程通信----软中断

    在计算机科学领域,进程间的通信(IPC)是多进程或线程程序设计中的一个关键环节,它允许不同的进程间共享数据、同步操作以及相互协作。软中断作为一种特殊的进程间通信机制,在本示例中被用来实现父子进程之间的...

    Android仿 QQ 微信 表情

    通过分析和学习该项目,我们可以掌握以下几个关键知识点: 1. **自定义键盘(Soft Keyboard)**: - Android系统提供了`InputMethodService`服务,允许开发者创建自定义的软键盘。我们需要继承此类,并在布局文件...

    Android 类似搜狗输入法android源码-IT计算机-毕业设计.zip

    其次,源码中可能会包含以下几个关键组件: 1. **拼音处理模块**:搜狗输入法的一个显著特点是其强大的拼音处理能力。这个模块可能包含拼音解析、声母韵母识别、多音字处理等算法。 2. **词库管理**:词库是输入法...

    Android 模仿手机QQ表情输入和表情预览框

    在实现表情功能时,可能需要处理以下几个关键点: 1. 表情编码:为每个表情分配一个唯一的代码,例如`:joy:`,在输入时检测并替换这些代码。 2. 图片资源:将表情图片存储为资源文件,可以通过`R.drawable`访问。...

    用单片机实现温度远程显示.doc

    #### 关键技术解析 ##### 1. RS-485总线通讯 **RS-485**是一种广泛应用于工业环境中的双向、平衡传输线标准接口。相较于其他通讯方式,RS-485具有以下显著优势: - **传输距离远**:最大传输距离可达1200米。 - **...

Global site tag (gtag.js) - Google Analytics