피터지고 치열하게 삶을 유지하다  
Front Page
Notice | Keyword | Tag | Location | Guestbook | Admin | Write Article   
 
Dialog에 해당하는 글 1건
2007/04/11   View-In-Dialog 를 위한 방법론들


View-In-Dialog 를 위한 방법론들
Dialog 속에 View를 넣는 것을 특히 HtmlView를 가지고 해보았던 것으로 기억한다.

그러나 역시 남의 생각을 빌었던 까닭에 이번에 ListView를 Dialog속에 넣으려 하니 이전 소스를 참고하거나 다른 사람의 힘을 빌리지 않고 바로 덤벼들어 스스로 해결하지 못하는 일이 발생했다.

이번 기회에 다시한번 Dialog 속에 View를 집어 넣는 방법들을 살펴보고 개념을 정리하고자 한다.

새삼 스럽지만 먼저 View / Document /Frame의 개념을 살펴볼 필요가 있지 않을까?

View / Document / Frame 의 분리
다음은 위의 내용을 전재한 것이다.

이번에 해 볼 것은 MFC의 AppWizard가 기본적으로 만들어주는 코드에서 View / Document / Frame을 차례대로 분리해 보려고 한다. 우선은 View부터 먼저 떼어내보자. 여기서 프로젝트 이름을 Hack 이라고 정했다. 우선 AppWizard(exe)에서 옵션은 기존에 있는 그대로 적용하여 SDI 프로젝트를 하나 만든다. (비주얼 C++ 6 최종분석, 베스트북)

- View의  제거

1) 프로젝트에서 HackView.h / cpp 파일을 지운다.
2) Hack.cpp 파일에서 #include "HackView.h" 부분을 지운다.
3) Hack.cpp 파일에서 다음 부분을 고친다.

원래 이런 내용을

       CSingleDocTemplate* pDocTemplate;
       pDocTemplate = new CSingleDocTemplate(
               IDR_MAINFRAME,
               RUNTIME_CLASS(CHackDoc),
               RUNTIME_CLASS(CMainFrame),       // main SDI frame window
               RUNTIME_CLASS(CHackView));    // 고치기 전
       AddDocTemplate(pDocTemplate);
 
이렇게 고친다.

       CSingleDocTemplate* pDocTemplate;
       pDocTemplate = new CSingleDocTemplate(
               IDR_MAINFRAME,
               RUNTIME_CLASS(CHackDoc),
               RUNTIME_CLASS(CMainFrame),       // main SDI frame window
               NULL);                               // 고친 후
       AddDocTemplate(pDocTemplate);

4) 그런 다음 컴파일하면 뷰가 없어진 것을 확인할 수 있다.
  (뭔가 달라진 게 조금 보일 것이다)


- Document의 제거 (View의 제거 후)

1) 프로젝트에서 HackDoc.h / cpp 파일을 지운다.
2) Hack.cpp 파일에서 #include "HackDoc.h" 부분을 지운다.
3) Hack.cpp 파일에서 다음 부분을 고친다. Document 까지 지워버리면 DocTemplate가 전혀 필요가 없기 때문이다.

View를 제거할 때 고쳤던 내용을

       CSingleDocTemplate* pDocTemplate;
       pDocTemplate = new CSingleDocTemplate(
               IDR_MAINFRAME,
               RUNTIME_CLASS(CHackDoc),
               RUNTIME_CLASS(CMainFrame),       // main SDI frame window
               NULL);
       AddDocTemplate(pDocTemplate);

모두 지우고 다음과 같이 고친다.

       // 메인 윈도우를 위한 클래스 변수 선언
       CMainFrame *pFrame = new CMainFrame();
       // 프레임 제작
       pFrame->LoadFrame(IDR_MAINFRAME);
       // 메인 윈도우로 지정
       m_pMainWnd = pFrame;

4) MainFrm.h 파일을 열어서      CMainFrame()을 protected 속성에서 public 속성으로 바꾼다.
5) 그런 다음 컴파일을 한다. View를 제거했을 때와 같은 창이 뜬다. Document는 눈에 띄지 않으니까.


- Frame의 제거 (View/Document 제거 후)

1) 프로젝트에서 리소스 파일을 모두 지운다. (*.rc *.ico, *.bmp 등)
2) MainFrm.cpp 파일을 열어 OnCreate() 함수를 보자.

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
       if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
               return -1;
       
       if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
               | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
               !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
       {
               TRACE0("Failed to create toolbar\n");
               return -1;      // fail to create
       }

       if (!m_wndStatusBar.Create(this) ||
               !m_wndStatusBar.SetIndicators(indicators,
                 sizeof(indicators)/sizeof(UINT)))
       {
               TRACE0("Failed to create status bar\n");
               return -1;      // fail to create
       }

       // TODO: Delete these three lines if you don't want the toolbar to
       //  be dockable
       m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
       EnableDocking(CBRS_ALIGN_ANY);
       DockControlBar(&m_wndToolBar);

       return 0;
}  

앞의 소스 대부분을 지워 다음과 같이 만든다.

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
       if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
               return -1;

       return 0;
}

3) MainFrm.h 파일을 열어 다음 두 멤버변수를 지운다. 보다시피 상태바와 툴바를 위한 것이다.

       CStatusBar  m_wndStatusBar;
       CToolBar    m_wndToolBar;

