基于GDI的简单界面框架

来源:互联网 发布:网络连接小图标不见了 编辑:程序博客网 时间:2024/05/22 06:19

在工作中经常需要为C++的对话框绘制界面,特别是按钮和背景等需要使用图片重新制成,而且这些绘制出来的“控件”都需要对点击等操作进行响应。为了方便大量的类似操作,自己动手写了一个简单的类,可实现对类似“控件”接近自动化的管理。


主要的想法如下:

1、实现对图片的自动管理,主要是销毁。

2、简化在对话框类中反复填写的代码工作量。

3、需要考虑常用的几种不同的控件及工作模式。

4、需要考虑控件在对话框上绘制时的层次问题。

5、文本可调整字体。

6、即使有大量控件,也可方便的对任意控件消息进行接收和处理。


类声明

#ifndef cyfguiplus_2014_03_28_cyfage_h_#define cyfguiplus_2014_03_28_cyfage_h_#pragma once/*************************GDI++的使用*************************Copyright by Cyfage2014-03-01*************************************************************//*************************导入GDI++库*************************///#include <locale.h>//#include <GdiPlus.h>//#pragma comment(lib, "gdiplus.lib")/*************************************************************//*************************GDI++的使用*************************1、加载GDI声明ULONG_PTR m_gdiplusToken;启动Gdiplus::GdiplusStartupInput gdiplusStartupInput;Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);卸载Gdiplus::GdiplusShutdown(m_gdiplusToken);2、显示中文字体::setlocale(LC_ALL, "chs");*************************************************************/#include <vector>#include <algorithm>/*************************对外投递消息*************************///控件发生事件时对外投递的消息,只有状态被改变时才投递(LPARAM)//目前简化版中,只有应该有消息的控件且在弹起消息时才被投递enum gui_ctrl_msg{msgiid = 21912,gui_msg_moveout, //缺省gui_msg_movein, //悬停gui_msg_kickdown, //按下gui_msg_kickup //弹起};/*************************************************************/enum gui_ctrl_type //控件类型{gui_ctrl_backround, //普通背景(根据传入的路径或资源ID直接绘制图片,可以响应点击移动等事件,也可以完全无图片,仅仅划分一块区域响应事件)gui_ctrl_txtbutton, //文字按钮(根据输入的文字直接生成相应大小的简单按钮)gui_ctrl_clickbutton, //点击型图片按钮(根据传入的资源ID生成相应大小的按钮,一般有多个态,也可以有居中显示的标题文字)gui_ctrl_animation, //动画gui_ctrl_checkbutton, //类似CHECK控件,点一下显示再点一下不显示gui_ctrl_lastempty //最后一项,仅用于计数};/**************************控件的模式*************************///1、背景图enum gui_backround_model //背景模式{gui_brmodel_normal, //正常背景图,除了绘制出来以外什么也不做gui_brmodel_kick //可点击的背景图,进入范围鼠标变手形状,点击有事件};//2、文字按钮//文字按钮只有统一的一种模式//3、点击型图片按钮enum gui_clickbutton_model //点击型图片按钮模式{gui_clickbtn_modeltwo, //常规两态按钮(缺省-悬停)gui_clickbtn_modelthree,gui_clickbtn_modelfour, //常规四态按钮(缺省-悬停-点击-禁止)};//4、动画//暂无//5、Check型选择图片按钮enum gui_checkbutton_model //Check型图片按钮模式{gui_checkbtn_modelone, //常规一态按钮(未选择-不绘制;选择-绘制)gui_checkbtn_modeltwo //常规两态按钮(未选择-0;选择-1)};/*************************************************************/enum gui_ctrl_style //控件状态{gui_move_out, //缺省gui_move_in, //悬停gui_kick_down, //按下gui_kick_disable //被禁止};struct gui_ctrl //界面类的控件管理结构{Gdiplus::Bitmap *img; //控件图片指针int imgserial; //指针共用图片序列号char setname[50]; //控件被设置的名字,具有唯一性char group[50]; //所属组名,具有唯一性float width; //控件宽度float height; //控件高度float x; //控件坐标float y;bool visible; //是否可见(等于该控件不存在,不会显示,也不会有任何功能和响应)bool disable; //是否禁止状态(该控件存在,显示为禁止,但不会有任何功能和响应,四态按钮特有功能)int type; //控件类型(参考gui_ctrl_type)int model; //控件模式(参考各控件的model)int style; //控件状态(具体各控件当前是否应显示,或者显示哪一部分的控制变量)int oldstyle; //控件的前一个状态(前后状态对比后可确定是否该改变显示的内容或者刷新什么的)int percent; //(进度条)展示当前图片的百分比byte level; //绘制优先度(当多个控件绘制区域重叠时先画哪个再画哪个的设置,同一类型中数值越高越优先)char text[100]; //控件文本Gdiplus::Font *font; //文本字体Gdiplus::SolidBrush *brush; //文本字体刷子float txtx; //文本坐标(不适用于简单文字按钮)float txty;};typedef std::vector<gui_ctrl> guique;typedef guique::iterator guiit;class cyfGUIPlus{public:cyfGUIPlus();virtual ~cyfGUIPlus();///////////////////////////////////////////////////////////////**************************设置函数**************************////////////////////////////////////////////////////////////////*************************************************************功能:初始化界面类参数:dlg-父对话框指针;msgid-父窗口消息ID;wpid-父窗口WPARAM返回:无说明:界面类必须依赖于所要绘制的对话框需求:无*************************************************************/virtual void Initialize(CDialog *dlg, UINT msgid, UINT wpid);/*************************************************************功能:界面绘制函数参数:graphics-目标对话框的GDI++绘制句柄返回:无说明:函数放置于目标对话框的OnPaint()函数内,导入graphics参数即可      自动绘制应该要绘制的东西需求:无*************************************************************/virtual void OnDlgDraw(Gdiplus::Graphics *graphics);/*************************************************************功能:鼠标移动刷新函数参数:point-鼠标移动坐标返回:无说明:函数放置于目标对话框的OnNcMouseMove()函数内,导入随着鼠标      移动而随时传递进来的point坐标即可需求:无*************************************************************/virtual void OnDlgMove(CPoint point);/*************************************************************功能:鼠标左键按下函数参数:point-鼠标当前坐标返回:无说明:函数放置于目标对话框的OnNcLButtonDown()函数内,导入随着鼠标      移动而随时传递进来的point坐标即可需求:无*************************************************************/virtual void OnDlgDown(CPoint point);/*************************************************************功能:鼠标左键(按下后)放开函数参数:point-鼠标当前坐标返回:无说明:函数放置于目标对话框的OnNcLButtonUp()函数内,导入随着鼠标      移动而随时传递进来的point坐标即可需求:无*************************************************************/virtual void OnDlgUp(CPoint point);///////////////////////////////////////////////////////////////**************************功能函数**************************////////////////////////////////////////////////////////////////*************************************************************功能:静态载入图片资源参数:nid-图片的资源ID;sourcetype-图片的资源类型返回:图片指针说明:图片必须以资源的方式被添加到了项目内,添加PNG图片时应在  资源视图中右键点击添加资源,然后选择导入再在文件夹里选择  一个图片进行添加。需求:需要加载GDI库*************************************************************/Gdiplus::Bitmap* LoadImg(UINT nid, char *sourcetype);/*************************************************************功能:动态载入图片文件参数:filepath-图片文件路径返回:图片指针说明:图片不存在时返回NULL,但无法区别错误的图片文件需求:需要加载GDI库*************************************************************/Gdiplus::Bitmap* LoadImg(char *filepath);/*************************************************************功能:创建背景控件参数:setname-设置的控件名称;img-图片指针;x,y-控件坐标;model-      控件工作模式;level-控件绘制优先等级返回:1-设置成功;0-设置失败说明:将图片设置为控件后才会纳入管理;工作模式参考gui_backround_model需求:无*************************************************************/int PushBackround(const char *setname, Gdiplus::Bitmap *img, int x, int y, int model = 0, byte level = 0);/*************************************************************功能:创建简单文字按钮控件参数:setname-设置的控件名称;title-按钮文字;x,y-控件坐标;model-      控件工作模式;level-控件绘制优先等级返回:1-设置成功;0-设置失败说明:简单文字按钮不需要图片需求:无*************************************************************/int PushTxtButton(const char *setname, char *title, int x, int y, byte level = 0);/*************************************************************功能:创建点击按钮控件参数:setname-设置的控件名称;img-图片指针;x,y-控件坐标;model-      控件工作模式;level-控件绘制优先等级返回:1-设置成功;0-设置失败说明:工作模式参考gui_picbutton_model需求:无*************************************************************/int PushClickButton(const char *setname, Gdiplus::Bitmap *img, int x, int y, int model = 0, byte level = 0);/*************************************************************功能:创建逐帧显示的动画控件参数:setname-设置的控件名称;img-图片指针;x,y-控件坐标;model-      控件工作模式;level-控件绘制优先等级返回:1-设置成功;0-设置失败说明:无需求:无*************************************************************/int PushAnimation(const char *setname, Gdiplus::Bitmap *img, int x, int y, int model = 0, byte level = 0);/*************************************************************功能:创建Check型图片按钮控件参数:setname-设置的控件名称;img-图片指针;x,y-控件坐标;model-      控件工作模式;level-控件绘制优先等级;group-组名返回:1-设置成功;0-设置失败说明:无需求:无*************************************************************/int PushCheckButton(const char *setname, const char *group, Gdiplus::Bitmap *img, int x, int y, int model = 0, byte level = 0);/*************************************************************功能:设置缺省字体和颜色参数:size-字体大小;bold-加粗;underline-下划线;transparent-透明度;      r-RGB之红色;g-RGB之绿色;b-RGB之蓝色返回:无意义说明:如果控件被设置了显示文本,将按此缺省字体和颜色进行显示;需求:无*************************************************************/virtual int SetDefaultFont(int size, bool bold = false, bool underline = false, int transparent = 0, int r = 0, int g = 0, int b = 0);/*************************************************************功能:设置某个控件的文本,同时可以单独调整字体和颜色参数:setname-控件名;text-文本内容;size-字体大小;bold-加粗;      underline-下划线;transparent-透明度;r-RGB之红色;g-RGB  之绿色;b-RGB之蓝色返回:1-成功;2-失败说明:无需求:无*************************************************************/virtual int SetText(const char *setname, char *text = NULL, int size = 0, bool bold = false, bool underline = false, int transparent = 0, int r = 0, int g = 0, int b = 0);/*************************************************************功能:获取某个控件被设置的文本参数:setname-控件名;text-文本内容缓冲区;tsize-缓冲区大小返回:1-成功;2-失败说明:无需求:无*************************************************************/virtual int GetText(const char *setname, char *text, int tsize);/*************************************************************功能:禁止/恢复某个控件可见参数:setname-控件名称;visible-是否可见返回:无说明:无需求:无*************************************************************/virtual void SetVisible(const char *setname, bool visible = true);/*************************************************************功能:手动设置某个控件的状态参数:setname-控件名称;style-状态值返回:无说明:目前主要用于CheckButton类,设置缺省状态,0-不绘制或者绘制左半边图,1-绘制或者绘制右半边图需求:无*************************************************************/virtual void SetStyle(const char *setname, int style);/*************************************************************功能:禁止/恢复某个控件可访问参数:setname-控件名称;disable-是否可访问返回:无说明:只对四态按钮有效需求:无*************************************************************/virtual void SetDisable(const char *setname, bool disable = true);/*************************************************************功能:移动某个控件到某个坐标参数:setname-控件名称;x-纵坐标;y-横坐标返回:无说明:无需求:无*************************************************************/virtual void Move(const char *setname, int x, int y);/*************************************************************功能:刷新某个控件参数:setname-控件名称返回:无说明:无需求:无*************************************************************/virtual void Invalidate(const char *setname);///////////////////////////////////////////////////////////////**************************状态查询**************************////////////////////////////////////////////////////////////////*************************************************************功能:获取响应事件的控件名称参数:setname-控件名称缓冲地址;ssize-可以容纳的缓冲地址长度返回:无说明:当某个控件响应事件,改变了状态的时候(鼠标进入退出按下弹起)      本类会向父对话框投递一个消息,父对话框这时调用本函数可  获知是哪个控件响应了消息。需求:无*************************************************************/virtual void GetPostCtrl(char *setname, int ssize);/*************************************************************功能:获取目标控件的宽度参数:setname-控件名称返回:控件宽度说明:对于多态的按钮或背景来说,宽度指的是一个态的宽度。需求:无*************************************************************/virtual int GetWidth(char *setname);/*************************************************************功能:获取目标控件的高度参数:setname-控件名称返回:控件高度说明:无需求:无*************************************************************/virtual int GetHeight(char *setname);/*************************************************************功能:获取目标控件的坐标参数:setname-控件名称;返回:无说明:一般指控件左上角的X和Y坐标需求:无*************************************************************/virtual void GetRECT(char *setname, int *x, int *y);protected:CDialog *m_maindlg;UINT m_msgid;UINT m_wpid;guique m_guique;Gdiplus::Font *m_font;Gdiplus::SolidBrush *m_brush;int m_size;bool m_bold;bool m_underline;int m_transparent;byte m_rgb[3];int m_imgserail;char m_postname[50];char m_log[1024];/*************************************************************功能:图片绘制排序参数:无返回:无说明:将m_guique队列中的图片按照gui_ctrl结构中的level变量进行排      序,越小的越前(先画)需求:无*************************************************************/virtual void LevelSort();/*************************************************************功能:按设定名称查询队列参数:setname-图片的设定名称返回:队列指针说明:如果没有查询到,指针返回为空(m_guique.end())需求:无*************************************************************/virtual guiit FindGUI(const char *setname);/*************************************************************功能:获取传入字体每个字符的宽度参数:font-传入的字体指针;text-传入的文本返回:字体宽度说明:测量字符串宽度必须先统计是否全角或半角字符需求:无*************************************************************/virtual float GetFontWidth(Gdiplus::Font *font, char *text);/*************************************************************功能:获取传入字体每个字符的高度参数:font-传入的字体指针返回:字体高度说明:正规的获取高度的方法都必须有Graphics参数作为设备对照,这里      使用的方法是事先枚举正常宋体1-N号字体所统计出的规律进行计算  的,否则使用Graphics参数非常麻烦。这样获得的字体宽度是片面  和不严格的,只依据宋体字体进行设置需求:无*************************************************************/virtual float GetFontHeight(Gdiplus::Font *font);/*************************************************************功能:设置控件附属文字的坐标参数:ctrl-控件指针返回:无说明:如果一个控件属于可以设置附属文字的类型,同时又有文字,则      根据传入的文字自动对齐控件坐标,尽量做到居中显示需求:无*************************************************************/virtual void SetTextCenter(gui_ctrl *ctrl);/*************************************************************功能:向父对话框投递事件消息参数:setname-事件的控件名称;status-事件类型返回:无说明:事件类型参考gui_ctrl_msg需求:无*************************************************************/virtual void Post(char *setname, int status);/*************************************************************功能:刷新控件参数:ctrl-控件指针返回:无说明:仅仅刷新控件所在的区域(坐标+宽和高)需求:无*************************************************************/virtual void Refresh(gui_ctrl *ctrl);/*************************绘制函数**************************/virtual void DrawBackround(gui_ctrl *ctrl, Gdiplus::Graphics *graphics);virtual void DrawTxtButton(gui_ctrl *ctrl, Gdiplus::Graphics *graphics);virtual void DrawClickButton(gui_ctrl *ctrl, Gdiplus::Graphics *graphics);virtual void DrawAnimation(gui_ctrl *ctrl, Gdiplus::Graphics *graphics);virtual void DrawCtlText(gui_ctrl *ctrl, Gdiplus::Graphics *graphics);virtual void DrawCheckButton(gui_ctrl *ctrl, Gdiplus::Graphics *graphics);/**********************************************************//*************************状态函数**************************/virtual void OnBackround(gui_ctrl *ctrl, int status);virtual void OnTxtButton(gui_ctrl *ctrl, int status);virtual void OnClickButton(gui_ctrl *ctrl, int status);virtual void OnAnimation(gui_ctrl *ctrl, int status);virtual void OnCheckButton(gui_ctrl *ctrl, int status);/**********************************************************/private:};#endif

