duilib進階教程 -- 改進窗口拖動 (12)

  如今你們應該都知道caption="0,0,0,32",是指示標題欄區了吧,若是想要整個窗口都能拖動呢? 那直接把高度改爲和窗口同樣不就得了~O(∩_∩)O~ide

  嗯,這樣是能夠,好比窗口高度是600,那麼咱們指定caption="0,0,0,600",這樣整個窗口就能夠拖動了,可是若是窗口大小改變了呢?假如調整窗口的大小到800,這個時候最下面的200個像素的高度就不能拖動啦,所以這裏進行一個改進,也是舉手之勞,在WindowImplBase::OnNcHitTest裏的函數

  RECT rcCaption = m_PaintManager.GetCaptionRect(); 下面添加ui

    if (-1 == rcCaption.bottom)
    {
        rcCaption.bottom = rcClient.bottom;
    }

  這樣只須要指定caption="0,0,0,-1",無論窗口大小如何變,均可以整個窗口拖動啦~spa

  不過問題又來了,當鼠標移到Slider、TreeView等控件上面時,能夠發現這些控件都沒有響應啦。這是由於下面只判斷了ButtonUI、OptionUI、TextUI,因此咱們須要排除掉其餘控件,Slider好辦,加上SliderUI的判斷就OK了,TreeView控件就不能這麼加啦,由於TreeView是由不少子控件組成的,很顯然,這裏須要遍歷獲取到父窗口,判斷父窗口的類型。然而還有一個問題就是,改了SliderUI以後,能夠發現還有ActiveX、Edit、List等一大波控件須要處理,就這樣直接加上十幾個判斷固然能夠解決問題,可是若是後面又加了幾個控件呢? 這裏不就得跟着改? 所以這裏採用排除法,無論以後加一個仍是十個控件,都不須要再改動這裏。而TreeView控件的遍歷也是同樣,採用排除法,所以Alberl提供了一個函數IsInStaticControl用來判斷是否在靜態控件中,這裏的靜態控件和MFC同樣,指的是Static、Text、Picture等文本控件。code

  這時,咱們只需將這段代碼blog

    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;

  換成這段代碼便可:get

    // 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函數的代碼以下:it

// 包含頭文件#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~io



相關文章
相關標籤/搜索