Duilib教程 自動布局2

2021-08-22 00:25:11 字數 2275 閱讀 8889

在上一節中,我簡單介紹了控制項隨父layout自由移動的設定。在這一節,我將介紹一種常見的情況:嵌入視窗。

uimanager.cpp 第750行:

case wm_size:

;event.type = uievent_windowsize;

event.psender = m_pfocus;

event.dwtimestamp = ::gettickcount();

m_pfocus->event(event);

}if( m_proot != null ) m_proot->needupdate();

}return true;

我們看到,視窗大小改變,root只是簡單的 needupdate,重繪而已,它的大小並沒有設定為與視窗一樣的大小。

在winimplbase.cpp 第214 行:

lresult windowimplbase::onsize(uint umsg, wparam wparam, lparam lparam, bool& bhandled)

#endif

bhandled = false;

return 0;

}

也是啥也沒做。

所以在onsize裡面設定視窗位置,並不會達到效果。

那麼duilib是在**設定root的大小呢?uimanager.cpp 第 615行,即在wm_paint中進行設定。

m_proot->setpos(rcclient);

1.setpos

當你看到這裡時,我想你已經知道第一種方法了。即在 onsize中,

rect rc;

getclientrect (m_hwnd, &rc);

m_paintmanager.getroot()->setpos (rc);

const rect& rc_pos = targer_ui_->getpos ();

::movewindow (move_wnd, rc_pos.left, rc_pos.top, rc_pos.right – rc_pos.left, rc_pos.bottom – rc_pos.top, true);

即我們主動設定大小,root設定了pos後,會將它的子控制項也設定pos,詳情請看原始碼。所以,我們就能夠得到正確的位置資訊了。

但是這並不是最好的方式,原因很簡單,onsize會被頻繁的呼叫,特別是在程式初始化的時候,onsize被呼叫n次,而且在最小化的時候也會被呼叫。而且當你看1.setpos時,你也猜到了會有第二種方式了。

2.委託onsize

假設我們的佔位控制項為 target_ui_,它有乙個委託成員變數:onsize。直接看**吧:

target_ui_->onsize+=makedelegate (this, &cyourwnd::ontargetsizechanged);

bool cyourwnd:: ontargetsizechanged (void* param)

如此簡單,又如此優美的**。

注意使用的是+=

在這裡,我們也看到了作者自己實現了委託的編寫(我不清楚是不是使用了開源庫),可見作者的c++功底是相當深厚的。

看ccontrolui的原始碼,你會發現如下委託物件:

public:

ceventsource oninit;

ceventsource ondestroy;

ceventsource onsize;

ceventsource onevent;

ceventsource onnotify;

顧名思義,無需贅述。

這裡說一下event和notify的區別。

event是控制項自己收到的訊息,比如滑鼠左鍵按下、彈起、雙擊等,duilib先向控制項自己發乙個事件。

notify通知,是向wnd傳送的通知訊息,類似mfc中對話方塊收到控制項的notify(包括按鈕的單擊),它預設情況下是由視窗接收的,在視窗的notify函式中進行響應。

duilib的處理流程是,先向control傳送事件,然後向wnd傳送通知。

onnotify相當有用,因為你可以定製每個控制項的響應,而不需要在wnd的notify中進行一大堆的if..else..了。

onevent用處也很大,看情況使用了。

Duilib教程 自動布局2

在上一節中,我簡單介紹了控制項隨父layout自由移動的設定。在這一節,我將介紹一種常見的情況 嵌入視窗。uimanager.cpp 第750行 case wm size event.type uievent windowsize event.psender m pfocus event.dwtim...

Duilib教程 自動布局1

我們要實現乙個帶標題欄和狀態列的程式,同時要支援拉伸,即包括最小化 最大化,圖如下 在duidesigner中,拖動視窗邊框,即可看到效果,標題欄和狀態列的位置都不變,即隨視窗大小而改變。看屬性,發現,status和title都有屬性 height,而中間的,什麼屬性都沒有。在視窗設定如下 可以知道...

Duilib教程 自動布局1

我們要實現乙個帶標題欄和狀態列的程式,同時要支援拉伸,即包括最小化 最大化,圖如下 在duidesigner中,拖動視窗邊框,即可看到效果,標題欄和狀態列的位置都不變,即隨視窗大小而改變。看屬性,發現,status和title都有屬性 height,而中間的,什麼屬性都沒有。在視窗設定如下 可以知道...