书接上文。
前面我们已经建立好test.xml文件了,现在要做的是把刚建好的xml文件和所用到的图标文件打包形成一个压缩包(test.zip)。在VS 编译器中导入这个test.zip的资源。我这里最后形成的ID是IDR_ZIPRES。一切准备就绪,下面就开始代码部分的说明了。
二、创建Dialog
新建一个win32项目,在_tWinMain函数中加入以下代码:
CPaintManagerUI::SetInstance(hInstance);
CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath()); // 设置资源的默认路径(此处设置为和exe在同一目录)
CTestUIDlg *pFrame = new CTestUIDlg(_T("test.xml"));
pFrame->Create(NULL, _T("这是一个最简单的测试用exe,修改test.xml就可以看到效果"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);
pFrame->CenterWindow();
pFrame->ShowModal();
CPaintManagerUI::MessageLoop(); //!消息循环
三、对话框类的介绍
上面代码中CTestUIDlg即是我们的对话框类,它继承于WindowImplBase类,WindowImplBase类是一个XML的包装类,封装了常用操作,以方便大家使用。 它是以XML作为界面描述的,所以用它的时候,我们必须将界面描述写到XML里。
下面是CTestUIDlg类的定义:
using namespace DuiLib;
class CTestUIDlg: public WindowImplBase
{
public:
virtual ~CTestUIDlg(void);
virtual LPCTSTR GetWindowClassName() const
{
return _T("TestButtonDlg");
}
virtual CDuiString GetSkinFile()
{
return m_strXMLPath;
}
virtual CDuiString GetSkinFolder()
{
return _T("");
}
virtual LPCTSTR GetResourceID() const
{
return MAKEINTRESOURCE(IDR_ZIPRES);
}
virtual UILIB_RESOURCETYPE GetResourceType() const
{
return UILIB_ZIPRESOURCE;
}
explicit CTestUIDlg(LPCTSTR pszXMLPath);
virtual void InitWindow();
virtual CControlUI* CreateControl(LPCTSTR pstrClassName);
virtual void Notify(TNotifyUI& msg);
virtual LRESULT HandleMessage(UINT uMsg,WPARAM wParam,LPARAM lParam);
private:
CButtonUI* m_BtnOk;
CButtonUI* m_BtnCancel;
CButtonUI* m_BtnClose;
CPaintManagerUI m_pm;
CDuiString m_strXMLPath;
};
CTestUIDlg类前面实现了一些父类的虚函数,用于返回一些基本信息。最重要的是下面的5个函数,下面为你一一解析。
1、explicit CTestUIDlg(LPCTSTR pszXMLPath);构造函数,同其他构造函数一样,做一些初始化操作。传入的参数是xml文件路径,也就是test.xml的路径。具体代码如下:
CTestUIDlg::CTestUIDlg( LPCTSTR pszXMLPath )
:m_strXMLPath(pszXMLPath)
,m_BtnOk(NULL)
,m_BtnCancel(NULL)
,m_BtnClose(NULL)
{
}
2、void InitWindow();初始化窗口信息,根据前面xml文件中我们说的控件唯一标识,创建空间,其余功能相当于MFC下的OnInitDialog(),用于一些控件的初始化之类的。具体代码如下:
void CTestUIDlg::InitWindow()
{
m_pm = this->m_PaintManager;
CenterWindow();
m_BtnOk = static_cast(m_pm.FindControl(_T("btnTest")));
m_BtnCancel = static_cast(m_pm.FindControl(_T("btnTest2")));
m_BtnClose = static_cast(m_pm.FindControl(_T("btnClose")));
m_BtnClose->SetEnabled(false);
}
3、CControlUI* CreateControl(LPCTSTR pstrClassName);用于自定义控件的创建,暂时先return NULL,后面会为大家介绍到。
4、void Notify(TNotifyUI& msg);操作消息响应,一般用于点击操作等的响应。用于处理duilib自己定义的一套消息,其消息类型请参见duilib的UIDefine.h。具体代码如下:
void CTestUIDlg::Notify( TNotifyUI& msg )
{
if( msg.sType == _T("click") )
{
if(msg.pSender == m_BtnOk)
{
MessageBox(NULL,"点击确定按钮","sure",MB_OK);
}
else if (msg.pSender == m_BtnCancel)
{
MessageBox(NULL,"点击取消定按钮","cancel",MB_OK);
}
if(msg.pSender == m_BtnClose)
{
PostQuitMessage(0);
}
}
}
5、LRESULT HandleMessage(UINT uMsg,WPARAM wParam,LPARAM lParam);消息响应,类似于MFC的DefWindowProc()。部分代码如下:
LRESULT CTestUIDlg::HandleMessage( UINT uMsg,WPARAM wParam,LPARAM lParam )
{
LRESULT lRes = 0;
BOOL bHandled = TRUE;
switch(uMsg)
{
case WM_SIZE: lRes = OnSize(uMsg, wParam, lParam, bHandled); break;
case WM_NCPAINT: lRes = OnNcPaint(uMsg, wParam, lParam, bHandled); break;
case WM_GETMINMAXINFO: lRes = OnGetMinMaxInfo(uMsg, wParam, lParam, bHandled); break;
case WM_SYSCOMMAND: lRes = OnSysCommand(uMsg, wParam, lParam, bHandled); break;
case WM_NCCALCSIZE: lRes = OnNcCalcSize(uMsg, wParam, lParam, bHandled); break;
}
return WindowImplBase::HandleMessage(uMsg,wParam,lParam);
}