現在大家應該都知道caption="0,0,0,32",是指示標題欄區了吧,如果想要整個窗口都能拖動呢? 那直接把高度改成和窗口一樣不就得了~O(∩_∩)O~
嗯,這樣是可以,比如窗口高度是600,那么我們指定caption="0,0,0,600",這樣整個窗口就可以拖動了,但是如果窗口大小改變了呢?假如調整窗口的大小到800,這個時候最下面的200個像素的高度就不能拖動啦,因此這里進行一個改進,也是舉手之勞,在WindowImplBase::OnNcHitTest里的
RECT rcCaption = m_PaintManager.GetCaptionRect(); 下面添加
if (-1 == rcCaption.bottom){rcCaption.bottom = rcClient.bottom;}
這樣只需要指定caption="0,0,0,-1",不管窗口大小如何變,都可以整個窗口拖動啦~
不過問題又來了,當鼠標移到Slider、TreeView等控件上面時,可以發現這些控件都沒有響應啦。這是因為下面只判斷了ButtonUI、OptionUI、TextUI,所以我們需要排除掉其他控件,Slider好辦,加上SliderUI的判斷就OK了,TreeView控件就不能這么加啦,因為TreeView是由很多子控件組成的,很顯然,這里需要遍歷獲取到父窗口,判斷父窗口的類型。然而還有一個問題就是,改了SliderUI之后,可以發現還有ActiveX、Edit、List等一大波控件需要處理,就這樣直接加上十幾個判斷當然可以解決問題,但是如果后面又加了幾個控件呢? 這里不就得跟著改? 因此這里采用排除法,不管之后加一個還是十個控件,都不需要再改動這里。而TreeView控件的遍歷也是一樣,采用排除法,因此Alberl提供了一個函數IsInStaticControl用來判斷是否在靜態控件中,這里的靜態控件和MFC一樣,指的是Static、Text、Picture等文本控件。
這時,我們只需將這段代碼
RECT rcCaption = m_PaintManager.GetCaptionRect();if( pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \&& pt.y >= rcCaption.top && pt.y < rcCaption.bottom ) {CControlUI* pControl = static_cast<CControlUI*>(m_PaintManager.FindControl(pt));if( pControl && _tcsicmp(pControl->GetClass(), _T("ButtonUI")) != 0 && _tcsicmp(pControl->GetClass(), _T("OptionUI")) != 0 &&_tcsicmp(pControl->GetClass(), _T("TextUI")) != 0 )return HTCAPTION;}return HTCLIENT;
換成這段代碼即可:
// bottom為-1時,則整個窗口的高度都可以拖動RECT rcCaption = m_PaintManager.GetCaptionRect();if (-1 == rcCaption.bottom){rcCaption.bottom = rcClient.bottom;}if( pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right&& pt.y >= rcCaption.top && pt.y < rcCaption.bottom ) {CControlUI* pControl = m_PaintManager.FindControl(pt);if (IsInStaticControl(pControl)){return HTCAPTION;}}return HTCLIENT;
IsInStaticControl函數的代碼如下:
// 包含頭文件#include <algorithm> BOOL WindowImplBase::IsInStaticControl(CControlUI *pControl) {BOOL bRet = FALSE;if (! pControl){return bRet;}CDuiString strClassName;std::vector<CDuiString> vctStaticName;strClassName = pControl->GetClass();strClassName.MakeLower();vctStaticName.push_back(_T("controlui"));vctStaticName.push_back(_T("textui"));vctStaticName.push_back(_T("labelui"));vctStaticName.push_back(_T("containerui"));vctStaticName.push_back(_T("horizontallayoutui"));vctStaticName.push_back(_T("verticallayoutui"));vctStaticName.push_back(_T("tablayoutui"));vctStaticName.push_back(_T("childlayoutui"));vctStaticName.push_back(_T("dialoglayoutui"));std::vector<CDuiString>::iterator it = std::find(vctStaticName.begin(), vctStaticName.end(), strClassName);if (vctStaticName.end() != it){CControlUI* pParent = pControl->GetParent();while (pParent){strClassName = pParent->GetClass();strClassName.MakeLower();it = std::find(vctStaticName.begin(), vctStaticName.end(), strClassName);if (vctStaticName.end() == it){return bRet;}pParent = pParent->GetParent();}bRet = TRUE;}return bRet; }
這樣不管大小怎么變,窗口都可以全屏拖動啦~O(∩_∩)O~