简述@H_404_1@
DuiLib的整体框架图
问:如何创建一个DuiLib的窗口程序?
答:实现一个类,这个类继承自DuiLib的CWindowWnd。
问:如何使得窗口界面和一个XML文件关联起来?
答:在窗口内部从XML文件创建出一个CControlUI对象,然后利用类的内部对象CPaintManagerUI对CControlUI对象做一次AttachDialog,这样XML内容会成为该窗口对象的界面。
常见问题@H_404_1@
- 必须实现的方法:由于CWindowWnd是一个虚基类,所以继承该类的类必须事项CWindowWnd的纯虚方法,所以CWindowWnd的子类必须实现GetWindowClassName方法。
- 什么时候绑定界面到窗口:Windows在创建窗口调用CreateWindow时,CreateWindow会调用一次WndProc,并且要求WndProc返回TRUE,而DuiLib使用HandleMessage函数代理该方法,所以可以在该代理函数的WM_CREATE的阶段绑定界面,但是需要注意的是,默认情况下该代理函数不能直接返回0。
- XML文件位置:查看DuiLib的源码会发现,DuiLib有两种模式加载皮肤文件,一种是直接加载XML文件,且该方法要求XML文件和程序文件处在同一个目录,另外一种方法是加载皮肤包,改皮肤包是放在程序所在目录的skin子目录下。
程序示例代码@H_404_1@
新建一个WIN32的空工程,然后编写一个DuiLib的子类实现上述的内容,即做一个使用XML作为界面的DuiLib程序。这里想通过DuiLib构建一个QQ聊天窗口的程序,不过由于对XML文件编写不熟,所以界面内容部分用了DuiLib的测试工程里的XML文件,而代码部分自己实现了,且实现的是最小的程序。
// QQTalk.h文件
#ifndef __QQ_TALK_H__
#define __QQ_TALK_H__
#include <DuiLib/DuiLibEnv.h>
#include <DuiLib/UIlib.h>
using namespace DuiLib;
#define QQ_TALK_XML _T("QQTalk.xml")
class CQQTalk : public CWindowWnd
{
public:
virtual LPCTSTR GetWindowClassName() const; // CWindowWnd的纯虚函数,必须实现
// 窗口消息处理回调函数
virtual LRESULT HandleMessage( UINT uMsg,WPARAM wParam,LPARAM lParam );
protected:
CPaintManagerUI m_paintManager; // 窗口消息类管理对象
private:
static LPCTSTR m_lpszWndClsName; // 窗口类名
};
#endif
// QQTalk.cpp文件
#include "QQTalk.h"
#include <exception>
LPCTSTR CQQTalk::m_lpszWndClsName = _T("QQTalk");
LPCTSTR CQQTalk::GetWindowClassName() const
{
return m_lpszWndClsName;
}
LRESULT CQQTalk::HandleMessage( UINT uMsg,LPARAM lParam )
{
switch(uMsg)
{
case WM_CREATE:
{
m_paintManager.Init(m_hWnd);
CDialogBuilder builder;
CControlUI* pRoot = builder.Create(QQ_TALK_XML,(UINT)0,NULL,&m_paintManager);
ASSERT(pRoot && "Failed to parse XML");
m_paintManager.AttachDialog(pRoot);
return 0;
}
case WM_DESTROY:
{
::PostQuitMessage(0L);
return 0;
}
default:
{
LRESULT lRes = 0;
if( m_paintManager.MessageHandler(uMsg,wParam,lParam,lRes) )
{
return lRes;
}
else
{
return CWindowWnd::HandleMessage(uMsg,lParam);
}
}
}
}
// main.cpp
// 测试文件
#include "QQTalk.h"
int WINAPI wWinMain( __in HINSTANCE hInstance,__in_opt HINSTANCE hPrevInstance,__in LPWSTR lpCmdLine,__in int nShowCmd )
{
// 初始化CPaintManagerUI
CPaintManagerUI::SetInstance(hInstance);
CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());
// 这一步可选
// CoInitialize是Windows提供的API函数
// 用来告诉 Windows以单线程的方式创建com对象
HRESULT Hr = ::CoInitialize(NULL);
if( Failed(Hr) ) return 0;
// 创建一个QQ对话界面
CQQTalk* pQQTalkDlg = new CQQTalk();
pQQTalkDlg->Create(NULL,_T("和XXX的对话"),UI_WNDSTYLE_FRAME,WS_EX_WINDOWEDGE);
pQQTalkDlg->CenterWindow();
pQQTalkDlg->ShowModal();
CPaintManagerUI::MessageLoop();
delete pQQTalkDlg; pQQTalkDlg = NULL;
// 逆初始化
::CoUninitialize();
return 0;
}
程序运行结果:
DuiLib的整体框架图
问:如何创建一个DuiLib的窗口程序?
答:实现一个类,这个类继承自DuiLib的CWindowWnd。
问:如何使得窗口界面和一个XML文件关联起来?
答:在窗口内部从XML文件创建出一个CControlUI对象,然后利用类的内部对象CPaintManagerUI对CControlUI对象做一次AttachDialog,这样XML内容会成为该窗口对象的界面。
- 必须实现的方法:由于CWindowWnd是一个虚基类,所以继承该类的类必须事项CWindowWnd的纯虚方法,所以CWindowWnd的子类必须实现GetWindowClassName方法。
- 什么时候绑定界面到窗口:Windows在创建窗口调用CreateWindow时,CreateWindow会调用一次WndProc,并且要求WndProc返回TRUE,而DuiLib使用HandleMessage函数代理该方法,所以可以在该代理函数的WM_CREATE的阶段绑定界面,但是需要注意的是,默认情况下该代理函数不能直接返回0。
- XML文件位置:查看DuiLib的源码会发现,DuiLib有两种模式加载皮肤文件,一种是直接加载XML文件,且该方法要求XML文件和程序文件处在同一个目录,另外一种方法是加载皮肤包,改皮肤包是放在程序所在目录的skin子目录下。
程序示例代码@H_404_1@
新建一个WIN32的空工程,然后编写一个DuiLib的子类实现上述的内容,即做一个使用XML作为界面的DuiLib程序。这里想通过DuiLib构建一个QQ聊天窗口的程序,不过由于对XML文件编写不熟,所以界面内容部分用了DuiLib的测试工程里的XML文件,而代码部分自己实现了,且实现的是最小的程序。
// QQTalk.h文件
#ifndef __QQ_TALK_H__
#define __QQ_TALK_H__
#include <DuiLib/DuiLibEnv.h>
#include <DuiLib/UIlib.h>
using namespace DuiLib;
#define QQ_TALK_XML _T("QQTalk.xml")
class CQQTalk : public CWindowWnd
{
public:
virtual LPCTSTR GetWindowClassName() const; // CWindowWnd的纯虚函数,必须实现
// 窗口消息处理回调函数
virtual LRESULT HandleMessage( UINT uMsg,WPARAM wParam,LPARAM lParam );
protected:
CPaintManagerUI m_paintManager; // 窗口消息类管理对象
private:
static LPCTSTR m_lpszWndClsName; // 窗口类名
};
#endif
// QQTalk.cpp文件
#include "QQTalk.h"
#include <exception>
LPCTSTR CQQTalk::m_lpszWndClsName = _T("QQTalk");
LPCTSTR CQQTalk::GetWindowClassName() const
{
return m_lpszWndClsName;
}
LRESULT CQQTalk::HandleMessage( UINT uMsg,LPARAM lParam )
{
switch(uMsg)
{
case WM_CREATE:
{
m_paintManager.Init(m_hWnd);
CDialogBuilder builder;
CControlUI* pRoot = builder.Create(QQ_TALK_XML,(UINT)0,NULL,&m_paintManager);
ASSERT(pRoot && "Failed to parse XML");
m_paintManager.AttachDialog(pRoot);
return 0;
}
case WM_DESTROY:
{
::PostQuitMessage(0L);
return 0;
}
default:
{
LRESULT lRes = 0;
if( m_paintManager.MessageHandler(uMsg,wParam,lParam,lRes) )
{
return lRes;
}
else
{
return CWindowWnd::HandleMessage(uMsg,lParam);
}
}
}
}
// main.cpp
// 测试文件
#include "QQTalk.h"
int WINAPI wWinMain( __in HINSTANCE hInstance,__in_opt HINSTANCE hPrevInstance,__in LPWSTR lpCmdLine,__in int nShowCmd )
{
// 初始化CPaintManagerUI
CPaintManagerUI::SetInstance(hInstance);
CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());
// 这一步可选
// CoInitialize是Windows提供的API函数
// 用来告诉 Windows以单线程的方式创建com对象
HRESULT Hr = ::CoInitialize(NULL);
if( Failed(Hr) ) return 0;
// 创建一个QQ对话界面
CQQTalk* pQQTalkDlg = new CQQTalk();
pQQTalkDlg->Create(NULL,_T("和XXX的对话"),UI_WNDSTYLE_FRAME,WS_EX_WINDOWEDGE);
pQQTalkDlg->CenterWindow();
pQQTalkDlg->ShowModal();
CPaintManagerUI::MessageLoop();
delete pQQTalkDlg; pQQTalkDlg = NULL;
// 逆初始化
::CoUninitialize();
return 0;
}
程序运行结果:
新建一个WIN32的空工程,然后编写一个DuiLib的子类实现上述的内容,即做一个使用XML作为界面的DuiLib程序。这里想通过DuiLib构建一个QQ聊天窗口的程序,不过由于对XML文件编写不熟,所以界面内容部分用了DuiLib的测试工程里的XML文件,而代码部分自己实现了,且实现的是最小的程序。// QQTalk.h文件 #ifndef __QQ_TALK_H__ #define __QQ_TALK_H__ #include <DuiLib/DuiLibEnv.h> #include <DuiLib/UIlib.h> using namespace DuiLib; #define QQ_TALK_XML _T("QQTalk.xml") class CQQTalk : public CWindowWnd { public: virtual LPCTSTR GetWindowClassName() const; // CWindowWnd的纯虚函数,必须实现 // 窗口消息处理回调函数 virtual LRESULT HandleMessage( UINT uMsg,WPARAM wParam,LPARAM lParam ); protected: CPaintManagerUI m_paintManager; // 窗口消息类管理对象 private: static LPCTSTR m_lpszWndClsName; // 窗口类名 }; #endif
// QQTalk.cpp文件 #include "QQTalk.h" #include <exception> LPCTSTR CQQTalk::m_lpszWndClsName = _T("QQTalk"); LPCTSTR CQQTalk::GetWindowClassName() const { return m_lpszWndClsName; } LRESULT CQQTalk::HandleMessage( UINT uMsg,LPARAM lParam ) { switch(uMsg) { case WM_CREATE: { m_paintManager.Init(m_hWnd); CDialogBuilder builder; CControlUI* pRoot = builder.Create(QQ_TALK_XML,(UINT)0,NULL,&m_paintManager); ASSERT(pRoot && "Failed to parse XML"); m_paintManager.AttachDialog(pRoot); return 0; } case WM_DESTROY: { ::PostQuitMessage(0L); return 0; } default: { LRESULT lRes = 0; if( m_paintManager.MessageHandler(uMsg,wParam,lParam,lRes) ) { return lRes; } else { return CWindowWnd::HandleMessage(uMsg,lParam); } } } }
// main.cpp // 测试文件 #include "QQTalk.h" int WINAPI wWinMain( __in HINSTANCE hInstance,__in_opt HINSTANCE hPrevInstance,__in LPWSTR lpCmdLine,__in int nShowCmd ) { // 初始化CPaintManagerUI CPaintManagerUI::SetInstance(hInstance); CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath()); // 这一步可选 // CoInitialize是Windows提供的API函数 // 用来告诉 Windows以单线程的方式创建com对象 HRESULT Hr = ::CoInitialize(NULL); if( Failed(Hr) ) return 0; // 创建一个QQ对话界面 CQQTalk* pQQTalkDlg = new CQQTalk(); pQQTalkDlg->Create(NULL,_T("和XXX的对话"),UI_WNDSTYLE_FRAME,WS_EX_WINDOWEDGE); pQQTalkDlg->CenterWindow(); pQQTalkDlg->ShowModal(); CPaintManagerUI::MessageLoop(); delete pQQTalkDlg; pQQTalkDlg = NULL; // 逆初始化 ::CoUninitialize(); return 0; }
程序运行结果: