前面那些教程都是為了讓小夥伴們從win32、MFC過渡到duilib,讓大家覺得duilib不是那麼陌生,如果大家現在還對duilib非常陌生的話,那就說明前面的教程做得不好,請大家在下面留言,我會一一檢視,并做出改進。 從這個教程開始就是見證奇迹的時刻啦~(^o^)/~
其實duilib主打的界面制作方式是XML + UI引擎 + win32架構,其實和浏覽器HTML + CSS + 渲染引擎的方式非常類似,可以将其了解為一個非常mini的浏覽器。
而用duilib寫界面時,大部分是在寫XML,類似于寫HTML,這點可能會讓習慣MFC等windows界面的夥伴們有點不習慣,需要克服克服,相信在看完Alberl的教程之後,就會習慣啦~
前面的教程所使用的界面制作方式大家應該不算陌生,那麼如果用XML來實作,會是什麼樣子呢?
其實也是很簡單的,
1、把if( uMsg == WM_CREATE ) 裡面的代碼改成下面這樣:
if( uMsg == WM_CREATE )
{
m_PaintManager.Init(m_hWnd);
CDialogBuilder builder;
CControlUI* pRoot = builder.Create(_T("duilib.xml"), (UINT)0, NULL, &m_PaintManager); // duilib.xml需要放到exe目錄下
ASSERT(pRoot && "Failed to parse XML");
m_PaintManager.AttachDialog(pRoot);
m_PaintManager.AddNotifier(this); // 添加控件等消息響應,這樣消息就會傳達到duilib的消息循環,我們可以在Notify函數裡做消息處理
return lRes;
}
複制代碼
2、設定XML的路徑: 在CPaintManagerUI::SetInstance(hInstance); 下面調用SetResourcePath函數:
CPaintManagerUI::SetInstance(hInstance);
CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath()); // 設定資源的預設路徑(此處設定為和exe在同一目錄)
3、建立XML: 建立一個XML,檔案名為“duilib.xml”,儲存為UTF-8格式(不要使用windows自帶的記事本編輯,可以使用UltraEdit、EditPlus等編輯器),内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<Window size="800,600"> <!-- 視窗的初始尺寸 -->
<HorizontalLayout bkcolor="#FF00FF00"> <!-- 整個視窗的背景 -->
</HorizontalLayout>
</Window>
4、将"duilib.xml"放到exe目錄下。 現在即可看到一個綠色的視窗,是不是也很簡單呢。
那麼我們繼續來添加Hello World按鈕吧~O(∩_∩)O~
上面的XML隻是描述了視窗的大小和背景色,但是并沒有添加按鈕,下面我們添加一個Hello 按鈕,隻需在XML裡面添加一行即可:
<Button name="btnHello" text="Hello World"/> <!-- 按鈕的屬性,如名稱、文本 -->
再次運作一下exe,是不是又看到了熟悉的畫面,怎麼樣,寫XML很簡單吧~O(∩_∩)O~ :
不過大家可以發現,改成XML後,視窗啟動後不居中了,怎麼辦呢?
在duiFrame.ShowModal上面那行加上duiFrame.CenterWindow();就可以啦
main.cpp的完整代碼如下:
#pragma once
#include
using namespace DuiLib;
#ifdef _DEBUG
# ifdef _UNICODE
# pragma comment(lib, "DuiLib_ud.lib")
# else
# pragma comment(lib, "DuiLib_d.lib")
# endif
#else
# pragma comment(lib, "DuiLib_u.lib")
# pragma comment(lib, "DuiLib.lib")
#endif
class CDuiFrameWnd : public CWindowWnd, public INotifyUI
{
public:
virtual LPCTSTR GetWindowClassName() const { return _T("DUIMainFrame"); }
virtual void Notify(TNotifyUI& msg)
{
if(msg.sType == _T("click"))
if(msg.pSender->GetName() == _T("btnHello"))
{
::MessageBox(NULL, _T("我是按鈕"), _T("點選了按鈕"), NULL);
}
}
virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
LRESULT lRes = 0;
if( uMsg == WM_CREATE )
// 以下3個消息WM_NCACTIVATE、WM_NCCALCSIZE、WM_NCPAINT用于屏蔽系統标題欄
else if( uMsg == WM_NCACTIVATE )
if( !::IsIconic(m_hWnd) )
return (wParam == 0) ? TRUE : FALSE;
else if( uMsg == WM_NCCALCSIZE )
return 0;
else if( uMsg == WM_NCPAINT )
if( m_PaintManager.MessageHandler(uMsg, wParam, lParam, lRes) )
return __super::HandleMessage(uMsg, wParam, lParam);
protected:
CPaintManagerUI m_PaintManager;
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
CPaintManagerUI::SetInstance(hInstance);
CDuiFrameWnd duiFrame;
duiFrame.Create(NULL, _T("DUIWnd"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);
duiFrame.CenterWindow();
duiFrame.ShowModal();
return 0;
}
注意:以上已給出完整代碼,由于最前面的17行是#include等資訊,基本不會變動,是以後面的教程不再列出這些代碼。