Monday, October 23rd 2017, 8:45pm UTC+2

You are not logged in.

  • Login
  • Register

Date of registration: Jun 9th 2017

Posts: 7

1

Sunday, June 25th 2017, 2:12pm

Dropwdown Event WM_NOTIFICATION_CLICKED not received

Hey, i'd like to create a dropdown. SO i used the GUI Builder to create the skeleton code.

My idea is: when the user presses the dropdown the list is supposed to expand, when the user presses somewhere outside the dropdown, the list should collapse.

Now i'm only receiving WM_NOTIFICATION_LOST_FOCUS events in my callback routine. The Event WM_NOTIFICATION_CLICKED never occurs. Does anybody know why?


Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/*********************************************************************
 *                                                                	*
 *            	SEGGER Microcontroller GmbH & Co. KG            	*
 *    	Solutions for real time microcontroller applications    	*
 *                                                                	*
 **********************************************************************
 *                                                                	*
 * C-file generated by:                                           	*
 *                                                                	*
 *    	GUI_Builder for emWin version 5.32                      	*
 *    	Compiled Oct  8 2015, 11:59:02                          	*
 *    	(c) 2015 Segger Microcontroller GmbH & Co. KG           	*
 *                                                                	*
 **********************************************************************
 *                                                                	*
 *    	Internet: www.segger.com  Support: support@segger.com   	*
 *                                                                	*
 **********************************************************************
 */

// USER START (Optionally insert additional includes)
#include "FramewinDLG_new.h"
#include "cmsis_os.h"
// USER END

/*********************************************************************
 *
 *   	Defines
 *
 **********************************************************************
 */
#define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
#define ID_DROPDOWN_0 (GUI_ID_USER + 0x04)

// USER START (Optionally insert additional defines)
///Maximale Breite des Displays
#define X_MAX 240

///Maximale Höhe des Displays
#define Y_MAX 320

//
// Recommended memory to run the sample with adequate performance
//
#define RECOMMENDED_MEMORY (1024L * 2)

// USER END

/*********************************************************************
 *
 *   	Static data
 *
 **********************************************************************
 */

// USER START (Optionally insert additional static data)
// USER END
/*********************************************************************
 *
 *   	_aDialogCreate
 */
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =
	{
		{ FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, X_MAX, Y_MAX, 0, 0x0, 0 },
		{ DROPDOWN_CreateIndirect, "Dropdown_menu", ID_DROPDOWN_0, 0, 0, 144, 25, 0, 0x0, 0 },
	// USER START (Optionally insert additional widgets)
	// USER END
		};

/*********************************************************************
 *
 *   	Static code
 *
 **********************************************************************
 */

// USER START (Optionally insert additional static code)
// USER END
/*********************************************************************
 *
 *   	_cbDialog
 */
