xfcbbs2 发表于 2021-7-23 14:03:58

emwin 动态软键盘

emwin 动态软键盘:

      中、英文字符输入时,使用动态键盘,更加美观方便。


   实现动态键盘[可以根据需要,调节按键的有无,以及位置大小等等],这是我多年梦寐以求的事情,今天把它实现了,


发个帖子,跟大家一起共享。


   请看如下的截图,以及操作视频:
   (视频更容易说明实际的操作过程)


1、英文键盘模式:


      

   2、中文键盘模式:
      

   3、实际操作视频:
      
   

   视频打成压缩包了,才上传上来




特别说明: 要是大家感兴趣的话,我几天我整理一下文件,把软件实现发上来。







eric2013 发表于 2021-7-23 15:02:57

效果不错,谢谢楼主分享

xfcbbs2 发表于 2021-7-23 22:15:04

动态软键盘实现代码如下:

static const GUI_WIDGET_CREATE_INFO _aDialogKeyBoard[] = {        
       { WINDOW_CreateIndirect,   0,      0,               207,      385,   386*1.4, 185*1.4},       
        { BUTTON_CreateIndirect,   "we",      GUI_ID_BUTTON0,   4*1.4,      -50,   36*1.4*2, 36*1.4},          //初始化时: 控件坐标为: 负值!
        { BUTTON_CreateIndirect,   0,         GUI_ID_BUTTON1,   80*1.4-5,   -50,   36*1.4,   36*1.4},       
        { BUTTON_CreateIndirect,   0,         GUI_ID_BUTTON2,   118*1.4-5,-50,   36*1.4,   36*1.4},
        { BUTTON_CreateIndirect,   0,         GUI_ID_BUTTON3,   156*1.4-5,-50,   36*1.4,   36*1.4},
        { BUTTON_CreateIndirect,   0,         GUI_ID_BUTTON4,   194*1.4-5,-50,   36*1.4,   36*1.4},
        { BUTTON_CreateIndirect,   0,         GUI_ID_BUTTON5,   232*1.4-5,-50,   36*1.4,   36*1.4},
        { BUTTON_CreateIndirect,   0,         GUI_ID_BUTTON6,   270*1.4-5,-50,   36*1.4,   36*1.4},       
        { BUTTON_CreateIndirect,   "<",       GUI_ID_BUTTON7,   308*1.4-5,-50,   36*1.4,   36*1.4},
        { BUTTON_CreateIndirect,   ">",       GUI_ID_BUTTON8,   346*1.4-5, -50,   36*1.4+5, 36*1.4},               
       
        { BUTTON_CreateIndirect,   "q",      GUI_ID_USER +50,   4*1.4,   15*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "w",      GUI_ID_USER +51,   42*1.4,    15*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "e",      GUI_ID_USER +52,   80*1.4,    15*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "r",      GUI_ID_USER +53,   118*1.4,   15*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "t",      GUI_ID_USER +54,   156*1.4,   15*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "y",      GUI_ID_USER +55,   194*1.4,   15*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "u",      GUI_ID_USER +56,   232*1.4,   15*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "i",      GUI_ID_USER +57,   270*1.4,   15*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "o",      GUI_ID_USER +58,   308*1.4,   15*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "p",      GUI_ID_USER +59,   346*1.4,   15*1.4,36*1.4,36*1.4},
       
        { BUTTON_CreateIndirect,   "a",      GUI_ID_USER +60,    23*1.4,   56*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "s",      GUI_ID_USER +61,    61*1.4,   56*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "d",      GUI_ID_USER +62,    99*1.4,   56*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "f",      GUI_ID_USER +63,    137*1.4,56*1.4,36*1.4,36*1.4},      
        { BUTTON_CreateIndirect,   "g",      GUI_ID_USER +64,    175*1.4,56*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "h",      GUI_ID_USER +65,    213*1.4,56*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "j",      GUI_ID_USER +66,    251*1.4,56*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "k",      GUI_ID_USER +67,    289*1.4,56*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "l",      GUI_ID_USER +68,    327*1.4,56*1.4,36*1.4,36*1.4},       
       
        { BUTTON_CreateIndirect,   "z",      GUI_ID_USER +69,    40*1.4,   97*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "x",      GUI_ID_USER +70,    78*1.4,   97*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "c",      GUI_ID_USER +71,    116*1.4,97*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "v",      GUI_ID_USER +72,    154*1.4,97*1.4,36*1.4,36*1.4},      
        { BUTTON_CreateIndirect,   "b",      GUI_ID_USER +73,    192*1.4,97*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "n",      GUI_ID_USER +74,    230*1.4,97*1.4,36*1.4,36*1.4},
        { BUTTON_CreateIndirect,   "m",      GUI_ID_USER +75,    268*1.4,97*1.4,36*1.4,36*1.4},       

        { BUTTON_CreateIndirect,   0,      GUI_ID_USER +76,    306*1.4,97*1.4,67*1.4,36*1.4},//BKSP       
       
        { BUTTON_CreateIndirect,   "Shift",GUI_ID_USER +77,    4*1.4,   138*1.4,50*1.4,36*1.4},                       
        { BUTTON_CreateIndirect,   "Space",GUI_ID_USER +78,    133*1.4, 138*1.4,133*1.4, 36*1.4},       
        { BUTTON_CreateIndirect,   "Enter",GUI_ID_USER +79,    306*1.4, 138*1.4,76*1.4,36*1.4},       
        { BUTTON_CreateIndirect,   "123..",GUI_ID_USER +80,    56*1.4,138*1.4,75*1.4,36*1.4},       
      { BUTTON_CreateIndirect,   0,      GUI_ID_USER +81,    268*1.4, 138*1.4,36*1.4,36*1.4},        //中/英文切换               
};




