EMWIN

文章目录

  • EMWIN
  • 前言
  • 一、窗口术语
  • 二、窗口回调机制
    • 1.不使用回调渲染
    • 2.使用回调渲染
    • 3.背景窗口重绘和回调
    • 4.无效化
  • 三、消息
    • 1.消息结构
    • 2.消息类型
  • 总结

前言

窗口是用户界面中最重要的部分,它是屏幕上与一个应用程序相对应的矩形区域,包括框架和客户区,是用户与产生该窗口的应用程序之间的可视界面。每当用户开始运行一个应用程序时,应用程序就创建并显示一个窗口;当用户操作窗口中的对象时,程序会作出相应反应。用户通过关闭一个窗口来终止一个程序的运行;通过选择相应的应用程序窗口来选择相应的应用程序。Emwin 同样提供了窗口管理器的
功能

一、窗口术语

使用emwin的窗口管理的时候,显示器上出现的任何内容都包含在窗口中——屏幕上的一个矩形区域,窗口可以为任何尺寸的,并且可以在一个屏幕上一次显示多个窗口,在学习窗口之前我们要先弄懂几个有关窗口的术语。
1、活动窗口——当前正用于绘制操作的窗口称为活动窗口,不一定就是最上面的窗口。
2、回调例程(回调函数)——回调例程由用户程序定义,指示在特定事件出现时图形系统调用特定的函数。它们通常用于在窗口内容更改时自动重绘窗口。
3、子窗口/父窗口,同属窗口——子窗口是相对于其他窗口(称为父窗口)定义的。只要父窗口移动,其子窗口就会相应移动。子窗口始终完全包含在其父窗口中,并在必要时会被裁剪。具有相同父窗口的多个子窗口被视为 “同属”窗口。
4、客户区——窗口的客户区就是其可用区域。如果窗口包含边框或标题栏,则客户区是内部的矩形区域。如果没有这种边框,则客户区的坐标与窗口自身的坐标相同
5、裁剪和裁剪区——裁剪是将输出限制为一个窗口或窗口一部分的过程。窗口的裁剪区域是其可见区域。它是窗口区域减去被更高 Z 轴阶层的同属窗口遮挡的区域,然后减去没有放入父窗口可见区域的任何部分。
6、坐标——坐标通常是 2 维坐标,以像素单位表示,坐标由 2 个值组成。第一个值指定水平分量(也
称为 x 坐标),第二个值指定垂直分量(也称为 y 坐标)。
7、桌面坐标——桌面坐标是桌面窗口的坐标。显示器的左上角位置(原点)为(0,0)。
8、桌面窗口——桌面窗口由窗口管理器自动创建,并且始终覆盖整个显示区域。它始终是最底层的窗口,在没有定义其他窗口时,它是默认(活动)窗口。所有窗口都是桌面窗口的后代窗口 (子窗口、
孙窗口等)
9、句柄——创建新窗口后,WM 会分配一个称为句柄的唯一标识符。句柄用于在该特定窗口中执行的
其他任何操作
10、隐藏/显示窗口——隐藏的窗口不可见,但是仍然存在(有一个句柄)。创建窗口时,如果不指定创建标记,默认情况下是隐藏的。显示窗口使其可见,隐藏窗口则使其不可见。
11、父坐标——父坐标是与父窗口相关的窗口坐标。窗口的左上角位置(原点)为 (0,0)。
12、透明性——具有透明区域的窗口包含不与窗口其余部分一起重绘的区域。这些区域就象其背后窗口
“透过”它们显示一样。在此情况下,在有透明区域的窗口之前重绘背后窗口非常重要。WM 自动按正确的顺序进行重绘
13、有效化/无效化——有效窗口是不需要重绘的完全更新窗口。无效窗口不会反映所有更新,因此需要完全或部分重绘。作出的更改影响了特定窗口时,WM 将该窗口标记为无效。下次窗口重绘时(手动或通过回调例程),将进行验证
14、窗口坐标——窗口坐标是窗口的坐标。窗口的左上角位置(原点)为 (0,0)。
15、Z位置,底部/顶部——尽管窗口显示在以 X 和 Y 表示的二维屏幕上,但是 WM 也管理所谓的 Z 位置或深度坐标 – 虚拟的第三维上的位置,该坐标确定从背景到前景的位置。各窗口因此可在其他窗口之上或之下出现。将某窗口设置为底部,会将该窗口置于其所有同属窗口 (如果有)的 “底部”;设置为顶部,则将其置于其同属窗口的 “顶部”。创建窗口时,如果不指定创建标记,默认情况下设置为顶部

二、窗口回调机制

回调机制是 EmWin 的一个重要的特性和功能,WM 可在有或无回调例程(回调函数)时使用,大多情况下最好使用回调。EmWin 为窗口和窗口对象(小工具)提供回调机制的根本概念是一个事件驱动系统。因为在大多数窗口式系统中,其原理是控制流不仅仅是从用户程序到图形系统,还要再通过用户程序提供的回调例程返回用户程序。此机制通常称为 “好莱坞原则”(“不要打电话给我们,我们会给你打电话的!”),窗口管理器需要它的主要目的是触发窗口重绘。这与传统编程相反,但是它能利用窗口管理器的无效化逻辑。

1.不使用回调渲染

回调例程不是必须使用的,但是如果这样做, WM 会失去管理窗口重绘(更新)的能力。也可能混合使用,例如让有些窗口使用回调,有些不使用。当然,如果窗口不使用回调机制,则由应用程序负责更新其内容。

2.使用回调渲染

如果要使用回调渲染的话,那么在调用函数 WM_CreateWindow()创建窗口之前必须先定义
一个回调函数,然后在调用函数 WM_CreateWindow()创建窗口的时候将这个回调函数作为参数。
回调函数原型如下:

void callback(WM_MESSAGE * pMsg);


回调函数里面具体做什么样的处理取决于接收到的消息(pMsg)的类型,一般情况下我们收到的 pMsg 里面会包含多种类型的消息,那么我们就可以使用 switch 语句来对不同的消息做出不同的处理,pMsg 里面至少会有 WM_PAINT

WM_PAINT 消息
窗口收到 WM_PAINT 消息时,应重绘自身,将此消息发送到窗口前,WM 确保它已被选定。
非透明窗口 (默认!)必须重绘其整个无效区域。
最简单的方式是重新着色窗口的整个区域。 WM 的裁剪机制确保了仅重绘无效区域。为
了加速绘制过程,仅重绘无效区域非常有用。另外,透明窗口不必重绘整个无效区域;它可让
窗口区域部分不受影响。此不受影响的区域会变成透明。WM 发送 WM_PAINT 消息到透明窗
口之前,下面的区域已经重绘(通过发送一条 WM_PAINT 消息到下面窗口)。

注意:处理 WM_PAINT 时,不得执行某些操作
处理 WM_PAINT 消息时,回调例程除了重绘窗口的内容外,不得执行其它操作。处理
WM_PAINT 事 件 时 , 下 列 函 数 不 能 调 用 : WM_SelectWindow() 、 WM_Paint() 、
WM_DeleteWindow() 和 WM_CreateWindow() 。更改窗口属性的其他任何函数也不能调用:
WM_Move() 、 WM_Resize()等等。

3.背景窗口重绘和回调

无效化窗口或窗口的一部分会告诉 WM 该窗口的无效区域在下次调用 GUI_Exec() 或GUI_Delay()时应重绘。emWin 的无效化例程不会重绘窗口的无效部分,只管理窗口的无效区域。

4.无效化

无效化窗口或窗口的一部分会告诉 WM 该窗口的无效区域在下次调用 GUI_Exec() 或GUI_Delay()时应重绘。emWin 的无效化例程不会重绘窗口的无效部分,只管理窗口的无效区域。
窗口的无效区域
对于每个窗口,WM 只使用一个矩形来存储包含整个无效区域的最小矩形。例如,如果左上角的一小部分和右下角的一小部分变为无效,则整个窗口即无效。
使用无效化的原因
使用窗口无效化而非立即重绘每个窗口的优点是只绘制窗口一次,即使其被无效化多次。例如,如果窗口的多个属性需要更改(如背景颜色、字体和窗口大小),与所有属性都更改后重绘一次窗口相比,每个属性更改后立即重绘窗口需要更多的次数。
重绘无效窗口
函数 GUI_Exec() 重绘所有无效窗口,这通过向每个无效窗口发送一条或多条 WM_PAINT消息完成。
渲染透明窗口
如果需要绘制透明窗口,则 WM 会自动确保在透明窗口收到 WM_PAINT 消息前绘制窗口的背景。方法为,在向透明窗口发送 WM_PAINT 消息前,首先重绘透明窗口无效区域下面的所有窗口区域。为确保窗口管理器能执行透明窗口的重绘,有必要响应 WM_PAINT 消息并重绘窗口,否则,不能保证透明窗口的外观是正确的。使用透明窗口比使用不透明窗口需要更多消耗 CPU。如果需要考虑性能问题,尝试避免使用透明窗口或许是一个选择
自动使用存储设备
窗口管理器的默认特性是向每个需要重绘的窗口发送一条 WM_PAINT,这会导致闪变效应,为抑制这些每个窗口的闪变效应, 可为重绘操作自动使用存储设备。 方法为,在创建窗口时设置标记 WM_CF_MEMDEV、使用函数 WM_SetCreateFlags() 设置默认创建标记,或使用函数 WM_EnableMemdev()。WM 然后会将 WM_PAINT 消息输出重定向到存储设备中,再复制到显示器中。如果整个窗口的内存不够,会自动使用分段,存储设备只是临时使用,在绘制操作完成后会移除。

