Emwin: Window Manager Widgets
Emwin: Window Manager Widgets
Emwin: Window Manager Widgets
Window Manager
Widgets
Document: AN03002
Revision: 1
Date: April 22, 2016
www.segger.com
2
Disclaimer
Specifications written in this document are believed to be accurate, but are not guar-
anteed to be entirely free of error. The information in this manual is subject to
change for functional or performance improvements without notice. Please make sure
your manual is the latest edition. While the information herein is assumed to be
accurate, SEGGER Microcontroller GmbH & Co. KG (SEGGER) assumes no responsibil-
ity for any errors or omissions. SEGGER makes and you receive no warranties or con-
ditions, express, implied, statutory or in any communication with you. SEGGER
specifically disclaims any implied warranty of merchantability or fitness for a particu-
lar purpose.
Copyright notice
You may not extract portions of this manual or modify the PDF file in any way without
the prior written permission of SEGGER. The software described in this document is
furnished under a license and may only be used or copied in accordance with the
terms of such a license.
© 2016 SEGGER Microcontroller GmbH & Co. KG, Hilden / Germany
Trademarks
Names mentioned in this manual may be trademarks of their respective companies.
Brand and product names are trademarks or registered trademarks of their respec-
tive holders.
Contact address
SEGGER Microcontroller GmbH & Co. KG
In den Weiden 11
D-40721 Hilden
Germany
Tel.+49 2103-2878-0
Fax.+49 2103-2878-28
E-mail: support@segger.com
Internet: http://www.segger.com
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
3
Manual versions
This manual describes the current software version. If any error occurs, inform us
and we will try to assist you as soon as possible.
Contact us for further information on topics or routines not yet specified.
Print date: April 22, 2016
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
4
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
5
Assumptions
This document assumes that you already have a solid knowledge of the following:
• The software tools used for building your application (assembler, linker, C com-
piler)
• The C programming language
• The target processor
• DOS command line
If you feel that your knowledge of C is not sufficient, we recommend The C Program-
ming Language by Kernighan and Richie (ISBN 0-13-1103628), which describes the
standard in C-programming and, in newer editions, also covers the ANSI C standard.
How to use this manual
This manual explains all the functions and macros that the product offers. It assumes
you have a working knowledge of the C language. Knowledge of assembly program-
ming is not required.
Typographic conventions for syntax
This manual uses the following typographic conventions:
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
6
emFile
File system
emFile is an embedded file system with
FAT12, FAT16 and FAT32 support. Vari-
ous Device drivers, e.g. for NAND and
NOR flashes, SD/MMC and Compact-
Flash cards, are available.
USB-Stack
USB device/host stack
A USB stack designed to work on any
embedded system with a USB control-
ler. Bulk communication and most stan-
dard device classes are supported.
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
7
Table of Contents
1 Introduction ......................................................................................................................9
1.1 Requirements.......................................................................................... 10
1.2 Overview ................................................................................................ 10
3 Example implementation................................................................................................21
3.1 Sample description .................................................................................. 22
3.2 Internal source code ................................................................................ 22
3.3 End user application................................................................................. 25
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
8
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
9
Chapter 1
Introduction
This document is intended to give a short and simple description on how to imple-
ment a custom emWin widget. This guide deals with an example implementation of a
button. The used functions are explained by their meaning as it is necessary to
understand the context.
A complete function reference can be found in the according chapter in the emWin
user manual, which can be downloaded at www.segger.com.
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
10 CHAPTER 1 Introduction
1.1 Requirements
In order to be able to use this document it is required to have a licensed copy of
emWin. This guide is written for emWin V5.20, but might be used for later versions
as well. Knowledge of the used emWin functions is not required, since cross-refer-
ences to the according function descriptions in the emWin user manual are included.
1.2 Overview
The actual task when implementing a custom widget is to provide the end user with
the following:
• Create()-function which returns a handle to the created widget and allows setting
callback function.
• Set()- and Get()-functions to request and set widget specific properties.
• Callback()-function to process messages which were sent to the custom widget.
In the following chapters the custom function are prefixed MYWIDGET_. These func-
tion are the ones which are meant to be used by the end user.
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
11
Chapter 2
This chapter describes how to implement a custom type of widget. This includes a
function to create the widget, a function to handle messages and functions to set and
get widget specific properties.
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
12 CHAPTER 2 Creating a custom widget type
2.1 Requirements
Since widgets are actually windows with enhanced functionality, it is required to cre-
ate a window with capabillities to store additional data. Depending on the actual type
of widget implemented, it is a good practice to add further parameters to the proto-
type of the Create() function in order to force the user to set up the widget correctly
from creation.
If a button widget has to be implemented and it is a requirement to define the text to
be displayed on the button, a pointer to a string may be added to the prototype.
WM_HWIN MYWIDGET_Create(int x0, int y0, int xSize, int ySize, WM_HWIN hWinParent,
U32 Style, WM_CALLBACK * pfCallback, int NumExtraBytes) {
WM_HWIN hWin;
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
13
typedef struct {
U8 Pressed;
GUI_COLOR aBkColor[3];
GUI_COLOR aTextColor[3];
GUI_COLOR FocusColor;
const char * pText;
int NumExtraBytes;
} MYWIDGET_Obj;
The background and text colors were declared as arrays, so the state of the widget
can be distinguished by its visual appearance. In later sections, the following defines
are used to access the color arrays according to the current state of the widget.
#define MYWIDGET_CI_UNPRESSED 0
#define MYWIDGET_CI_PRESSED 1
#define MYWIDGET_CI_DISABLED 2
Warning: The end user must not use the function WM_GetUserData() or
WM_SetUserData() with a widget of a custom type as it is imple-
mented using this guide, since the user would either overwrite widget
specific data, or not retrieve the expected data.
Therefore custom functions for these purposes have to be implemented as shown in
the following:
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
14 CHAPTER 2 Creating a custom widget type
MYWIDGET_GetUserData()
Function description
Copies the given number of bytes of user data to the destination buffer.
Implementation
int MYWIDGET_GetUserData(MYWIDGET_Handle hWin, void * pDest, int SizeOfBuffer) {
MYWIDGET_Obj MyWidget;
int NumBytes;
U8 * pExtraBytes;
if (SizeOfBuffer <= 0) {
return 0;
}
WM_GetUserData(hWin, &MyWidget, sizeof(MYWIDGET_Obj));
pExtraBytes = (U8 *)malloc(sizeof(MYWIDGET_Obj) + MyWidget.NumExtraBytes);
if (pExtraBytes) {
WM_GetUserData(hWin, pExtraBytes,
sizeof(MYWIDGET_Obj) + MyWidget.NumExtraBytes);
if (SizeOfBuffer >= MyWidget.NumExtraBytes) {
NumBytes = MyWidget.NumExtraBytes;
} else {
NumBytes = SizeOfBuffer;
}
GUI_MEMCPY(pDest, pExtraBytes + sizeof(MYWIDGET_Obj), NumBytes);
free(pExtraBytes);
return NumBytes;
}
return 0;
}
Parameter Description
hWin Handle to the Widget.
pDest Pointer to the destination buffer.
SizeOfBuffer Size of the destination buffer.
Table 2.1: MYWIDGET_GetUserData() parameter list
Return value
Number of copied bytes.
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
15
MYWIDGET_SetUserData()
Function description
Sets the given number of bytes of the source buffer as user data.
Implementation
int MYWIDGET_SetUserData(MYWIDGET_Handle hWin, void * pSrc, int SizeOfBuffer) {
MYWIDGET_Obj MyWidget;
int NumBytes;
U8 * pExtraBytes;
if (SizeOfBuffer <= 0) {
return 1;
}
WM_GetUserData(hWin, &MyWidget, sizeof(MYWIDGET_Obj));
pExtraBytes = (U8 *)malloc(sizeof(MYWIDGET_Obj) + MyWidget.NumExtraBytes);
if (pExtraBytes) {
WM_GetUserData(hWin, pExtraBytes,
sizeof(MYWIDGET_Obj) + MyWidget.NumExtraBytes);
if (SizeOfBuffer >= MyWidget.NumExtraBytes) {
NumBytes = MyWidget.NumExtraBytes;
} else {
NumBytes = SizeOfBuffer;
}
GUI_MEMCPY(pExtraBytes + sizeof(MYWIDGET_Obj), pSrc, NumBytes);
WM_SetUserData(hWin, pExtraBytes,
sizeof(MYWIDGET_Obj) + MyWidget.NumExtraBytes);
free(pExtraBytes);
return 0;
}
return 1;
}
Parameter Description
hWin Handle to the Widget.
pSrc Pointer to the source buffer.
SizeOfBuffer Size of the source buffer.
Table 2.2: MYWIDGET_SetUserData() parameter list
Return value
0, on success.
1, on error.
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
16 CHAPTER 2 Creating a custom widget type
These values are used when the widget is created. The function MYWIDGET_Create()
changes as follows:
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
17
if (pfCallback) {
pfUsed = pfCallback;
} else {
pfUsed = MYWIDGET_Callback;
}
hWin = WM_CreateWindowAsChild(x0, y0, xSize, ySize, hWinParent, Style,
pfUsed, sizeof(MYWIDGET_Obj) + NumExtraBytes);
MyWidget = MYWIDGET_Default;
MyWidget.NumExtraBytes = NumExtraBytes;
if (pText) {
MyWidget.pText = pText;
}
WM_SetUserData(hWin, &MyWidget, sizeof(MYWIDGET_Obj));
return hWin;
}
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
18 CHAPTER 2 Creating a custom widget type
hWin = pMsg->hWin;
//
// Get the window coordinates and widget specific data
//
WM_GetWindowRectEx(hWin, &WinRect);
GUI_MoveRect(&WinRect, -WinRect.x0, -WinRect.y0);
WM_GetUserData(hWin, &MyWidget, sizeof(MYWIDGET_Obj));
switch (pMsg->MsgId) {
case WM_PAINT:
//
// Determine the color according to the current state
//
if (WM_IsEnabled(hWin)) {
if (MyWidget.Pressed) {
ColorIndex = MYWIDGET_CI_PRESSED;
} else {
ColorIndex = MYWIDGET_CI_UNPRESSED;
}
} else {
ColorIndex = MYWIDGET_CI_DISABLED;
}
//
// Draw the background
//
GUI_SetColor(MyWidget.aBkColor[ColorIndex]);
GUI_FillRectEx(&WinRect);
//
// Draw the focus rectangle
//
if (WM_HasFocus(hWin)) {
GUI_SetColor(MyWidget.FocusColor);
GUI_DrawRectEx(&WinRect);
}
//
// Display the text.
//
GUI_SetColor(MyWidget.aTextColor[ColorIndex]);
GUI_SetTextMode(GUI_TM_TRANS);
GUI_DispStringInRect(MyWidget.pText, &WinRect, GUI_TA_HCENTER | GUI_TA_VCENTER);
break;
default:
WM_DefaultProc(pMsg);
}
}
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
19
At this point the code can be run and the widget can be recognized as a rectangle on
the screen. Since this is going to be a button, one may expect a change when it is
clicked, but nothing happens. The reason is that the variable MyWidget.Pressed is
never changed, so the widget is drawn the same way regardless the pressed state. In
order to update the state, it is required to react to the message WM_TOUCH:
hWin = pMsg->hWin;
WM_GetWindowRectEx(hWin, &WinRect);
GUI_MoveRect(&WinRect, -WinRect.x0, -WinRect.y0);
WM_GetUserData(hWin, &MyWidget, sizeof(MYWIDGET_Obj));
switch (pMsg->MsgId) {
case WM_PAINT:
if (WM_IsEnabled(hWin)) {
if (MyWidget.Pressed) {
ColorIndex = MYWIDGET_CI_PRESSED;
} else {
ColorIndex = MYWIDGET_CI_UNPRESSED;
}
} else {
ColorIndex = MYWIDGET_CI_DISABLED;
}
GUI_SetColor(MyWidget.aBkColor[ColorIndex]);
GUI_FillRectEx(&WinRect);
if (WM_HasFocus(hWin)) {
GUI_SetColor(MyWidget.FocusColor);
GUI_DrawRectEx(&WinRect);
}
GUI_SetColor(MyWidget.aTextColor[ColorIndex]);
GUI_SetTextMode(GUI_TM_TRANS);
GUI_DispStringInRect(MyWidget.pText, &WinRect, GUI_TA_HCENTER | GUI_TA_VCENTER);
break;
case WM_TOUCH:
if (pMsg->Data.p) {
pState = (GUI_PID_STATE *)pMsg->Data.p;
if (MyWidget.Pressed != pState->Pressed) {
MyWidget.Pressed = pState->Pressed;
WM_SetUserData(hWin, &MyWidget, sizeof(MYWIDGET_Obj));
if (MyWidget.Pressed) {
WM_SetFocus(hWin);
}
WM_InvalidateWindow(hWin);
}
} else {
MyWidget.Pressed = 0;
WM_SetUserData(hWin, &MyWidget, sizeof(MYWIDGET_Obj));
WM_InvalidateWindow(hWin);
}
break;
default:
WM_DefaultProc(pMsg);
}
}
The additional code retrieves the PID state which is sent along with the WM_TOUCH-
message and sets the user data accordingly. After updating the widget specific data
the widget is invalidated in order to receive a new WM_PAINT-message.
When running this code clicking the widget will cause the color to change. Neverthe-
less the focus rectangle is not drawn, although the function WM_SetFocus() is called
when the widget receives a pressed PID state. The reason for this behavior is that
the widget never "accepts" the focus. To do so the callback function needs to react to
the WM_SET_FOCUS-message as shown below:
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
20 CHAPTER 2 Creating a custom widget type
hWin = pMsg->hWin;
WM_GetWindowRectEx(hWin, &WinRect);
GUI_MoveRect(&WinRect, -WinRect.x0, -WinRect.y0);
WM_GetUserData(hWin, &MyWidget, sizeof(MYWIDGET_Obj));
switch (pMsg->MsgId) {
case WM_PAINT:
if (WM_IsEnabled(hWin)) {
if (MyWidget.Pressed) {
ColorIndex = MYWIDGET_CI_PRESSED;
} else {
ColorIndex = MYWIDGET_CI_UNPRESSED;
}
} else {
ColorIndex = MYWIDGET_CI_DISABLED;
}
GUI_SetColor(MyWidget.aBkColor[ColorIndex]);
GUI_FillRectEx(&WinRect);
if (WM_HasFocus(hWin)) {
GUI_SetColor(MyWidget.FocusColor);
GUI_DrawRectEx(&WinRect);
}
GUI_SetColor(MyWidget.aTextColor[ColorIndex]);
GUI_SetTextMode(GUI_TM_TRANS);
GUI_DispStringInRect(MyWidget.pText, &WinRect, GUI_TA_HCENTER | GUI_TA_VCENTER);
break;
case WM_TOUCH:
pState = (GUI_PID_STATE *)pMsg->Data.p;
if (MyWidget.Pressed != pState->Pressed) {
MyWidget.Pressed = pState->Pressed;
WM_SetUserData(hWin, &MyWidget, sizeof(MYWIDGET_Obj));
if (MyWidget.Pressed) {
WM_SetFocus(hWin);
}
WM_InvalidateWindow(hWin);
}
break;
case WM_SET_FOCUS:
if (pMsg->Data.v) {
pMsg->Data.v = 0;
}
WM_InvalidateWindow(hWin);
break;
default:
WM_DefaultProc(pMsg);
}
}
pMsg->Data.v = 1 means that the widget receives the focus. In order to let the Win-
dow Manager "know" that the focus was accepted, the value has to be set to 0. Oth-
erwise the focus is not received. Once the widget gains or loses the focus, it should
be invalidated so the appearance changes accordingly, if it is intended to do so.
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
21
Chapter 3
Example implementation
This chapter shows an example application, which includes the complete source code
which was explained in the previous chapter as well as the usage of a custom user
callback function and user data. Additionally a BUTTON widget is used to make the
change of the focus recognizable.
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
22 CHAPTER 3 Example implementation
/*********************************************************************
*
* Color indices
*/
#define MYWIDGET_CI_UNPRESSED 0
#define MYWIDGET_CI_PRESSED 1
#define MYWIDGET_CI_DISABLED 2
/*********************************************************************
*
* Typedef
*/
typedef WM_HMEM MYWIDGET_Handle;
/*********************************************************************
*
* MYWIDGET_Obj
*/
typedef struct {
U8 Pressed;
GUI_COLOR aBkColor[3];
GUI_COLOR aTextColor[3];
GUI_COLOR FocusColor;
const char * pText;
int NumExtraBytes;
} MYWIDGET_Obj;
/*********************************************************************
*
* MYWIDGET_Default
*/
const MYWIDGET_Obj MYWIDGET_Default = {
0,
{ GUI_DARKBLUE, GUI_LIGHTBLUE, GUI_GRAY },
{ GUI_WHITE, GUI_DARKGRAY, GUI_LIGHTGRAY },
GUI_ORANGE,
NULL,
0
};
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
23
/*********************************************************************
*
* MYWIDGET_Callback
*/
void MYWIDGET_Callback(WM_MESSAGE * pMsg) {
MYWIDGET_Handle hWin;
GUI_PID_STATE * pState;
MYWIDGET_Obj MyWidget;
GUI_RECT WinRect;
int ColorIndex;
hWin = pMsg->hWin;
WM_GetWindowRectEx(hWin, &WinRect);
GUI_MoveRect(&WinRect, -WinRect.x0, -WinRect.y0);
WM_GetUserData(hWin, &MyWidget, sizeof(MYWIDGET_Obj));
switch (pMsg->MsgId) {
case WM_PAINT:
if (WM_IsEnabled(hWin)) {
if (MyWidget.Pressed) {
ColorIndex = MYWIDGET_CI_PRESSED;
} else {
ColorIndex = MYWIDGET_CI_UNPRESSED;
}
} else {
ColorIndex = MYWIDGET_CI_DISABLED;
}
GUI_SetColor(MyWidget.aBkColor[ColorIndex]);
GUI_FillRectEx(&WinRect);
if (WM_HasFocus(hWin)) {
GUI_SetColor(MyWidget.FocusColor);
GUI_DrawRectEx(&WinRect);
}
GUI_SetColor(MyWidget.aTextColor[ColorIndex]);
GUI_SetTextMode(GUI_TM_TRANS);
GUI_DispStringInRect(MyWidget.pText, &WinRect, GUI_TA_HCENTER | GUI_TA_VCENTER);
break;
case WM_TOUCH:
if (pMsg->Data.p) {
pState = (GUI_PID_STATE *)pMsg->Data.p;
if (MyWidget.Pressed != pState->Pressed) {
MyWidget.Pressed = pState->Pressed;
WM_SetUserData(hWin, &MyWidget, sizeof(MYWIDGET_Obj));
if (MyWidget.Pressed) {
WM_SetFocus(hWin);
}
WM_InvalidateWindow(hWin);
}
} else {
MyWidget.Pressed = 0;
WM_SetUserData(hWin, &MyWidget, sizeof(MYWIDGET_Obj));
WM_InvalidateWindow(hWin);
}
break;
case WM_SET_FOCUS:
if (pMsg->Data.v) {
pMsg->Data.v = 0;
}
WM_InvalidateWindow(hWin);
break;
default:
WM_DefaultProc(pMsg);
}
}
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
24 CHAPTER 3 Example implementation
/*********************************************************************
*
* MYWIDGET_GetUserData
*/
int MYWIDGET_GetUserData(MYWIDGET_Handle hWin, void * pDest, int SizeOfBuffer) {
MYWIDGET_Obj MyWidget;
int NumBytes;
U8 * pExtraBytes;
if (SizeOfBuffer <= 0) {
return 0;
}
WM_GetUserData(hWin, &MyWidget, sizeof(MYWIDGET_Obj));
pExtraBytes = (U8 *)malloc(sizeof(MYWIDGET_Obj) + MyWidget.NumExtraBytes);
if (pExtraBytes) {
WM_GetUserData(hWin, pExtraBytes,
sizeof(MYWIDGET_Obj) + MyWidget.NumExtraBytes);
if (SizeOfBuffer >= MyWidget.NumExtraBytes) {
NumBytes = MyWidget.NumExtraBytes;
} else {
NumBytes = SizeOfBuffer;
}
GUI_MEMCPY(pDest, pExtraBytes + sizeof(MYWIDGET_Obj), NumBytes);
free(pExtraBytes);
return NumBytes;
}
return 0;
}
/*********************************************************************
*
* MYWIDGET_SetUserData
*/
int MYWIDGET_SetUserData(MYWIDGET_Handle hWin, void * pSrc, int SizeOfBuffer) {
MYWIDGET_Obj MyWidget;
int NumBytes;
U8 * pExtraBytes;
if (SizeOfBuffer <= 0) {
return 1;
}
WM_GetUserData(hWin, &MyWidget, sizeof(MYWIDGET_Obj));
pExtraBytes = (U8 *)malloc(sizeof(MYWIDGET_Obj) + MyWidget.NumExtraBytes);
if (pExtraBytes) {
WM_GetUserData(hWin, pExtraBytes,
sizeof(MYWIDGET_Obj) + MyWidget.NumExtraBytes);
if (SizeOfBuffer >= MyWidget.NumExtraBytes) {
NumBytes = MyWidget.NumExtraBytes;
} else {
NumBytes = SizeOfBuffer;
}
GUI_MEMCPY(pExtraBytes + sizeof(MYWIDGET_Obj), pSrc, NumBytes);
WM_SetUserData(hWin, pExtraBytes,
sizeof(MYWIDGET_Obj) + MyWidget.NumExtraBytes);
free(pExtraBytes);
return 0;
}
return 1;
}
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
25
/*********************************************************************
*
* MYWIDGET_Create
*/
MYWIDGET_Handle MYWIDGET_Create(int x0, int y0, int xSize, int ySize,
WM_HWIN hWinParent, U32 Style, const char * pText,
WM_CALLBACK * pfCallback, int NumExtraBytes) {
MYWIDGET_Handle hWin;
MYWIDGET_Obj MyWidget;
WM_CALLBACK * pfUsed;
if (pfCallback) {
pfUsed = pfCallback;
} else {
pfUsed = MYWIDGET_Callback;
}
MyWidget = MYWIDGET_Default;
MyWidget.NumExtraBytes = NumExtraBytes;
if (pText) {
MyWidget.pText = pText;
}
hWin = WM_CreateWindowAsChild(x0, y0, xSize, ySize, hWinParent, Style,
pfUsed, sizeof(MYWIDGET_Obj) + NumExtraBytes);
WM_SetUserData(hWin, &MyWidget, sizeof(MYWIDGET_Obj));
return hWin;
}
switch (pMsg->MsgId) {
case WM_PAINT:
MYWIDGET_Callback(pMsg);
MYWIDGET_GetUserData(pMsg->hWin, acText, sizeof(acText));
GUI_SetColor(GUI_WHITE);
GUI_SetTextMode(GUI_TM_TRANS);
WM_GetWindowRectEx(pMsg->hWin, &WinRect);
GUI_MoveRect(&WinRect, -WinRect.x0, -WinRect.y0);
GUI_DispStringInRect(acText, &WinRect, GUI_TA_HCENTER | GUI_TA_VCENTER);
break;
default:
MYWIDGET_Callback(pMsg);
}
}
/*********************************************************************
*
* MainTask
*/
void MainTask(void) {
MYWIDGET_Handle hMyWidget;
char acExtraBytes[] = "Extrabytes";
GUI_Init();
hMyWidget = MYWIDGET_Create(10, 10, 100, 50, WM_HBKWIN, WM_CF_SHOW, NULL,
_cbMyWidget, strlen(acExtraBytes));
MYWIDGET_SetUserData(hMyWidget, acExtraBytes, strlen(acExtraBytes));
BUTTON_Create(10, 100, 100, 50, 0, WM_CF_SHOW);
while (1) {
GUI_Delay(100);
}
}
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
26 CHAPTER 3 Example implementation
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
27
Index
Symbols N
_cbMyWidget ......................................25 NumExtraBytes ................................... 13
C O
Callback function .................................17 Overview ........................................... 10
Callback mechanism .............................18
Color indices .......................................22 R
Creating the window ............................12
Requirements ................................ 10, 12
Custom widget type .............................11
S
D
Sample description .............................. 22
Default properties ................................16 Syntax, conventions used ....................... 5
E T
emWin user manual .............................. 9
Typedef ............................................. 22
End user .............................................13
typedef .............................................. 12
End user application .............................25
Example implementation ......................21
W
G Widget handle .................................... 12
Widget specific callback function ........... 18
GUI_PID_STATE ..................................19 Widget specific data ............................ 13
WM_CreateWindowAsChild ................... 12
I WM_GetUserData ................................ 13
Internal source code ............................22 WM_HMEM ......................................... 12
Introduction ......................................... 9 WM_PAINT ......................................... 18
WM_SET_FOCUS ................................. 18
M WM_SetUserData ................................ 13
WM_TOUCH ....................................... 18
MainTask ............................................25
www.segger.com ................................... 9
Mandatory properties ...........................17
MYWIDGET_Callback ...................... 18, 23
MYWIDGET_CI_DISABLED .............. 13, 18
MYWIDGET_CI_PRESSED ................ 13, 18
MYWIDGET_CI_UNPRESSED ............ 13, 18
MYWIDGET_Create ................... 12–13, 25
MYWIDGET_Default ........................ 16, 22
MYWIDGET_GetUserData ................ 14, 24
MYWIDGET_Handle ..............................12
MYWIDGET_Obj ............................. 13, 22
MYWIDGET_SetUserData ................ 15, 24
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG
28 Index
AN03002 Custom Widget Type Creation Guide © 2016 SEGGER Microcontroller GmbH & Co. KG