硬汉嵌入式论坛

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

[emWin教程入门篇] 【STemWin教程】第38章 控件基础知识

[复制链接]

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
发表于 2015-2-15 20:04:22 | 显示全部楼层 |阅读模式
特别说明:完整STemWin的1-60期教程和配套实例下载地址:链接
第38章 控件基础知识

    本期教程开始给大家讲控件方面的知识,这部分知识主要来自官方手册。
    控件是具有对象类型属性的各种窗口,是组成用户界面的元素。它们可自动对某些事件作出反应;例如,按下某按钮后,它可以不同状态显示。小工具需要创建,具有可在存续期间随时更改的属性,并通常在不再需要时被删除。正如窗口一样,小工具通过其创建函数返回的句柄进行引用。
    控件要求使用窗口管理器。控件创建后,可像其他任何窗口一样处理它;WM确保了在必要时随时正确显示 (并重绘)它。控件不是编写应用程序或用户界面所必需的,但它们可大大简化编程。
    38. 1 当前支持的控件
    38. 2 控件的重绘机制
    38. 3 如何使用控件
    38. 4 控件配置选项
    38. 5 通用控件API
    38. 6 常用函数
    38. 7 总结

38.1 当前支持的控件
    这部分内容在前面1.3.6小节已经有讲解了,这里就是给大家提示一下。

38.2 控件的重绘机制
     控件根据其属性绘制自身,此操作在调用WM_Exec()、GUI_Exec()或GUI_Delay()时执行。在多任务环境中,通常由后台任务来调用WM_Exec()并更新控件(以及所有其他具有回调函数的窗口)。
    控件的属性更改后,该控件的窗口 (或部分窗口)会被标记为无效,但不会立即重绘。因此,代码段的执行速度会非常快。重绘由WM在稍后执行,或者通过为该小工具调用WM_Paint()强制执行(或直到重绘所有窗口时调用WM_Exec())。

38.3 如何使用控件
    假设我们要显示一个进度条。所需的只是以下代码:
