就是输入法输入特殊字符时用的那个小键盘,比如紫光输入法上的小键盘按钮按下之后,就会弹出一个小键盘。本文就说一下如何做到这个功能:
这篇是我参考紫光拼音软键盘编码和一些输入法软键盘编码整理的文档: 软键盘的编码.rar

这个是我最近做的一个软键盘类:软键盘类.rar
下载所有输入法源码参见: http://www.cnblogs.com/realfun/archive/2005/06/26/181302.html

C++语言: 输入法的小键盘(软键盘)类
//这是以前写的输入法的小键盘(软键盘)类
//就是输入法输入特殊字符时用的那个小键盘
//比如搜狗输入法上的小键盘按钮按下之后,就会弹出一个小键盘
//
//注意:这是多个文件合在一起了,下载打包好的文件参见相关文章链接:
//    http://www.cnblogs.com/realfun/archive/2005/03/28/127174.html

//
//      CIMESoftKbd.h

/*
* author : yuchifang(realfun)
* email : realfun at gmail dot com
*/

#ifndef _IME_SOFTKBD_H_
#define _IME_SOFTKBD_H_

#include
#include
#include
#include
using namespace std;

const SOFT_KEY_COUNT = 47;

//表示一个软键盘布局
class CIMESkbTab
{
public:
    CIMESkbTab(const TCHAR keys[], const TCHAR shiftKeys[], LPCTSTR name);
    CIMESkbTab(const CIMESkbTab &skb);
    TCHAR GetChar(int index);
    TCHAR GetShiftChar(int index);
    //转换键盘按键到软键盘字符,不存在则返回0
    TCHAR ConvVKey2SKBChar(UINT vKey, bool bShift);
    //获取tab名称
    void GetName(TCHAR name[]) { _tcscpy(name, this->name); }
private:
    TCHAR tab[SOFT_KEY_COUNT];  //软键盘布局
    TCHAR shiftTab[SOFT_KEY_COUNT];  //Shift后的软键盘布局
    TCHAR name[10];  //软键盘布局名称
};

//该类封装了软键盘操作
class CIMESoftKbd
{
public:
    CIMESoftKbd();

//显示下一个软键盘布局
    void ShowNext()
    {
        m_tabIndex = (m_tabIndex + 1) % m_tabs.size();
        Show();
    }

//显示前一个软键盘布局
    void ShowPrev()
    {
        m_tabIndex = (m_tabIndex + m_tabs.size() - 1) % m_tabs.size();
        Show();
    }

//显示指定位置的软键盘布局
    void ShowAtPos(int index)
    {
        m_tabIndex = abs(index) % m_tabs.size();
        Show();
    }

//显示并更新软键盘
    void Show();

//隐藏软键盘
    void Hide();

//判断软键盘是否打开
    bool IsOpen() { return m_bSkbOpened; }

//转换键盘按键字符到软键盘字符
    TCHAR GetSkbChar(UINT vk, bool bShift);

int GetCurrIndex() const { return m_tabIndex; }

private:
    bool m_bSkbOpened;  //软键盘是否打开
    int m_tabIndex;  //当前的软键盘编号
    vector m_tabs; //存储所有软键盘布局信息
    HWND m_hWndSkb;  //软键盘窗口句柄
};

#endif//_IME_SOFTKBD_H_

//
//      CIMESoftKbd.cpp

/*
* author : yuchifang(realfun)
* email : realfun at gmail dot com
*/

#pragma warning(disable:4786)
#include "CIMEDebug.h"
#include "CIMESoftKbd.h"
#include "CIMEUIStatus.h"
#include "CIMEUtils.h"

//
// CIMESoftKbdTab Implementations
//

CIMESkbTab::CIMESkbTab(const TCHAR keys[], const TCHAR shiftKeys[], LPCTSTR name)
{
    for (int i=0; i<SOFT_KEY_COUNT; i++)
    {
        tab[i] = keys[i];
        shiftTab[i] = shiftKeys[i];
    }

_tcsncpy(this->name, name, 10);
    this->name[9] = _T('\0');
}

