记录duilib自学过程。
最近年底公司也没啥事情,自己就想着上网看看duilib怎么制作界面,因为之前想学习一直没时间,现在来看看。
其实学习的就好办法就是看demo,关于duilib网上的学习教程并不多,自己跟着demo敲一遍代码大概就知道怎么回事了。我自己是下了这个demo.
里面有个duidemo工程,里面有较多控件,基于这个demo就可以修改成自己想要的界面。一边修改一遍学习。
首先是duilib库的引入,我个人是使用DLL的方式,什么头文件源文件一起打包到工程里面,用DLL静态链接的方式引入到win32工程中就可以了。需要引入的头文件是 #include <UIlib.h>
。编译没问题就可以开始了。 按照上面说的是修改duidemo的工程,直接将duidemo文件夹拷贝出来编译下图就是程序运行成功的界面。
可以看出里面已经有很多控件了,那我们需要的关注的就是怎么使用这些控件以及窗口管理。
duilib的消息机制就像是MFC那样的,具体区别我也没太去研究,这里只关注怎么使用。先看工程里面DuiDemo.h和DuiDemo.cpp,程序入口就在DuiDemo.cpp里面,函数如下:
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int nCmdShow)
// 创建主窗口CMainWnd* pMainWnd = new CMainWnd();if( pMainWnd == NULL ) return 0;pMainWnd->Create(NULL, _T("sqlop"), UI_WNDSTYLE_FRAME, 0L, 0, 0, 800, 572);pMainWnd->CenterWindow();
上面就是创建主窗口的代码,重点关注CMainWnd
这个类,找到这个类的文件。duilib的窗口布局都是基于XML文件的,所以CMainWnd首先会找到自己的布局文件XML_MAIN
,这里是做了映射吧,对应的XML文件时main.xml,我没注意看,后续我自己的窗口都是用xxx.xml这种名称加载XML布局文件的。加载布局函数是DuiLib::CDuiString GetSkinFile();
可以看到里面返回了一个XML文件的名称,你可以试试修改成其它错误的名称,就会导致程序报错,因为找不到相应的XML文件。
再来值得关注的函数还有void InitWindow();
这个函数使用了做窗口的初始化的,你可以在里面获取到XML里面的控件对应的句柄,然后用句柄做一些相应的初始胡。比如:
//获取树形控件句柄,控件名称为treeview
CTreeViewUI* treeview = static_cast<CTreeViewUI*>(m_pm.FindControl(_T("treeview")));
if (treeview)
{CTreeNodeUI* pNode = new CTreeNodeUI();pNode->SetFixedHeight(30);pNode->SetItemText(L"123");treeview->AddAt(pNode, 0);pNode->SetAttribute(_T("itemattr"), _T("valign="center""));pNode->SetAttribute(_T("Style"), _T("treeview_item_style"));
}
控件在XML中都是或者这样方式写的,像上面的tree控件在XML写为
<TreeView name="treeview" bkcolor="#ffffffff" visiblefolderbtn="true" visiblecheckbtn="false" vscrollbar="true" >
获取句柄的方式:m_pm.FindControl(_T(“树形控件的name”))),注意使用的时候判断一下句柄是否为空,若是返回NULL还是使用改句柄会造成程序报错。
记获取XML控件句柄方式:CxxxUI* myUI= static_cast<CxxxUI*>(m_pm.FindControl(_T("控件name")));
看看所有控件的父类,你都会发现所有控件都会继承CControlUI
类。所以,所有类都会有一些共用的方法,比如:
virtual void SetVisible(bool bVisible = true);
//控件可见性virtual void SetText(LPCTSTR pstrText);
//设置控件文本
接下来需要关注的函数是void Notify(TNotifyUI& msg);
这个函数会接收窗口的所有消息,所以我们很多响应操作都是在这里完成的。TNotifyUI& msg;
包含了消息的相应类型,可以根据里面的类型进行判断。
CDuiString name = msg.pSender->GetName();
这一句是获取到对应消息的控件的名称,也就是XML文件里面控件的name
属性。
msg.sType;
这个是消息的类型,比如单击为if( msg.sType == _T("click") );
双击树形控件节点为if (msg.sType == DUI_MSGTYPE_TREEITEMDBCLICK);
#define DUI_MSGTYPE_TREEITEMDBCLICK (_T("treeitemdbclick"))
在判断消息类型的时候可以使用UIDefine.h
里面的宏定义也可以直接使用字符串的形式,都是一样的。
上面都是系统消息,duilib也是可以做自定义消息的。
首先要定义消息映射表。
//头文件
DUI_DECLARE_MESSAGE_MAP()
//源文件
DUI_BEGIN_MESSAGE_MAP(CMainPage, CNotifyPump)DUI_END_MESSAGE_MAP()
是不是觉得很熟悉,其实跟MFC的消息映射时一样的,使用PostMessage或者SendMessage都是可以触发消息从而跳转到映射的函数里面,具体不做展开,可以自行百度MFC自定义消息,或者之间百度duilib自定义消息,很简单的。
太多了,就写到这里,还是需要自己去实践使用才能逐渐掌握。下面是我自己做的一个数据库查询工具,数据库是mysql的,所以还添加mysql的库,因为需要导出的文件是xlsx/xls,所以还需要添加libxl库。界面截图。
代码下载链接:https://download.csdn.net/download/qq_27731413/14675848