硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3169|回复: 6
收起左侧

[emWin] WM_KEY消息的响应机制

[复制链接]

6

主题

14

回帖

32

积分

新手上路

积分
32
发表于 2020-1-3 12:31:42 | 显示全部楼层 |阅读模式
1.控件中Framwin,TEXT,WINDOW没有输入焦点功能,没有焦点的话,由Framwin建立的窗口内只有TEXT控件怎么来响应WM_KEY消息?
2.如果窗口有有BUTTON或者其他可以设置焦点的控件,然后怎么让回调函数WM_KEY消息执行比如ESC或者其他按键输入操作? 就是执行窗口退出等功能,不使用不带参数的发送消息功能的情况下。
3.回调函数响应WM_KEY机制一直不太明白,控件可以自己处理的按键信息会自动处理,不会处理的就进入WM_KEY消息?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106913
QQ
发表于 2020-1-3 14:28:21 | 显示全部楼层
1、自定义窗口消息比较方便
2、WM_KEY是这样,比如聚焦在button上,如果用户发送的KEY消息是BUTTON不支持的,会进入到WM_KEY里面,如果是BUTTON支持的,就不会再进入到WM_KEY
回复

使用道具 举报

6

主题

14

回帖

32

积分

新手上路

积分
32
 楼主| 发表于 2020-1-3 21:26:43 | 显示全部楼层
eric2013 发表于 2020-1-3 14:28
1、自定义窗口消息比较方便
2、WM_KEY是这样,比如聚焦在button上,如果用户发送的KEY消息是BUTTON不支持 ...

#include "GUI.h"
#include "DIALOG.h"
#include "TEXT.h"
#include "BUTTON.h"
#include "Menu_GUI.h"
#include "Menu_FUN.h"

#define Desk_BKColor 0x00E8E8E8

extern WM_HWIN        Menu_WM_hWin;
extern GUI_RECT Header_RECT;
extern GUI_RECT Mid_RECT;
extern Header_Setting Header_Setting_Val;
extern Mid_Setting Mid_Setting_Val;

WM_HWIN Setting_hWin;

#define ID_WINDOW_0      (GUI_ID_USER + 0x00)
#define ID_TEXT_0                (GUI_ID_USER + 0x01)
#define ID_BUTTON_0      (GUI_ID_USER + 0x02)
#define ID_BUTTON_1      (GUI_ID_USER + 0x03)
#define ID_BUTTON_2      (GUI_ID_USER + 0x04)

static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =
{
        { WINDOW_CreateIndirect, "Setting_WM", ID_WINDOW_0, 0, 0, 240, 320, 0, 0x0, 0 },
        { TEXT_CreateIndirect, "Setting_TXT", ID_TEXT_0, 5, 10, 230, 20, 0, 0x64, 0 },
        { BUTTON_CreateIndirect, "Sound_Setting_Button", ID_BUTTON_0, 5, 40, 230, 30, 0, 0x0, 0 },
        { BUTTON_CreateIndirect, "Brightness_Setting_Button", ID_BUTTON_1, 5, 72, 230, 30, 0, 0x0, 0 },
        { BUTTON_CreateIndirect, "Shutdown_Setting_Button", ID_BUTTON_2, 5, 104, 230, 30, 0, 0x0, 0 },
};

