先简单介绍一下:继承CWndSplitter类的CSpliiterDlg类,为了能在对话框的Edit Control中画两条分割线,一条将edit control分割为上下两半,另一条将上面的部分再分为两半,在右上,左上,下,三个部分中分别加入LISTVIEW或TreeView控件。
现在的问题是,我想要限制这两条分割线的移动范围。我重载了OnMouseMove,OnLButtonDown和OnLButtonUp,虽然能够大致限制其范围。但是有时鼠标拖动得快点,这种限制会失效。并且在达到限制临界点时,还是可以一点点的移动分割线。怎么解决这个问题呢?
多谢指导。

解决方案 »

  1.   

    不行吗?在OnSize中重设视图的尺寸应该可以的。
      

  2.   

    加了onsize之后,画面会混乱……    m_wndSplitterX.CreateStatic(this, 2, 1);
    //CInvRecordList继承CListView
        m_wndSplitterX.CreateView(1,0,RUNTIME_CLASS(CInvRecordList), CSize(0,30), NULL);    m_wndSplitterY.CreateStatic(&m_wndSplitterX, 1, 2, WS_CHILD|WS_VISIBLE, m_wndSplitterX.IdFromRowCol(0, 0)); 
    //CInvItemTree继承CTreeView
        m_wndSplitterY.CreateView(0,0,RUNTIME_CLASS(CInvItemTree), CSize(50,50), NULL);
    //CInvItemDetailList继承CListView
        m_wndSplitterY.CreateView(0,1,RUNTIME_CLASS(CInvItemDetailList), CSize(0,50), NULL);
    //IDC_EDITSPLITTER是EDIT CONTROL
        CRect rect;
        GetDlgItem(IDC_EDITSPLITTER)->GetWindowRect(&rect);
        ScreenToClient(&rect);
        m_wndSplitterX.MoveWindow(&rect);    m_wndSplitterX.SetRowInfo(0, 150, 0);
        //m_wndSplitterX.SetRowInfo(1, 150, 100);
        m_wndSplitterX.RecalcLayout();这是splitter的create代码,应该么问题吧,为什么会产生混乱呢……
      

  3.   

    楼主如果放treelist等控件放到edit是没必要的啊
    完全可以直接放对话框上,可以上网找下有人写个splitterBar类
    比那个重写splitterWnd类好用的多多了,感觉重写那个不是特别稳定,那时你再限制试试
      

  4.   

    给你个思路看看能不能行其实你可以用一个bool来开启和关闭拖动控制这个bool条件则是几个视图的大小只要被分隔的几部分限定了长或宽 当小于这个长宽的时候 控制bool是true or false 在用bool判断语句控制分隔线是否可拖动.主要就是根据规定几个视图的窗口上下限来限制分割线
      

  5.   

    void CxxxDialog::OnSize(UINT nType, int cx, int cy) 
    {
       CDialog::OnSize(nType, cx, cy);   CRect rect;
       GetWindowRect( &rect );
       if( m_bSplitterCreated )  // m_bSplitterCreated set in OnCreateClient
       {
    m_wndSplitterX.SetRowInfo(0, 150, 10);
           m_wndSplitterY.SetColumnInfo(0, rect.Width()/2, 10);
           m_wndSplitterY.SetColumnInfo(1, rect.Width()/2, 10);
          m_wndSplitterX.RecalcLayout();
       }
    }
      

  6.   


    但是有时鼠标拖动得快点,这种限制会失效。并且在达到限制临界点时,还是可以一点点的移动分割线在mousemove里处理不大好  该做计时器的方式 当鼠标在分割线中lbuttondown的时候 启动计时器 抬起的时候关闭计时器.这样那条线肯定不会乱跑
      

  7.   

    void CSplitterWndEx::OnMouseMove(UINT nFlags, CPoint point) 
    {
    if ( m_bTracking && GetCapture() == this )
    {
    // Work out which panes are left or above the splitter (horiz and vert).
    bool bSizingCol = false;
    bool bSizingRow = false;
    int nCol;
    int nRow;

    if ( m_htTrack >= hSplitterBar1 && m_htTrack <= hSplitterBar15 )
    {
    nCol = m_htTrack - hSplitterBar1;
    bSizingCol = true;
    }
    else if ( m_htTrack >= vSplitterBar1 && m_htTrack <= vSplitterBar15 )
    {
    nRow = m_htTrack - vSplitterBar1;
    bSizingRow = true;
    }
    else if ( m_htTrack >= splitterIntersection1 && m_htTrack <= splitterIntersection225 )
    {
    nCol = ( m_htTrack - splitterIntersection1 ) % 15;
    nRow = ( m_htTrack - splitterIntersection1 ) / 15;
    bSizingCol = true;
    bSizingRow = true;
    } // if

    // Get client rect for limit calculations.
    CRect rectClient;
    GetClientRect( rectClient );

    point.Offset( m_ptTrackOffset ); // point is the upper right of hit detect

    // Limit row.
    if ( bSizingRow )
    {
    int nLimit1 = m_cyBorder; // Start with top border.

    // If top splitter...
    if ( nRow == 0 )
    {
    nLimit1 += m_pRowInfo[ 0 ].nMinSize; // ...just add first row minimum size.
    }
    // If pane above splitter at minimum size...
    else if ( m_pRowInfo[ nRow ].nCurSize == m_pRowInfo[ nRow ].nMinSize )
    {
    for ( int i = 0; i < nRow; i++ )
    {
    nLimit1 += m_pRowInfo[ i ].nCurSize; // ...add previous rows' sizes and splitters.
    nLimit1 += m_cySplitter;
    } // for
    nLimit1 += m_pRowInfo[nRow].nCurSize;
    }
    // Otherwise...
    else
    {
    for ( int i = 0; i < nRow; i++ )
    {
    nLimit1 += m_pRowInfo[ i ].nMinSize; // ...add previous rows' minimum sizes and splitters.
    nLimit1 += m_cySplitter;
    } // for
    nLimit1 += m_pRowInfo[nRow].nMinSize;
    } // if

    int nLimit2 = rectClient.bottom; // Start with bottom.
    nLimit2 -= m_cyBorder; // Take off bottom border.

    // If bottom splitter...
    if ( nRow + 1 == m_nRows - 1 )
    {
    nLimit2 -= m_pRowInfo[ nRow + 1 ].nMinSize; // ...just take off last row minimum size.
    }
    // Otherwise...
    else
    {
    for ( int i = m_nRows - 1; i > nRow + 1; i-- )
    {
    nLimit2 -= m_pRowInfo[ i ].nMinSize; // ...take off following rows' minimum sizes and splitters.
    nLimit2 -= m_cySplitter;
    } // for
    nLimit2 -= m_pRowInfo[nRow].nMinSize;
    } // if

    nLimit2 -= m_cySplitter / 2; // Take off half a splitter.

    if ( point.y < nLimit1 + m_cySplitter / 2 - 2 )
    {
    point.y = nLimit1 + m_cySplitter / 2 - 2;
    } // if

    if ( point.y > nLimit2 - m_cySplitter / 2 )
    {
    point.y = nLimit2 - m_cySplitter / 2;
    } // if
    } // if

    // Limit column.
    if ( bSizingCol )
    {
    int nLimit1 = 0;// = m_cxBorder; // Start with left border.

    // If left splitter...
    if ( nCol == 0 )
    {
    nLimit1 += m_pColInfo[ 0 ].nMinSize; // ...just add first column minimum size.
    }
    // If pane left of splitter at minimum size...
    else if ( m_pColInfo[ nCol ].nCurSize == m_pColInfo[ nCol ].nMinSize )
    {
    for ( int i = 0; i < nCol; i++ )
    {
    nLimit1 += m_pColInfo[ i ].nCurSize; // ...add previous columns' sizes and splitters.
    nLimit1 += m_cxSplitter;
    } // for
    nLimit1 += m_pColInfo[nCol].nCurSize;
    }
    // Otherwise...
    else
    {
    for ( int i = 0; i < nCol; i++ )
    {
    nLimit1 += m_pColInfo[ i ].nMinSize; // ...add previous columns' minimum sizes and splitters.
    nLimit1 += m_cxSplitter;
    } // for
    nLimit1 += m_pColInfo[nCol].nMinSize; // Minimum height of each column,
    } // if


    int nLimit2 = rectClient.right; // Start with right.
    nLimit2 -= m_cxBorder; // Take off right border,

    // If right splitter...
    if ( nCol + 1 == m_nCols - 1 )
    {
    nLimit2 -= m_pColInfo[ nCol + 1 ].nMinSize; // ...just take off last column minimum size.
    }
    // Otherwise...
    else
    {
    for ( int i = m_nCols - 1; i > nCol + 1; i-- )
    {
    nLimit2 -= m_pColInfo[ i ].nMinSize; // ...take off following columns' minimum sizes and splitters.
    nLimit2 -= m_cxSplitter;
    } // for
    nLimit2 -= m_pColInfo[nCol].nMinSize;
    } // if

    nLimit2 -= m_cxSplitter / 2; // Take off half a splitter,

    if ( point.x < nLimit1/* + m_cxSplitter / 2 - 2*/ )
    {
    point.x = nLimit1 /*+ m_cxSplitter / 2 - 2*/;
    } // if

    if ( point.x > nLimit2 - m_cxSplitter / 2 )
    {
    point.x = nLimit2 - m_cxSplitter / 2;
    } // if
    } // if

    // Restore offset 'cos CSplitterWnd::OnMouseMove will do it again.
    point.Offset( -m_ptTrackOffset ); // point is the upper right of hit detect
    } // if

    // Call base class.
    CSplitterWnd::OnMouseMove(nFlags, point);
    }
      

  8.   

    有个很简单的方法:
    一、新建一个类CMySplitter,基类为CSplitterWnd
    二、重载该类的OnMouseMove函数:
    void CMySplitter::OnMouseMove(UINT nFlags, CPoint point)

    // 限制切分条的运动范围。 
    if(point.x<228||point.x>600) 

    CWnd::OnMouseMove(nFlags, point); 

    else 

    CSplitterWnd::OnMouseMove(nFlags, point); 

    }