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



相关文章
相关标签/搜索