手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>程序设计>C/C++>列表

用VC 实现应用程序窗口的任意分割

来源:互联网 作者:西部数码 时间:2008-04-09
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

{
 DECLARE_DYNAMIC(CViewExSplitWnd)
 // Implementation
 public:
  CViewExSplitWnd();
  ~CViewExSplitWnd();
  CWnd* GetActivePane(int* pRow = NULL, int* pCol = NULL);
};
class C3WaySplitterFrame : public CMDIChildWnd
{
 DECLARE_DYNCREATE(C3WaySplitterFrame)
 protected:
  C3WaySplitterFrame(); // protected constructor used by dynamic creation
  // Attributes
 protected:
  CViewExSplitWnd m_wndSplitter;
  CViewExSplitWnd m_wndSplitter2; // embedded in the first
  // Implementation
 public:
  virtual ~C3WaySplitterFrame();
  virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
  // Generated message map functions
  //{{AFX_MSG(C3WaySplitterFrame)
  //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};
/////////////////////////////splitter.cpp文件;
#include "stdafx.h"
#include "viewex.h"
#include "splitter.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
// CSplitterFrame
// Create a splitter window which splits an output text view and an input view
// |
// TEXT VIEW (CTextView) | INPUT VIEW (CInputView)
// |
IMPLEMENT_DYNCREATE(CSplitterFrame, CMDIChildWnd)
CSplitterFrame::CSplitterFrame()
{}

CSplitterFrame::~CSplitterFrame()
{}
BOOL CSplitterFrame::OnCreateClient(LPCREATESTRUCT,
CCreateContext* pContext)
{
 // create a splitter with 1 row, 2 columns
 if (!m_wndSplitter.CreateStatic(this, 1, 2))
 {
  TRACE0("Failed to CreateStaticSplitter\n");
  return FALSE;
 }
 // add the first splitter pane - the default view in column 0
 if (!m_wndSplitter.CreateView(0, 0,pContext->m_pNewViewClass, CSize(130, 50), pContext))
 {
  TRACE0("Failed to create first pane\n");
  return FALSE;
 }
 // add the second splitter pane - an input view in column 1
 if (!m_wndSplitter.CreateView(0, 1,RUNTIME_CLASS(CInputView), CSize(0, 0), pContext))
 {
  TRACE0("Failed to create second pane\n");
  return FALSE;
 }
 // activate the input view
 SetActiveView((CView*)m_wndSplitter.GetPane(0,1));
 return TRUE;
}
BEGIN_MESSAGE_MAP(CSplitterFrame, CMDIChildWnd)
 //{{AFX_MSG_MAP(CSplitterFrame)
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()
// C3WaySplitterFrame - just like CSplitterFrame except the input view is
// the first pane, and there are two output views

// | Text View (CTextView)
// INPUT VIEW (CInputView) |------------------------
// | Color View (CColorView)
IMPLEMENT_DYNCREATE(C3WaySplitterFrame, CMDIChildWnd)
C3WaySplitterFrame::C3WaySplitterFrame()
{}

C3WaySplitterFrame::~C3WaySplitterFrame()
{}

BOOL C3WaySplitterFrame::OnCreateClient(LPCREATESTRUCT lpcs,CCreateContext* pContext)
{
 // create a splitter with 1 row, 2 columns
 if (!m_wndSplitter.CreateStatic(this, 1, 2))
 {
  TRACE0("Failed to CreateStaticSplitter\n");
  return FALSE;
 }
 // add the first splitter pane - the default view in column 0
 if (!m_wndSplitter.CreateView(0, 0,pContext->m_pNewViewClass, CSize(200, 50), pContext))
 {
  TRACE0("Failed to create first pane\n");
  return FALSE;
 }
 // add the second splitter pane - which is a nested splitter with 2 rows
 if (!m_wndSplitter2.CreateStatic(&m_wndSplitter, // our parent window is the first splitter
2, 1, // the new splitter is 2 rows, 1 column
WS_CHILD | WS_VISIBLE | WS_BORDER, // style, WS_BORDER is needed
m_wndSplitter.IdFromRowCol(0, 1) ))
// new splitter is in the first row, 2nd column of first splitter
{
 TRACE0("Failed to create nested splitter\n");
 return FALSE;
}
// now create the two views inside the nested splitter
int cyText = max(lpcs->cy - 70, 20); // height of text pane
if (!m_wndSplitter2.CreateView(0, 0,RUNTIME_CLASS(CTextView), CSize(0, cyText), pContext))
{
 TRACE0("Failed to create second pane\n");
 return FALSE;
}
if (!m_wndSplitter2.CreateView(1, 0,RUNTIME_CLASS(CColorView), CSize(0, 0), pContext))
{
 TRACE0("Failed to create third pane\n");
 return FALSE;
}
// it all worked, we now have two splitter windows which contain
// three different views
return TRUE;
}
BEGIN_MESSAGE_MAP(C3WaySplitterFrame, CMDIChildWnd)
//{{AFX_MSG_MAP(C3WaySplitterFrame)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
IMPLEMENT_DYNAMIC(CViewExSplitWnd, CSplitterWnd)
CViewExSplitWnd::CViewExSplitWnd()
{}

CViewExSplitWnd::~CViewExSplitWnd()
{}

CWnd* CViewExSplitWnd::GetActivePane(int* pRow, int* pCol)
{
 ASSERT_VALID(this);
 // attempt to use active view of frame window
 CWnd* pView = NULL;
 CFrameWnd* pFrameWnd = GetParentFrame();
 ASSERT_VALID(pFrameWnd);
 pView = pFrameWnd->GetActiveView();
 // failing that, use the current focus
 if (pView == NULL)
  pView = GetFocus();
 return pView;
}
  四、小结

  本实例通过灵活运用CsplitterWnd类,实现了窗口的任意拆分。另外,需要补充的内容是,在具体应用中可以通过对CSplitterWnd原有方法的覆盖或者增加新的方法来扩展CSplitterWnd。我们在此仅举两个方面的例子,一是锁定切分条;二是定制自己的切分条。对于锁定切分条,不希望用户通过拖动切分条来调节窗口的大小这个问题,最简单的解决方法莫过于不让CSplitterWnd来处理WM_LBUTTONDOWN,WM_MOUSEMOVE,WM_SETCURSOR消息,而是将这些消息交给CWnd窗口进行处理,从而屏蔽掉这些消息。那么如何定制自己的切分条呢?通过重载CSplitterWnd的虚方法OnDrawSplitter()和OnInvertTracker()可以达到这样的目的。下面的代码生成的效果是分割窗口的边界颜色为红色,分割条的颜色为绿色代码如下:

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!