WTL的分割窗口CSplitterWindow非常好用。具体参见我的
http://data.blueanywhere.cn/wtl/ 第7章节
但美中不足的是有两点:
- 没有设置移动范围
- 双击分隔条每次都是默认居中分隔,其实这个很多时候不是本意,双击应该是最恰当的而不是最居中的。
幸好WTL全部有代码,小修小补一下即可满足以上要求。打开相关的文件:c:\YourWTL\include\atlsplit.h
红色是修改部分
1.增加内部变量
class CSplitterImpl { public: enum { m_nPanesCount = 2, m_nPropMax = 10000 }; HWND m_hWndPane[m_nPanesCount]; RECT m_rcSplitter; int m_xySplitterPos; int m_nDefActivePane; int m_cxySplitBar; // splitter bar width/height static HCURSOR m_hCursor; int m_cxyMin; // minimum pane size int m_cxyMax; //【修改之处】cxyMax = -1 就是没设置,和原来一样 int m_cxyMid; //【修改之处】cxyMid = -1 就是没,和原来一样 int m_cxyBarEdge; // splitter bar edge bool m_bFullDrag; int m_cxyDragOffset; int m_nProportionalPos; bool m_bUpdateProportionalPos; DWORD m_dwExtendedStyle; // splitter specific extended styles int m_nSinglePane; // single pane mode
2. 初始化
// Constructor CSplitterImpl() : m_xySplitterPos(-1), m_nDefActivePane(SPLIT_PANE_NONE), m_cxySplitBar(0), m_cxyMin(0), m_cxyMax(-1),m_cxyMid(-1),//【修改之处】 m_cxyBarEdge(0), m_bFullDrag(true), m_cxyDragOffset(0), m_nProportionalPos(0), m_bUpdateProportionalPos(true), m_dwExtendedStyle(SPLIT_PROPORTIONAL), m_nSinglePane(SPLIT_PANE_NONE)
3.双击处理
LRESULT OnLButtonDoubleClick(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { T* pT = static_cast<T*>(this); if (m_cxyMid == -1 ) {//【修改之处】 pT->SetSplitterPos(); // middle } else { pT->SetSplitterPos(m_cxyMid,true);//【修改之处】 } return 0; }
4.移动范围设定 SetSplitterPos
bool SetSplitterPos(int xyPos = -1, bool bUpdate = true) { if(xyPos == -1) // -1 == middle { if(t_bVertical) xyPos = (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) / 2; else xyPos = (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge) / 2; } // Adjust if out of valid range int cxyMax = 0; if (m_cxyMax == -1 ) {//【修改之处】 if(t_bVertical) cxyMax = m_rcSplitter.right - m_rcSplitter.left; else cxyMax = m_rcSplitter.bottom - m_rcSplitter.top; } else {//【修改之处】 if(t_bVertical) cxyMax = ((m_rcSplitter.right - m_rcSplitter.left)>m_cxyMax?m_cxyMax:(m_rcSplitter.right - m_rcSplitter.left));//【修改之处】 else cxyMax = ((m_rcSplitter.bottom - m_rcSplitter.top)>m_cxyMax?m_cxyMax:(m_rcSplitter.bottom - m_rcSplitter.top));//【修改之处】 } if(xyPos < m_cxyMin + m_cxyBarEdge) xyPos = m_cxyMin; else if(xyPos > (cxyMax - m_cxySplitBar - m_cxyBarEdge - m_cxyMin)) xyPos = cxyMax - m_cxySplitBar - m_cxyBarEdge - m_cxyMin;
设置一下编译通过了。我的应用程序里这么处理,初始化一下系统变量
CSplitterWindow m_wndVertSplit; ....... m_wndVertSplit.m_cxySplitBar = 1; m_wndVertSplit.m_cxyMin = 80; m_wndVertSplit.m_cxyMax = 480; m_wndVertSplit.m_cxyMid = 200;
然后分割条就只能在80-480之间移动了,双击分割条,自动恢复到200的位置,而不是原来的中间位置。
以上修改在 Visual C++ 6.0 WTL 8.0 通过