三、消息

在窗口的回调函数中根据不同的消息相应的做出不同的处理

1.消息结构

回调例程被调用时,它会收到以其 pMsg 参数指定的消息,此消息实际上是一个WM_MESSAGE 数据结构,如下所示:

struct WM_MESSAGE
{int MsgId; WM_HWIN hWin; WM_HWIN hWinSrc; union
{const void * p; int v;GUI_COLOR Color;} Data;
}

2.消息类型

系统定义的消息
WM_CREATE
窗口创建后立即发送,使窗口可以初始化并创建任何子窗口。
WM_DELETE
要删除窗口前发送,告诉窗口释放其数据结构(如果有)
WM_GET_ID 发送到窗口,请求窗口的 Id
WM_INIT_DIALOG 创建对话框后立即发送到对话框窗口。
WM_KEY 按下某个键后发送到当前包含焦点的窗口。
WM_MOVE 窗口移动后立即发送到窗口。
WM_NOTIFY_PARENT 告知父窗口,其子窗口中发生了某些改变。
WM_NOTIFY_VIS_CHANGED 窗口可见性更改时发送到窗口。
WM_PAINT 窗口变为无效并应重绘时,发送到窗口。
WM_POST_PAINT 最后一条 WM_PAINT 消息处理后发送到窗口
WM_PRE_PAINT 第一条 WM_PAINT 消息发出前发送到窗口
WM_SET_FOCUS 获得或失去输入焦点时发送到窗口。
WM_SET_ID 发送到窗口以更改窗口 Id。
WM_SIZE 窗口大小更改后发送到窗口。
WM_TIMER 定时器到期后发送到窗口。
指针输入设备(PID)消息
WM_MOUSEOVER
指针输入设备接触到窗口轮廓时发送到窗口,仅在启用鼠标支持时发送。
WM_MOUSEOVER_END
指针输入设备已移出窗口轮廓时发送到窗口。仅在启用鼠标支持时发送。
WM_PID_STATE_CHANGED
按下状态已更改时,发送到指针输入设备指向的窗口。
WM_TOUCH
指针输入设备接触到处于按下状态的窗口轮廓时发送到窗口。
WM_TOUCH_CHILD 指针输入设备已接触到子窗口时发送到父窗口。
通知代码
WM_NOTIFICATION_CHILD_DELETED
此通知消息将在某窗口被删除前,从该窗口发
送到其父窗口。
WM_NOTIFICATION_CLICKED 此通知消息将在点击窗口后发送。
WM_NOTIFICATION_LOST_FOCUS 此通知消息将在窗口失去焦点时发送。
WM_NOTIFICATION_MOVED_OUT 此通知消息将在指针移出窗口并点击时发送。
WM_NOTIFICATION_RELEASED
此通知消息将在被点击的小工具已被释放时发送。
WM_NOTIFICATION_SCROLL_CHANGED
此通知消息将在附加的 SCROLLBAR(滚动条)小工具的滚动位置更改时发送。
WM_NOTIFICATION_SCROLLBAR_ADDED 此通知消息在将
WM_NOTIFICATION_SEL_CHANGED 此通知消息将在小工具选择已更改时发送。
WM_NOTIFICATION_VALUE_CHANGED
此通知消息将在小工具的特定值已更改时发送。用户定义的消息
WM_USER
应用程序可使用 WM_USER 常数来定义私人消息,通常形式为 WM_USER+X,其中 X 为整数值。

总结

这一节是一些重要的基础知识,api函数和案例在下一节。