PROGBAR_Handle hProgBar;
GUI_DispStringAt(&quotrogress bar", 100, 20);
hProgBar = PROGBAR_Create(100, 40, 100, 20, WM_CF_SHOW);
38.1.png
    其中第一行为控件的句柄保留内存,最后一行实际创建该控件。稍后或者在某单独任务中调用WM_Exec()时,窗口管理器会自动绘制此控件。每种类型的控件都有若干能够修改其外观的成员函数。控件创建后,可通过调用其成员函数之一更改其属性。这些函数使用控件的句柄作为第一个自变量。要使上述创建的进度条显示45%并将条颜色从默认设置 (深灰/浅灰)更改为绿色/红色,可使用以下代码段:
PROGBAR_SetBarColor(hProgBar, 0, GUI_GREEN);
PROGBAR_SetBarColor(hProgBar, 1, GUI_RED);
PROGBAR_SetValue(hProgBar, 45);
38.2.png

38.3.1 默认配置
    所有控件都还具有一个或多个配置宏,它们定义各种默认设置 (如所使用的字体和颜色)。在后面讲解到这些控件的时候再跟大家详细讲解。

38.3.2 控件如何通讯
     控件通常作为子窗口创建,父窗口可为任何窗口类型,甚至是另一种控件。为了确保同步,无论何时父窗口的任何子项有任何事件发生,通常都应通知父窗口。有事件发生时,子窗口控件通过发送WM_NOTIFY_PARENT消息与其父窗口通信。作为消息一部分发送的通知代码取决于事件。大多数控件都有定义不同类型事件的一个或多个通知代码,每种控件可用的通知代码 (如果有)会在后面的教程中给大家列出。

38.3.3 皮肤设置
    控件的外观可使用其各自的成员函数进行修改,其中一些支持皮肤设置。如果对某控件使用了皮肤设置,则 “皮肤”将决定该控件的外观,且一些成员函数将失效。这个会在后面专门抽一章节跟大家讲。

38.3.4 控件的动态内存使用
    在嵌入式应用中,由于分裂效应,通常都不太希望使用动态内存。可使用许多不同策略来避免此情况,但只要内存区域被应用程序中的指针引用,这些策略的使用都有局限性。因此,emWin使用不同的方法:所有对象 (以及运行时存储的所有数据)都存储在被句柄引用的内存区域中。这使它能够在运行时重新分配已分配的内存区域,因此避免了使用指针时会发生的长期分配问题。所以所有控件都使用句柄引用。

38.3.5 确定控件的类型
    没有像WM_GetWidgetType()一样的函数来确定控件的类型,其类型仅可通过将特定控件的回调函数与控件API的公共回调函数进行比较来确定。在回调函数未被覆盖时此方法很有效。如下所示为如何确定控件类型的简短示例。如果回调函数被覆盖,则应相应调整方法:
    WM_CALLBACK * pCb = WM_GetCallback(hWidget);
    if (pCb == BUTTON_Callback) {
    /* Widget is a button */
    } else if (pCb == DROPDOWN_Callback) {
    /* Widget is a dropdown */
    } else if (pCb == LISTBOX_Callback) {
    /* Widget is a listbox */
    } else if (...) {
    ...
    }

38.4 控件配置选项

默认值
描述

WIDGET_USE_PARENT_EFFECT

0

设置为1时,控件的每个子控件都具有与其父控件相同的效果。例如,如果列表框需要创建一个滚动条,则新滚动条具有与列表框相同的效果。

WIDGET_USE_SCHEME_LARGE

0

设置为1时,控件的默认外观为大尺寸。这意味着所有显示文本的控件都配置为使用大尺寸的默认字体。

WIDGET_USE_SCHEME_MEDIUM

0

设置为1时,控件的默认外观为中等尺寸。这意味着所有显示文本的控件都配置为使用中等尺寸的默认字体

WIDGET_USE_SCHEME_SMALL

1

设置为1时,控件的默认外观为小尺寸。这意味着所有显示文本的控件都配置为使用小尺寸的默认字体。

WIDGET_USE_FLEX_SKIN

0

设置为1时,默认使用Flex皮肤来绘制控件。

WIDGET_USE_SCHEME_XXX显示的效果如下:
38.3.png
38.4.png


38.5 通用控件API
     由于控件质上就是窗口,所以它们与任何窗口管理器API例程都兼容。窗口的句柄用作hWin参数,且窗口的处理方式与其他任何窗口都相同。最常用于控件的WM函数如下所列:

例程

描述

WM_DeleteWindow()

删除窗口。

WM_DisableMemdev()

禁止使用存储设备进行重绘。

WM_EnableMemdev()

启用存储设备用于重绘。

WM_InvalidateWindow()

使窗口无效。

WM_Paint()

立即绘制或重绘窗口。


38.6 常用函数
    下面是控件中常用的函数:

例程

描述

<WIDGET>_Callback()

默认回调函数。

<WIDGET>_CreateIndirect()

用于对话框中的自动创建。

<WIDGET>_CreateUser()

使用额外字节作为用户数据创建小工具。

<WIDGET>_GetUserData()

检索用<WIDGET>_SetUserData设置的数据。

<WIDGET>_SetUserData()

设置小工具的额外数据。

WIDGET_GetDefaultEffect()

返回用于小工具的默认效果。

WIDGET_SetDefaultEffect()

设置用于小工具的默认效果。

WIDGET_SetEffect()

设置用于给定小工具的效果。

这里咱们重点说其中的两个函数,这两个在以后的项目中用的最多,其它的几个函数大家可以看用户手册进行了解。

38.6.1 <WIDGET>_CreateIndirect()函数
    这个函数在前面的几期教程中使用的非常多,在对话框中创建控件主要的就是用这个函数。任何控件都可使用适宜的前缀间接创建。例如:
        BUTTON_CreateIndirect()    可间接创建一个按钮控件,
        CHECKBOX_CreateIndirect()  可间接创建一个复选框控件,等等。
    仅在控件要被包含在对话框中时,才需要间接创建它。否则,可使用<WIDGET>_Create()函数直接创建它。
GUI_WIDGET_CREATE_INFO数据结构在对话框资源表中定义如下:
typedef struct {
    GUI_WIDGET_CREATE_FUNC * pfCreateIndirect; // Create function
    const char * pName; // Text (not used for all widgets)
    I16 Id; // Window ID of the widget
    I16 x0, y0, xSize, ySize; // Size and position of the widget
    I16 Flags; // Widget-specific flags (or 0)
    I32 Para; // Widget-specific parameter (or 0)
    U32 NumExtraBytes; // Number of extra bytes usable
                                  // with <WIDGET>_SetUserData &
                                 // <WIDGET>_GetUserData
} GUI_WIDGET_CREATE_INFO;
控件标记和参数是可选的,并随控件类型不同而不同。

38.6.2 WIDGET_SetDefaultEffect()函数
    通过这个函数可以设置控件的三种状态,效果如下:
38.5.png

    这里有一点要注意,如果大家设置控件的皮肤,那么设置这三种状态是无效的。

38.7 总结
    对于本期教程,大家要了解这些基本的知识,在后面的学习中,我们会用到。懂得这些知识,在后面学习控件的时候会事半功倍。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

0

主题

19

回帖

0

积分

新手上路

积分
0
QQ
发表于 2016-10-23 10:24:09 | 显示全部楼层
[s:152]  [s:151]  [s:150]  [s:149]  [s:146]  [s:147]  [s:148]  [s:144]  [s:143]  [s:142]  [s:141]  [s:138]  [s:139]  [s:140]
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-23 16:59 , Processed in 0.244979 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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