在工作中经常需要为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 Cyfage
2014-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-字体大小;