关于对话框的分割,有前辈们的如下的代码:到目前为止,只有基于文档/视图的程序才能使用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类了。
SDI,MDI中在CreateClient中使用CSplitterWnd分割,那Dialog中该在那里分割??大虾指教下~~~最好给个例子。

解决方案 »

  1.   

    http://www.codeguru.com/Cpp/W-D/dislog/splitterwindowswithingdialogs/article.php/c2031/http://www.codeguru.com/Cpp/W-D/dislog/splitterwindowswithingdialogs/article.php/c4973/
      

  2.   

    http://www.vccode.com/file_show.php?id=2023
    在对话框中使用切分窗口
      

  3.   

    To:laiyiling(最熟悉的陌生人) ( )    那里面的例子中的Dialog分割出来的窗口只能是VC中controls面板中的控件,不能是dialog或formview之类的。huaboy408(竹一木) ( ) 给的网址刚打开,看了一眼界面,大概也是和laiyiling(最熟悉的陌生人) ( ) 提供的一样。
      

  4.   

    www.codeguru.com
    www.codeproject.com这里面的东西比较多了,没事可以去看看,里面基本上都可以找到想要的东西