static void _cbDialog(WM_MESSAGE * pMsg)
{
        WM_HWIN hItem;
        WM_HWIN hDlg;
        int     NCode;
        int     Id;

        hDlg = pMsg->hWin;
        switch (pMsg->MsgId)
        {
                case WM_PAINT:                                                                                        //2D内容需要手动重绘制
                        GUI_SetBkColor(Desk_BKColor);                                                //设置菜单栏的背景色
                        GUI_Clear();
                        GUI_SetColor(Header_Setting_Val.Header_Bk_Color);
                        GUI_FillRectEx(&Header_RECT);                                                //头部背景色填充
                        GUI_SetColor(Mid_Setting_Val.Mid_Bk_Color);
                        GUI_FillRectEx(&Mid_RECT);                                                        //中部背景色填充                       
                        break;
                case WM_INIT_DIALOG:
                        // Initialization of 'Setting_TXT'
                        hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_0);
                        TEXT_SetText(hItem, "Setting");
                        TEXT_SetTextColor(hItem, GUI_MAKE_COLOR(0x00000000));
                        TEXT_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
                        TEXT_SetFont(hItem, GUI_FONT_20B_ASCII);

                        // Initialization of 'Sound_Setting_Button'
                        hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
                        BUTTON_SetFont(hItem, GUI_FONT_20B_ASCII);
                        BUTTON_SetText(hItem, "Sound Setting");

                        // Initialization of 'Brightness_Setting_Button'
                        hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
                        BUTTON_SetFont(hItem, GUI_FONT_20B_ASCII);
                        BUTTON_SetText(hItem, "Brightness Setting");

                        // Initialization of 'Shutdown_Setting_Button'
                        hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_2);
                        BUTTON_SetFont(hItem, GUI_FONT_20B_ASCII);
                        BUTTON_SetText(hItem, "Shutdown Setting");
                        break;
                case WM_NOTIFY_PARENT:
                        Id = WM_GetId(pMsg->hWinSrc);
                        NCode = pMsg->Data.v;
                        switch (Id)
                        {
                                case ID_BUTTON_0: // Notifications sent by 'Sound_Setting_Button'
                                        switch (NCode)
                                        {
                                                case WM_NOTIFICATION_CLICKED:
                                                        break;
                                                case WM_NOTIFICATION_RELEASED:
                                                        CreateSound_Setting_GUI();
                                                        break;
                                        }
                                        break;
                                case ID_BUTTON_1: // Notifications sent by 'Brightness_Setting_Button'
                                        switch (NCode)
                                        {
                                                case WM_NOTIFICATION_CLICKED:
                                                        break;
                                                case WM_NOTIFICATION_RELEASED:
                                                        CreateBrightness_Setting_GUI();
                                                        break;
                                        }
                                        break;
                                case ID_BUTTON_2: // Notifications sent by Shutdown_Setting_Button'
                                        switch (NCode)
                                        {
                                                case WM_NOTIFICATION_CLICKED:
                                                        break;
                                                case WM_NOTIFICATION_RELEASED:
                                                        CreateShutdown_Setting_GUI();
                                                        break;
                                        }
                                        break;
                        }
                        break;
                case WM_KEY:                //上下键切换选型控件焦点切换   退出键返回   确认键进入相应设置
                        switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key)
                        {
                                case GUI_KEY_ESCAPE:
                                        GUI_EndDialog(pMsg->hWin, 1);
                                        break;
                                default:
                                        break;
                        }
                        break;
                default:
                        WM_DefaultProc(pMsg);
                        break;
        }
}

void FUN_SettingClicked(void)
{
        Setting_hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, Menu_WM_hWin, 0, 0);
        GUI_Delay(5);
}


1.页面A建立了三个按钮,按钮进入三个不同页面;
2.刚进入A页面的时候,按键ESC可以退出A页面,但是鼠标点击任何一个按钮进入页面后,然后从页面退出到A页面,按下ESC怎么都没反应,WM_KEY一直就是不响应,断点设置在WM_KEY后,按任何键都进入不到WM_KEY里面,难道被其他页面读取键值了?
回复

使用道具 举报

2

主题

13

回帖

19

积分

新手上路

积分
19
发表于 2022-10-11 16:13:59 | 显示全部楼层
这个问题我也遇到了,在官网找到了答案
[C] 纯文本查看 复制代码
hWin = GUI_CreateDialogBox(.....);
WM__ahWinFocus[0] = hWin;
回复

使用道具 举报

2

主题

13

回帖

19

积分

新手上路

积分
19
发表于 2022-10-11 16:45:32 | 显示全部楼层
关于这个问题还有个有意思的后续,我觉得跟 WM_KEY 的消息机制也有关系。我的程序希望在按 ESC 的时候在两个 dialog 中切换,于是我在 dialog 的回调函数里写了类似如下的代码
[C] 纯文本查看 复制代码
	
case WM_KEY:
		switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key)
		{
		case GUI_KEY_ESCAPE:
			GUI_EndDialog(hWin, 0);
			//GUI_Delay(1000);
			WM__ahWinFocus[0] = GUI_CreateDialogBox(_aDialogCreate0, GUI_COUNTOF(_aDialogCreate0), _cbDialog0, WM_HBKWIN, 0, 0);
			break;
                }
		break;


当我按 ESC 的时候,成功从 dialog1 切换到了 dialog2;然而,随即迅速切回了 dialog1 (我在 dialog2 的回调函数里做了同样的事情:按 ESC 切换到另外一个 dialog)。

那么,为什么会这样呢?我只按了一次 ESC,为什么新创建的 dialog2 也接收到了这个 WM_KEY 的消息?
回复

使用道具 举报

19

主题

371

回帖

428

积分

高级会员

积分
428
发表于 2022-10-12 10:33:51 | 显示全部楼层
试一下,每次操作时,清key的缓冲区
回复

使用道具 举报

2

主题

13

回帖

19

积分

新手上路

积分
19
发表于 2022-10-12 11:08:44 | 显示全部楼层
试过了,没有作用。查看了一下 ucgui 的源码,发现还是自己代码写的不好,加个判断解决了。
[C] 纯文本查看 复制代码
  case WM_KEY:
	  keyInfo = (WM_KEY_INFO*)(pMsg->Data.p);
	  if (keyInfo->PressedCnt > 0) {
		  switch (keyInfo->Key)
		  {
		  case GUI_KEY_ENTER:
			  GUI_EndDialog(hWin, 0);
			  WM__ahWinFocus[0] =
				  GUI_CreateDialogBox(_aDialogCreate1, GUI_COUNTOF(_aDialogCreate1), _cbDialog1, WM_HBKWIN, 0, 0);
			  break;
		  }
	  }
	  break;

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-10 01:41 , Processed in 0.166290 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表