CSDN=>FAQ=>FAQ 展示
  • 问题内容:怎样实现Winnap 或者千千静听那样 窗体停靠效果
  • 原讨论链接:http://community.csdn.net/expert/topicview1.asp?id=5105230
  • 所属论坛:界面     审核组:VC/MFC
  • 提问者:AsenWei     解决者:happyness44
  • 感谢:carloshs starytx Saimen
  • 关键字:VC/MFC 窗体 界面 矩形 停靠 nsep m_rectwnd abs dock pwndmain cdockdlg gap
  • 答案:

    如题!
    给个思路 或者给个例子最好!
    ---------------------------------------------------------------

    计算与窗口或屏幕的距离。然后小于多少间距就赋值为0就行了。看着就像粘上了。
    ---------------------------------------------------------------

    以顶部停靠为例
    在OnMove事件中检测窗体的top值,如果小于某个值(比如5),就将top设为0,同时调用MovwWindow即可
    ---------------------------------------------------------------

    在每个窗口的 OnMoving 中处理一下就行啦
    ---------------------------------------------------------------

    需要停靠的窗口
    /////////////////////////////
    BEGIN_MESSAGE_MAP(CDockDlg, CDialog)
    //{{AFX_MSG_MAP(CDockDlg)
    ON_WM_CLOSE()
    ON_WM_MOVING()
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()

    /////////////////////////////////////////////////////////////////////////////
    // CDockDlg message handlers

    void CDockDlg::OnClose() 
    {
    // TODO: Add your message handler code here and/or call default
    CDockWndDlg *pWnd;
    pWnd = (CDockWndDlg *)this->FromHandle(m_hParent);
    pWnd->InverseState();
    }

    BOOL CDockDlg::Init(HWND hParent)
    {
    m_hParent = hParent;
    return Create(IDD_DISPLAY,this->GetDesktopWindow());
    }

    // 定义两个域值
    #define THRESHOLD 1
    #define GAP 30
    void CDockDlg::Dock(UINT nDirection,CWnd *pWndMain)
    {
    // 得到主窗体矩形区域
    CRect rectMain;
    pWndMain->GetWindowRect(&rectMain);

    // 进行停靠操作
    m_nDirection = nDirection;

    if (nDirection == LEAVE)
    m_nDirection = NO_DIRECTION;

    // 不再停靠
    else if (!IsDocking(rectMain,m_rectWnd,nDirection))
    Dock(LEAVE,pWndMain);

    int nSep;
    switch (m_nDirection)
    {
    case LEFT:
    // 从左方停靠
    nSep = rectMain.left - m_rectWnd.right;
    if (abs(nSep) > THRESHOLD && abs(nSep) <= GAP)
    {
    m_rectWnd.OffsetRect(nSep,0);
    Dock(LEFT,pWndMain);
    }
    else if (abs(nSep) > GAP)
    Dock(LEAVE,pWndMain);
    break;
    case RIGHT:
    // 从右边停靠
    nSep = rectMain.right - m_rectWnd.left;
    if (abs(nSep) > THRESHOLD && abs(nSep) <= GAP)
    {
    m_rectWnd.OffsetRect(nSep,0);
    Dock(RIGHT,pWndMain);
    }
    else if (abs(nSep) > GAP)
    Dock(LEAVE,pWndMain);
    break;
    case TOP:
    // 从上边停靠
    nSep = rectMain.top - m_rectWnd.bottom;
    if (abs(nSep) > THRESHOLD && abs(nSep) <= GAP)
    {
    m_rectWnd.OffsetRect(0,nSep);
    Dock(TOP,pWndMain);
    }
    else if (abs(nSep) > GAP)
    Dock(LEAVE,pWndMain);
    break;
    case BOTTOM:
    // 从下面停靠
    nSep = rectMain.bottom - m_rectWnd.top;
    if (abs(nSep) > THRESHOLD && abs(nSep) <= GAP)
    {
    m_rectWnd.OffsetRect(0,nSep);
    Dock(BOTTOM,pWndMain);
    }
    else if (abs(nSep) > GAP)
    Dock(LEAVE,pWndMain);
    break;
    case NO_DIRECTION:
    // 子窗体未停靠
    break;
    case LEAVE:
    // 不再是停靠状态
    m_nDirection = NO_DIRECTION;
    }
    }

    UINT CDockDlg::GetDirection() const
    {
    return m_nDirection;
    }

    BOOL CDockDlg::OnInitDialog() 
    {
    CDialog::OnInitDialog();

    // TODO: Add extra initialization here
    CWnd *pWnd;
    pWnd = this->FromHandle(m_hParent);

    // 得到主窗体矩形
    CRect rectMain;
    pWnd->GetWindowRect(&rectMain);

    // 获得自身矩形
    this->GetWindowRect(&m_rectWnd);

    // 左对齐
    m_rectWnd.right = rectMain.left + m_rectWnd.Width();
    m_rectWnd.left = rectMain.left;

    // 开始将子窗体停靠在主窗体的下方
    m_rectWnd.bottom = rectMain.bottom + m_rectWnd.Height();
    m_rectWnd.top = rectMain.bottom;
    this->MoveWindow(&m_rectWnd);

    return TRUE;  // return TRUE unless you set the focus to a control
                  // EXCEPTION: OCX Property Pages should return FALSE
    }

    void CDockDlg::OnMoving(UINT fwSide, LPRECT pRect) 
    {
    // TODO: Add your message handler code here
    // 得到自身矩形区域
    m_rectWnd.CopyRect(pRect);

    // 得到主窗体指针
    CWnd *pWnd;
    pWnd= this->FromHandle(m_hParent);

    Dock(m_nDirection,pWnd);
    *pRect = m_rectWnd;
    }

    BOOL CDockDlg::IsDocking(CRect &rectMain, CRect &rectMine, UINT nDirection)
    {
    if (nDirection == LEFT || nDirection == RIGHT)
    {
    if (rectMine.top >= rectMain.top && rectMine.top <= rectMain.bottom)
    return TRUE;
    else if (rectMine.bottom >= rectMain.top && rectMine.bottom <= rectMain.bottom)
    return TRUE;
    }
    else if (nDirection == TOP || nDire

  • 评价: 有价值 给朵鲜花(101) 无价值 扔个鸡蛋(15)
相关FAQ
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo