ITPub博客

首页 > IT基础架构 > 网络安全 > 怎样在一个一般窗口或是Dialog上面使用分割窗口. (转)

怎样在一个一般窗口或是Dialog上面使用分割窗口. (转)

原创 网络安全 作者:worldblog 时间:2007-12-03 11:13:28 0 删除 编辑
怎样在一个一般窗口或是Dialog上面使用分割窗口. (转)[@more@]

  小弟初次贴文,水平不高,希望不要丢东西.呵呵.

  大家都知道可以在一个CFrameWnd上面使用CSplitterWnd以做出分割窗口的效果(呵呵,顺便,分割窗口可是MFC程序的一大特色.原来(Delphi没有加上这个的支持之前),你只要看到了分割窗口,几乎可以肯定是MFC的.(哈哈,当然,也有人用SDK做一个出来,有这种闲的家伙么?呵呵,好象废话太多了点).

  可是现实中的情况是,有的时候我们要在一个一般的CWnd上面做一个SplitterWnd的效果.怎么办呢?MS的SplitterWnd只可以用于CFrameWnd(好像也可以用于CView类,MS的文档里说的).之所以有这个限制是因为TMD狗屎MS在SplitterWnd里面把所有要取Parent窗口的地方都设为CFrameWnd了.但实际上,它又没有用到CFrameWnd的任何特性.所以我们应该怎么做,好像是很明显的了.就是去翻MS的SplitterWnd的源码,把所有的用到了Parent的地方都改掉.啊!!!不是的,这还叫狗屁oop?应该是重载一个我们自己的.

文件:

// SplitWnd.h : implementation file
//
class CxSplitterWnd : public CSplitterWnd
{
 // Construction
 public:
 CxSplitterWnd() {};
 virtual ~CxSplitterWnd() {};

 // Operations
 public:
 // Overrides
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CxSplitterWnd)
 //}}AFX_VIRTUAL

 // Implementation
 public:
 // These are the methods to be overridden
 virtual void StartTracking(int ht);
 virtual CWnd* GetActivePane(int* pRow = NULL, int* pCol = NULL);
 virtual void SetActivePane( int row, int col, CWnd* pWnd = NULL );
 virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
 virtual BOOL OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult );
 virtual BOOL OnWndMsg( UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult );

 // Generated message map functions
 protected:
 //}}AFX_MSG(CxSplitterWnd)
 // NOTE - the ClassWizard will add and remove member functions here.
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};

还有实现文件:


// SplitWnd.cpp : implementation file
//
#include "stdafx.h"
#include "SplitWnd.h"

#ifdef _DEbug
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// HitTest return values (values and spacing between values is important)
// Had to adopt this because it has module SCOpe
enum HitTestValue
{
 noHit = 0,
 vSplitterBox = 1,
 hSplitterBox = 2,
 bothSplitterBox = 3, // just for keyboard
 vSplitterBar1 = 101,
 vSplitterBar15 = 115,
 hSplitterBar1 = 201,
 hSplitterBar15 = 215,
 splitterIntersection1 = 301,
 splitterIntersection225 = 525
};

/////////////////////////////////////////////////////////////////////////////
// CxSplitterWnd

BEGIN_MESSAGE_MAP(CxSplitterWnd, CSplitterWnd)
//{{AFX_MSG_MAP(CxSplitterWnd)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

CWnd* CxSplitterWnd::GetActivePane(int* pRow, int* pCol)
{
 ASSERT_VALID(this);
 CWnd* pView = GetFocus();
 // make sure the pane is a child pane of the splitter
 if (pView != NULL && !IsChildPane(pView, pRow, pCol))
 pView = NULL;
 return pView;
}

void CxSplitterWnd::SetActivePane( int row, int col, CWnd* pWnd)
{
 // set the focus to the pane
 CWnd* pPane = pWnd == NULL ? GetPane(row, col) : pWnd;
 pPane->SetFocus();
}

void CxSplitterWnd::StartTracking(int ht)
{
ASSERT_VALID(this);
 if (ht == noHit)
 return;
 // GetHitRect will restrict 'm_rectLimit' as appropriate
 GetInsideRect(m_rectLimit);
 if (ht >= splitterIntersection1 && ht <= splitterIntersection225)
 {
 // split two directions (two tracking rectangles)
 int row = (ht - splitterIntersection1) / 15;
 int col = (ht - splitterIntersection1) % 15;
 GetHitRect(row + vSplitterBar1, m_rectTracker);
 int yTrackOffset = m_ptTrackOffset.y;
 m_bTracking2 = TRUE;
 GetHitRect(col + hSplitterBar1, m_rectTracker2);
 m_ptTrackOffset.y = yTrackOffset;
 }
 else if (ht == bothSplitterBox)
 {
 // hit on splitter boxes (for keyboard)
 GetHitRect(vSplitterBox, m_rectTracker);
 int yTrackOffset = m_ptTrackOffset.y;
 m_bTracking2 = TRUE;
 GetHitRect(hSplitterBox, m_rectTracker2);
 m_ptTrackOffset.y = yTrackOffset;
 // center it
 m_rectTracker.OffsetRect(0, m_rectLimit.Height()/2);
 m_rectTracker2.OffsetRect(m_rectLimit.Width()/2, 0);
 }
 else
 {
 // only hit one bar
 GetHitRect(ht, m_rectTracker);
 }

 // steal focus and capture
 SetCapture();
 SetFocus();
 // make sure no updates are pending
 RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);
 // set tracking state and appropriate cursor
 m_bTracking = TRUE;
 OnInvertTracker(m_rectTracker);
 if (m_bTracking2)
 OnInvertTracker(m_rectTracker2);
 m_htTrack = ht;
 SetSplitCursor(ht);
}

/////////////////////////////////////////////////////////////////////////////
// CSplitterWnd command routing
BOOL CxSplitterWnd::OnCommand(WPARAM wParam, LPARAM lParam)
{
 if (CWnd::OnCommand(wParam, lParam))
 return TRUE;
 // route commands to the splitter to the parent frame window
 return GetParent()->SendMessage(WM_COMMAND, wParam, lParam);
}

BOOL CxSplitterWnd::OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult )
{
 if (CWnd::OnNotify(wParam, lParam, pResult))
 return TRUE;
 // route commands to the splitter to the parent frame window
 *pResult = GetParent()->SendMessage(WM_NOTIFY, wParam, lParam);
 return TRUE;
}

BOOL CxSplitterWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
 // The code line below is necessary if using CxSplitterWnd in a regular dll
 // AFX_MANAGE_STATE(AfxGetStaticModuleState());
 return CWnd::OnWndMsg(message, wParam, lParam, pResult);
}

把这个文件给包含进你的工程,就可以用CxSplitterWnd了.

 

 

 

 

 


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-987617/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    6241
  • 访问量
    2411031