类定义

#pragma once#include "stdafx.h"#include "cyfGUIPlus.h"cyfGUIPlus::cyfGUIPlus(){m_maindlg = NULL;m_msgid = 0;m_wpid = 0;m_font = NULL;m_brush = NULL;m_size = 0;m_bold = false;m_underline = false;m_transparent = 0;m_imgserail = 0;memset(m_rgb, 0, sizeof(m_rgb));::setlocale(LC_ALL, "chs");}cyfGUIPlus::~cyfGUIPlus(){if (NULL != m_font){delete m_font;m_font = NULL;}if (NULL != m_brush){delete m_brush;m_brush = NULL;}for (guiit it = m_guique.begin(); it != m_guique.end(); ++ it){if (NULL != (*it).font){delete (*it).font;(*it).font = NULL;}if (NULL != (*it).brush){delete (*it).brush;(*it).brush = NULL;}}typedef std::vector<int> seriesque;typedef seriesque::iterator seriesit;seriesque que;for (guiit it = m_guique.begin(); it != m_guique.end(); ++ it){if (NULL == (*it).img){continue;}if (0 == (*it).imgserial){delete (*it).img;(*it).img = NULL;}else{bool found = false;for (seriesit is = que.begin(); is != que.end(); ++ is){if ((*is) == (*it).imgserial){found = true;(*it).img = NULL;break;}}if (false == found){que.push_back((*it).imgserial);delete (*it).img;(*it).img = NULL;}}}}void cyfGUIPlus::Initialize(CDialog *dlg, UINT msgid, UINT wpid){m_maindlg = dlg;m_msgid = msgid;m_wpid = wpid;}void cyfGUIPlus::OnDlgDraw(Gdiplus::Graphics *graphics){for (guiit it = m_guique.begin(); it != m_guique.end(); ++ it){if (true != (*it).visible){continue;}switch ((*it).type){case gui_ctrl_backround:{DrawBackround(&(*it), graphics);}break;case gui_ctrl_txtbutton:{DrawTxtButton(&(*it), graphics);}break;case gui_ctrl_clickbutton:{DrawClickButton(&(*it), graphics);}break;case gui_ctrl_animation:{DrawAnimation(&(*it), graphics);}break;case gui_ctrl_checkbutton:{DrawCheckButton(&(*it), graphics);}break;}}}void cyfGUIPlus::OnDlgMove(CPoint point){for (guiit it = m_guique.begin(); it != m_guique.end(); ++ it){if (true != (*it).visible){continue;}int status;if ((point.x > (*it).x && point.x < (*it).x + (*it).width) && (point.y > (*it).y && point.y < (*it).y + (*it).height)){status = gui_msg_movein;}else{status = gui_msg_moveout;}switch ((*it).type){case gui_ctrl_backround:{OnBackround(&(*it), status);}break;case gui_ctrl_txtbutton:{OnTxtButton(&(*it), status);}break;case gui_ctrl_clickbutton:{OnClickButton(&(*it), status);}break;case gui_ctrl_animation:{OnAnimation(&(*it), status);}break;case gui_ctrl_checkbutton:{OnCheckButton(&(*it), status);}break;}}}void cyfGUIPlus::OnDlgDown(CPoint point){for (guiit it = m_guique.begin(); it != m_guique.end(); ++ it){if (true != (*it).visible){continue;}if ((point.x > (*it).x && point.x < (*it).x + (*it).width) && (point.y > (*it).y && point.y < (*it).y + (*it).height)){switch ((*it).type){case gui_ctrl_backround:{OnBackround(&(*it), gui_msg_kickdown);}break;case gui_ctrl_txtbutton:{OnTxtButton(&(*it), gui_msg_kickdown);}break;case gui_ctrl_clickbutton:{OnClickButton(&(*it), gui_msg_kickdown);}break;case gui_ctrl_animation:{OnAnimation(&(*it), gui_msg_kickdown);}break;case gui_ctrl_checkbutton:{OnCheckButton(&(*it), gui_msg_kickdown);}break;}}}}void cyfGUIPlus::OnDlgUp(CPoint point){for (guiit it = m_guique.begin(); it != m_guique.end(); ++ it){if (true != (*it).visible){continue;}if ((point.x > (*it).x && point.x < (*it).x + (*it).width) && (point.y > (*it).y && point.y < (*it).y + (*it).height)){switch ((*it).type){case gui_ctrl_backround:{OnBackround(&(*it), gui_msg_kickup);}break;case gui_ctrl_txtbutton:{OnTxtButton(&(*it), gui_msg_kickup);}break;case gui_ctrl_clickbutton:{OnClickButton(&(*it), gui_msg_kickup);}break;case gui_ctrl_animation:{OnAnimation(&(*it), gui_msg_kickup);}break;case gui_ctrl_checkbutton:{OnCheckButton(&(*it), gui_msg_kickup);}break;}}}}Gdiplus::Bitmap* cyfGUIPlus::LoadImg(UINT nid, char *sourcetype){HINSTANCE hInstance = AfxGetResourceHandle();HRSRC hRsrc = ::FindResource(hInstance, MAKEINTRESOURCE(nid), sourcetype);if (!hRsrc){int res = GetLastError();return NULL;}DWORD len = SizeofResource(hInstance, hRsrc);BYTE *lpRsrc = (BYTE*)LoadResource(hInstance, hRsrc);if (!lpRsrc){return NULL;}HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);BYTE *pmem = (BYTE*)GlobalLock(m_hMem);memcpy(pmem, lpRsrc, len);IStream *pstm;CreateStreamOnHGlobal(m_hMem, FALSE, &pstm);Gdiplus::Bitmap *img = Gdiplus::Bitmap::FromStream(pstm);GlobalUnlock(m_hMem);GlobalFree(m_hMem);pstm->Release();FreeResource(lpRsrc);return img;}Gdiplus::Bitmap* cyfGUIPlus::LoadImg(char *filepath){CFileFind find;int res = find.FindFile(filepath);find.Close();if (0 == res){return NULL;}wchar_t tmp[1024] = {0};mbstowcs(tmp, filepath, sizeof(tmp));return (Gdiplus::Bitmap*)Gdiplus::Image::FromFile(tmp);}int cyfGUIPlus::PushBackround(const char *setname, Gdiplus::Bitmap *img, int x /* = 0 */, int y /* = 0 */, int model /* = 0 */, byte level /* = 0 */){if (m_guique.end() != FindGUI(setname)){return 0;}if (NULL == img){return 0;}gui_ctrl gui = {0};gui.img = img;gui.x = x;gui.y = y;gui.type = gui_ctrl_backround;gui.level = level;gui.model = model;gui.visible = true;gui.width = img->GetWidth();gui.height = img->GetHeight();strcpy(gui.setname, setname);for (guiit it = m_guique.begin(); it != m_guique.end(); ++ it){if (img == (*it).img){if (0 == (*it).imgserial){++ m_imgserail;(*it).imgserial = m_imgserail;}gui.imgserial = (*it).imgserial;break;break;}}m_guique.push_back(gui);LevelSort();return 1;}int cyfGUIPlus::PushTxtButton(const char *setname, char *title, int x /* = 0 */, int y /* = 0 */, byte level /* = 0 */){if (m_guique.end() != FindGUI(setname)){return 0;}gui_ctrl gui = {0};gui.x = x;gui.y = y;gui.type = gui_ctrl_txtbutton;gui.level = level;gui.visible = true;gui.width = GetFontWidth(m_font, title);gui.height = GetFontHeight(m_font);strcpy(gui.setname, setname);strcpy(gui.text, title);m_guique.push_back(gui);LevelSort();return 1;}int cyfGUIPlus::PushClickButton(const char *setname, Gdiplus::Bitmap *img, int x, int y, int model /* = 0 */, byte level /* = 0 */){if (m_guique.end() != FindGUI(setname)){return 0;}if (NULL == img){return 0;}gui_ctrl gui = {0};gui.img = img;gui.x = x;gui.y = y;gui.type = gui_ctrl_clickbutton;gui.level = level;gui.model = model;gui.visible = true;strcpy(gui.setname, setname);switch (gui.model){case gui_clickbtn_modeltwo:{gui.width = img->GetWidth() / 2;}break;case gui_clickbtn_modelthree:{gui.width = img->GetWidth() / 3;}break;case gui_clickbtn_modelfour:{gui.width = img->GetWidth() / 4;}break;}gui.height = img->GetHeight();for (guiit it = m_guique.begin(); it != m_guique.end(); ++ it){if (img == (*it).img){if (0 == (*it).imgserial){++ m_imgserail;(*it).imgserial = m_imgserail;}gui.imgserial = (*it).imgserial;break;break;}}m_guique.push_back(gui);LevelSort();return 1;}int cyfGUIPlus::PushAnimation(const char *setname, Gdiplus::Bitmap *img, int x, int y, int model /* = 0 */, byte level /* = 0 */){return 1;}int cyfGUIPlus::PushCheckButton(const char *setname, const char *group, Gdiplus::Bitmap *img, int x, int y, int model /* = 0 */, byte level /* = 0 */){if (m_guique.end() != FindGUI(setname)){return 0;}if (NULL == img){return 0;}gui_ctrl gui = {0};gui.img = img;gui.x = x;gui.y = y;gui.type = gui_ctrl_checkbutton;gui.level = level;gui.model = model;gui.visible = true;gui.height = img->GetHeight();strcpy(gui.setname, setname);if (NULL != group){strcpy(gui.group, group);}if (gui_checkbtn_modelone == model){gui.width = img->GetWidth();}else if (gui_checkbtn_modeltwo == model){gui.width = img->GetWidth() / 2;}m_guique.push_back(gui);for (guiit it = m_guique.begin(); it != m_guique.end(); ++ it){if (img == (*it).img){if (0 == (*it).imgserial){++ m_imgserail;(*it).imgserial = m_imgserail;}else{gui.imgserial = (*it).imgserial;}break;}}LevelSort();return 1;return 1;}int cyfGUIPlus::SetDefaultFont(int size, bool bold /* = false */, bool underline /* = false */, int transparent /* = 0 */, int r /* = 0 */, int g /* = 0 */, int b /* = 0 */){int fstyle = Gdiplus::FontStyleRegular;if (true == bold){fstyle += Gdiplus::FontStyleBold;}if (true == underline){fstyle += Gdiplus::FontStyleUnderline;}if (NULL != m_font){delete m_font;m_font = NULL;}Gdiplus::Font *newfont = new Gdiplus::Font(L"宋体", size, fstyle);m_font = newfont;if (NULL != m_brush){delete m_brush;m_brush = NULL;}Gdiplus::SolidBrush *newbrush = new Gdiplus::SolidBrush(Gdiplus::Color(transparent, r, g, b));m_brush = newbrush;//记录缺省字体和颜色设置m_size = size;m_bold = bold;m_underline = underline;m_transparent = transparent;m_rgb[0] = r;m_rgb[1] = g;m_rgb[2] = b;return 1;}int cyfGUIPlus::SetText(const char *setname, char *text /* = NULL */, int size /* = 0 */, bool bold /* = false */, bool underline /* = false */, int transparent /* = 0 */, int r /* = 0 */, int g /* = 0 */, int b /* = 0 */){guiit it = FindGUI(setname);if (it == m_guique.end()){return 0;}if (NULL != text){memset((*it).text, 0, sizeof((*it).text));strcpy((*it).text, text);}int fstyle = Gdiplus::FontStyleRegular;if (true == bold){fstyle += Gdiplus::FontStyleBold;}if (true == underline){fstyle += Gdiplus::FontStyleUnderline;}int fsize = size;if (0 == fsize){fsize = m_size;}int ftrnas = transparent;if (0 == ftrnas){ftrnas = m_transparent;}byte rgb[3] = {0};rgb[0] = r;rgb[1] = g;rgb[2] = b;for (int i = 0; i < 3; ++ i){if (0 == rgb[i]){rgb[i] = m_rgb[i];}}if (NULL != (*it).font){delete (*it).font;}Gdiplus::Font *newfont = new Gdiplus::Font(L"宋体", fsize, fstyle);(*it).font = newfont;if (NULL != (*it).brush){delete (*it).brush;}Gdiplus::SolidBrush *newbrush = new Gdiplus::SolidBrush(Gdiplus::Color(ftrnas, rgb[0], rgb[1], rgb[2]));(*it).brush = newbrush;if (gui_ctrl_txtbutton != (*it).type){this->SetTextCenter(&(*it));}else{(*it).width = GetFontWidth((*it).font, (*it).text);(*it).height = GetFontHeight((*it).font);}return 1;}int cyfGUIPlus::GetText(const char *setname, char *text, int tsize){guiit it = FindGUI(setname);if (it == m_guique.end()){return 0;}if (tsize < strlen((*it).text)){return 0;}memcpy(text, (*it).text, sizeof(char) * strlen((*it).text));return 1;}void cyfGUIPlus::SetVisible(const char *setname, bool visible /* = true */){guiit it = FindGUI(setname);if (it == m_guique.end()){return;}(*it).visible = visible;CRect rect;rect.left = (*it).x;rect.right = (*it).x + (*it).width;rect.top = (*it).y;rect.bottom = (*it).y + (*it).height;m_maindlg->InvalidateRect(&rect, FALSE);}void cyfGUIPlus::SetStyle(const char *setname, int style){guiit it = FindGUI(setname);if (it == m_guique.end()){return;}(*it).style = style;Refresh(&(*it));//CHECK类控件如果有组,按下其中某一个时,组内其余控件会自动恢复缺省if (gui_ctrl_checkbutton == (*it).type && 0 != (*it).group[0] && 1 == style){for (guiit ie = m_guique.begin(); ie != m_guique.end(); ++ ie){if (ie == it){continue;}if (0 == strcmp((*it).group, (*ie).group)){(*ie).style = 0;Refresh(&(*ie));}}}}void cyfGUIPlus::SetDisable(const char *setname, bool disable /* = true */){guiit it = FindGUI(setname);if (it == m_guique.end()){return;}if (gui_clickbtn_modelfour != (*it).model || gui_ctrl_clickbutton != (*it).type){return;}(*it).disable = disable;}void cyfGUIPlus::Move(const char *setname, int x, int y){guiit it = FindGUI(setname);if (it == m_guique.end()){return;}(*it).x = x;(*it).y = y;m_maindlg->Invalidate(FALSE);}void cyfGUIPlus::Invalidate(const char *setname){guiit it = FindGUI(setname);if (it == m_guique.end()){return;}CRect rect;rect.left = (*it).x;rect.right = (*it).x + (*it).width;rect.top = (*it).y;rect.bottom = (*it).y + (*it).height;m_maindlg->InvalidateRect(&rect, FALSE);}void cyfGUIPlus::GetPostCtrl(char *setname, int ssize){if (ssize < strlen(m_postname)){return;}strcpy(setname, m_postname);}int cyfGUIPlus::GetWidth(char *setname){guiit it = FindGUI(setname);if (m_guique.end() == it){return 0;}return (*it).width;}int cyfGUIPlus::GetHeight(char *setname){guiit it = FindGUI(setname);if (m_guique.end() == it){return 0;}return (*it).height;}void cyfGUIPlus::GetRECT(char *setname, int *x, int *y){guiit it = FindGUI(setname);if (m_guique.end() == it){return;}if (NULL != x){*x = (*it).x;}if (NULL != y){*y = (*it).y;}}void cyfGUIPlus::LevelSort(){if (m_guique.size() <= 0){return;}guique que;guique tmp[gui_ctrl_lastempty];for (guiit it = m_guique.begin(); it != m_guique.end(); ++ it){for (int i = 0; i < gui_ctrl_lastempty; ++ i){if (i == (*it).type){tmp[i].push_back((*it));}}}for (int i = 0; i < gui_ctrl_lastempty; ++ i){while (tmp[i].size() > 0){guiit ie = tmp[i].end();byte level = 255;for (guiit it = tmp[i].begin(); it != tmp[i].end(); ++ it){if ((*it).level < level){ie = it;level = (*it).level;}}if (ie != tmp[i].end()){que.push_back((*ie));tmp[i].erase(ie);}else //这是出错了{break;}}}m_guique.clear();m_guique = que;}guiit cyfGUIPlus::FindGUI(const char *setname){for (guiit it = m_guique.begin(); it != m_guique.end(); ++ it){if (0 == strcmp(setname, (*it).setname)){return it;}}return m_guique.end();}float cyfGUIPlus::GetFontWidth(Gdiplus::Font *font, char *text){return font->GetSize() * 1.52 * strlen(text) / 2 + strlen(text) * font->GetSize() * 0.05;}float cyfGUIPlus::GetFontHeight(Gdiplus::Font *font){return font->GetSize() * 1.52;}void cyfGUIPlus::SetTextCenter(gui_ctrl *ctrl){if (0 == ctrl->text[0]){return;}if (gui_ctrl_backround != ctrl->type && gui_ctrl_clickbutton != ctrl->type && gui_ctrl_checkbutton != ctrl->type){return;}float txtheight = GetFontHeight(ctrl->font);if (txtheight >= ctrl->height){ctrl->txty = ctrl->y + (float)0;}else{ctrl->txty = ctrl->y + ctrl->height / (float)2 - txtheight / (float)2;}float txtwidth = GetFontWidth(m_font, ctrl->text) - (float)(strlen(ctrl->text)) * (float)(ctrl->font->GetSize()) * (float)0.1;if (txtwidth >= ctrl->width){ctrl->txtx = ctrl->x + (float)0;}else{ctrl->txtx = ctrl->x + ctrl->width / (float)2 - txtwidth / (float)2;}}void cyfGUIPlus::Post(char *setname, int status){strcpy(m_postname, setname);::PostMessage(m_maindlg->m_hWnd, m_msgid, m_wpid, status);}void cyfGUIPlus::Refresh(gui_ctrl *ctrl){CRect rect;rect.left = ctrl->x;rect.right = ctrl->x + ctrl->width;rect.top = ctrl->y;rect.bottom = ctrl->y + ctrl->height;m_maindlg->InvalidateRect(&rect, FALSE);}void cyfGUIPlus::DrawBackround(gui_ctrl *ctrl, Gdiplus::Graphics *graphics){using namespace Gdiplus;if (NULL != ctrl->img){graphics->DrawImage(ctrl->img, Rect((int)ctrl->x, (int)ctrl->y, (int)ctrl->width, (int)ctrl->height), 0, 0, (int)ctrl->width, (int)ctrl->height, UnitPixel);}DrawCtlText(ctrl, graphics);}void cyfGUIPlus::DrawTxtButton(gui_ctrl *ctrl, Gdiplus::Graphics *graphics){using namespace Gdiplus;//1、设想过根据字体的设置颜色,在四种状态下自动变换颜色,发现太TM不靠谱了//Color clr;//brush->GetColor(&clr);//Gdiplus::SolidBrush newbrush(Color(clr.GetAlpha(), clr.GetR(), clr.GetG(), clr.GetB()));if (NULL == ctrl->text || 0 == ctrl->text[0]){return;}Gdiplus::Font *font = ctrl->font;if (NULL == font){font = m_font;}Gdiplus::SolidBrush *brush = ctrl->brush;if (NULL == brush){brush = m_brush;}if (NULL == font || NULL == brush){return;}//2、外面有使用GetTextExtentPoint32来获取字符串宽度的,但测试结果更不靠谱,不知道是不是类似于//打印机原始设备和显示设备之间转换的问题wchar_t txt[512] = {0};mbstowcs(txt, ctrl->text, sizeof(ctrl->text));switch (ctrl->style){case gui_move_out:{RectF lay(ctrl->x, ctrl->y, ctrl->width, ctrl->height);graphics->DrawString((WCHAR*)txt, (int)wcslen(txt), font, lay, NULL, brush);}break;case gui_move_in:{RectF lay(ctrl->x + 1, ctrl->y + 1, ctrl->width, ctrl->height);graphics->DrawString((WCHAR*)txt, (int)wcslen(txt), font, lay, NULL, brush);}break;case gui_kick_down:{RectF lay(ctrl->x + 1, ctrl->y + 1, ctrl->width, ctrl->height);graphics->DrawString((WCHAR*)txt, (int)wcslen(txt), font, lay, NULL, brush);}break;case gui_kick_disable:{RectF lay(ctrl->x, ctrl->y, ctrl->width, ctrl->height);graphics->DrawString((WCHAR*)txt, (int)wcslen(txt), font, lay, NULL, brush);}break;}}void cyfGUIPlus::DrawClickButton(gui_ctrl *ctrl, Gdiplus::Graphics *graphics){using namespace Gdiplus;if (NULL != ctrl->img){graphics->DrawImage(ctrl->img, Rect((int)ctrl->x, (int)ctrl->y, (int)ctrl->width, (int)ctrl->height), 0 + (int)ctrl->style * (int)ctrl->width, 0, (int)ctrl->width, (int)ctrl->height, UnitPixel);}DrawCtlText(ctrl, graphics);}void cyfGUIPlus::DrawAnimation(gui_ctrl *ctrl, Gdiplus::Graphics *graphics){using namespace Gdiplus;}void cyfGUIPlus::DrawCtlText(gui_ctrl *ctrl, Gdiplus::Graphics *graphics){using namespace Gdiplus;if (0 == ctrl->text[0]){return;}Gdiplus::Font *font = ctrl->font;if (NULL == font){font = m_font;}Gdiplus::SolidBrush *brush = ctrl->brush;if (NULL == brush){brush = m_brush;}if (NULL == font || NULL == brush){return;}wchar_t txt[512] = {0};mbstowcs(txt, ctrl->text, sizeof(ctrl->text));int width = (int)GetFontWidth(font, ctrl->text);int height = (int)GetFontHeight(font);RectF lay(ctrl->txtx, ctrl->txty, (float)width, (float)height);graphics->DrawString((WCHAR*)txt, wcslen(txt), font, lay, NULL, brush);}void cyfGUIPlus::DrawCheckButton(gui_ctrl *ctrl, Gdiplus::Graphics *graphics){using namespace Gdiplus;if (NULL != ctrl->img){switch (ctrl->model){case gui_checkbtn_modelone:{if (1 == ctrl->style){graphics->DrawImage(ctrl->img, Rect((int)ctrl->x, (int)ctrl->y, (int)ctrl->width, (int)ctrl->height), 0, 0, (int)ctrl->width, (int)ctrl->height, UnitPixel);}}break;case gui_checkbtn_modeltwo:{if (0 == ctrl->style){graphics->DrawImage(ctrl->img, Rect((int)ctrl->x, (int)ctrl->y, (int)ctrl->width, (int)ctrl->height), 0, 0, (int)ctrl->width, (int)ctrl->height, UnitPixel);}else if (1 == ctrl->style){graphics->DrawImage(ctrl->img, Rect((int)ctrl->x, (int)ctrl->y, (int)ctrl->width, (int)ctrl->height), (int)ctrl->width, 0, (int)ctrl->width, (int)ctrl->height, UnitPixel);}}break;}}DrawCtlText(ctrl, graphics);}void cyfGUIPlus::OnBackround(gui_ctrl *ctrl, int status){switch (ctrl->model){case gui_brmodel_normal:{switch (status){case gui_msg_moveout:{}break;case gui_msg_movein:{}break;case gui_msg_kickdown:{}break;case gui_msg_kickup:{}break;}}break;case gui_brmodel_kick:{switch (status){case gui_msg_moveout:{ctrl->style = gui_move_out;}break;case gui_msg_movein:{ctrl->style = gui_move_in;SetCursor(LoadCursor(NULL, IDC_HAND));}break;case gui_msg_kickdown:{}break;case gui_msg_kickup:{SetCursor(LoadCursor(NULL, IDC_HAND));Post(ctrl->setname, gui_msg_kickup);}break;}}break;}if (ctrl->style == ctrl->oldstyle){return;}ctrl->oldstyle = ctrl->style;Refresh(ctrl);}void cyfGUIPlus::OnTxtButton(gui_ctrl *ctrl, int status){switch (status){case gui_msg_moveout:{ctrl->style = gui_move_out;}break;case gui_msg_movein:{ctrl->style = gui_move_in;SetCursor(LoadCursor(NULL, IDC_HAND));}break;case gui_msg_kickdown:{ctrl->style = gui_kick_down;}break;case gui_msg_kickup:{ctrl->style = gui_move_in;SetCursor(LoadCursor(NULL, IDC_HAND));Post(ctrl->setname, gui_msg_kickup);}break;}if (ctrl->style == ctrl->oldstyle){return;}ctrl->oldstyle = ctrl->style;Refresh(ctrl);}void cyfGUIPlus::OnClickButton(gui_ctrl *ctrl, int status){switch (ctrl->model){case gui_clickbtn_modeltwo:{switch (status){case gui_msg_moveout:{ctrl->style = gui_move_out;}break;case gui_msg_movein:{ctrl->style = gui_move_in;SetCursor(LoadCursor(NULL, IDC_HAND));}break;case gui_msg_kickdown:{}break;case gui_msg_kickup:{SetCursor(LoadCursor(NULL, IDC_HAND));Post(ctrl->setname, gui_msg_kickup);}break;}}break;case gui_clickbtn_modelthree:{switch (status){case gui_msg_moveout:{ctrl->style = gui_move_out;}break;case gui_msg_movein:{ctrl->style = gui_move_in;SetCursor(LoadCursor(NULL, IDC_HAND));}break;case gui_msg_kickdown:{ctrl->style = gui_kick_down;}break;case gui_msg_kickup:{ctrl->style = gui_move_in;SetCursor(LoadCursor(NULL, IDC_HAND));Post(ctrl->setname, gui_msg_kickup);}break;}}break;case gui_clickbtn_modelfour:{if (false == ctrl->disable){switch (status){case gui_msg_moveout:{ctrl->style = gui_move_out;}break;case gui_msg_movein:{ctrl->style = gui_move_in;SetCursor(LoadCursor(NULL, IDC_HAND));}break;case gui_msg_kickdown:{ctrl->style = gui_kick_down;}break;case gui_msg_kickup:{ctrl->style = gui_move_in;SetCursor(LoadCursor(NULL, IDC_HAND));Post(ctrl->setname, gui_msg_kickup);}break;}}}break;}if (ctrl->style == ctrl->oldstyle){return;}ctrl->oldstyle = ctrl->style;Refresh(ctrl);}void cyfGUIPlus::OnAnimation(gui_ctrl *ctrl, int status){}void cyfGUIPlus::OnCheckButton(gui_ctrl *ctrl, int status){if (gui_msg_kickup != status){return;}if (NULL == ctrl->group[0]){if (1 == ctrl->style){ctrl->style = 0;}else if (0 == ctrl->style){ctrl->style = 1;}Refresh(ctrl);}else{if (0 == ctrl->style){ctrl->style = 1;Refresh(ctrl);for (guiit it = m_guique.begin(); it != m_guique.end(); ++ it){if (0 == strcmp(ctrl->group, (*it).group) && 0 != strcmp(ctrl->setname, (*it).setname)){(*it).style = 0;Refresh(&(*it));}}}}Post(ctrl->setname, gui_msg_kickup);}

