Property Sheet Control Class
Brief Introduction to Property Sheet Control Class
Property Sheet control class is composed of independent property pages, and each property page has a tongue. We can click the tongue to switch between different property pages. The property pages here are the page controls that can accommodate other controls. We usually use the method similar to establishing dialog box, which is the method of defining the dialog box template, to add property page to the property sheet.
The most common purpose of property sheet control class is placing interaction content of different categories into the same dialog box by category, and displaying different content through category switch. On the one hand, it saves the space of dialog box, on the other hand, it makes it easier to use the interaction interface.
The class inheritance relation of the window and its derived class is as follows:
mPropSheet
mPropSheet
Control name:
NCSCTRL_PROPSHEET
English name:
PropSheet
Brief introduction: It is composed of multiple independent property pages. Each property page has a tongue, and switching between the property pages are carried out through the tongue.
Schematic diagram:

Style of mPropSheet
mPropSheet
It is inherited from the style of mWidget
.
Style name
miniStudio property name
Explanation
NCSS_PRPSHT_SIMPLE
style->Simple
Style of controlling the tongue width of the property page: tongues of all the property pages have the same width.
NCSS_PRPSHT_COMPACTTAB
style->Compact
Style of controlling the tongue width of the property page: tongue width of the property page is decided by the length of the title text of the property page.
NCSS_PRPSHT_SCROLLABLE
style->Scrollable
Style of controlling the tongue width of the property page: tongue width of the property page is decided by the length of the title text of the property page. When there are too many property page tongues, left and right arrows will automatically appear to adjust the currently visible property page tongue.
NCSS_PRPSHT_TOP
TabPos->Top
Style of controlling the display direction of the property page tongue in the property sheet: property page tongue is displayed on the top of the property sheet.
NCSS_PRPSHT_BOTTOM
TabPos->Bottom
Style of controlling the display direction of the property page tongue in the property sheet: property page tongue is displayed on the bottom of the property sheet.
Property of mPropSheet
mPropSheet
It is inherited from the property of mWidget
.
Property ID
miniStudio name
Type
Authority
Explanation
NCSP_PRPSHT_MINTABWIDTH
TabMinWidth
int
RW
Minimum width of the tongue
NCSP_PRPSHT_TABMARGIN
TabMargin
int
RW
Tongue boundary value. Under normal condition, the value plus the literal width is the tongue width
NCSP_PRPSHT_ACTIVEPAGE
-
mPage*
RW
Pointer of the current active page
NCSP_PRPSHT_ACTIVEPAGEIDX
ActivePageIndex
int
RW
Index of the current active page
NCSP_PRPSHT_FIRSTVIEWPAGE
-
mPage*
RO
Pointer of the currently first visible page
NCSP_PRPSHT_FIRSTVIEWPAGEIDX
-
int
RO
Index of the currently first visible page
NCSP_PRPSHT_PAGECOUNT
-
int
RO
Current property page number
Event of mPropSheet
mPropSheet
It is inherited from the event of mWidget.
Event ID
Parameter
Explanation
NCSN_PRPSHT_ACTIVECHANGED
--
The active property page has changed
Method of mPropSheet
mPropSheet
It is inherited from the method of mWidget.
Add property page
After creating property sheet control, property page can be added to the property sheet through addPage
method. dlgTemplate
of the method is used to transfer dialog box template, and handlers is used to transfer event callback handling function of the property page. Prototype of the function is as below:
mPage* addPage(mPropSheet *self, \
PDLGTEMPLATE dlgTemplate, \
const NCS_EVENT_HANDLER* handlers);
As shown in the Instance program, the codes below are utilized to add multiple property pages to the property sheet control:
PageSysInfo.controls = CtrlSysInfo;
PageSysInfo.caption = "Version Info";
PageSysInfo.dwAddData = PAGE_VERSION;
_c(propsheet)->addPage(propsheet, &PageSysInfo, mypage_handlers);
PageSysInfo.caption = "CPU Info";
PageSysInfo.dwAddData = PAGE_CPU;
_c(propsheet)->addPage(propsheet, &PageSysInfo, mypage_handlers);
PageSysInfo.caption = "MEM Info";
PageSysInfo.dwAddData = PAGE_MEMINFO;
_c(propsheet)->addPage(propsheet, &PageSysInfo, mypage_handlers);
PageSysInfo.caption = "Partition Info";
PageSysInfo.dwAddData = PAGE_PARTITION;
_c(propsheet)->addPage(propsheet, &PageSysInfo, mypage_handlers);
PageSysInfo.caption = "MiniGUI Info";
PageSysInfo.dwAddData = PAGE_MINIGUI;
_c(propsheet)->addPage(propsheet, &PageSysInfo, mypage_handlers);
Events of the property pages are handled as:
static void mypage_onInitPage(mWidget* self, DWORD add_data)
{
get_systeminfo ((mPage*)self);
}
static int mypage_onShowPage(mWidget* self, HWND hwnd, int show_cmd)
{
return 1;
}
static int mypage_onSheetCmd(mWidget* self, DWORD wParam, DWORD lParam)
{
if (wParam == IDC_REFRESH) {
get_systeminfo ((mPage*)self);
}
return 0;
}
static NCS_EVENT_HANDLER mypage_handlers[] = {
{MSG_INITPAGE, mypage_onInitPage},
{MSG_SHOWPAGE, mypage_onShowPage},
{MSG_SHEETCMD, mypage_onSheetCmd},
{0 , NULL }
};
Remove the Property Page
To remove certain property page, it is only necessary to call the removePage
or removePageByIndex
method of the property sheet control. It needs to be noted that after a property page is removed, it may change the index value of other property pages. removePage
removes the appointed page through the class pointer of the property page, and removePageByIndex
removes the appointed page through property page index.
Prototype of the function is as below:
BOOL removePageByIndex(mPropSheet *self, int pageIndex);
BOOL removePage(mPropSheet *self, mPage* page);
If you want to remove the first property page in the property sheet, you can implement the following operation:
_c(propsheet)->removePageByIndex(propsheet, 0);
Index Property Page
To get the index page class pointer of the appointed index, it is necessary to call getPageByIndex
method of property sheet control; while to get index of certain appointed property page, it is only necessary to call getPageIndex
method of property sheet control. Prototype of the function is as below:
int getPageIndex(mPropSheet *self, mPage* page);
mPage* getPageByIndex(mPropSheet *self, int pageIndex);
Such as get index of the appointed property page:
mPage *page;
... ...
_c(propsheet)->getPageIndex(propsheet, page);
Or get the class pointer of the first property page, and then operate the property page through the method of mPage control:
mPage *page = _c(propsheet)->getPageByIndex(propsheet, 0);
HWND hPanel = _c(page)->getPanel(page);
... ...
Traverse Property Page
In the property sheet control, traversal find function to all the property pages can be realized through getNextPage
and getPrevPage
method. getNextPage
is used to traverse property pages from the appointed property page towards the back; getPrevPage
is used to traverse the property pages from the appointed property page towards the front.
mPage* getNextPage(mPropSheet *self, mPage* page);
mPage* getPrevPage(mPropSheet *self, mPage* page);
For example:
mPage *page = _c(propsheet)->getNextPage(propsheet, NULL);
while (page) {
... ...
page = _c(propsheet)->getNextPage(propsheet, page);
}
Broadcast Message
Property sheet control can broadcast message to all the property pages through broadCastMsg
method. Content of the message is transmitted through param1
and param2
. When the property sheet control receives non null value returned by any property page after handling the broadcast message, the returned value of the property sheet will plus one for the index value of the property page with message broadcasting interrupted. Through this method, function operations such as invalid input processing etc. can be realized.
int broadCastMsg(mPropSheet *self, DWORD param1, DWORD param2);
Renderer of mPropSheet
mPropSheet
It is inherited from the renderer of mWidget
.
Instance of mPropSheet
mPropSheet
This Instance demonstrates how to use propsheet to display some system information of the computer to the users, such as CPU
type and memory size etc.

Figure 1 Output of propsheet Program
List 1 propsheet.c
/*
** propsheet.c: Sample program for mGNCS Programming Guide
** The demo application for PropSheet.
**
** Copyright (C) 2009 ~ 2019 FMSoft Technologies.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// START_OF_INCS
#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
#include <mgncs/mgncs.h>
// END_OF_INCS
#define PAGE_VERSION 1
#define PAGE_CPU 2
#define PAGE_MEMINFO 3
#define PAGE_PARTITION 4
#define PAGE_MINIGUI 5
#define BUF_LEN 10240
#define IDC_PROPSHEET 100
#define IDC_SYSINFO 101
#define IDC_REFRESH 102
static size_t read_sysinfo (const char* file, char* buff, size_t buf_len)
{
size_t size;
FILE *fp = fopen (file, "r");
if (fp == NULL) return 0;
size = fread (buff, 1, buf_len, fp);
fclose (fp);
return size;
}
static void get_systeminfo (mPage* page)
{
int type;
HWND hwnd;
char buff [BUF_LEN + 1];
size_t size = 0;
type = (int)GetWindowAdditionalData (page->hwnd);
hwnd = GetDlgItem(_c(page)->getPanel(page), IDC_SYSINFO);
buff [BUF_LEN] = 0;
switch (type) {
case PAGE_VERSION:
size = read_sysinfo ("/proc/version", buff, BUF_LEN);
buff [size] = 0;
break;
case PAGE_CPU:
size = read_sysinfo ("/proc/cpuinfo", buff, BUF_LEN);
buff [size] = 0;
break;
case PAGE_MEMINFO:
size = read_sysinfo ("/proc/meminfo", buff, BUF_LEN);
buff [size] = 0;
break;
case PAGE_PARTITION:
size = read_sysinfo ("/proc/partitions", buff, BUF_LEN);
buff [size] = 0;
break;
case PAGE_MINIGUI:
size = snprintf (buff, BUF_LEN,
"MiniGUI version %d.%d.%d.\n"
"Copyright (C) 1998-2009 ~ 2019 FMSoft Technologies.\n\n"
"MiniGUI is a mature, rich-featured, embedded "
"GUI support system.\n\n"
"For more information, please visit\n\n"
"http://www.minigui.com\n",
MINIGUI_MAJOR_VERSION, MINIGUI_MINOR_VERSION, MINIGUI_MICRO_VERSION);
break;
}
if (size) {
SetWindowText (hwnd, buff);
}
GetWindowText(hwnd, buff, BUF_LEN+1);
}
// START_OF_PAGEHANDLERS
static void mypage_onInitPage(mWidget* self, DWORD add_data)
{
get_systeminfo ((mPage*)self);
}
static int mypage_onShowPage(mWidget* self, HWND hwnd, int show_cmd)
{
return 1;
}
static int mypage_onSheetCmd(mWidget* self, DWORD wParam, DWORD lParam)
{
if (wParam == IDC_REFRESH) {
get_systeminfo ((mPage*)self);
}
return 0;
}
static NCS_EVENT_HANDLER mypage_handlers[] = {
{MSG_INITPAGE, mypage_onInitPage},
{MSG_SHOWPAGE, mypage_onShowPage},
{MSG_SHEETCMD, mypage_onSheetCmd},
{0 , NULL }
};
// END_OF_PAGEHANDLERS
static void btn_notify(mWidget *self, int id, int nc, DWORD add_data)
{
mPropSheet *obj =
(mPropSheet *)ncsGetChildObj(GetParent(self->hwnd), IDC_PROPSHEET);
if (obj) {
_c(obj)->broadCastMsg(obj, IDC_REFRESH, 0);
}
}
static NCS_EVENT_HANDLER btn_handlers [] = {
NCS_MAP_NOTIFY(NCSN_BUTTON_PUSHED, btn_notify),
{0, NULL}
};
static NCS_RDR_INFO btn_rdr_info[] =
{
{"classic","classic", NULL}
};
static NCS_WND_TEMPLATE _ctrl_tmpl[] = {
{
NCSCTRL_BUTTON,
IDC_REFRESH,
10, 240, 70, 25,
WS_VISIBLE | WS_TABSTOP,
WS_EX_NONE,
"Refresh",
NULL,
btn_rdr_info,
btn_handlers,
NULL,
0,
0
},
{
NCSCTRL_BUTTON,
IDCANCEL,
330, 240, 70, 25,
WS_VISIBLE | WS_TABSTOP,
WS_EX_NONE,
"Close",
NULL,
NULL,
NULL,
NULL,
0,
0
},
};
static DLGTEMPLATE PageSysInfo =
{
WS_BORDER | WS_CAPTION,
WS_EX_NONE,
0, 0, 0, 0,
"",
0, 0,
1, NULL,
0
};
static CTRLDATA CtrlSysInfo [] =
{
{
CTRL_STATIC,
WS_VISIBLE | SS_LEFT,
10, 10, 370, 180,
IDC_SYSINFO,
"test",
0
}
};
static NCS_RDR_INFO prop_rdr_info[] =
{
{"classic", "classic", NULL},
};
static int init_propsheet (mDialogBox* self)
{
// START_OF_CREATEPRPSHT
mPropSheet *propsheet =
(mPropSheet*) ncsCreateWindow (NCSCTRL_PROPSHEET,
"", WS_VISIBLE | NCSS_PRPSHT_SCROLLABLE, WS_EX_NONE,
IDC_PROPSHEET,
10, 10, 390, 225, self->hwnd,
NULL, prop_rdr_info, NULL, 0);
// END_OF_CREATEPRPSHT
if (!propsheet) {
fprintf (stderr, "Error> Create propsheet failure.\n");
return 1;
}
// START_OF_ADDPAGES
PageSysInfo.controls = CtrlSysInfo;
PageSysInfo.caption = "Version Info";
PageSysInfo.dwAddData = PAGE_VERSION;
_c(propsheet)->addPage(propsheet, &PageSysInfo, mypage_handlers);
PageSysInfo.caption = "CPU Info";
PageSysInfo.dwAddData = PAGE_CPU;
_c(propsheet)->addPage(propsheet, &PageSysInfo, mypage_handlers);
PageSysInfo.caption = "MEM Info";
PageSysInfo.dwAddData = PAGE_MEMINFO;
_c(propsheet)->addPage(propsheet, &PageSysInfo, mypage_handlers);
PageSysInfo.caption = "Partition Info";
PageSysInfo.dwAddData = PAGE_PARTITION;
_c(propsheet)->addPage(propsheet, &PageSysInfo, mypage_handlers);
PageSysInfo.caption = "MiniGUI Info";
PageSysInfo.dwAddData = PAGE_MINIGUI;
_c(propsheet)->addPage(propsheet, &PageSysInfo, mypage_handlers);
// END_OF_ADDPAGES
return 0;
}
static NCS_MNWND_TEMPLATE mymain_tmpl = {
NCSCTRL_DIALOGBOX,
1,
0, 0, 420, 305,
WS_CAPTION | WS_BORDER | WS_VISIBLE,
WS_EX_NONE,
"PropSheet Demo",
NULL,
NULL,
NULL,
_ctrl_tmpl,
sizeof(_ctrl_tmpl)/sizeof(NCS_WND_TEMPLATE),
0,
0, 0,
};
int MiniGUIMain(int argc, const char* argv[])
{
ncsInitialize();
mDialogBox* mydlg = (mDialogBox *)ncsCreateMainWindowIndirect
(&mymain_tmpl, HWND_DESKTOP);
init_propsheet(mydlg);
_c(mydlg)->doModal(mydlg, TRUE);
MainWindowThreadCleanup(mydlg->hwnd);
ncsUninitialize();
return 0;
}
<< Progress Bar Control Class | Table of Contents | Edit Box and Derived Classes >>
Last updated