static void _cbDialog(WM_MESSAGE * pMsg)
{

	//TODO weg
	volatile uint8_t test = 0;

	WM_HWIN hItem;
	int NCode;
	int Id;
	// USER START (Optionally insert additional variables)
	// USER END

	switch (pMsg->MsgId)
	{
	case WM_INIT_DIALOG:
		//
		// Initialization of 'Dropdown_menu'
		//
		hItem = WM_GetDialogItem(pMsg->hWin, ID_DROPDOWN_0);
		DROPDOWN_SetFont(hItem, GUI_FONT_20_1);
		DROPDOWN_AddString(hItem, "Show Menue");
		DROPDOWN_AddString(hItem, "Show Ike");
		DROPDOWN_AddString(hItem, "Show Sensor Values");
		// USER START (Optionally insert additional code for further widget initialization)
		// USER END
		break;
	case WM_NOTIFY_PARENT:

		test++;
		test += 11;
		test -= 9;
		Id = WM_GetId(pMsg->hWinSrc);
		NCode = pMsg->Data.v;
		switch (Id)
		{
		case ID_DROPDOWN_0: // Notifications sent by 'Dropdown_menu'
			switch (NCode)
			{
			case WM_NOTIFICATION_CLICKED:
				// USER START (Optionally insert code for reacting on notification message)
				hItem = WM_GetDialogItem(pMsg->hWin, ID_DROPDOWN_0);

				test++;
				test += 4;
				test--;

				DROPDOWN_Expand(hItem);
				// USER END
				break;
			case WM_NOTIFICATION_RELEASED:
				// USER START (Optionally insert code for reacting on notification message)
				// USER END
				break;
			case WM_NOTIFICATION_SEL_CHANGED:
				// USER START (Optionally insert code for reacting on notification message)
				// USER END
				break;
				// USER START (Optionally insert additional code for further notification handling)
			case WM_NOTIFICATION_LOST_FOCUS:

				// USER START (Optionally insert code for reacting on notification message)
				hItem = WM_GetDialogItem(pMsg->hWin, ID_DROPDOWN_0);

				test++;
				test += 4;
				test--;

				DROPDOWN_Collapse(hItem);

				// USER END
			}
			break;
			// USER START (Optionally insert additional code for further Ids)
			// USER END
		}
		break;
		// USER START (Optionally insert additional message handling)
		// USER END
	default:
		WM_DefaultProc(pMsg);
		break;
	}
}

/*********************************************************************
 *
 *   	Public code
 *
 **********************************************************************
 */
/*********************************************************************
 *
 *   	CreateFramewin
 */
WM_HWIN CreateFramewin_new(void)
{
	WM_HWIN hWin;

	//
	// Check if recommended memory for the sample is available
	//
	if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY)
	{
		GUI_ErrorOut("Not enough memory available.");
		return 0;
	}

	hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
	return hWin;
}

// USER START (Optionally insert additional public code)
// USER END

/*************************** End of file ****************************/


my display thread looks like this

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void DisplayThread(void const * argument)
{

	//Display Init.
	GUI_Init();


	CreateFramewin_new();

   

	const size_t nMax = 32;
	uint8_t * touchcoords[nMax];

	for (;;)
	{




		snprintf((char *) touchcoords, nMax, "X: %04d, Y: %04d", touchX, touchY);
		GUI_DispStringAt((char *) touchcoords, 0, 0);

		WM_Exec();

		osDelay(500);

	}
}


The GUI_TOUCH_StoreStateEx() is called in a separate thread every 25ms to get the newest touched coordinates (that part works, since i'm receiving events)

Now my question is, how can i expand the dropdown list when pressing on it?

Thx for your help :)

SEGGER - Schoenen

Super Moderator

Date of registration: Aug 13th 2015

Posts: 389

2

Monday, July 10th 2017, 3:36pm

Hi,

I tested you application but it caused a crash because of an endless loop generated with the functions DROPDOWN_Expand/Collapse(). Below is the application slightly changed. Now the DROPDOWN widget closes if anywhere outside the widget a pressed event occures.

C/C++ Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include "DIALOG.h"

/*********************************************************************
*
*	Defines
*
**********************************************************************
*/
#define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
#define ID_DROPDOWN_0 (GUI_ID_USER + 0x04)

// USER START (Optionally insert additional defines)
///Maximale Breite des Displays
#define X_MAX 240

///Maximale Höhe des Displays
#define Y_MAX 320

/*********************************************************************
*
*	Static data
*
**********************************************************************
*/
/*********************************************************************
*
*	_aDialogCreate
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, X_MAX, Y_MAX, 0, 0x0, 0 },
  { DROPDOWN_CreateIndirect, "Dropdown_menu", ID_DROPDOWN_0, 0, 0, 144, 80, 0, 0x0, 0 },
};

static WM_HWIN _hDropDown;

/*********************************************************************
*
*	Static code
*
**********************************************************************
*/

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

  switch (pMsg->MsgId) {
  case WM_INIT_DIALOG:
	//
	// Initialization of 'Dropdown_menu'
	//
	_hDropDown = hItem = WM_GetDialogItem(pMsg->hWin, ID_DROPDOWN_0);
	DROPDOWN_SetFont(hItem, GUI_FONT_20_1);
	DROPDOWN_AddString(hItem, "Show Menue");
	DROPDOWN_AddString(hItem, "Show Ike");
	DROPDOWN_AddString(hItem, "Show Sensor Values");
	break;
  case WM_NOTIFY_PARENT:
	Id = WM_GetId(pMsg->hWinSrc);
	NCode = pMsg->Data.v;
	switch (Id)
	{
	case ID_DROPDOWN_0: // Notifications sent by 'Dropdown_menu'
  	switch (NCode) {
  	case WM_NOTIFICATION_CLICKED:
    	break;
  	case WM_NOTIFICATION_RELEASED:
    	break;
  	case WM_NOTIFICATION_SEL_CHANGED:
    	break;
  	case WM_NOTIFICATION_LOST_FOCUS:
    	break;
  	}
  	break;
	}
	break;
  default:
	WM_DefaultProc(pMsg);
	break;
  }
}

/*********************************************************************
*
*	CreateFramewin
*/
static void _PidHook(GUI_PID_STATE * pState) {
  WM_HWIN hListBox;

  //
  // Check if pState is not a null pointer
  //
  if (pState) {
	//
	// Get the LISTBOX attached to the dropdown, if it not 0 the DROPDOWN is expansed
	//
	hListBox = DROPDOWN_GetListbox(_hDropDown);
	if (hListBox) {
  	//
  	// If PID is pressed..
  	//
  	if (pState->Pressed) {
    	//
    	// .. and the window under the input is not the DROPDOWN
    	// or the LISTBOX widget, close the DROPDOWN.
    	//
    	if ((hListBox   != WM_Screen2hWin(pState->x, pState->y)) &&
        	(_hDropDown != WM_Screen2hWin(pState->x, pState->y))) {
      	DROPDOWN_Collapse(_hDropDown);
    	}
  	}
	}
  }
}

/*********************************************************************
*
*	Public code
*
**********************************************************************
*/
/*********************************************************************
*
*	CreateFramewin
*/
WM_HWIN CreateFramewin_new(void) {
  WM_HWIN hWin;

  hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
  return hWin;
}

/*********************************************************************
*
*   	Public code
*
**********************************************************************
*/
void MainTask(void) {
  GUI_Init();
  CreateFramewin_new();
  GUI_PID_SetHook(_PidHook);
  while(1) {
	GUI_Delay(1000);
  }
}


In WM_INIT_DIALOG we remember the handle of the DROPDOWN widget and check in _PidHook if the input is outside the DROPDOWN widget and outside the attached LISTBOX widget.
After setting the _PidHook function it gets called each time a new PID input gets passed to emWin.

Depending on the emWin version you are using the function GUI_PID_SetHook() might not be available (it was introduced with version 5.38). If this the case try to call GUI_PID__SetHook() instead (it works almost the same but gets called after the PID input is passed to emWin).

Regards,
Sven

Date of registration: Jun 9th 2017

Posts: 7

3

Sunday, July 16th 2017, 11:14pm

hey
big thx for your great help. :)
I have been working with your solution this weekend and it works very well. :D
Based on your solution i was able to implement my own menu.
I couldn't figure out, what emWin Version ST is using, but it didn't support GUI_PID_SetHook(), but GUI_PID__SetHook() works fine as well :)

SEGGER - Schoenen

Super Moderator

Date of registration: Aug 13th 2015

Posts: 389

4

Wednesday, July 19th 2017, 4:57pm

Hi,

to get the emWin version search for GUI_Version.h. In that file is a define like:

#define GUI_VERSION 54011

The version above would V5.40k.

Regards,
Sven

Date of registration: Jun 9th 2017

Posts: 7

5

Thursday, July 20th 2017, 10:30pm

hey,
thx for the info :)
ST uses #define GUI_VERSION 53202 =>V5.32.
Seems like a rather old version :|