实际使用时,首先在目标对话框类中声明一个变量

cyfGUIPlus m_gui;
然后进行初始化设置

m_gui.Initialize(this, 10086, 9001);m_gui.SetDefaultFont(10, false, true, 254, 1, 1, 1);
设置相应的控件
Gdiplus::Bitmap *imgbackround = m_gui.LoadImg(IDR_PNG_DLG_MEMBER, "PNG");m_gui.PushBackround("背景", imgbackround, 0, 0);
Gdiplus::Bitmap *imgbtnlogin = m_gui.LoadImg(IDR_PNG_BTN_LOGIN, "PNG");m_gui.PushClickButton("登录按钮", imgbtnlogin, 77, 155, gui_clickbtn_modelthree);
在对话框的三个鼠标消息函数中进行加载

LRESULT memberDlg::OnNcHitTest(CPoint point){LRESULT nHitTest = CDialog::OnNcHitTest(point); return (nHitTest == HTCLIENT) ? HTCAPTION : nHitTest;}void memberDlg::OnSysCommand(UINT nID, LPARAM lParam){CDialog::OnSysCommand(nID, lParam);if(SC_MOVE == (nID &0xFFF0)){PostMessage(WM_NCLBUTTONUP, nID, lParam);}}void memberDlg::OnNcLButtonDown(UINT nHitTest, CPoint point){CDialog::OnNcLButtonDown(nHitTest, point);ScreenToClient(&point);m_gui.OnDlgDown(point);}void memberDlg::OnNcLButtonUp(UINT nHitTest, CPoint point){CDialog::OnNcLButtonUp(nHitTest, point);ScreenToClient(&point);m_gui.OnDlgUp(point);}void memberDlg::OnNcMouseMove(UINT nHitTest, CPoint point){CDialog::OnNcMouseMove(nHitTest, point);ScreenToClient(&point);m_gui.OnDlgMove(point);}

