界面外观及特效
一.外观渲染器及窗口元素属性
1.前言
1.1为什么引入渲染器
以前的版本在编译前就必须进行编译配置,选定界面风格,在 fashion、 classic 和 flat 中选其一
1.2优点
可以通过MiniGUI配置文件来修改界面外观
也可以通过函数接口来控制界面外观
1.3作用
实现窗口以及控件外观的绘制
1.4实现
窗口元素的属性,包括窗口元素的颜色、尺寸、字体等信息
窗口元素的渲染方法,定义如何绘制窗口元素
1.5四种渲染器
classic、 flat、 fashion、 skin
默认:classic
fashion 渲染器需要组件 mGPlus 的支持
2.窗口属性元素
caption 窗口标题栏大小
bgc_desktop WE_BGC_DESKTOP 桌面背景色
修改这个配置文件中的窗口元素的属性值,以改变运行时窗口的外观
3.皮肤渲染器的窗口皮肤属性
用渲染器替换原先 MGExt 库中的 SKIN 相关接口,我们使用了皮肤渲染器
4.窗口属性操作函数
序里面对窗口外观进行定制。 为了方便对窗口属性的操作, MiniGUI 定义了下面的函数接口,来实现对窗口属性的操作。
用来获取指定窗口的某个元素属性的属性值
MG_EXPORT DWORD GUIAPI GetWindowElementAttr (HWND hwnd, int we_attr_id);
hwnd:窗口句柄
we_attr_id: 窗口元素属性id
返回值: DWORD 属性值
设置窗口某个元素属性的属性值
MG_EXPORT DWORD GUIAPI SetWindowElementAttr (HWND hwnd, int we_attr_id,DWORD we_attr);
hwnd:窗口句柄
we_attr_id:窗口元素属性id
we_attr: 属性值
获取窗口元素的颜色值
MG_EXPORT gal_pixel GUIAPI GetWindowElementPixelEx (HWND hwnd,HDC hdc, int we_attr_id);
hwnd: 窗口句柄
hdc: DC句柄
we_attr_id:窗口元素属性id
返回值:gal_pixel 颜色值
设置当前窗口的渲染器
MG_EXPORT BOOL GUIAPI SetWindowElementRenderer (HWND hWnd,const char* werdr_name, const WINDOW_ELEMENT_ATTR* we_attrs);
hwnd:窗口句柄
werdr_name:渲染器名字
we_attrs:窗口属性的结构体数组
typedef struct _WINDOW_ELEMENT_ATTR {
int we_attr_id; //属性名
DWORD we_attr; //属性值
} WINDOW_ELEMENT_ATTR;
数组的最后一个元素,其窗口元素 ID 为 -1,表示结尾
返回值:BOOL 设置成功返回真 设置失败返回假
5.渲染器管理——怎样绘制窗口
typedef struct _WINDOW_ELEMENT_RENDERER {
const char name[LEN_RENDERER_NAME+1];//渲染器名字 LEN_RENDERER_NAME = 15
int (*init) (PWERENDERER renderer);//渲染器初始化指针 用来初始化渲染器的基本信息,包括窗口元素的尺寸、字体、颜色等窗口属性信息和渲染器私有信息。
int (*deinit) (PWERENDERER renderer);//渲染器销毁指针
DWORD (*calc_3dbox_color) (DWORD color, int flag);//三维立体颜色计算函数指针
void (*draw_3dbox) (HDC hdc, const RECT* pRect, DWORD color, DWORD flag);//三维立体框绘制函数指针
void (*draw_radio) (HDC hdc, const RECT* pRect, DWORD color, int status);//单选框绘制函数指针
void (*draw_checkbox) (HDC hdc, const RECT* pRect, DWORD color,int status);//非选中复选框绘制函数指针
void (*draw_checkmark) (HDC hdc, const RECT* pRect, DWORD color,int status);//选中复选框绘制函数指针
void (*draw_arrow) (HWND hWnd, HDC hdc, const RECT* pRect, DWORD color, int status);箭头绘制函数指针
void (*draw_fold) (HWND hWnd, HDC hdc, const RECT* pRect, DWORD color,int status, int next);打开的或者是关闭的文件夹、树控件的缩进、展开标志的绘制函数指针
void (*draw_focus_frame) (HDC hdc, const RECT *pRect, DWORD color);焦点方框绘制函数指针
void (*draw_normal_item) (HWND hWnd, HDC hdc, const RECT* pRect,DWORD color);正常状态的列表框子项的绘制函数指针
void (*draw_hilite_item) (HWND hWnd, HDC hdc, const RECT* pRect,DWORD color);高亮状态的列表框子项的绘制函数指针
void (*draw_disabled_item) (HWND hWnd, HDC hdc, const RECT* pRect,DWORD color);无效状态的列表框子项的绘制函数指针
void (*draw_significant_item) (HWND hWnd, HDC hdc, const RECT* pRect,DWORD color);需重点标识的列表框子项的绘制函数指针
void (*draw_push_button) (HWND hWnd, HDC hdc, const RECT* pRect,DWORD color1, DWORD color2, int status);PUSH 按钮绘制函数指针
void (*draw_radio_button) (HWND hWnd, HDC hdc, const RECT* pRect, int status);单选按钮绘制函数指针
void (*draw_check_button) (HWND hWnd, HDC hdc, const RECT* pRect, int status);复选框按钮绘制函数指针
void (*draw_border) (HWND hWnd, HDC hdc, BOOL is_active);窗口边框绘制函数指针
void (*draw_caption) (HWND hWnd, HDC hdc, BOOL is_active);窗口标题栏绘制函数指针
void (*draw_caption_button) (HWND hwnd, HDC hdc, int ht_code, int state);窗口标题栏按钮绘制函数指针。标题栏按钮包括:最小化按钮、最大化按钮、关闭按钮
void (*draw_scrollbar) (HWND hWnd, HDC hdc, int sb_pos);滚动条绘制函数指针
void (*calc_trackbar_rect) (HWND hWnd, LFRDR_TRACKBARINFO *info,DWORD dwStyle, const RECT* rcClient, RECT* rcRuler,RECT* rcBar, RECT* rcBorder);轨迹条外框绘制函数指针
void (*draw_trackbar) (HWND hWnd, HDC hdc, LFRDR_TRACKBARINFO *info);轨迹条绘制函数指针
int (*calc_we_area) (HWND hWnd, int which, RECT* we_area);窗口各元素区域计算函数指针
int (*calc_we_metrics) (HWND hWnd,LFRDR_WINSTYLEINFO* style_info, int which);窗口各元素尺寸的计算函数指针
int (*hit_test) (HWND hWnd, int x, int y);获取鼠标所点击的窗口元素的函数指针
int (*on_click_hotspot) (HWND hWnd, int which);当鼠标点击到热点区域时,进行相应处理的函数指针
void (*draw_custom_hotspot) (HWND hWnd, HDC hdc, int ht_code, int state);热点区域的绘制函数指针
void (*calc_thumb_area) (HWND hWnd, BOOL vertical,LFSCROLLBARINFO* sb_info);水平滚动条和垂直滚动条游标区域的计算函数指针
void (*disabled_text_out) (HWND hWnd, HDC hdc, const char* spText,PRECT rc, DWORD dt_fmt);无效区域文字的输出函数指针
void (*draw_tab) (HWND hWnd, HDC hdc, RECT *rect, char *title,DWORD color, int flag, HICON icon);属性页控件标签的绘制函数指针
void (*draw_progress) (HWND hWnd, HDC hdc,int nMax, int nMin, int nPos, BOOL fVertical);进度条绘制函数
void (*draw_header) (HWND hWnd, HDC hdc, const RECT* pRect, DWORD color);列表框或者网格控件的表头绘制函数指针
DWORD (*on_get_rdr_attr) (int we_attr_id);渲染器私有信息获取函数指针
DWORD (*on_set_rdr_attr) (int we_attr_id, DWORD we_attr, BOOL change);渲染器私有信息设置函数指针
void (*erase_background) (HWND hWnd, HDC hdc, const RECT *rect);窗口背景擦除绘制函数指针
void (*draw_normal_menu_item) (HWND hWnd, HDC hdc, const RECT* pRect,DWORD color);正常状态菜单项绘制函数指针
void (*draw_hilite_menu_item) (HWND hWnd, HDC hdc, const RECT* pRect,DWORD color);高亮状态菜单项绘制函数指针
void (*draw_disabled_menu_item) (HWND hWnd, HDC hdc, const RECT* pRect,DWORD color);无效状态菜单项绘制函数指针
int we_metrics [WE_METRICS_NUMBER];窗口尺寸属性
DWORD we_colors [WE_COLORS_NUMBER][3];窗口颜色属性
PLOGFONT we_fonts [WE_FONTS_NUMBER];窗口字体属性
HICON we_icon [2][SYSICO_ITEM_NUMBER];窗口所使用的图标句柄
unsigned int refcount;渲染器引用计数
const void* private_info;渲染器私有信息指针
} WINDOW_ELEMENT_RENDERER;
通过名称获得渲染器
MG_EXPORT const WINDOW_ELEMENT_RENDERER* GUIAPI GetWindowRendererFromName (const char* name);
name:渲染器名称
返回值:WINDOW_ELEMENT_RENDERER 渲染器句柄
获取默认渲染器
MG_EXPORT const WINDOW_ELEMENT_RENDERER* GUIAPI GetDefaultWindowElementRenderer (void);
添加渲染器到MiniGUI
MG_EXPORT BOOL GUIAPI AddWindowElementRenderer (const char* name, const WINDOW_ELEMENT_RENDERER* we_rdr);
name:渲染器名称
we_rdr: 渲染器
从MiniGUI移出渲染器
MG_EXPORT BOOL GUIAPI RemoveWindowElementRenderer (const char* name);
name:渲染器名称
设置默认渲染器
MG_EXPORT const char* GUIAPI SetDefaultWindowElementRenderer (const char* name);
name:渲染器名称
指定窗口渲染器
MG_EXPORT BOOL GUIAPI SetWindowElementRenderer (HWND hWnd, const char* werdr_name, const WINDOW_ELEMENT_ATTR* we_attrs);
hWnd:窗口句柄
werdr_name:渲染器名称
we_attrs:外观属性表
6.主窗口的创建
创建一个主窗口
MG_EXPORT HWND GUIAPI CreateMainWindowEx (PMAINWINCREATE pCreateInfo,const char* werdr_name, const WINDOW_ELEMENT_ATTR* we_attrs,const char* window_name, const char* layer_name);
pCreateInfo:主窗口结构体
werdr_name:渲染器名字
we_attr: 窗口元素属性表
window_name和layer_name 是保留参数给后续版本使用
返回值: HWND 窗口句柄
static inline HWND GUIAPI CreateMainWindow (PMAINWINCREATE pCreateInfo)
{
return CreateMainWindowEx (pCreateInfo, NULL, NULL, NULL, NULL);
}
7.控件的创建
MG_EXPORT HWND GUIAPI CreateWindowEx2 (const char* spClassName,const char* spCaption, DWORD dwStyle, DWORD dwExStyle,int id, int x, int y, int w, int h, HWND hParentWnd,const char* werdr_name, const WINDOW_ELEMENT_ATTR* we_attrs,DWORD dwAddData);
static inline HWND GUIAPI CreateWindowEx (const char* spClassName,const char* spCaption, DWORD dwStyle, DWORD dwExStyle,int id, int x, int y, int w, int h, HWND hParentWnd,DWORD dwAddData)
{
return CreateWindowEx2 (spClassName, spCaption, dwStyle, dwExStyle,id, x, y, w, h, hParentWnd, NULL, NULL, dwAddData);
}
#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)
8.对话框的创建
模态对话框
MG_EXPORT int GUIAPI DialogBoxIndirectParamEx (PDLGTEMPLATE pDlgTemplate,HWND hOwner, WNDPROC DlgProc, LPARAM lParam,const char* werdr_name, WINDOW_ELEMENT_ATTR* we_attrs,const char* window_name, const char* layer_name);
static inline int GUIAPI DialogBoxIndirectParam (PDLGTEMPLATE pDlgTemplate,HWND hOwner, WNDPROC DlgProc, LPARAM lParam)
{
return DialogBoxIndirectParamEx (pDlgTemplate, hOwner, DlgProc, lParam,NULL, NULL, NULL, NULL);
}
非模态对话框
MG_EXPORT HWND GUIAPI CreateMainWindowIndirectParamEx (PDLGTEMPLATE pDlgTemplate,HWND hOwner, WNDPROC DlgProc, LPARAM lParam,const char* werdr_name, WINDOW_ELEMENT_ATTR* we_attrs,const char* window_name, const char* layer_name);
static inline HWND GUIAPI CreateMainWindowIndirectParam (PDLGTEMPLATE pDlgTemplate,HWND hOwner, WNDPROC DlgProc, LPARAM lParam)
{
return CreateMainWindowIndirectParamEx (pDlgTemplate, hOwner, DlgProc, lParam,NULL, NULL, NULL, NULL);
}
二.主窗口双缓冲区
作用:1.绘制到主窗口DC相匹配的内存DC中 ——- (数据运用各种算法) ——– 界面的特效
2.提高窗口绘屏时的效率,解决主窗口绘屏时的闪烁问题
2.双缓冲窗口扩展风格
#define WS_EX_AUTOSECONDARYDC 0x00001000L
3.双缓冲区机制的相关函数
创建双缓冲DC
MG_EXPORT HDC GUIAPI CreateSecondaryDC (HWND hwnd);
hwnd:窗口句柄
返回值: HDC —–> 兼容的内存DC
双缓冲区的屏幕 DC 数据复制回调函数
typedef int (* ON_UPDATE_SecondaryDC)(HWND hwnd, HDC secondary_dc, HDC real_dc, cont RECT* update_rc, DWORD area_flags);
创建好的内存DC设置为目标主窗口的双缓冲区
MG_EXPORT HDC GUIAPI SetSecondaryDC (HWND hwnd, HDC secondary_dc, ON_UPDATE_SECONDARYDC on_update_secondarydc);
主窗口有WS_EX_AUTOSecondaryDC风格 —> 取消该风格 —> DeleteSecondaryDC删除已有缓冲区 —-> 返回HDC_SCREEN
主窗口没有WS_EX_AUTOSecondaryDC —-> 原先的双缓冲区句柄 —–> 原先的双缓冲区由应用程序自行管理
HDC_SCREEN,将取消窗口缓冲机制
复制函数: 自动完成从双缓冲区到屏幕DC的复制
双缓冲区句柄获取函数GetSecondaryDC
MG_EXPORT HDC GUIAPI GetSecondaryDC (HWND hwnd);
hwnd:窗口句柄
返回值: HDC 双缓冲区句柄
该函数用于双缓冲窗体的客户区绘制 DC
MG_EXPORT HDC GUIAPI GetSecondaryClientDC (HWND hwnd);
hwnd:窗口句柄
返回值: HDC 双缓冲区句柄
释放双缓冲 DC
MG_EXPORT void GUIAPI ReleaseSecondaryDC (HWND hwnd, HDC hdc);
主窗体本身的双缓冲 DC,则什么也不处理;否则释放该 DC
该函数删除由 CreateSecondaryDC 创建的内存 DC
static inline void GUIAPI DeleteSecondaryDC (HWND hwnd);
该函数仅针对双缓冲,在私有窗口 DC 基础上创建子 DC,使之可以作为主窗口的客户 DC,或者控件的 DC 使用。
HDC GUIAPI GetSecondarySubDC (HDC secondary_dc, HWND hwnd_main, HWND hwnd_child, BOOL client);
该函数释放私有 DC 的子 DC。
void GUIAPI ReleaseSecondarySubDC (HDC secondary_subdc, HWND hwnd_child)
三.桌面定制
应用程序可以控制桌面窗口对各种消息的响应
1.桌面定制结构体
typedef struct _DESKTOPOPS {
void* (*init) (void);//初始化操作集的函数,返回 context
void (*deinit) (void* context);//销毁操作集的函数;
void (*paint_desktop) (void* context,HDC dc_desktop, const RECT* inv_rc);//desktop 的重绘函数
void (*keyboard_handler) (void* context,int message, WPARAM wParam, LPARAM lParam);//键盘事件处理函数
void (*mouse_handler) (void* context,int message, WPARAM wParam, LPARAM lParam);//鼠标事件处理函数
void (*customize_desktop_menu) (void* context,HMENU hmenu, int start_pos);//用户自定义的弹出式菜单构造函数
void (*desktop_menucmd_handler) (void* context, int id);//弹出式菜单的响应函数
} DESKTOPOPS;
键盘事件处理
MSG_DT_KEYDOWN
MSG_DT_KEYUP
MSG_DT_KEYLONGPRESS:
MSG_DT_KEYALWAYSPRESS:
MSG_DT_CHAR:
MSG_DT_SYSKEYDOWN:
MSG_DT_SYSCHAR:
MSG_DT_SYSKEYUP
鼠标事件
MSG_DT_LBUTTONDOWN
MSG_DT_LBUTTONUP
MSG_DT_LBUTTONDBLCLK
MSG_DT_MOUSEMOVE
MSG_DT_RBUTTONDOWN
MSG_DT_RBUTTONDBLCLK
MSG_DT_RBUTTONUP