void Virtual_KeyboardWin(void)
{       
        GUI_UC_SetEncodeUTF8();       
       
        BUTTON_SetDefaultFont(&GUI_Font8x16);               
       
        hwinInc=FRAMEWIN_CreateEx(207, 335,386*1.4, 30,0,WM_CF_HIDE| WM_CF_STAYONTOP,0,0,"Virtual KeyBoard",_cbWinInc_key);               
        hButton_top=FRAMEWIN_AddButton(hwinInc,FRAMEWIN_BUTTON_RIGHT,0,GUI_ID_USER +100);       
        WM_SetCallback(hButton_top, _cbTopClose); //添加增加按钮的回调函数

      hKeyBoard= GUI_CreateDialogBox(_aDialogKeyBoard,GUI_COUNTOF(_aDialogKeyBoard),_cbDialogKeyBoard, WM_HBKWIN, 0, 0);
        WM_SetStayOnTop(hwinInc, 1);
        WM_SetStayOnTop(hKeyBoard, 1);
                                                                                                                                       
        WM_HideWindow(hKeyBoard); //隐藏                  
}




/****************************************************************************       
* 功    能:   虚拟键盘任务---------[任务优先级: ]
*---------------------------------------------------------------------------*
* 入口参数:
* 出口参数:
****************************************************************************/
void vTask_Virtual_Keyboard(void *p_arg)
{       
       (void)p_arg;          
       
       while(1)
          {      
                Virtual_KeyboardWin();
             GUI_Delay(100);                       
        }
}



/****************************************************************************       
* 功    能: 键盘加宽调整-----函数
*---------------------------------------------------------------------------*
* 入口参数:hDlg-----窗口句柄;
*         dir------方向:1:加宽; 0:变窄
* 出口参数:nil
****************************************************************************/       