CIMESkbTab::CIMESkbTab(const CIMESkbTab &skb)
{
    for (int i=0; i<SOFT_KEY_COUNT; i++)
    {
        tab[i] = skb.tab[i];
        shiftTab[i] = skb.shiftTab[i];
    }
    _tcscpy(name, skb.name);
}

TCHAR CIMESkbTab::GetChar(int index)
{
    assert(index>=0 && index <SOFT_KEY_COUNT);
    return tab[index];
}

TCHAR CIMESkbTab::GetShiftChar(int index)
{
    assert(index>=0 && index <SOFT_KEY_COUNT);
    return shiftTab[index];
}

TCHAR CIMESkbTab::ConvVKey2SKBChar(UINT vKey, bool bShift)
{
    /*
    vKey的内容分配:
    键盘上的位置 0-9  a-z  ;   =   ,   -   .   /   `   [   \   ]   '
    对应的vKey位置 48-57 65-90 186 187 188 189 190 191 192 219 220 221 222
    */

int pos = -1;
    if (vKey >= 48 && vKey <=57)
        pos = vKey - 48;
    else if (vKey >= 65 && vKey <=90)
        pos = vKey - 65 + 10; //10为前面10个数字位置
    else if (vKey >= 186 && vKey <=192)
        pos = vKey - 186 + 10 + 26; //26为26字母占的位置
    else if (vKey >= 219 && vKey <= 222)
        pos = vKey - 219 + 10 + 26 + 7; //7为前面七个;=,-./`占的位置

if (pos == -1) return L'\0';
    TCHAR ch = bShift ? shiftTab[pos] : tab[pos];
    if (ch == L' ')
        return L'\0';
    return ch;
}

//
// CIMESoftKbd Implementations
//

CIMESoftKbd::CIMESoftKbd()
{
    CIMEDebug::DebugLog(L"CIMESoftKbd::CIMESoftKbd()");

TCHAR tabNames[][10] =
    {
        L"常用符号", L"标点符号", L"特殊符号", L"表格线",
        L"数字序号", L"数学符号", L"单位符号", L"拼音符号",
        L"注音符号", L"日文平假名", L"日文片假名", L"希腊字母",
        L"俄文字母",
    };

WORD wSoftKBDDatas[][2][SOFT_KEY_COUNT] =
    {
        /*
        {//正常的键盘
        {
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
        'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
        'u', 'v', 'w', 'x', 'y', 'z', ';', '=', ',', '-',
        '.', '/', '`', '[', '\\', ']', '\''
        },
        {
        ')', '!', '@', '#', '$', '%', '^', '&', '*', '(',
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
        'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
        'U', 'V', 'W', 'X', 'Y', 'Z', ':', '+', '<', '_',
        '>', '?', '~', '{', '|', '}', '"'
        }
        },
        */

{//#常用符号
            {//下档键(没按住shift)
                L'⑽', L'⑴', L'⑵', L'⑶', L'⑷', L'⑸', L'⑹', L'⑺', L'⑻', L'⑼',
                    L'■', L'α', L'∑', L'▲', L'⒊', L'●', L'★', L'【', L'⒏', L'】',
                    L'『', L'‘', L'γ', L'β', L'⒐', L'⒑', L'⒈', L'⒋', L'◆', L'⒌',
                    L'⒎', L'§', L'⒉', L'‰', L'⒍', L'$', L';', L'=', L',', L'-',
                    L'。', L'/', L'`', L'[', L'、', L']', L'’'
            },
            {//下档键(按住shift)
                L'㈩', L'㈠', L'㈡', L'㈢', L'㈣', L'㈤', L'㈥', L'㈦', L'㈧', L'㈨',
                    L'□', L'±', L'∏', L'△', L'Ⅲ', L'○', L'☆', L'〖', L'Ⅷ', L'〗',
                    L'』', L'“', L'÷', L'×', L'Ⅸ', L'Ⅹ', L'Ⅰ', L'Ⅳ', L'◇', L'Ⅴ',
                    L'Ⅶ', L'※', L'Ⅱ', L'℃', L'Ⅵ', L'¥', L':', L'+', L'《', L'_',
                    L'》', L'?', L'~', L'{', L'?', L'}', L'”'
                }
        },
            //下同,略过了
    };

int size = sizeof(wSoftKBDDatas) / sizeof(TCHAR) / 2 / SOFT_KEY_COUNT;
    for (int i=0; i<size; i++)
        m_tabs.push_back(CIMESkbTab(wSoftKBDDatas[i][0], wSoftKBDDatas[i][1], tabNames[i]));
    m_bSkbOpened = false;
    m_tabIndex = 0;
}

void CIMESoftKbd::Show()
{
    CIMEDebug::DebugLog(L"CIMESoftKbd::Show()");

if (!m_bSkbOpened)
    {
        m_bSkbOpened = true;
        //显示软键盘
        RECT rc;
        int w;
        int h;
        int cx = GetSystemMetrics(SM_CXSCREEN);
        int cy = GetSystemMetrics(SM_CYSCREEN);
        m_hWndSkb = ImmCreateSoftKeyboard(SOFTKEYBOARD_TYPE_C1, FindWindow(CIMEUIStatus::GetUIClassName(), NULL), 0, 0);
        ImmShowSoftKeyboard(m_hWndSkb, SW_HIDE);
        GetWindowRect(m_hWndSkb, &rc);
        w = rc.right - rc.left;
        h = rc.bottom - rc.top;
        MoveWindow(m_hWndSkb, cx / 2, cy - 2*h, w, h, TRUE);
        ShowWindow(m_hWndSkb, SW_SHOWNOACTIVATE);
    }

//更新软键盘布局
    SOFTKBDDATA sbd;
    int i;
    for (i=0; i<256; i++)
    {
        sbd.wCode[0][i] = _T(' ');
        sbd.wCode[1][i] = _T(' ');
    }
    CIMESkbTab &skbTab = m_tabs[m_tabIndex];

/*
    vKey的内容分配:
    键盘上的位置 0-9  a-z  ;   =   ,   -   .   /   `   [   \   ]   '
    对应的vKey位置 48-57 65-90 186 187 188 189 190 191 192 219 220 221 222
    */
    int index2SoftKBDPos[SOFT_KEY_COUNT] =
    {
        48, 49, 50, 51, 52, 53, 54, 55, 56, 57, //'0'-'9'
        65, 66, 67, 68, 69, 70, 71, 72, 73, 74, //'a'-'j'
        75, 76, 77, 78, 79, 80, 81, 82, 83, 84, //'k'-'t'
        85, 86, 87, 88, 89, 90,     //'u'-'z'
        186, 187, 188, 189, 190,    // ; = , - .
        191, 192, 219, 220, 221, 222   // / ` [ \ ] '
    };

for (i=0; i<SOFT_KEY_COUNT; i++)
    {
        sbd.wCode[0][index2SoftKBDPos[i]] = skbTab.GetChar(i);
        sbd.wCode[1][index2SoftKBDPos[i]] = skbTab.GetShiftChar(i);
    }

sbd.uCount = 2;
    SendMessage(m_hWndSkb, WM_IME_CONTROL, IMC_SETSOFTKBDDATA, (LPARAM)&sbd);
    CIMEDebug::DebugLog(L"Leaving CIMESoftKbd::Show() safely!");
}

void CIMESoftKbd::Hide()
{
    if (!m_bSkbOpened) return;

if(m_hWndSkb)
    {
        ImmDestroySoftKeyboard(m_hWndSkb);
    }
    m_bSkbOpened = false;
}

TCHAR CIMESoftKbd::GetSkbChar(UINT vk, bool bShift)
{
    CIMEDebug::DebugLog(L"CIMESoftKbd::GetSkbChar");
    CIMEDebug::DebugLog(vk);

return m_tabs[m_tabIndex].ConvVKey2SKBChar(vk, bShift);
}

转载于:https://www.cnblogs.com/realfun/archive/2005/03/28/127174.html

输入法编程教程---软键盘(小键盘?)类,C++编写相关推荐

  1. Android软键盘工具类

    Android软键盘工具类 public class SoftKeyboardUtils {/*** 隐藏或显示软键盘* 如果现在是显示调用后则隐藏 反之则显示*/public static void ...

  2. android 软键盘工具类,Android软键盘管理工具类

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 一个软键盘管理类,单例模式实现的. /** * 类功能描述:软键盘管理界面 * */ public class Inpu ...

  3. android 软键盘工具类,Android开发之弹出软键盘工具类简单示例

    本文实例讲述了Android开发之弹出软键盘工具类.分享给大家供大家参考,具体如下: package com.maobang.imsdk.util; import android.content.Co ...

  4. java 弹出软键盘_Android开发之弹出软键盘工具类简单示例

    本文实例讲述了Android开发之弹出软键盘工具类.分享给大家供大家参考,具体如下: package com.maobang.imsdk.util; import android.content.Co ...

  5. java怎么编写软键盘_输入法编程教程---软键盘(小键盘?)类,C++编写

    //这是以前写的输入法的小键盘(软键盘)类 //就是输入法输入特殊字符时用的那个小键盘 //比如搜狗输入法上的小键盘按钮按下之后,就会弹出一个小键盘 // //注意:这是多个文件合在一起了,下载打包好 ...

  6. C# 调用系统软键盘帮助类(兼容.netframework2.0)

    前言 最近再做触屏系统的时候需要手动调用打开系统软键盘的需求,网上查找到的资料很多,在高版本的fx上也能用,但是刚好我这个现场程序是基于fx2.0开发的,只能在之前的基础上改造支持.目前已经调整到可以 ...

  7. wince手写输入法以及软键盘拼音输入法的问题

    首先给大家分享一个巨牛巨牛的人工智能教程,是我无意中发现的.教程不仅零基础,通俗易懂,而且非常风趣幽默,还时不时有内涵段子,像看小说一样,哈哈-我正在学习中,觉得太牛了,所以分享给大家!点这里可以跳转 ...

  8. android 手机键盘输入法,如何控制输入法软键盘的出现方式

    调用 open(null);/** * 当前弹出则关闭 * 否则弹出 * @param v */ @SuppressWarnings("static-access") public ...

  9. QT 嵌入式 输入法 软键盘

    设计自己的输入法需要继承QWSInputMethod. 需要重新实现:     virtual void updateHandler ( int type );     //type值是枚举变量Upd ...

最新文章

  1. Springboot [日志管理LogBack]
  2. laravel 模型查找数据
  3. Python学习:装饰器使用,timeit()记录程序运行在哪里,耗时多少
  4. Altiumnbsp;designernbsp;学习教程
  5. 架构师之路17年精选80篇
  6. 【matlab】画图的文字调整大小
  7. 七个高效的文本编辑习惯(以Vim为例)
  8. XSS-Game level 11
  9. yolov2 损失函数_目标检测算法之YOLOv2损失函数详解
  10. CABasicAnimation添加动画离开屏幕就动画停止的问题
  11. matlab遗传算法工具箱及应用 pdf,MATLAB遗传算法工具箱及应用(雷英杰)
  12. 遗传算法(GA)求解车辆路径问题(VRP)——matlab实现
  13. 51单片机制作简易计算器(动态数码管、矩阵按键)
  14. 华为自研OS操作系统,今秋是否真的会面市?
  15. 1005打印任务取消不了 hp_(完整版)hp打印机无法取消打印的文档解决方法
  16. java 通过ffmpeg 将海康视频转码
  17. 企业信息系统架构要点
  18. 如何快速提升教育直播间人气
  19. Redis——底层数据结构原理
  20. Redis之sql缓存

热门文章

  1. CCF的A类期刊和会议有哪些?人工智能顶会ACL,ICML,NeurIPS,ICLR论文投稿时间以及影响因子等
  2. 华人一作统一「视觉-语言」理解与生成:一键生成图像标注,完成视觉问答,Demo可玩...
  3. 量子力学与机器学习相结合,预测高温下的化学反应
  4. 物理学家发现粒子是如何自我组装的
  5. 赛迪展望 | 一文了解“2021年中国先进计算产业发展趋势”
  6. 日本精密减速器,到底牛在哪?
  7. 5条出人意外的大脑秘密,奇奇怪怪的知识又增加了!
  8. 日本面向未来的特定科技领域技术预见分析
  9. 下一个10年,解决问题靠“大脑”
  10. 剑桥大学发布2019年度AI发展报告,预测未来12个月AI产业6件大事