返回首页

  ; & #160;下载演示项目 - 14.2 KB &# 160; 下载源 - 3.65 KB & #160;
{S0} 简介   ;
是的,它的又一拆分窗口类。所以为什么我发布一个新的 & #160; 类,当有很多相似的类?答案很简单。所有 在CodeProject拆分窗口类可以分为两部分恕我直言: & #160; 这些来自原始的MFC CSplitterWnd的。他们期待尼斯 很多古典CSplitterWnd的优势,但派生 & #160; 从CSplitterWnd的限制你只使用CView派生 在它窗户。 别人,我可以使用在各种Windows - 但是当我编译和测试 他们,他们不看漂亮的CSplitterWnd的。
在这篇文章中,我提供了一个类,它是不是从CSplitterWnd的派生。  0; 它允许您使用简单的CWnd派生的窗口。但它   ; 结合原CSplitterWnd的专业。 &# 160; 我从MFC源代码的某些例程。请可忍而读 这篇文章。这是我的第一篇文章:在CodeProject)。 特点
我CSimpleSplitterWnd设计的目标是模拟的基本 对CSplitterWnd的功能。有了这个类,你可以多次  60; 水平或垂直排列的窗格。它不提供自动 &# 160; 分裂,共享的滚动条和路口跟踪。我没有觉得很 有用 - 但是,如果有足够多的人,谁做了,我可以添加一些 这些功能:)CSimpleSplitter想法(以CSplitterWnd的) & #160; 是窗格窗口是相互独立的,因此他们也 负责他们的滚动和边界。  0; 使用代码
分配器布局是在构造函数: CSimpleSplitter(INT nPanes,UINT nOrientation = SSP_HORZ nMinSize = 30,INT nBarThickness = 3);
nPanes窗格的数量,应nOrientation  60; SSP_HORZ或SSP_VERT。 nMinSize是  60; 任何窗格的最小高度(或宽度) - 重要的是在重新计算 布局算法,当你调整分离器。 nBarThickness是 酒吧窗格之间的高度或宽度。所有这些属性保持不变 在分离器实例的生命周期。分离器和它的创造 窗格很简单: 布尔创建(的CWnd * pParent,UINT NID = AFX_IDW_PANE_FIRST);BOOL CreatePane(INT参数nIndex的CWnd * pPaneWnd,DWORD dwStyle, DWORD dwExStyle,LPCTSTR lpszClassName = NULL);
窗格索引从0到nPanes - 1。参数 dwStyle,dwExStyle和lpszClassName 通过pPaneWnd - GT; CreateEx()(如果你想绑定创建 一个窗格的窗口,而不是使用SetPane)。您可以指定 例如边界窗格有。在演示程序中,"大"窗格有WS_EX_CLIENTEDGE 扩展风格,而三个"平"窗格WS_EX_STATICEDGE 扩展样式。单独的分隔栏只是一个灰色的矩形,因此,如果您   ; 不指定任何边缘,灰色的背景设置窗格窗口,您可以使用 在对话框中的分配器。   ;
以下五个方法CSplitterWnd的方法类似, & #160; 所以他们并不需要一个特殊的文件。& #160; INT GetPaneCount()const的;无效SetPane(INT参数nIndex的CWnd * pPaneWnd);的CWnd * GetPane(INT参数nIndex)const的;虚拟无效SetActivePane(INT参数nIndex);的CWnd * GetActivePane(INT * pIndex)常量;
然而,设置窗格的宽度或高度使用不同的技术: 无效SetPaneSizes(const int的大小); & #160;
通过nPanes整数数组。他们指定的相对大小  60; 窗格。您可以使用任何规模的,窗格的大小比例的 阵列成员的总和。当调整整个分离器,尺寸 窗格改变自己的实际大小比例。如果有必要,他们  0;调整m_nMinSize。

void GetPaneRect(int nIndex, CRect& rcPane) const;

void GetBarRect(int nIndex, CRect& rcBar) const;

,有了这些功能,您可以检索窗格分离器客户端的位置 坐标。酒吧的索引从1到nPanes - 1。
这就是所有。看看SimpleSplitterApp演示,特别是在CMainFrame::OnCreate中 代码,你就会知道一切! 兴趣点
当我编程的分离器,我很困惑,框架如何重绘 调整大小的窗口。如果调整的顶部或左边框,框架的第一只移动  ; 窗口的内容在相应的方向,然后它调用的OnPaint()。 所以窗口重绘两次,并在分离器,这看起来丑陋。
幸运的是,有一个消息处理程序的CWnd::OnWindowPosChanging。 您可避免最初的移动内容,如果你看到SWP_NOCOPYBITS 正如你看到的CSimpleSplitter和CChildWnd代码。我 认为这是在许多情况下非常有用,分配器。 历史  60; 11。 2。 2004年 - 第一个版本发布 24。 3。 2004 - 一些错误固定(见下面的消息)。在SetPaneSizes &# 160; 功能,现在你应该通过唯一的相对大小,而不是绝对。

