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 通过
来源:CSDN
作者:stevenkoh
链接:https://blog.csdn.net/stevenkoh/article/details/8686003