mrohit2011

Beginner

Date of registration: Jul 1st 2017

Posts: 16

6

Wednesday, September 13th 2017, 4:15pm

Hi Sven,

I am also facing the same issue, I just tested the code modified by you. But still i am facing the same issue.
Please find the screen shot of call stack window in the attachment.

Also One more interesting thing is if I Add string of character size i.e. "Fe","Zn","Al".. and check the dropdown , it does not crashes.
But when i increase the size more than 2 chars i.e. Fe_Steel, Zn_Si.... it crashes.

Please help ....

Thanks and Best Regards,
Rohit.
mrohit2011 has attached the following image:
  • call_stack_dropdown_crash.jpg

mrohit2011

Beginner

Date of registration: Jul 1st 2017

Posts: 16

7

Friday, September 15th 2017, 7:41am

I am not able to solve this problem....
If anyone faced the same issue pls reply.....

Date of registration: Jun 9th 2017

Posts: 7

8

Friday, September 15th 2017, 6:21pm

why are you getting a task exit error?
Are you using an RTOS? If so could you check if a task accidentally breaks out of his loop.
For me i took the code posted above and it works really nicely. I did not make any big adjustments :thumbup:
The only adjustment i made was: since i'm using an RTOS i canot use GUI_DELAY(). I had to use the RTOS own delay function in combination with GUI_EXEC();
Both (GUI_EXEC() and the delay function are called in a separate task :)

mrohit2011

Beginner

Date of registration: Jul 1st 2017

Posts: 16

9

Saturday, September 16th 2017, 9:01am

i am using freeRtos.

"why are you getting a task exit error?"
The Scheduler is checking for any task exit error before context switch.



When DROPDOWN_Expand is called the program crashes. This is due to some memory locking issue ?


When i tested this condition with stm32f429 stemwin library it is working fine. But there is some issue with stm32f7 stemwin library......?

Is there any work around to get rid of the lockout condition....?

Thanks and Best Regards,
Rohit

Date of registration: Jun 9th 2017

Posts: 7

10

Sunday, September 17th 2017, 10:24pm

Just to clarify. You simply replaced the Stemwin library file (aka the libStemWin****.a file) from the Stm32F7 Cube Package with the library file from the STM32F4 Cube package?
The code is the same?

You MUST NOT use GUI_DELAY() with an RTOS. i'm not sure what exactly GUI_DELAY internally does, but it is always better to use the RTOS own task delay functions, i.e. osDelay (delay in ms) or vTaskDelay(delay in ticks).


I once made the bad fault to use HAL_DELAY() in a freertos project, the scheduler did not like that :P

Use GUI_Exec and osDelay()/vTaskDelay() instead.

Note: Use vTaskDelay if your task has been created using FreeROS Functions, use osDelay if your task has been created using the CMSIS FreeRtos API. :thumbup:

This post has been edited 4 times, last edit by "JuliusCaesar" (Sep 17th 2017, 10:53pm)


SEGGER - Schoenen

Super Moderator

Date of registration: Aug 13th 2015

Posts: 389

11

Tuesday, September 19th 2017, 9:11am

Hi,

@mrohit2011
How much memory did you spend emWin (GUI_ALLOC_AssignMemory() in the function GUI_X_Config()), try to increase the amount of memory.

@JuliusCaesar
Of course it is allowed to call GUI_Delay() with a RTOS. A GUI_Delay() performs all required operations to keep the GUI 'alive' (like checking for touch, check for timer, updating any windows, etc) beside of that it also calles a delay of the RTOS. Of course, this works only if it configured correctly. Check the functions below if they are implemented correctly:

GUI_X_GetTime()
GUI_X_Delay()
GUI_X_ExecIdle()

Attached are some sample implementation for different RTOS.

Regards,
Sven
SEGGER - Schoenen has attached the following file:
  • GUI_X.zip (8.27 kB - 23 times downloaded - Last download: Today, 1:57pm)