WTL CSplitterWindow 修改

拥有回忆 提交于 2019-11-28 05:50:01

WTL的分割窗口CSplitterWindow非常好用。具体参见我的 http://data.blueanywhere.cn/wtl/ 第7章节

但美中不足的是有两点:

  1. 没有设置移动范围
  2. 双击分隔条每次都是默认居中分隔,其实这个很多时候不是本意,双击应该是最恰当的而不是最居中的。

幸好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 通过
 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!