注意鼠标消息函数需要在消息队列中设置

ON_WM_NCHITTEST()ON_WM_SYSCOMMAND()ON_WM_NCLBUTTONDOWN()ON_WM_NCLBUTTONUP()ON_WM_NCMOUSEMOVE()
然后在对话框的绘制函数中加载(这里使用了双缓冲进行绘制)
void memberDlg::OnPaint(){CPaintDC DC(this);using namespace Gdiplus;CDC *pDC = GetDC();CDC memDC;CRect rect;HBITMAP mBitmap;BITMAPINFO bmi;memset(&bmi, 0, sizeof(bmi));GetWindowRect(rect);bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);bmi.bmiHeader.biWidth = rect.Width();bmi.bmiHeader.biHeight = rect.Height();bmi.bmiHeader.biPlanes = 1;bmi.bmiHeader.biBitCount = 32;bmi.bmiHeader.biCompression = BI_RGB;bmi.bmiHeader.biSizeImage = rect.Width() * rect.Height() * 4;mBitmap = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, 0, 0, 0);memDC.CreateCompatibleDC(pDC);memDC.SelectObject(mBitmap);Graphics graphics(memDC.m_hDC);/************************************************************/m_gui.OnDlgDraw(&graphics);/************************************************************/DWORD dwExStyle = GetWindowLong(m_hWnd, GWL_EXSTYLE);if((dwExStyle &0x80000) != 0x80000){SetWindowLong(m_hWnd, GWL_EXSTYLE, dwExStyle^0x80000);}POINT ptWinPos={rect.left, rect.top};SIZE sizeWindow={rect.Width(), rect.Height()};POINT ptSrc={0, 0};BLENDFUNCTION Blend={0, 0, 255, 1};UpdateLayeredWindow(pDC, &ptWinPos, &sizeWindow, &memDC, &ptSrc, 0, &Blend, 2);DeleteObject(mBitmap);memDC.DeleteDC();ReleaseDC(pDC);}
最后在消息函数中处理收到的操作
LRESULT memberDlg::OnMessage(WPARAM wParam, LPARAM lParam){switch (wParam){case 9001:{char ctrl[50] = {0};m_gui.GetPostCtrl(ctrl, sizeof(ctrl));if (0 == strcmp(ctrl, "关闭按钮")){}if (0 == strcmp(ctrl, "登录按钮")){}if (0 == strcmp(ctrl, "记住密码按钮")){}if (0 == strcmp(ctrl, "自动登录按钮")){}if (0 == strcmp(ctrl, "忘记密码按钮")){}if (0 == strcmp(ctrl, "注册账号按钮")){}}break;}return 1;}

其实这个类没啥技术含量,但有了之后,至少自我感觉工作中方便了不少。还有很多不完善的地方,不过慢慢补充就是。



0 0
原创粉丝点击