回答

评论会员:errieman 时间:2011/12/01
大家好,

我到Visual Studio 2010。有人可以指导我一步一步如何使用简单的分配器与CWnd派生窗格。例如我打开Visual Studio中我创建一个项目或我下一步要做什么?所有的帮助是非常赞赏
评论会员:。ChrisJohnShort 时间:2011/12/01
GetBarRect功能(而不是在代码中使用),似乎是不正确的。这是我的修复...

无效CSimpleSplitter:GetBarRect(INT参数nIndex,CRECT rcBar)const的
{
断言参数nIndex> 0(参数nIndex GetOtherWnd ());[/代码]
我用这说明我的调试器,这个问题的MoveWindow函数的原因是pParentWnd指针是不是有效!

任何想法?
评论会员:奥尔特温Basselmann 时间:2011/12/01
您都做了很好的实施。你有分裂DoKeyboardSplit(如键盘输入的解决方案)吗?
评论会员:Diarrhio 时间:2011/12/01
您好,

我以前的一些特殊问题。
我需要创建一个分离器与独立的意见和一个CWnd的派生类内的所有。
所以,我已经提供一个CWnd类和内定期CFrameWnd派生类内分路控制。
是否有任何身体知道如何解决这个问题?请帮助我。

在此先感谢。

Snehasish保罗
(印度)

Snehasish保罗
评论会员:xrestassuredx 时间:2011/12/01
如果有人关心,我已经修改了代码,以便您可以添加窗格,其中有一个任意的父(通常是拆分窗口的父)。我基本上修改ResizePanes使传递的MoveWindow RECT到客户端窗格的父空间,而不是分离器的客户端空间转换。我敢肯定有另一种方式来做到这一点,但这个工程。

下面是代码。只需要修改这个ResizePanes:

void CSimpleSplitter::ResizePanes()

{

	int i;

	CRect rcOuter, rect;

 

	GetClientRect(rcOuter);

	if (m_nOrientation == SSP_HORZ)	

		for (i = 0; i < m_nPanes; i++)

		{

			if (m_pane[i])

			{

				rect.left = m_orig[i];

				rect.top = 0;

				rect.right = rect.left + m_orig[i + 1] - m_orig[i] - m_nBarThickness;

				rect.bottom = rect.top + rcOuter.Height();

 

				ClientToScreen( &rect );

				m_pane[i]->GetParent()->ScreenToClient( &rect );

				m_pane[i]->MoveWindow( &rect );

			}

		}

	else

		for (i = 0; i < m_nPanes; i++)

		{

			if (m_pane[i])

			{

				rect.left = 0;

				rect.top = m_orig[i];

				rect.right = rect.left + rcOuter.Width();

				rect.bottom = rect.top + m_orig[i + 1] - m_orig[i] - m_nBarThickness;

 

				ClientToScreen( &rect );

				m_pane[i]->GetParent()->ScreenToClient( &rect );

				m_pane[i]->MoveWindow( &rect );

			}

		}

}

评论会员:会员4582054 时间:2011/12/01
我无法创建一个拆分窗口包含对话框项目。我有一个CFrameWnd的派生类,它包含几个分离器和对话框控件:
CEdit m_txtEntry;
CEdit m_msgDisplay;
CListBox的m_usrList;
CButton的m_sndButton;
CSimpleSplitter m_mainSplit,m_entrySplit,m_displaySplit; CBrush m_bkgBlank,m_bkgWhite;
CChatFrame:CChatFrame():
m_mainSplit(2 SSP_VERT,30,3),
m_entrySplit(2 SSP_HORZ,30,3),
m_displaySplit(2 SSP_HORZ,30,3),
m_bkgBlank(:GetSysColor(COLOR_BTNFACE))
m_bkgWhite(RGB(255,255,255))
{} crsArrow HCURSOR =::LoadCursor(0,IDC_ARROW);
CString的classBlank = AfxRegisterWndClass(CS_DBLCLKS,crsArrow,(HBRUSH)m_bkgBlank,0);
CString的classWhite = AfxRegisterWndClass(CS_DBLCLKS,crsArrow,(HBRUSH)m_bkgWhite,0);
UINT listFlags = WS_CHILD | WS_VISIBLE | LBS_NOSEL | LBS_HASSTRINGS | LBS_SORT | WS_VSCROLL;

const int的horz_splitter_sizes [2] = {4,1}
const int的vert_splitter_sizes [2] = {2,1}
m_mainSplit.Create(本);
m_mainSplit.SetPaneSizes(vert_splitter_sizes); m_displaySplit.Create(m_mainSplit);
m_displaySplit.SetPaneSizes(horz_splitter_sizes);m_mainSplit.SetPane(0,m_displaySplit) m_displaySplit.CreatePane(0 m_msgDisplay,0,0,classWhite);m_displaySplit.CreatePane(1 m_usrList,listFlags,WS_EX_STATICEDGE,classBlank)
m_entrySplit.Create(m_mainSplit);
m_entrySplit.SetPaneSizes(horz_splitter_sizes);m_mainSplit.SetPane(1,m_entrySplit) m_entrySplit.CreatePane(0,m_txtEntry,WS_CHILD | WS_VISIBLE,WS_EX_STATICEDGE,classWhite);m_entrySplit.CreatePane(1 m_sndButton,0,WS_EX_STATICEDGE,classBlank)
创建窗口并正确显示,但我无法操纵对话框项目,编辑文本,添加到列表框中的字符串等是否有另一种方式,我应该努力做到这一点?
评论会员:安德鲁菲利普斯 时间:2011/12/01
尝试创建对话框控件和一个标准的方式之后,他们投入CSimpleSplitter分配器:SetPane。如果创建与CSimpleSplitter:CreatePane,分配器将创建它们像CWnd的正常窗口:CreateEx,我认为,你不能创建CWnd的对话框控件:CreateEx。
评论会员:pank007 时间:2011/12/01
这是正确的

现在对我来说是非常有用的。

例如:
改变CButton的(例如)"为"
语句CWnd的定义CRECT RECT;
(I = 0;我LT; 3;我)
{
m_wndRightTop [我]创建(_T("标题"),WS_CHILD | WS_VISIBLE,矩形,m_wndSplitterVert,我AFX_IDW_PANE_FIRST);
m_wndSplitterVert.SetPane(I,m_wndRightTop [I])
}

CWnd的是一个真正可见的CWnd:按钮可以看出推

修改于2008年4月18日(星期五),上午11:23
评论会员:RealityC 时间:2011/12/01
一个优秀的代码。这是简单的了解还非常有用。 (为什么不能MFC源代码那么简单吗?)

我有几个建议:

1。这将是很好的,如果分离器以某种方式调整大小窗口时,它是嵌入在调整大小。但因为我使用的唯一窗口的一个resizeable对话框中,我这样做:

无效CMyDialog::OnSize(UINT nType,INT,INT CX CY)
{
CBCGDialogBar:OnSize(nType,CX,CY); / /调用基类
 0; 的CWnd * PW = GetTopWindow()/ /得到分离器
(PW = NULL)
{
CRECT RECT;
GetClientRect(RECT);
PW ->的MoveWindow(RECT); / /调整分路相匹配的父
}
}

2。 GetCapture()可能会返回一个临时的CWnd指针。所以:

(GetCapture()==)...

可能并不总是可行的。你也可以使用一个标志,或者一个成员变量:

(GetCapture()= NULL,GetCapture() - > m_hWnd == m_hWnd)...
3。如果孩子分隔条调整大小的窗口拖,而不仅仅是绘图拆分矩形(中InvertTracker),这可能是很好的。大部分的电脑速度不够快,重绘的窗户上飞,但你可以把它万一有人选项的复杂绘图代码。

4。我也有一个SetPane位代码(安全):

ASSERT((pPaneWnd - >对getStyle()WS_CHILD | WS_VISIBLE)== WS_CHILD | WS_VISIBLE);
&# 160; ASSERT(pPaneWnd -> GetParent()==);!/ /确保分配器父



安德鲁十字
aphillips@expertcomsoft.com
评论会员:安德鲁菲利普斯 时间:2011/12/01
嗨,罗伯特,
我喜欢这个分离器,但你或其他人可以帮助创建Newsbin临编这样的分配器?
或我在哪里可以找到这样的一个窗口?THX,
托尼
评论会员:肖恩刘 时间:2011/12/01
我发现的截图。你有代码(或发现)然后CWnd派生的窗口左侧的列表框一个正确的选项卡式窗口和底部,并把它们的CSimpleSplitter窗格。

罗伯特安东尼

"朋友来离开,但teddybears永远留。"
评论会员:DonGuitar 时间:2011/12/01
这是一个不错的的类... ...谢谢你

但我有一个问题。
我想所有控件的父是主对话框

但它似乎SetPane功能pPaneWnd的母公司是拆分窗口。
是吗?
感谢您的帮助有一个愉快的一天

现实

欢迎
评论会员:YongSei 时间:2011/12/01
是,有一个分割窗口,其中包含的窗格窗口。您应该创建在CYourDialog分割窗口:OnCreate和调整它的大小,以对话的整个客户区。

罗伯特安东尼

"真的不知道,那里是错误,我的感觉,电脑只是跳过了所有的意见!"