加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

【2】使用DuiLib的XML文件创建界面

发布时间:2020-12-15 22:46:48 所属栏目:百科 来源:网络整理
导读:简述 DuiLib的整体框架图 问:如何创建一个DuiLib的窗口程序? 答:实现一个类,这个类继承自DuiLib的CWindowWnd。 问:如何使得窗口界面和一个XML文件关联起来? 答:在窗口内部从XML文件创建出一个CControlUI对象,然后利用类的内部对象CPaintManagerUI对

简述


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子目录下。

程序示例代码

新建一个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;
}

程序运行结果:
界面显示效果
可以看出来,本示例确实把XML文件定义的界面显示出来了,不过由于本示例只关注了显示效果,没有处理界面的交互,所以不能处理界面的操作,点击关闭按钮程序虽然“消失了”,但是实际上没有退出来,该进程仍然存活,如何处理这一部分就属于后续消息处理的内容了。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读