duilib 子窗口位置_Duilib学习笔记《02》— 界面布局
2. 簡單空白窗體界面
此處以創建一個簡單的空白的灰色背景窗體為例。對應的XML布局文件對應的也就很簡單。如下:
1<?xml version="1.0" encoding="UTF-8"?>
2
3
4
5
根據字面意思可以很容易看出XML文件所表示的窗體屬性,窗體大小(size)為800X600,窗口圓角大小(roundcorner)為(3,3)等等。
接下來,創建DuilibDemo程序來讀取解析該XML文件創建對應的窗體(注:對應的具體實現代碼暫不作具體解釋,在筆記最后會給出配對的代碼方便下載查閱。本節主要是針對XML窗體布局部分,具體代碼如何顯示后續會具體單獨詳解),效果如下:
3. 標題欄創建
通過第二步中創建的簡單空白窗體,可能發現最終窗體效果和MFC方式創建的并沒什么太大區別。因為上述簡單窗體的創建只是讀取解析XML然后創建對應的窗體,具體的相關消息流程都暫未做處理。所以,接下來,我們通過做一個標題欄的創建來演示說明。
3.1 屏蔽系統標題欄
在此之間,我們得屏蔽掉系統標題欄。在消息處理函數中,我們通過在消息處理函數HandleMessage中對消息WM_NCACTIVATE、WM_NCCALCSIZE、WM_NCPAINT處理來屏蔽系統標題欄,具體屏蔽消息處理代碼如下(可在配對的代碼中查看):
1LRESULT CMainWndDlg::OnNcActivate(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL& bHandled)
2{
3if( ::IsIconic(*this) ) bHandled = FALSE;
4return (wParam == 0) ? TRUE : FALSE;
5}
6LRESULT CMainWndDlg::OnNcCalcSize(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL& bHandled)
7{
8return 0;
9}
10LRESULT CMainWndDlg::OnNcPaint(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL& bHandled)
11{
12return 0;
13}
這樣之后運行就會得到一個不帶系統標題欄的灰色空白窗體。
3.2 創建自繪標題欄
屏蔽系統標題欄之后,接下來就可以創建自繪標題欄了。其實創建自繪標題欄不需要額外修改程序代碼部分,只需要在XML中添加標題欄Caption部
分的布局即可。對于標題欄,我們所熟知的主要是分為兩部分:左上角的title和右上角的系統按鈕。再加上標題欄本身占有一部分區域,而且在該區域可以支
持鼠標拖動窗體的,所有在原有的xml文件基礎上對應的我們需要添加修改的地方有三處:
3.2.1)區域大小聲明。在創建窗體的時候根據需要提前指定窗體可拖動標題欄大小邊距。
1
3.2.2)Title區域
1
2
3
4
5
6
7
3.2.3)系統按鈕區域
1
2
3
4
5
6
7
注意:為了使界面更加美觀,引入了一些圖片資源。比如窗體背景、按鈕圖片等等。具體使用方法很簡單,參考代碼使用即可。雖
然界面效果達到了,但細心的人可能會發現,鼠標點擊標題欄區域時還是會彈出系統自帶的菜單等。這是因為我們目前只是在界面上達到了屏蔽了系統自帶標題欄,
并自繪標題欄的效果,但消息的處理還沒改變。所以此處還需要添加對點擊等操作的消息處理,即在HandleMessage中添加對消息
WM_NCHITTEST的處理。對應OnNcHitTest分支下的處理函數如下:
1LRESULT CMainWndDlg::OnNcHitTest(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL& bHandled)
2{
3POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam);
4::ScreenToClient(*this, &pt);
5RECT rcClient;
6::GetClientRect(*this, &rcClient);
7RECT rcCaption = m_PaintManager.GetCaptionRect();
8if( pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \
9&& pt.y >= rcCaption.top && pt.y < rcCaption.bottom ) {
10CControlUI* pControl =static_cast(m_PaintManager.FindControl(pt));
11if( pControl && _tcscmp(pControl->GetClass(), _T("ButtonUI")) != 0 &&
12_tcscmp(pControl->GetClass(), _T("OptionUI")) != 0 &&
13_tcscmp(pControl->GetClass(), _T("TextUI")) != 0 )
14return HTCAPTION;
15}
16return HTCLIENT;
17}
這樣一來也就達到了預期的效果。當然,這只是最簡單的界面效果,想要得到復雜的界面效果,首先還需要根據實際需要在界面添加相關控件繪制等等。具體
的布局可以直接在上述XML文件中繼續添加完善;其次,還需要對界面一些控件的消息響應的處理,具體消息效應會在后續章節提到。上述布局完成后對應的效果
如下:
4. UIDesigner
Duilib中實際上提供了所見即所得的窗體設計器UIDesigner。如下圖所示:
對于習慣了MFC對話框中直接拖控件來布局的人來說或許很喜歡這個設計器。這個設計器同樣也是可以直接拖放相關控件來完成布局,最終保存會自動生成
對應的XMl文件。如果熟悉了XML布局后,實際上手寫起來或許會更方便,而且對于一些復雜的界面布局來說,手動寫XML文件應該比用該設計器要方便的
多。
5. 補充說明
1)上述的布局只是簡單的布局,在布局中很多控件的屬性可以參考下載的duilib中的“屬性文件.xml”中羅列的信息。
2)全局屬性。在上述最終的Demo圖片中可以發現字體和默認的有些不一樣,實際上是進行了相關設置。對于字體、Default之類的的屬性設置具體參考例子代碼:
1
2
3
4
這里我們定義了四種字體樣式,序號默認從0開始依次遞增。而要具體使用時,如Demo中標題欄的字體設置:
1
這里font=”3″就表示Label中的文字使用序號3對應的這種樣式。
3)布局這塊,上述只是簡單的一個布局,引導大家熟悉。對于如何更好的學會布局,一方面可以隨著后續深入學習,進一步熟悉相關控件及屬性后,要能靈
活運用大到實際例子中;另一方面,一個很好的方法就是查看一些例子,通過例子來學習。對于設計好的布局,可以直接通過UIDesigner來打開XML文
件可以很方便的即時查看界面樣例。
最后附上本節對應的代碼(說明,后續章節都是基于此代碼逐步完善)。代碼下載
總結
以上是生活随笔為你收集整理的duilib 子窗口位置_Duilib学习笔记《02》— 界面布局的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python怎么连接socket_pyt
- 下一篇: hdfs user 连接_Python入