65.9K
CodeProject 正在变化。 阅读更多。
Home

类似 3D Studio 的可滑动对话框栏

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.93/5 (27投票s)

2002年2月18日

1分钟阅读

viewsIcon

272788

downloadIcon

8146

你是否见过 3D Studio 2.5 的可滑动对话栏?想知道他们是如何实现的吗?

引言

Kinetix 和 Autodesk 总是以其出色的 GUI 给我留下深刻印象。3D Studio Max 具有用户可以上下滑动的可滑动对话栏……这里是如何自己实现它的方法。这可能是迄今为止我展示过的最简单的代码之一,任何具有 VC++ / MFC 经验的人都可以理解。(我实际上发布它是因为我从未见过其他程序员或公司创建与 3DS Max 类似的 GUI)

这是其背后的神奇理论

  1. 创建一个任何类型的 CWnd 派生类。这将是你的顶级窗口(可以是 CDialog / CDialogBar / CButton 任何...)

    假设 CDialogBarExt .... 派生自 CDialogBar

  2. 创建一个 CWnd 派生类,它将包含实际的滑动对话框。

    假设 CDlgContainer .... 派生自 CWnd

  3. CDialogBarExt 创建一个类型为 CDlgContainer 的成员变量。

  4. 创建一个 CDialog 派生类。

    假设 CInnerDlg (这是实际的滑动对话框!!!)

  5. CDlgContainer 创建一个类型为 CInnerDlg 的成员变量....

所以到目前为止,我们有 CDialogBarExt--->CDlgContainer--->CInnerDlg ? 好的? 下面的代码用于滑动对话框,应该输入到 CInnerDlg

最容易理解的方法是查看代码,它非常简单!!!

void CInnerDlg::OnLButtonUp(UINT nFlags, CPoint point) 
{
    /// IF WE WHERE DRAGGING THEN RELEASE THE MOUSE CAPTURE
    if(m_bDragging)
    {
        ReleaseCapture();
        m_bDragging = FALSE;
    }
    
    CDialog::OnLButtonUp(nFlags, point);
}

void CInnerDlg::OnMouseMove(UINT nFlags, CPoint point) 
{

 int ydiff;

    if(m_bDragging && nFlags & MK_LBUTTON)
    {
       // GET DIALOGS WINDOW SCREEN COORDINATES
       CRect rcWnd;
       GetWindowRect(&rcWnd);

       // GET PARENTS CLIENT RECTANGLE
       CRect prect;
       GetParent()->GetClientRect (prect);

       // IF WE HAVE TO GO DOWN OR UP // 
       if (m_ptDragFrom.y>point.y) {    
          ydiff = point.y - m_ptDragFrom.y;
          posY+=ydiff;
       }// IF WE HAVE TO GO DOWN OR UP // 
       if (m_ptDragFrom.y<point.y) {    
          ydiff = m_ptDragFrom.y -point.y;
          posY-=ydiff;
       }
       //////////////////////////////


       // CALCULATE IF WE ARE GOING TO EXCEED BOTTOM DIALOG BORDER
       int tmp=prect.Height ()-rcWnd.Height ();
       
       // CONSTRAINTS !
       if (posY<tmp+1) posY=tmp+1;
       if (posY>-1) posY=-1;

       // MOVE THE DIALOG 
        SetWindowPos(NULL, 3, 
                     posY, 
                     rcWnd.Width(), 
                     rcWnd.Height(), SWP_SHOWWINDOW|SWP_NOSIZE);


    }    
    
    CDialog::OnMouseMove(nFlags, point);
}

void CInnerDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{
   // START DRAGGING 
   SetCapture();
   m_bDragging = TRUE;
   m_ptDragFrom = point;
   ::SetCursor(AfxGetApp()->LoadCursor (IDC_CURSOR_HAND));
   CDialog::OnLButtonDown(nFlags, point);
}
© . All rights reserved.