文件名称:RINGSDK包含界面库和图象库。
文件大小:7.41MB
文件格式:RAR
更新时间:2014-10-06 04:19:45
RingSDK,界面库
RINGSDK包含界面库和图象库。
本项目为编译环境为VC6,需要先安装platform sdk.不断修改中,会陆续上传其他相关文档及DEMO
设置:
VC6菜单tools->Options,选择Directoris页,把include,lib目录加入到相应文件列表,如果要调试,需要把libsrc目录下的各个子目录加入到Source files文件列表中。
工程依赖几个第三方库,需要先编译livsrc\free_lib下几个目录的工程,然后打开ringsdk.dsw编译。工程都已经设置好了,编译即可。
由于VC的智能提示不能识别界面库里的宏,因此建议安装VA(Visual.Assist)
创建基于RingSDK的工程:
新建一个Win32 Application的工程,不要让VC写任何代码,空的工程。然后选择菜单Project->settings...,
选择C/C++页,Category选择Code Generation,然后在Use run-time library选择:
DEBUG选择Debug Multithreaded
RELEASE选择MultiThreaded
工程设置完毕,然后可以加入CPP和H文件了。
类库使用:
1、头文件:
头文件包含"ringmain.h"就可以,如果要使用图象库,还需要包含"ringdib.h"
2、窗口类声明:
窗口定义为如下格式:
BEGIN_SETUPWINDOW(窗口名,窗口类型)
BINNDID(对话框ID) //当窗口类型是对话框才需要写这个宏,且是可选的,即不写也可以
BEGIN_DEF_VAR(初始化标记)
//这里定义类成员数据
END_DEF_VAR
//这里定义类成员函数
//定义窗口消息处理函数
BEGIN_DEFMSG
DEFMSG(消息代码)
DEFMSGEX(自定义消息处理函数名)
...
DEFCMD(命令处理函数名)
...
DEFNOTIFY(通知消息代码)
END_DEFMSG(窗口名)
END_SETUPWINDOW(窗口名)
这里对上面代码中的中文进行说明:
窗口名:窗口名同时也是该窗口类的对象名,比如窗口名为MainWindow,则该窗口类名为RingWnd_MainWindow,
同时声明了RingWnd_MainWindow* MainWindow=NULL;
以后只要调用MainWindow = NewRingObj(MainWindow);然后MainWindow就可以使用了。
以上代码相当于:
class RingWnd_MainWindow
{
...
}
RingWnd_MainWindow* MainWindow=NULL;
类名可以用RINGCLASS(窗口名)宏来得到
窗口类型:为IS_WINDOW,IS_MDIFRAME,IS_MDICHILD,IS_DIALOG,IS_PROPPAGE,IS_PROPSHEET这几个值之一,一看名称就知道,不需要多讲了。
其实这个只是声明了窗口类是从哪个类继承。
初始化标记:为NEED_INIT和NO_INIT两个值之一,指定了是否需要成员数据的初始化,一般成员数据的初始化可以在WM_CREATE消息里完成,
如果需要事先初始化,可以指定NEED_INIT,但是需要在CPP文件实现一个INITWINDOW(窗口名)的函数,进行初始化。
这个BEGIN_DEF_VAR(初始化标记)和END_DEF_VAR是可选的,即可以不写这两个宏,一样可以声明成员数据或函数。
消息代码:窗口消息代码,例:WM_CREATE
自定义消息处理函数名:响应自定义消息的处理函数,这个可以随便取名,例:OnCustomMessage
命令处理函数名:响应菜单命令或控件命令的处理函数,这个可以随便取名,例:OnOpenFile,OnButton1Click
通知消息代码:控件的通知消息代码,例:LVN_SELECTCHANGE
对话框ID:当窗口类型是对话框才需要写这个宏,且是可选的,即不写也可以。写了这句,对话框创建时可以不写参数,例:
BEGIN_SETUPWINDOW(DlgAbout,IS_DIALOG)
BINDID(IDD_ABOUT)
...
这样创建:
DlgAbout = NewRingObj(DlgAbout);
DlgAbout->DoModal();
就弹出了对话框。
如果没有BINGID,则创建时需要写参数:DlgAbout->DoModal(MAKEINTRESOURCE(对话框ID));
3、主窗口:
主窗口的窗口名固定为window,有且只有一个主窗口,定义时可以用另外一套宏,不用写该窗口名:
BEGIN_SETUPMAINWINDOW(窗口类型)
BEGIN_DEF_VAR(初始化标记)
//这里定义类成员数据
END_DEF_VAR
//这里定义类成员函数
//定义窗口消息处理函数
BEGIN_DEFMSG
DEFMSG(消息代码)
DEFMSGEX(自定义消息处理函数名)
...
DEFCMD(命令处理函数名)
...
DEFNOTIFY(通知消息代码)
END_DEFMAINMSG
END_SETUPMAINWINDOW
主窗口创建后可以就调用window->成员函数()
4、消息注册:
窗口消息的处理需要注册,注册后才会调用相应的处理函数,注册的消息处理函数必须已声明过(用DEFMSG,DEFCMD等声明过),格式如下:
BEGIN_REGMSG(窗口名)
REGMSG(消息代码)
REGMSGEX(自定义消息代码,自定义消息处理函数名)
...
REGCMD(命令代码,命令处理函数名)
REGCMDRANGE(命令代码起始值,命令代码终止值,命令处理函数名)
...
REGNOTIFY(通知消息代码)
...
END_REGMSG
这段代码应该放在CPP文件,其中的中文意思上面已经说明过了,命令代码为菜单命令或控件ID,例:CM_OPEN,IDC_BUTTON1
主窗口的消息注册同样可以用MAIN代替而不用写窗口名,即:BEGIN_REGMAINMSG
注:REGCMD和REGMSG其实有一个冲突的地方,就是WM_COMMAND,这个要看WM_COMMAND放置的次序,REGMSG(WM_COMMAND)之前的
REGCMD的函数会执行,之后的REGCMD的函数则会被屏蔽,不会执行到,不管WM_COMMAND消息里是否处理了这些命令。
5、主函数及创建主窗口:
界面库封装了WinMain,因此主入口函数改成了RingMain,函数原型为:
int RingMain()
必须实现该函数,在函数内创建主窗口。创建主窗口可以用以下宏:
APP_CREATEWINDOW(窗口标题,窗口类名,窗口类型,菜单资源字符串);
APP_CREATEWINDOWEX(窗口标题,窗口类名,窗口类型,窗口扩展类型,菜单资源字符串);
APP_CREATEDIALOG(对话框资源字符串);
这里的窗口类名不是C++的类,而是注册窗口时的窗口类名,以后可以调用API函数FindWindow(窗口类名,窗口标题)来查找窗口。
同样窗口类型不是上面提到的窗口类型,而是WS_OVERLAPPEDWINDOW之类数值。
资源字符串如果是定义了ID,需要用MAKEINTRESOURCE(ID)转换。
窗口消息循环:界面库内建了一个RingApp对象,可以调用RingApp.Run()来启动消息循环。
综上所述,RingMain的一般实现为:
int RingMain()
{
APP_CREATEWINDOW("RingSDK演示程序","RINGSDK_DEMO",WS_OVERLAPPEDWINDOW,MAKEINTRESOURCE(IDR_MAINMENU));
return RingApp.Run();
}
程序的启动参数可以用LPSTR lpszCmdLine = RingApp.GetCmdLine()来得到。
程序实例句柄可以用GetInstance()来得到。
6、窗口消息处理:
界面库封装了窗口过程,用户注册了消息处理函数,窗口过程会自动调用这些函数,因此只需实现这些处理函数。函数原型为:
RINGMSG(窗口名,消息代码或自定义消息处理函数名)
如果是主窗口的窗口消息,为:
RINGMAINMSG(消息代码或自定义消息处理函数名)
例:RINGMAINMSG(WM_CREATE)
这两个宏隐藏了参数,上例展开为:LRESULT RingWnd_window::On_WM_CREATE(HWND hWnd,RINGPARAMS& param)
RINGPARAMS的结构定义为:
typedef struct tagRingParams
{
UINT uMsg; //窗口消息
union
{
struct
{
WORD low; //wParam
WORD high; //wParam
}shortval; //wParam
HDC hdc; //wParam
HRGN hrgn; //WM_NCPAINT,etc.
WPARAM wParam;
};
union
{
LPCREATESTRUCT lpcreate; //WM_CREATE(lParam)
LPNMHDR lpnmhdr; //WM_NOTIFY(lParam)
LPROPVNOTIFY lpropvnm; //for OptionView NOTIFY(lParam)
LPWINDOWPOS lpwindowpos; //WM_WINDOWPOSXXX(lParam)
LPDRAWITEMSTRUCT lpdrawitem; //WM_DRAWITEM(lParam)
LPMEASUREITEMSTRUCT lpmeasureitem; //WM_MEASUREITEM(lParam)
LPNCCALCSIZE_PARAMS lpncsp; //WM_NCCALCSIZE(lParam)
LPDELETEITEMSTRUCT lpdeleteitem; //WM_DELETEITEM(lParam)
LPNMTREEVIEW lpnmtreeview; //WM_NOTIFY(lParam-treeview)
LPNMLISTVIEW lpnmlistview; //WM_NOTIFY(lParam-listview)
POINTS mousept; //鼠标消息(lParam)
HANDLE handle; //(lParam)
DWORD dwval; //(lParam)
int intval; //(lParam)
LPARAM lParam;
};
}RINGPARAMS,*LPRINGPARAMS;
因此可以在函数内部使用param来访问消息参数,例:
RINGMAINMSG(WM_CREATE)
{
if(param.lpcreate->lpCreateParams)
...
return 0;
//return DefaultProc(param); //如果需要可以调用系统默认处理函数
}
命令处理:
RINGCMD(窗口名,命令处理函数名)
如果是主窗口的窗口消息,为:
RINGMAINCMD(命令处理函数名)
例:RINGMAINCMD(OnButton1Click)
这个宏同样隐藏了一个参数:event,表示控件的NOTIFY消息,如EN_UPDATE等
7、窗口类对象指针的有效性判断及获取:
可以根据窗口句柄获取窗口对象指针:
RingWnd* pwnd = (RingWnd*)GetWindowPtr(hWnd);
判断窗口对象指针是否有效(对象已创建且已创建窗口):
BOOL bIsValid = IswindowPtr(pwnd);
8、创建子窗口:
子窗口类声明并注册完消息后,可以用NewRingObj来产生对象,如定义了窗口类ChildWin,这样创建:
ChildWin = NewRingObj(ChildWin);
ChildWin->Create(窗口标题,窗口类名,窗口类型,窗口扩展类型,x,y,width,height,父窗口句柄,菜单句柄,LPARAM);
从窗口扩展类型参数开始,后面的参数都有默认值,可以不写。
NewRingObj为产生窗口类对象,函数原型为:
template