Files
minigui-docs/programming-guide-zh/MiniGUIProgGuidePart2Chapter04-zh.md
lisimeng123 045211f6c4 add
2022-11-17 09:47:52 +08:00

666 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 基础类介绍
## 1 `mObject`
### 1.1 `mObject` 介绍
`mObject` 是所有 mGNCS 的基础类,它:
* 封装了 mGNCS 继承和虚函数实现
* 定义了最基本的类成员结构
同时,定义了一组类操作函数,以控制类的行为
__该类为基础类不能直接使用__
* 直接子类:
* `mComponent`
### 1.2 `mObject` 操作函数
在 NCS 中,诸多关于类的操作都是以 `mObject` 指针为参数,这些有
* 类型判断操作: `ncsInstanceOf`, 相当于 java 的 `instanceof` 操作符,判断一个指针是否是指定的类的实例
```c
/**
* \fn BOOL ncsInstanceOf(mObject* object, mObjectClass* clss);
* \brief check an object is the class instance or not,
* same as \b instanceof operator in Java
*
* \param object - the pointer of object being to test
* \param clss - the pointer of class for test
*
* \return TRUE - object is instance of clss, FALSE - not
*/
BOOL ncsInstanceOf(mObject* object, mObjectClass* clss);
```
为方便操作,提供宏
```c
#define INSTANCEOF(obj, clss) \
ncsInstanceOf((mObject*)(obj), \
(mObjectClass*)(void*)(&Class(clss)))
```
使用举例
```c
if(INSTANCEOF(obj, mWidget)) //判断对象obj是否是一个mWidget对象
.....
```
另外,为判断一个指针是否是 `mObject` 对象,可以使用 `ncsIsValidObj`
```c
/**
* \fn static inline mObject* ncsIsValidObj(mObject* obj);
* \brief Check a pointer is a valid mObject or not
*
* \param obj - the excpeted object pointer
*
* \return mObject * the pointer of obj or other NULL if obj is an invalid mObject pointer
*/
static inline mObject* ncsIsValidObj(mObject* obj){
return (INSTANCEOF(obj, mObject)?(obj):NULL);
}
```
对应的宏是
```c
/**
* \def CHECKOBJ
* \brief the wrapper of ncsIsValidObj
*
* \sa ncsIsValidObj
*/
#define CHECKOBJ(obj) ncsIsValidObj((mObject*)obj)
```
* 类型转换操作 : `ncsSafeCast`, 安全的类型转换,类似 C++ 的 `dynamic_cast` 操作符
```c
/**
* \fn mObject* ncsSafeCast(mObject* obj, mObjectClass *clss);
* \brief safe type cast function, like the \b dynamic_cast operator in C++
*
* \param obj - the mObject pointer being casted
* \param clss - the target type to cast
*
* \return mObject * - the object pointer if cast safe, NULL otherwise
*
* \sa ncsInstanceOf
*/
mObject* ncsSafeCast(mObject* obj, mObjectClass *clss);
```
对应的宏是
```c
/**
* \def SAFE_CAST
* \brief wrapper of ncsSafeCast, check the class type before cast.
*
* \note this macro is same as \b dynamic_cast in C++
*
* \sa ncsSafeCast
*/
#define SAFE_CAST(Type, obj) \
TYPE_CAST(Type, ncsSafeCast((mObject*)obj,(mObjectClass*)(void*)(&(Class(Type)))))
```
使用举例
```c
//将一个obj转为mWidget指针
mWidget * widget = SAFE_CAST(mWidget, obj);
//如果obj是一个mWidget类型或者mWidget子类类型则转换成功否则widget == NULL
if(widget)
....
```
* 其他函数 : `newObject`, `deleteObject`, `TYPENAME` 宏。
```c
/**
* \fn mObject * newObject(mObjectClass *_class);
* \brief new a object instance, like \b new operator in C++
*
* \param _class - the class of the object
*
* \return the new pointer of object
*
*/
mObject * newObject(mObjectClass *_class);
/**
* \fn void deleteObject(mObject *obj);
* \brief delete a object intance, like \b delete operator in C++
*
* \param obj - the object want to delete
*
*/
void deleteObject(mObject *obj);
/**
* \def TYPENAME
* \brief Get the class name form a Object pointer
*/
#define TYPENAME(obj) ((obj)?(((obj)->_class)?((obj)->_class)->typeName:""):"")
```
创建一个对象,要用 `newObject`,因为它会调用对象的构造函数。
删除一个对象,要使用 `deleteObject`,因为他会调用对象的析构函数。
## 2 `mComponent`
### 2.1 `mComponent` 介绍
`mComponent` 提供了组件最基本的实现。组件是构成 mGNCS 程序最基本的原件
__该类为基础类不能直接使用__
* 继承自: `mObject`
* 直接子类
* `mWidget`
* `mInvsbComp`
### 2.2 `mComponent` 方法
* `setProperty`
```c
BOOL (*setProperty)(clss *_this, int id, DWORD value);
```
* * 设置组件的属性
* Return : `TRUE` -- 设置成功;`FALSE`--设置失败
* Params
* int id - 属性的 ID
* `DWORD` value - 属性值
* `getProperty`
```c
DWORD (*getProperty)(clss *_this, int id);
```
* * 获取组件的属性
* Return: 属性值或者 `DWORD(-1)`
* Params
* int id - 属性 ID
* `setId`
```c
int (*setId)(clss *_this, int id);
```
* * 设置组件的 Id
* Return : 返回老的 Id
* Params
* int id - new id
* `getId`
```c
int (*getId)(clss *_this);
```
* * 获取组件 Id
* Return : 组件 Id
* `getReleated`
```c
mComponent* (*getReleated)(clss*_this, int releated);
```
* * 取得和该组件相关的组件,例如父组件,子组件和兄弟组件
* Return : `NULL` 或者对应的组件对象指针
* Params:
* int releated: 关系类型 :`NCS_COMP_NEXT` , `NCS_COMP_PREV` , `NCS_COMP_PARENT` , `NCS_COMP_CHILDREN` 之一
* `setReleated`:
```c
mComponent* (*setReleated)(clss *_this, mComponent* comp, int releated);
```
* * 设置关联组件
* Return : 设置后的关联组件指针如果没有设置成功返回NULL
* Params
* `mComponent` *comp - 被设置的组件指针
* int releated - 同 `getReletaed`
* `getChild`
```c
mComponent* (*getChild)(clss* _this, int id);
```
* * 获取id指定的子组件
* Return : `NULL` 或者对应的组件指针
* Params:
* int id - 要获取的组件的 id
### 2.3 `mComponent` 操作函数
Component 支持一些通用的操作
* 事件安装和卸载函数
```c
/**
* A struct of event-handler map
*
* \note only used for param
*
* \sa NCS_EVENT_HANDLER_NODE
*/
typedef struct _NCS_EVENT_HANDLER {
/**
* The event code
*/
int message;
/**
* The event callback pointer
*/
void *handler;
}NCS_EVENT_HANDLER;
/**
* \fn void * ncsSetComponentHandler(mComponent* comp, int message, void *handler);
* \brief set the component handler
*
* \param comp the compont to set
* \param message the event code
* \param handler the event callback pointer
*
* \return old event callback if it has been set
*
* \sa ncsSetComponentHandlers
*/
void * ncsSetComponentHandler(mComponent* comp, int message, void *handler);
/**
* \fn void ncsSetComponentHandlers(mComponent* comp, \
NCS_EVENT_HANDLER* handlers, \
int count);
* \brief set an array of event handlers
*
* \param comp - the component to set
* \param handlers - the array of \ref NCS_EVENT_HANDLER
* \param count - the count of array handlers.
*
* \note if count == -1, handlers must end by {-1, NULL};
* anywhere, ncsSetComponentHandlers would stop
* if it find an element of array handlers is equal {-1, NULL},
* whether count is equal -1 or not
*
* \sa ncsSetComponentHandler
*/
void ncsSetComponentHandlers(mComponent* comp, \
NCS_EVENT_HANDLER* handlers, \
int count);
/**
* \fn void* ncsGetComponentHandler(mComponent* comp, int message);
* \brief get an event callback
*
* \param comp
* \param message - event code
*
* \return void * the handler of message, or NULL if not set
*/
void* ncsGetComponentHandler(mComponent* comp, int message);
```
* 注册相关函数
```c
/**
* \fn BOOL ncsRegisterComponent(mComponentClass *compCls, \
DWORD dwStyle, \
DWORD dwExStyle, \
int idCursor, \
int idBkColor);
* \brief register a component class into MiniGUI, so that \ref ncsCreateWindow and
* \ref ncsCreateWindow can find a \mComponentClass instance
*
* \param compCls the \ref mComponentClass to be registered
* \param dwStyle the default style
* \param dwExStyle the default extend style
* \param idCursor the default cursor
* \param idBkColor the default background color
*
* \return TRUE - success, FALSE - failed
*
* \sa ncsGetComponentClass, ncsCreateWindow,
* ncsCreateWindowIndirect, ncsCreateMainWindow,
* ncsCreateMainWindowIndirect
*/
BOOL ncsRegisterComponent(mComponentClass *compCls, \
DWORD dwStyle, \
DWORD dwExStyle, \
int idCursor, \
int idBkColor);
/**
* \fn mComponentClass * ncsGetComponentClass(const char* class_name, BOOL check);
* \brief Get a \ref mComponentClass instance from MiniGUI
*
* \note the class_name must be registered into MiniGUI by calling ncsRegisterComponent
*
* \param class_name the class name to find
* \param check check the class name with found mComponentClass instance,
* to ensure that we found the right class
*
* \return the mComponentClass pointer if sucess, NULL otherwise
*/
mComponentClass * ncsGetComponentClass(const char* class_name, BOOL check);
```
## 3 `mWidget`
### 3.1 `mWidget` 介绍
`mWidget` 是所有控件的基础类
* 继承自: `mComponent`
* 直接子类
* `mStatic`
* `mButton`
* `mPanel`
* `mScrollWidget`
* `mProgressBar`
* `mPropSheet`
* `mSlider`
* `mSpinbox`
### 3.2 `mWidget` 风格
| 风格 ID | mStudio 属性名 | 说明 |
|:--------------|:--------------|:-----|
| `NCSS_NOTIFY` | Notify | 决定控件是否产生 Notification 事件 |
### 3.3 `mWidget` 属性
| 属性名 | mStudio 属性名 | 类型 | RW | 说明 |
|:---------------------------|:--------------|:--------------|:-----|:-------|
| `NCSP_WIDGET_RDR` | Renderer | `const char*` | W | 设置控件当前渲染器 |
| `NCSP_WIDGET_TEXT` | Text | `const char*` | W | 设置当前控件的文本内容 |
| `NCSP_WIDGET_BKIMAGE` | `BkImage` | `PBITMAP` | `RW` | 设置或获取当前背景图片 |
| `NCSP_WIDGET_BKIMAGE_MODE` | `BkImageMode` | [ImageDrawMode](programming-guide-zh/MiniGUIProgGuideAppendixC-zh.md) | 设置或者获取当前背景图片绘制模式 | |
| `NCSP_WIDGET_BKIMAGE_FILE` | - | `const char*` | 设置当前背景图片,自动从文件名加载 | |
### 3.4 `mWidget` 方法
### 3.5 `mWidget` 事件
* `MSG_NCCREATE`
* 描述: 当窗口非客户区创建时。窗口的第一个消息, 此时窗口尚未建成,以窗口句柄为参数的函数不能调用
* 回调: void (* NCS_CB_ONNCCREATE)(mWidget *);
* 返回值: 无
* 参数
* `mWidget` * 事件产生者对象指针
* `MSG_CREATE`
* 描述: 当窗口创建时产生。
* 回调: typedef BOOL(*) NCS_CB_ONCREATE (mWidget *, DWORD dwAddData)
* 返回值: `TRUE` - 继续创建了;`FALSE` - 退出创建
* 参数
* mWidget *
* DWORD dwAddData 附加数据
* 通知消息
* 所有通知消息产生的事件都使用该回调
* void (* NCS_CB_NOTIFY)(mWidget *, int nc_code);
* 返回值: 无
* 参数
* `mWidget` * 事件产生者对象指针
* int nc_code : 事件通知码,用于区别不通的事件
__注所有通知事件的回调都是 `NCS_CB_NOTIFY`__
### 3.6 `mWidget` 操作函数
* 创建控件的函数
```c
/**
* A struct wrap the NCS_CREATE_INFO
*
* \note only allowed using in \ref ncsCreateMainWindow
* Don't use it directly
*
* \sa NCS_CREATE_INFO, ncsCreateMainWindow , ncsCreateMainWindowIndirect
*/
typedef struct _NCS_MAIN_CREATE_INFO {
/**
* The class name of a mMainWnd or its child class
*
* \note if className is NULL or an invalidate class name
* \ref ncsCreateMainWindow and ncsCreateMainWindowIndirect
* use \ref CTRL_MINIMAINWND replaced
*
* \sa CTRL_MINIMAINWND
*/
const char* className;
/**
* NCS_CREATE_INFO pointer
*/
NCS_CREATE_INFO * create_info;
}NCS_MAIN_CREATE_INFO;
/**
* \fn mWidget* ncsCreateMainWindow (const char *class_name, const char *caption,
* DWORD style, DWORD ex_style, \
* int id, int x, int y, int w, int h, HWND host, \
* HICON hIcon, HMENU hMenu, NCS_PROP_ENTRY * props, \
* NCS_RDR_INFO * rdr_info, \
* NCS_EVENT_HANDLER * handlers, \
* DWORD add_data);
*
* \brief create a NCS main window
*
* \param class_name the class name of widget.
* the class name must be register by \ref ncsRegisterComponent.
* And must be \ref CTRL_MINIMAINWND or its dirved class.
* \param caption the caption of the main window
* \param style the style of main window
* \param ex_style the extend style of main window
* \param id the id of main window
* \param x the x position of main window
* \param y the y position of main window
* \param w the width of main window
* \param h the height of main window
* \param host the handle of host window, can be NULL
* \param hIcon the icon of main window
* \param hMenu the menu bar handle
* \param props the properties array pointer, end by {-1, 0} if it's not NULL
* \param rdr_info the renderer info pointer
* \param handlers the handlers of event array pointer,
* end by {-1, NULL}, if it's not NULL
* \param add_data the additional data send to callback \ref NCS_CB_ONCREATE
* and \ref NCS_CB_ONINITDLG
*
* \return mWidget* - a mWidget pointer, must be a mMainWnd instance
*
* \sa ncsCreateWindow,ncsCreateWindowIndirect, nscCreateMainWindowIndirect,
* NCS_PROP_ENTRY, NCS_RDR_INFO, NCS_EVENT_HANDLER, NCS_CB_ONCREATE,
* mWidget, mInvisibleComponent , mMainWnd
*
*
*/
mWidget* ncsCreateMainWindow (const char *class_name, const char *caption,
DWORD style, DWORD ex_style, \
int id, int x, int y, int w, int h, HWND host, \
HICON hIcon, HMENU hMenu,
NCS_PROP_ENTRY * props, \
NCS_RDR_INFO * rdr_info, \
NCS_EVENT_HANDLER * handlers, \
DWORD add_data);
/**
* A struct include all the creating info, used by ncsCreateWindowIndirect
*
* \sa NCS_CREATE_INFO
*/
struct _NCS_WND_TEMPLATE{
/**
* The class name of mComponent, must be registered by \ref ncsRegisterComponent
*
* \note support \ref mInvisibleComponent class
*/
const char* class_name;
/**
* The id of commponet
*/
int id;
/**
* The Location and Size of mWidget, ignored if class_name
* is a \ref mInvisibleComponent
*/
int x, y, w, h;
/**
* The style of mWidget, ignored if class_name is a \ref mInvisibleComponent
*/
DWORD style;
/**
* The extend style of mWidget, ignored if class_name is a \ref mInvisibleComponent
*/
DWORD ex_style;
/**
* The caption of mWidget, ignored if class_name is a \ref mInvisibleComponent
*/
const char* caption;
//same struct as NCS_CREATE_INFO
/**
* Same as NCS_CREATE_INFO
*
* \sa NCS_CREATE_INFO
*/
NCS_PROP_ENTRY* props;
NCS_RDR_INFO* rdr_info;
NCS_EVENT_HANDLER* handlers;
NCS_WND_TEMPLATE* ctrls;
int count;
DWORD user_data;
//FIXED ME Maybe I should not put these two param here
DWORD bk_color;
PLOGFONT font;
};
//create control window indirect
/**
* \fn mWidget* ncsCreateWindowIndirect( const NCS_WND_TEMPLATE* tmpl, HWND hParent);
* \brief create a mComponent by \ref NCS_WND_TEMPLATE,
*
* \param tmpl the template pointer
* \param hParent the parent handle, if NCS_WND_TEMPLATE.class_name
* is a \ref mInvisibleComponent, hParent must releated a mWidget object
*
* \return mWidget* - then pointer of object or NULL if failed
*
* \sa ncsCreateWindow, NCS_WND_TEMPLATE
*/
mWidget* ncsCreateWindowIndirect( const NCS_WND_TEMPLATE* tmpl, HWND hParent);
/**
* A struct include all the creating info for ncsCreateMainWindowIndirect,
*
* \note same as \ref ncsCreateMainWindow 's params
*
* \sa NCS_WND_TEMPLATE, ncsCreateMainWindow
*/
typedef struct _NCS_MAINWND_TEMPLATE{
const char* class_name;
int id;
int x, y, w, h;
DWORD style;
DWORD ex_style;
const char* caption;
NCS_PROP_ENTRY* props;
NCS_RDR_INFO* rdr_info;
NCS_EVENT_HANDLER* handlers;
NCS_WND_TEMPLATE* ctrls;
int count;
DWORD user_data;
//FIXED ME Maybe I should not put these two param here
DWORD bk_color;
PLOGFONT font;
HICON hIcon;
HMENU hMenu;
}NCS_MAINWND_TEMPLATE;
/**
* \fn mWidget* ncsCreateMainWindowIndirect(const NCS_MAINWND_TEMPLATE* tmpl, HWND hHost);
* \biref create a main window from a template
*
* \param tmpl - the template of main window
* \param hHost - the host window handler of the main window
*
* \return mWidget * - the Instance of mMainWnd or NULL
*
* \sa ncsCreateMainWindow, NCS_MAINWND_TEMPLATE
*/
mWidget* ncsCreateMainWindowIndirect(const NCS_MAINWND_TEMPLATE* tmpl, HWND hHost);
```
* 对象指针和窗口句柄直接的关联操作
```c
/**
* \fn static inline mWidget* ncsObjFromHandle(HWND hwnd);
* \brief Get a Object from window handle
*
* \param hwnd - the handle of window
*
* \return mWidget * the instance releated this handle, or NULL
*/
static inline mWidget* ncsObjFromHandle(HWND hwnd)
{
if(IsWindow(hwnd))
return (mWidget*)(GetWindowAdditionalData2(hwnd));
return NULL;
}
/**
* \fn static inline mWidget* ncsGetChildObj(HWND hwnd, int id);
* \breif Get the child object pointer of window
*
* \param hwnd - the handle of window, which can be a normal
* MiniGUI window or a NCS window
* \param id - the child id. The child must be a NCS window
*
* \return mWidget * the instance releated id, or NULL
*/
static inline mWidget* ncsGetChildObj(HWND hwnd, int id)
{
return ncsObjFromHandle(GetDlgItem(hwnd,id));
}
/**
* \fn static inline mWidget* ncsGetParentObj(HWND hwnd)
* \brief Get the parent object pointer of window
*
* \param hwnd - the handle of child window, which can be a
* normal MiniGUI window or a NCS window
*
* \return mWidget * the instance of parent of hwnd
*/
static inline mWidget* ncsGetParentObj(HWND hwnd)
{
return ncsObjFromHandle(GetParent(hwnd));
}
```
### 3.7 `mWidget` 示例
不能直接使用 `mWidget`