STM32——EMWIN窗口管理(九)相关推荐

  1. STM32——EMWIN窗口小工具(十三)

    EMWIN 文章目录 EMWIN 前言 一.小工具基础知识 二. 如何使用小工具 1.重绘机制 2.小工具的使用 三.通用控件 API 函数 1.用于控件的 WM 函数 2.常用 API 函数 3._ ...

  2. STEMWIN窗口管理学习

    STEMWIN窗口管理学习 STEMWIN窗口管理学习 什么是窗口管理 窗口管理的一些理解 窗口管理一些API 窗口管理的结构体,消息列表 窗口重绘 一些窗口管理的例子 STEMWIN窗口管理学习 本 ...

  3. STM32笔记--电源管理

    为什么STM32需要电源管理: 在很多应用场合,对电子设备的功耗要求非常苛刻.如某些传感器信息采集设备,仅靠小型的电池提供电源,要求工作长达数年之久,且期间不需要任何维护.为此,大多数 MCU 都会提 ...

  4. Android窗口管理服务WindowManagerService计算窗口Z轴位置的过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8570428 通过前面几篇文章的学习,我们知道了 ...

  5. Android窗口管理服务WindowManagerService计算Activity窗口大小的过程分析

    在Android系统中,Activity窗口的大小是由WindowManagerService服务来计算的.WindowManagerService服务会根据屏幕及其装饰区的大小来决定Activity ...

  6. wpf窗口向左向上_PaperWM:GNOME 下的平铺窗口管理

    我使用 Gnome 已有很长时间了,但是我仍然有点想念平铺窗口管理器.六个月前,一个朋友告诉我有关 PaperWM 的消息,它使你可以在 Gnome 中平铺窗口!我立即安装了它,并从那时起我一直在使用 ...

  7. [转][android深入学习]android窗口管理机制

    在学习 WindowManager 接口的时候,了解到这个接口很重要,因为它可以直接与Window Manager(窗口管理器)进行交互,那这个 Window Manager 究竟是怎么一回事呢? 通 ...

  8. android窗口管理机制

    在学习 WindowManager 接口的时候,了解到这个接口很重要,因为它可以直接与Window Manager(窗口管理器)进行交互,那这个 Window Manager 究竟是怎么一回事呢? 通 ...

  9. IDEA不能一个窗口管理多个项目?那是你不会用!

    你身边有没有这样的Eclipse用户吐槽IDEA:"不能一个窗口管理多个项目!太不方便了!" 对于一个窗口同时管理多个项目的需求,在我们日常开发时候是经常需要的.尤其当我们在分布式 ...

最新文章

  1. retinaface 训练笔记
  2. SQLite学习手册(C/C++接口简介)
  3. RSA算法原理——(2)RSA简介及基础数论知识
  4. Hotstar赛事直播编码组合优化
  5. 小米10解锁bl跳过168_2021年小米红米手机官方解锁BL详细教程+跳过168小时方法合集...
  6. 挑战程序设计竞赛 (秋叶拓哉 / 岩田阳一 / 北川宜稔 著)
  7. python实现栈的操作入站出站查找元素等_Python实现的栈(Stack)
  8. android 7.0 解锁亮屏,Android7.0亮屏流程分析
  9. VS Code编译Python
  10. 思科无线路由EA6500代理服务器,思科EA6500路由器怎样设置
  11. 戴尔电脑开机卡logo无法开机问题及解决办法
  12. 共享计算机用户帐户限制怎么办,win7系统使用共享功能被提示用户账户限制的解决方法...
  13. 刘宇凡:新型鸡汤如何击溃传统鸡汤?
  14. 二进制炸弹实验binarybomb 拆弹
  15. 统治IT行业的定律-安迪-比尔定律
  16. 机器人控制算法四之迭代法求解四轴机器人逆解
  17. Linux下搭建ESP-IDF 开发环境教程,适合ESP32/S2/C3/S3系列模组二次开发
  18. ‘DatePicker.RangePicker‘ cannot be used as a JSX component.
  19. 【Abp VNext】实战入门(四):Windows系统服务制作
  20. 《企业级大数据平台构建:架构与实现》阅读总结

热门文章

  1. 如何阅读AUTOSAR官方文档
  2. 关于Kingst VIS 显示内存不足的解决方案
  3. Java 多行字符串
  4. java基础6 面向对象的详解
  5. 在荷兰男人为了公益涂指甲油 为了响应一位绝症男孩的愿望
  6. Socket通信C#项目,完整的服务端和客户端
  7. Eclipse JavaWeb 关于Servlet的部分笔记
  8. hdu 5100 数学几何题
  9. 如何恢复台式计算机出厂设置,如何在Lenovo台式计算机上恢复出厂设置?
  10. Handler msg用法