对每个控件而言,MiniGUI都为其定义了几个重要的数据结构:
1. WNDCLASS:窗口类信息,主要定义了控件的外观,风格等参数,用来注册控件时使用
typedef struct _WNDCLASS
{
/** 类名,比如ListExCtrl */
char* spClassName;
/** internal field, operation type */
DWORD opMask;
/** 窗口的风格 */
DWORD dwStyle;
/** 扩展风格 */
DWORD dwExStyle;
/** 光标句柄 */
HCURSOR hCursor;
/** 背景色的像素值 */
int iBkColor;
/** 窗口消息回调处理函数 */
int (*WinProc) (HWND, int, WPARAM, LPARAM);
/** 私有数据区 */
DWORD dwAddData;
} WNDCLASS;
typedef WNDCLASS* PWNDCLASS;
2. CTRLCLASSINFO:以上类信息的控制结构,内部使用
typedef struct _CTRLCLASSINFO
{
char name[MAXLEN_CLASSNAME + 1];
DWORD dwStyle; // Default control styles.
DWORD dwExStyle; // Default control extended styles.
HCURSOR hCursor; // control cursor
int iBkColor; // control background color.
int (*ControlProc)(HWND, int, WPARAM, LPARAM);
// control procedure.
DWORD dwAddData; // the additional data.
int nUseCount; // use count.
struct _CTRLCLASSINFO* next;
// next class info
}CTRLCLASSINFO;
typedef CTRLCLASSINFO* PCTRLCLASSINFO;
3. CONTROL:定义了一个具体控件的形状,外观,风格,背景色等参数
typedef struct tagCONTROL
{
short DataType; // the data type
short WinType; // the window type
int left, top; // the position of control in main window's
int right, bottom; // client area.
int cl, ct; // the positio of control client in main window's
int cr, cb; // client area.
DWORD dwStyle; // the styles of child window.
DWORD dwExStyle; // the extended styles of child window.
int iBkColor; // the background color.
HMENU hMenu; // handle of menu.
HACCEL hAccel; // handle of accelerator table.
HCURSOR hCursor; // handle of cursor.
HICON hIcon; // handle of icon.
HMENU hSysMenu; // handle of system menu.
PLOGFONT pLogFont; // pointer to logical font.
HDC privCDC; // the private client DC.
INVRGN InvRgn; // the invalid region of this control.
PGCRINFO pGCRInfo; // pointer to global clip region info struct.
PZORDERNODE pZOrderNode;
// the Z order node,
// only for control with WS_EX_CTRLASMAINWIN.
PCARETINFO pCaretInfo; // pointer to system caret info struct.
DWORD dwAddData; // the additional data.
DWORD dwAddData2; // the second addtional data.
int (*ControlProc) (HWND, int, WPARAM, LPARAM);
char* spCaption; // the caption of control.
int id; // the identifier of child window.
SCROLLBARINFO vscroll; // the vertical scroll bar information.
SCROLLBARINFO hscroll; // the horizital scroll bar information.
PMAINWIN pMainWin; // the main window that contains this control.
struct tagCONTROL* pParent;// the parent of this control.
/*
* Child windows.
*/
struct tagCONTROL* children;
// the first child control.
struct tagCONTROL* active;
// the active child control.
struct tagCONTROL* old_under_pointer;
// the old under pointer child control.
struct tagCONTROL* primitive;
// the primitive child of mouse event.
NOTIFPROC notif_proc; // the notification callback procedure.
/*
* window element data.
*/
struct _wnd_element_data* wed;
/*
* The following members are only implemented for control.
*/
struct tagCONTROL* next; // the next sibling control.
struct tagCONTROL* prev; // the prev sibling control.
PCTRLCLASSINFO pcci; // pointer to Control Class Info struct.
}CONTROL;
typedef CONTROL* PCONTROL;
控件注册:
控件在可以被使用之前需要调用RegisterWindowClass函数,在这个函数里 向HWND_DESKTOP窗口管理器发送MSG_REGISTERWNDCLASS消息。这里可以看到传入的参数是一个pWndClass的指针
return SendMessage (HWND_DESKTOP,
MSG_REGISTERWNDCLASS, 0, (LPARAM)pWndClass) == ERR_OK;
HWND_DESKTOP窗口管理器在它的消息处理函数DesktopWinProc函数中如何处理MSG_REGISTERWNDCLASS消息?
case MSG_REGISTERWNDCLASS:
return AddNewControlClass ((PWNDCLASS)lParam);
调用了AddNewControlClass函数,该函数将控件类信息添加到MiniGUI维护的一张保存所有控件的CTRLCLASSINFO的表中去,该表名为ccitable,按字母分成26个链表,AddNewControlClass函数为待添加控件生成一个CTRLCLASSINFO实例,根据传入的PWNDCLASS结构的实例,填充相应的数据,并加入到相应的ccitable链表中。
创建控件:
注册完控件就可以使用CreateWindow创建一个控件。CreateWindow是CreateWindowEx的一个宏。
#define CreateWindow(class_name, caption, style, \
id, x, y, w, h, parent, add_data) \
CreateWindowEx(class_name, caption, style, 0, \
id, x, y, w, h, parent, add_data)
CreateWindow首先向HWND_DESKTOP窗口管理器发送一个MSG_GETCTRLCLASSINFO消息,获取CTRLCLASSINFO信息,然后定义一个PCONTROL变量,对控件进行初始化,然后向HWND_DESKTOP窗口管理器发送一个MSG_NEWCTRLINSTANCE消息
SendMessage (HWND_DESKTOP,
MSG_NEWCTRLINSTANCE, (WPARAM)hParentWnd, (LPARAM)pNewCtrl);
接着向新创建的控件本身发送MSG_CREATE消息:
if (SendMessage ((HWND)pNewCtrl, MSG_CREATE, (WPARAM)hParentWnd, (LPARAM)dwAddData)) {
SendMessage (HWND_DESKTOP,
MSG_REMOVECTRLINSTANCE, (WPARAM)hParentWnd, (LPARAM)pNewCtrl);
goto error;
}
阅读(2185) | 评论(1) | 转发(1) |