WEB开发网
开发学院软件开发VC 使用VC6.0实现窗口的任意分割 阅读

使用VC6.0实现窗口的任意分割

 2010-07-06 20:43:38 来源:WEB开发网   
核心提示:三、关于对话框的分割到目前为止,只有基于文档/视图的程序才能使用CSplitterWnd,使用VC6.0实现窗口的任意分割(4),而基于对话框的应用程序却不支持CSplitterWnd,但是如果我们在继承类中重载一些虚拟方法,也能使CSplitterWnd 在对话框程序中使用,// CWnd* pView = NULL

三、关于对话框的分割

到目前为止,只有基于文档/视图的程序才能使用CSplitterWnd,而基于对话框的应用程序却不支持CSplitterWnd,但是如果我们在继承类中重载一些虚拟方法,也能使CSplitterWnd 在对话框程序中使用。从MFC的源程序WinSplit.cpp中可以看出,为了获得父窗口的地方程序都调用了虚拟方法GetParentFrame(),因此如果在对话框中使用,我们必须将它改为GetParent();因此我们将CSplitterWnd的下面几个方法重载。

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 );

具体实现如下,实现中我将给出原有代码的主要部分以及修改后的代码以作对比。

在cpp文件中加入下面的枚举类型。

enum HitTestValue
{
         noHit = 0,//表示没有选中任何对象
         vSplitterBox = 1,
         hSplitterBox = 2,
         bothSplitterBox = 3,
         vSplitterBar1 = 101,//代表各个方向的水平分割条
         vSplitterBar15 = 115,
         hSplitterBar1 = 201,//代表垂直方向的各个分割条
         hSplitterBar15 = 215,
         splitterIntersection1 = 301,//代表各个交叉点
         splitterIntersection225 = 525
};

CWnd* CxSplitterWnd::GetActivePane(int* pRow, int* pCol)
     {
         ASSERT_VALID(this);
         //获得当前的获得焦点的窗口
         //下面注释粗体的是原有的代码的主要部分。
         // CWnd* pView = NULL;
         //CFrameWnd* pFrameWnd = GetParentFrame();
         //ASSERT_VALID(pFrameWnd);
         //pView = pFrameWnd->GetActiveView();
         //if (pView == NULL)
         // pView = GetFocus();
         CWnd* pView = GetFocus();
         if (pView != NULL && !IsChildPane(pView, pRow, pCol))
             pView = NULL;
         return pView;
}

void CxSplitterWnd::SetActivePane( int row, int col, CWnd* pWnd)
{
         CWnd* pPane = pWnd == NULL ? GetPane(row, col) : pWnd;
         //下面加注释粗体的是原有代码的主要部分。
         //FrameWnd* pFrameWnd = GetParentFrame();
         //ASSERT_VALID(pFrameWnd);
         //pFrameWnd->SetActiveView((CView*)pPane);
         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);
         }

     //下面加注释的将从程序中删去。
     //CView* pView = (CView*)GetActivePane();
     //if (pView != NULL && pView->IsKindOf(RUNTIME_CLASS(CView)))
     //{
     // ASSERT_VALID(pView);
     // CFrameWnd* pFrameWnd = GetParentFrame();
     //ASSERT_VALID(pFrameWnd);
     //pView->OnActivateFrame(WA_INACTIVE, pFrameWnd);
     // }
     // 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);
}

BOOL CxSplitterWnd::OnCommand(WPARAM wParam, LPARAM lParam)
{
         if (CWnd::OnCommand(wParam, lParam))
             return TRUE;
         //下面粗体的是原程序的语句
     //return GetParentFrame()->SendMessage(WM_COMMAND, wParam, lParam);

         return GetParent()->SendMessage(WM_COMMAND, wParam, lParam);

}
BOOL CxSplitterWnd::OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult )
{
         if (CWnd::OnNotify(wParam, lParam, pResult))
             return TRUE;
         //下面粗体的是源程序的语句
         //*pResult = GetParentFrame()->SendMessage(WM_NOTIFY,
     wParam, lParam);
         *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类了。

上一页  1 2 3 4 5  下一页

Tags:使用 VC 实现

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接