voidKeyboard_Widen_Process(WM_HWINhDlg,int dir)       
{
        int i;        

      static uint8_t flag_widen=0; //键盘加宽标志变量                       
       
        WM_HWIN hItem ;               
       
        if((flag_widen==1)&&(dir==0)){ //变窄
               
                flag_widen=0; //set-----改变状态                                                                               
               
                for (i = 0; i < 5; i++) { //最下端一行:SHIFT---ENTER
                        hItem = WM_GetDialogItem(hDlg,GUI_ID_USER +77 + i);       
                        WM_SetYSize(hItem,50); //改变按钮的宽度               
                        WM_MoveWindow(hItem, 0,-14);        //dx:Horizontal distance; dy:Vertical distance to move                                       
                }       
               
                for (i = 0; i < 8; i++) { //倒数第2行:Z---M
                        hItem = WM_GetDialogItem(hDlg,GUI_ID_USER +69 + i);               
                     WM_SetYSize(hItem,50); //改变按钮的宽度       
                     if(i==7){//BKSP
                           BUTTON_SetBitmapEx(hItem, 0, &bmkey_bksp, 24, 9);//添加BMP图形
                           BUTTON_SetBitmapEx(hItem, 1, &bmkey_bksp, 24, 9);        
                        }                               
                        WM_MoveWindow(hItem, 0,-22);        //dx:Horizontal distance; dy:Vertical distance to move                                       
                }       
               
                for (i = 0; i < 9; i++) { //倒数第3行:A---L
                        hItem = WM_GetDialogItem(hDlg,   GUI_ID_USER +60 + i);
                        WM_SetYSize(hItem,50);//改变按钮的宽度                               
                        WM_MoveWindow(hItem, 0,-30);        //dx:Horizontal distance; dy:Vertical distance to move                                    
                }       
               
                for (i = 0; i < 10; i++) { //倒数第4行:Q---P
                        hItem = WM_GetDialogItem(hDlg,   GUI_ID_USER +50 + i);       
                        WM_SetYSize(hItem,50);                       
                        WM_MoveWindow(hItem, 0,-40);        //dx:Horizontal distance; dy:Vertical distance to move             
                }       
               
                for (i = 0; i < 9; i++) {
                        hItem = WM_GetDialogItem(hDlg,GUI_ID_BUTTON0 + i);                                                               
                        WM_MoveWindow(hItem, 0,-64);        //dx:Horizontal distance; dy:Vertical distance to move               
                        WM_HideWindow(hItem);        //保险起见,加以隐藏               
                }       

        }else if((flag_widen==0)&&(dir==1)){ //加宽
               
                flag_widen=1; //set-----改变状态                                                                               
                                                               
                for (i = 0; i < 5; i++) { //最下端一行:SHIFT---ENTER
                        hItem = WM_GetDialogItem(hDlg,GUI_ID_USER +77 + i);       
                        WM_SetYSize(hItem,42);//改变按钮的宽度                       
                        WM_MoveWindow(hItem, 0,14);        //dx:Horizontal distance; dy:Vertical distance to move                                       
                }       
               
                for (i = 0; i < 8; i++) { //倒数第2行:Z---M
                        hItem = WM_GetDialogItem(hDlg,GUI_ID_USER +69 + i);               
                        WM_SetYSize(hItem,42);//改变按钮的宽度       
                        if(i==7){//BKSP
                            BUTTON_SetBitmapEx(hItem, 0, &bmkey_bksp, 24, 5);
                            BUTTON_SetBitmapEx(hItem, 1, &bmkey_bksp, 24, 5);        
                        }                                                       
                        WM_MoveWindow(hItem, 0,22);        //dx:Horizontal distance; dy:Vertical distance to move                                       
                }       
               
                for (i = 0; i < 9; i++) { //倒数第3行:A---L
                        hItem = WM_GetDialogItem(hDlg,   GUI_ID_USER +60 + i);       
                         WM_SetYSize(hItem,42);        //改变按钮的宽度                               
                        WM_MoveWindow(hItem, 0,30);        //dx:Horizontal distance; dy:Vertical distance to move                                       
                }       
               
                for (i = 0; i < 10; i++) { //倒数第4行:Q---P
                        hItem = WM_GetDialogItem(hDlg,   GUI_ID_USER +50 + i);       
                        WM_SetYSize(hItem,42);   //改变按钮的宽度                               
                        WM_MoveWindow(hItem, 0,40);        //dx:Horizontal distance; dy:Vertical distance to move                                       
                }                       
               
                for (i = 0; i < 9; i++) {
                        hItem = WM_GetDialogItem(hDlg,GUI_ID_BUTTON0 + i);             
                        WM_SetYSize(hItem,42);//改变按钮的宽度                       
                        WM_MoveWindow(hItem, 0,64);        //dx:Horizontal distance; dy:Vertical distance to move       
                         WM_ShowWindow(hItem);                       
                }                       
        }       
}




