본문 바로가기

3.구현/VC++

[MFC]분할 윈도우를 생성하는 방법

아래는 서광철님의 분할윈도우 생성하는 방법니다.

탐색기에서 보신, 분할 윈도우란 CSplitterWnd 라는 클래스를 말하는 것으로서,,
CFrameWnd 나 CMDIChildWnd 의 프레임에만 붙일수있는 콘트롤입니다....
분할 윈도우를 생성하려면 CFrameWnd::OnCreateClient 함수안에서 하게 되는데...
우선, 귀하의 예로는 두개의 폼뷰어를 만들고 각각 Grid control과 Web control을 각각 배치하여 FormView의 코드를 완성하고...
CMainFrame::OnCreateClient 함수를 이와 같이 생성합니다...

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)  
{
   CRect rect;
   GetClientRect(&rect);
   CSize size1(MulDiv(rect.Width(), 30, 100), ::GetSystemMetrics(SM_CYSCREEN)); // 폭(30%)
   CSize size2(MulDiv(rect.Width(), 70, 100), ::GetSystemMetrics(SM_CYSCREEN)); // 폭(70%)
   // create a splitter with 1 row, 2 columns
   if (!m_wndSplitter.CreateStatic(this, 1, 2)) {
       TRACE0("Failed to CreateStatic Splitter \n");
       return FALSE;
   }
    // 사용자가 만든 CFormView1 을 좌측에 배치합니다...
   if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CFormView1), size1, pContext)) {
       TRACE0("Failed to create CFormView1 pane \n");
       return FALSE;
   }
     // 사용자가 만든 CFormView2 을 우측에 배치합니다...
   if (!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CFormView2), size2, pContext)) {
       TRACE0("Failed to create CFormView2 pane \n");
       return FALSE;
   }
   return TRUE;
}

물론 MainFrm.h 파일에

protected:  // control bar embedded members
   CStatusBar    m_wndStatusBar;
   CToolBar        m_wndToolBar;
   CSplitterWnd    m_wndSplitter; // --> 이부분을 추가 해야합니다...

추가가 되었으면 컴파일, 링크 시키고 실행시켜 보세요... 짜잔.... 귀하의 앞에 분활된 창이 보일겁니다..(^__^)..

--------------------------------------------------------------------

그러나 문제가 있는 부분이 있어서 내용을 추가하였다.

문제 : 위처럼 입력하고 빌드했는데 에러가 많이 뜨는데 이상한 메시지가 뜨는 경우가 있다. 특히 CSplitterWnd가 사용한 곳에 RUNTIME_CLASS()를 사용한 부분에서 사용하는 클래스 명을 include을 하지 않으면 해당 클래스명이 네임스페이스 범위에 없다고 나온다. 다시 include하면 이상한 오류 메시지가 뜨는 경우 문제 해결

해결 : 해당 예를 CFromView에서 GetDocument() 부분을 일단 없애자. 그리고 다시 컴파일 하면 에러 없음.

문제 : 분할까지 이상없는데 뷰 하나만 뜨는 상태이다. 분명히 CreateView()로 두개의 뷰를 만들놓았고 빌드시 에러가 없을 경우이다.

해결 : 프래임 클래스에서 OnCreateClient()에서 자동으로 추가된 다음 코드인

return CFrameWnd::OnCreateClient(lpcs, pContext);

를 제거해주면 된다.

다음은 어떤분이 4분할 위도우 만드는 것을 문의했는데 해당 코드와 결과 그림이다.

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
  CRect rect; 
  GetClientRect(&rect);

  // 아래는 좌우 폭 비율
  CSize size1(MulDiv(rect.Width(), 30, 100), MulDiv(rect.Height(), 50, 100)); // 폭(30%), 높이(50%)
  CSize size2(MulDiv(rect.Width(), 70, 100), MulDiv(rect.Height(), 50, 100)); // 폭(70%), 높이(50%)

  // 아래는 상하 폭 비율 (절반)
  //CSize size1(MulDiv(rect.Width(), 50, 100), ::GetSystemMetrics(SM_CXSCREEN)); // 높이(50%)

  // create a splitter with 2 row, 2 columns 
  if (!m_wndSplitter.CreateStatic(this, 2, 2)) { 
      TRACE0("Failed to CreateStatic Splitter \n"); 
      return FALSE; 
  }

  // 사용자가 만든 CFormView1 을 좌측에 배치합니다... 
  if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CFormView1), size1, pContext)) { 
      TRACE0("Failed to create CFormView1 pane \n"); 
      return FALSE; 
  }

  // 사용자가 만든 CFormView2 을 우측에 배치합니다... 
  if (!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CFormView2), size2, pContext)) { 
      TRACE0("Failed to create CFormView2 pane \n"); 
      return FALSE; 
  }

  if (!m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(CFormView3), size1, pContext)) { 
      TRACE0("Failed to create CFormView3 pane \n"); 
      return FALSE; 
  }

  if (!m_wndSplitter.CreateView(1, 1, RUNTIME_CLASS(CFormView4), size2, pContext)) { 
      TRACE0("Failed to create CFormView4 pane \n"); 
      return FALSE; 
  }

  return TRUE;
  //return CFrameWnd::OnCreateClient(lpcs, pContext);
}

다음은 결과 화면이다.

그때 작성한 클래스 구성이다.

참고

반응형