4) Hack.cpp 파일을 열어 Document를 제거할 때 고쳤던 부분을 보자.

       // 메인 윈도우를 위한 클래스 변수 선언
       CMainFrame *pFrame = new CMainFrame();
       // 프레임 제작
       pFrame->LoadFrame(IDR_MAINFRAME);
       // 메인 윈도우로 지정
       m_pMainWnd = pFrame;

리소스를 지워버렸기 때문에 이 부분에서 문제가 발생한다. 다음과 같이 고친다.

       CMainFrame *pFrame = new CMainFrame();
       LPCTSTR new_class = AfxRegisterWndClass
               (CS_HREDRAW|CS_VREDRAW,
                LoadCursor(IDC_ARROW),
                (HBRUSH)GetStockObject(WHITE_BRUSH));
       pFrame->Create(new_class, NULL,
               WS_OVERLAPPED|WS_SYSMENU, CRect(0, 0, 300, 100));
       m_pMainWnd = pFrame;

5) 이제 컴파일해 보면 툴바도 없고, 메뉴도 없고, 상태바도 없는 썰렁한 윈도우가 하나 뜨는 것을 볼 수 있다.



기본적으로 MFC는 Document, Frame, View를 한 묶음으로 한 Document Template 클래스를 이용하도록 하고 있습니다. 이때 이 Template 리스트가 하나이냐 두개 이상이냐에 따라 SDI, MDI로 구분하고 있습니다.

그러나 Document가 없는 View를 만들경우 굳이 Document Tamplate 클래스를 이용할 필요가 없습니다.
기본적으로 View는 View가 들어갈 Frame을 갖기만 하면 됨으로 CFrameWnd의 CreateView함수를 이용 View를 생성해 주면 됩니다. 이때 필요한 파라미터가 CCreateContext이며 여기에는 생성될 View의 Runtime Class와 만약 필요하다면 사용할 Document를 지정해주면 됩니다. 다음은 이를 이용해 View를 생성하는 방법입니다.

다이얼로그에 View를 포함하기 위한 아주 Simple한 방법이라고 한다. Creating a View in Dialog (An easy way)
테스트 결과 Dialog Based App의 경우 정상 동작하나, MDI, SDI에서는 Dialog DoModal후 View로 Focus 변경시
문제가 발생한다.

좀더 복잡한 Creating a View on a Dialog - 이건 따로 분석하지 않았다.

아래 예는 역시 CFrameWnd를 이용하는 방법으로 CFrameWnd를 상속받아 위에서 해주던 방법을 상속받은 클래스에서 자체적으로 처리한다는 것만 다를 뿐 나름 같은 개념이다.

CFrameWnd를 상속받아 마치 다이얼로그 처럼 창을 띄어주는 예이다. 만약 다이얼로그 컨트롤들을 사용하고 싶다면 제한적이나마 DialogBar를 배치하여 보완할 수 있다. : 이번에 ListView를 별도 창에 띄어주기 위해 이 방법을 사용하였다.  An alternative to the often asked view-in-dialog problem using a dialog bar

Frame - Document - View 를 추가로 Embedded 했던 방법도 있었던 것으로 기억하는데 해당 링크를 찾지 못하겠다. - 다음에 발견하면 추가하겠다. 나름 유용했던것으로 기억한다.

View를 다루는 것과 관련 다음의 자료를 보는 것도 많은 도움이 될것으로 생각된다.
VSWAP32 Demos Multiple-View Switching in SDI
크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기
Tag : ,
Track this back : http://www.codeforum.net/blog/pitoosung/trackback/56

name    password    homepage
 hidden


BLOG main image
피투성의 IT 분투기
 Notice
(2009.11.30) - ㅠ.ㅠ 안녕! 서버 H/W 시스템 교체(서버보드 사망, HP Workstation으로 교체)
(2008.2.2) IP : 195.225.178.29 - 스팸 차단 조치
(2008.1.14) 오후 06:34 ~ 08:07 : 시스템 복구
(2008.1.14) 오전 00:25(?) : 시스템 다운 - 흠 심각하군!
(2008.1.13) 오후 11:31 : 시스템 리부팅됨
(2008.1.13) 시스템 복구 : 오전(?)~오후 1:00
 Category
전체 (148)
프로그래밍 (42)
IT 세상속으로 (42)
세상 엿보기 (26)
지하창고 (18)
책의 향기 (12)
생각의 힘(바둑) (4)
OCR-내가 다 읽어줄께 (1)
두발의 짐승 (2)
지능형 로봇 (1)
 Calendar
«   2010/09   »
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    
 Recent Entries
투명 Display 그리고 Augm... (2)
64bits(x64) Windows OS...
NFS & Eclipse & CDT & In...
행복에 대해 생각하며
Virtual Audio Cable (가...
 Recent Comments
^^ 안녕! 축하축하. 난 아...
피투성 - 03/16
오랜만에들림니다 아이폰...
쭌 - 03/15
Thanks for your kind tra...
hyungju - 2009
정보 감사합니다 덕분에...
허수 - 2009
관리자만 볼 수 있는 댓글...
- 2009
 Recent Trackbacks
내가 생각하는 한의학의...
Life Is Always Emergency
FreeBSD 6.2, 64bit, 메모...
엘레노아의 작업로그
알약 백신 제대로 사용하...
촌철살인
유용한 블로그 툴 몇개..
ENTClic@blog...just anot...
국내의 검색엔진에 등록하...
케이알선의 이야기
 Archive
2010/01
2009/12
2009/07
2008/09
2008/03
 Link Site
00_피투성의 지식창고_00
 Visitor Statistics
Total : 70561
Today : 55
Yesterday : 46
텍스트큐브 배너
Eolin
rss