//回调函数----主要代码部分
static void _cbDialogKeyBoard(WM_MESSAGE * pMsg) {

case WM_NOTIFY_PARENT:
          Id    = WM_GetId(pMsg->hWinSrc);      /* Id of widget */
         NCode = pMsg->Data.v;               /* Notification code */
         switch (NCode)
         {      case WM_NOTIFICATION_CLICKED:                                               
                        //..........
                        break;       
                  case WM_NOTIFICATION_RELEASED:                                       
                        if(Id==GUI_ID_USER +81){ //中英文切换                                               
                           if(key_language ==0){ //英文                                                               
                                key_language=1; //中文                                                               
                                SetUser_Button_Skinning();                                                               
                                Keyboard_Widen_Process(hDlg,1); //键盘加宽---转到中文键盘模式       

                              //........

                           }else{ //原来是中文输入状态                                                       
                                key_language=0; //英文                                                               
                              SetUser_Button_Skinning();                                                       
                               Keyboard_Widen_Process(hDlg,0); //键盘变窄---恢复英文键盘模式   

                                 //........
                                                
                                hItem =WM_GetDialogItem(hDlg, GUI_ID_USER +81);
                                BUTTON_SetFocussable(hItem, 0);   /* Set all buttons non focussable */   
                                BUTTON_SetFont(hItem, &hzSY16);                        
                                BUTTON_SetText(hItem,"英");                                                        
                           }
                        }
                        break;

            }

       //..........

      }


}




xfcbbs2 发表于 2021-7-30 21:45:57

编辑了一小段avi视频放上来,看到视频,大家才能体会到实际的效果:



eric2013 发表于 2021-7-31 08:38:26

xfcbbs2 发表于 2021-7-30 21:45
编辑了一小段avi视频放上来,看到视频,大家才能体会到实际的效果:

不错。

peterlao98 发表于 2021-7-31 09:36:26

看到视频,效果很好

strang 发表于 2022-8-29 11:28:17

不错,强大{:8:}

tao475824827 发表于 2022-12-4 12:38:33

mark,效果看起来很棒

天马行空 发表于 2022-12-4 19:31:13

练练手可以,一个键盘几十个Button,实际项目这样搞太浪费空间,,,,拿1个button改改,明明一个控件就可以搞定的。。。。。

hhh535 发表于 2022-12-7 19:26:28

天马行空 发表于 2022-12-4 19:31
练练手可以,一个键盘几十个Button,实际项目这样搞太浪费空间,,,,拿1个button改改,明明一个控件就可 ...

请问1个Button怎么改,能给下思路吗

天马行空 发表于 2022-12-9 09:58:43

hhh535 发表于 2022-12-7 19:26
请问1个Button怎么改,能给下思路吗

GUI和触摸的本质都是“点哪里?怎么显示?”,一个BUTTON也就是一个窗口,把这个窗口区域再细划分各个键值区域,就是一个键盘了。。。。我一直用的都是古老的ucGUI,很多控件都被我改的面目全非了。emWin作为它的升级版,应该原理都一样的。。。

vlong5461 发表于 2024-1-19 11:43:00

中文输入是如何实现的呢?有demol分享么?谢谢!

eric2013 发表于 2024-1-20 08:54:25

vlong5461 发表于 2024-1-19 11:43
中文输入是如何实现的呢?有demol分享么?谢谢!

这个有个例子的。

第9期:全键盘拼音输入法界面设计
https://www.armbbs.cn/forum.php?mod=viewthread&tid=5603&fromuid=58
(出处: 硬汉嵌入式论坛)

wzbtp 发表于 2024-3-23 21:18:01

emwin 动态软键盘,我想付费升级一下
154698310@qq.com
页: [1]
查看完整版本: emwin 动态软键盘