상세 컨텐츠

본문 제목

[MFC] 다이얼로그 FormView, CDialog 관련

프로그래밍 관련/MFC

by AlrepondTech 2020. 9. 10. 04:34

본문

반응형

 

 

=================================

=================================

=================================

 

 

출처: http://blog.xozu.net/210

 

 


Dialog 의 속성을 아래와 같이 설정한다.

Border : None
Style : Chiled



아래의 코드를 추가한다.



view plaincopy to clipboardprint?

  1. //CMainFrame.h  
  2. #pragma once  
  3. class CMainFrame : public CFrameWnd  
  4. {  
  5.     public:  
  6.         CDialogBar m_wndDialogBar; // 추가할 부분  
  7. }  

view plaincopy to clipboardprint?

  1. //CMainFrame.cpp  
  2. int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)  
  3. {  
  4.     // 중략  
  5.     // Quest List bar ------------------------------------------------------  
  6.     if(!m_wndQuestListBar.Create(this, IDD_DIALOG1, // DIALOG에 설정된 ID  
  7.     CBRS_LEFT | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_HIDE_INPLACE,  
  8.     IDS_STRING_TEST)) //스트링 테이블에서 작성하세요  
  9.     {  
  10.         TRACE0("Failed to create dialog bar m_wndDialogBar\n");  
  11.         return -1;        // fail to create  
  12.     }  
  13.   
  14.     m_wndQuestListBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT);  
  15.     EnableDocking(CBRS_ALIGN_ANY);  
  16.     DockControlBar(&m_wndQuestListBar);  
  17.     //-----------------------------------------------------------------------  
  18.     return 0;  
  19. }  

 

 

=================================

=================================

=================================

 

 

 

출처: https://m.blog.naver.com/PostView.nhn?blogId=xtelite&logNo=50022212767&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F

 

Modeless Dialog(모달리스/모델리스 대화상자)

 

1. Modal  Modeless

 

             Modal은 대화상자가 출력되고 있는 동안 프로그램의 모든 제어권을 독점하고 있어 대화상자가 종료되기

             전까지 다른 작업을 할 수가 없다.

             Modeless는 대화상자가 출력되고 있는 동안에도 다른 작업을 할 수가 있다.

 

2. 대화상자 출력시 차이점

 

구분 Modal Modeless
생성 DoModal Create
종료 EndDialog DestroyWindow
인스턴스 선언 지역변수 동적할당

 

-       Modeless DoModal 함수로 생성된 것이 아니기 때문에 EndDialog를 사용할 수 없다.

-       IDOK 또는 IDCANCEL 같은 ID를 가진 버튼을 만들지 않는 것이 좋으며 꼭 이 버튼을
추가해야 할 경우에는 OnOK  OnCancel 같은 함수를 재정의하고 그 안에서 CDialog 클래스의
OnOK 
함수나 OnCancel 함수가 호출되지 않도록 해 주어야 한다.

 

3. Instance 생성

 

             Modeless 대화상자를 프로그램 전체에서 사용할 수도 있는데 그럴 경우 CMainFrame, CXXXApp, CXXXView, CXXXDoc

             등의 멤버로 CModelessDlg를 선언하고 필요할 경우 생성/해제 하는 방법을 사용해도 된다.

             필요할 때 생성하는 방법은 아래와 같다

 

        CModelessDlg *pDlg = new CModelessDlg;

        pDlg->Create(IDD_MODELESS);

        pDlg->ShowWindow(SW_SHOW);

 

4. 예제

 

1)     대화상자를 하나 만든다이때 버튼은 [OK] 버튼이나 [CANCEL] 버튼을 만들지 않고 IDC_CLOSE 라는 버튼을 만들었다.
 2. 번 참조
다른 컨트롤들을 넣고 싶다면 이것은 Modal 대화상자와 완전히 동일하므로 필요한 대로 Design 하면 된다.



 

그 다음 대화상자용 클래스를 만든다.

 

 

 

2)     대화상자를 생성하고 싶은 곳에 아래 코드를 추가한다프로그램 전체에 걸쳐 사용하고 싶은 경우는 멤버로
CModelessDlg *m_pDlg; 
를 선언해 놓으면 된다.

 

                     CModelessDlg *pDlg = new CModelessDlg;

                pDlg->Create(IDD_MODELESS);

                pDlg->ShowWindow(SW_SHOW);

 

3)     대화상자 클래스의 Close 버튼의 이벤트 핸들러를 만들어서 다음 코드를 추가한다이 코드는 대화상자를 닫게 만든다.

 

               void CModelessDlg::OnBnClickedClose()

               {

                       // TODO: Add your control notification handler code here

                       DestroyWindow();

               }

 

4)     대화상자를 만들면서 동적 메모리를 할당한 것이 있다면 이것도 해제시켜 주어야 하는데 이것은 PostNcDestroy()에서
해주면 된다. PostNcDestroy()는 대화상자가 완전히 소멸된 후에 호출되기 때문에 안전하게 삭제할 수 있다.

 

               void CModelessDlg::PostNcDestroy()

               {

                       // TODO: Add your specialized code here and/or call the base class

                       delete this;

 

                       //CDialog::PostNcDestroy();

               }

 

 

 

 

=================================

=================================

=================================

 

 

 

 

 

출처 : http://www.anymodules.com/xe/?mid=TechNote&search_target=tag&search_keyword=IT%C2%B7%EC%BB%B4%ED%93%A8%ED%84%B0&listStyle=webzine&document_srl=313

 

예) 부모 : CFirstDlg      /     자식 : CChildDlg

 

1. 리소스 뷰에 다이얼로그를 추가 -> 편집한다. (자식 다이얼로그로 디스플레이될 것임.)

2.
 추가한 다이얼로그에 클래스를 연결한다.
    2-1. 추가한 다이얼로그 창을 더블 클릭
    2-2. 클래스 추가 : CChildDlg
    2-3. 클래스가 추가되면 ChildDlg.cpp 와 ChildDlg.h 가 생성된다. (Solution Explorer)

3.
 FirstDlg.h 에 ChildDlg.h 를 인클루드 한다. (#include "ChildDlg.h")

4. FirstDlg.h 의 CFirstDlg Definition 안에 CChildDlg 를 다음과 같이 선언한다.
class CFirstDlg : public CDialog
{
    ...
public :                // 임의로 public 지정했음
    CChildDlg ChildDlg;
    ...
}

5. FirstDlg.cpp 에서 자식 다이얼로그를 생성할 부분에 다음과 같이 코딩한다.

void CFirstDlg::func()
{
...
  자식 다이얼로그 생성
  {
      ...
      ChildDlg.Create(CChildDlg::IDD, this);                // this 를 사용하여 부모를 지정.
      ChildDlg.CenterWindow();
      ChildDlg.ShowWindow(SW_SHOW);
      ...
  }
...
  자식 다이얼로그 파괴                               // 이 부분 중요함. 메모리 누수 방지, 자식다이얼로그에서 할당했던 메모리들을 해제해야 한다.
  {

      ......
      ChildDlg.DestroyWindow(); 

  }
}


......................................................................또는 이렇게도 할 수 있다...................................................................

 

 

void CFirstDlg::func()

{
...

  CChildDlg *pChDlg = new CChildDlg(this);
  자식 다이얼로그 생성
  {
      ...
      pChDlg ->CenterWindow(IDD_CHILDDLG);    // IDD_CHILDDLG 는 자식 다이얼로그의 ID.
      pChDlg ->ShowWindow(SW_SHOW);
      ...
  }
...
  자식 다이얼로그 파괴                   //   이 부분 중요함. 메모리 누수 방지, 자식다이얼로그에서 할당했던 메모리들을 해제해야 한다.
  {

      ......
      delete pChDlg ;
  }
}

 

 

 

=================================

=================================

=================================

 

 

 

출처: http://egloos.zum.com/sunyoungis/v/1022109

 

 

  1. <MFC> Test 프로젝트 생성 (다중문서선택)

 

 




    2. 솔루션 탐색기 아래 탭에서 [리소스뷰] - [Menu] - [IDR_MAINFRAME] - Test/다이얼로그 만들기 



 


     3. 다이얼로그 마우스 오른쪽 클릭 -> ID 부분 편집한다.


 



    4. ID편집후 -> 이벤트 처리기 추가 


 


    5. CMainFrame 선택후 [ 추가 및 편집 ]


 


    6. 솔루션 탐색기 아래 탭에서 [리소스뷰] - [Dialog] - 오른쪽 마우스 클릭 ->  Dialog삽입



 



    7.다이얼로그 오른쪽 마우스 클릭후 -> 클래스 추가 


 

 



    8. 클래스 추가 ///   클래스이름을 지정하고 기본클래스를  CDialog 로 꼭! 지정해야한다. 



 


    9. mainFrm.cpp 로가서 #include "---------.h"   다이얼로그 클래스 8번 에서지정한 [클래스 이름].h 헤더 선언



 



    10. MainFrm.cpp 마지막부에 / 3.4.5. 에서만든 메뉴에 대한 이벤트 처리부분이다.  
        OnTest()  에서 Test는 ID값으로 지정한 값.
        명령 처리기 코드를 작성하고 실행
    
        Dlg1    aboutDlg;             //Dlg1 <- 다이얼로그 클래스이름 
        aboutDlg.DoModal();         

 


열려있는 창을 닫기누르면 아래와 같은 창으로 바뀐다. 

 

 


다이얼로그 메뉴를 클릭하면 다이얼로그창이 뜬다.! 결과


 



이상 1주차 과제 복습이였습니다.

 

 

=================================

=================================

=================================

 

 

 

출처: http://qnnpnet.nayana.com/board/view.php?id=study&category=19&keyword=&st=&sc=&sn=&op=&site_no=1&order=title&desc=desc¤t_page=4&no=13

 

 

이얼로그 리소스대로 폼뷰 크기 설정하기

 

 

OnInitialUpdate 멤버 함수에 다음 두 라인을 첨가한다.
ResizeParentToFit(FALSE);
ResizeParentToFit();

 ResizeParentToFit() 함수를 두 번 호출하였는데, 첫 번째 호출은 뷰가 확장되도록 하기위한 것이며, 두 번째 호출은 뷰의 크기가 다이얼로그 리소스에 맞게 축소되도록 하기 위한 것이다.

 

 

=================================

=================================

=================================

 

 

 

출처: http://asus200.tistory.com/entry/MFC-2%EA%B0%9C%EC%9D%98-%EB%8B%A4%EC%9D%B4%EC%96%BC%EB%A1%9C%EA%B7%B8-%EB%A7%81%ED%81%AC-%EC%8B%9C%ED%82%A4%EB%8A%94-%EB%B0%A9%EB%B2%95

 

 

 

[새로운 다이얼로그 추가하는 방법]

 

오늘은 MFC 초보자가  2개 이상의  다이얼로그를 연결시키는 방법에 대해 포스팅 할까 합니다

 

먼저 대화상자 기반의 프로젝트는 만들어져 있다고 가정하겠습니다

 

다음 순서를 따라 하시면 되겠습니다

 

1  새로 추가할 다이얼로그를 만들기위해 리소스 뷰에서 리소스 추가를 선택합니다  그러면 새로운 다이얼로그가 생성됩니다

 

 

 

2 새로운 다이얼로그는 사용자가 원하는데로 디자인 합니다

   그리고 속성창에서 ID를 용도에 맞는 이름으로 바꿔줍니다

 

 

 

3 다이얼로그를 컨트롤 할 클래스를 추가합니다 

   ( 다이얼로그 창 전체에 포커스가 가게한 뒤 마우스 우측 클릭을 하면 아래와 같은 버튼이 나타납니다 그중 클래스 추가를 클릭합니다)

 

 

 

4  클래스 이름을 알맞게 설정합니다 그후 마침을 누르면 .cpp와 .h파일이 생성됩니다

 

 

 

 

5  mian다이얼로그에서 새로추가한 클래스의 헤더파일 즉 UsbMainDlg.h를 include 시켜 줍니다 

 

 

 

6  main 다이얼로그 헤더파일에 새로추가한 다이얼로그를 콘트롤할수 있도록 멤버 변수를 추가해줍니다

 

 

 

 

7 main 다이얼로그 호출 하는 부분에서 아래와 같이 코드를 적어 주시면 됩니다 (새로 만든 다이얼로그를 호출하는 부분입니다  2번째 줄의 IDD_USB_MAINDIALOG 는 위에 2번 항목에서 설정한 ID값을 넣어주면 됩니다)

 

 

 

8 마지막으로 프로그램을 실행시켜 메인 다이얼로그에서 버튼을 클릭하면 새로 만든 다이얼로그가 표시 되는 화면입니다

 

 

 

이런 방법으로 새로운 다이얼로그를 계속 만들어 링크 시킬수 있습니다     

(물론 main다이얼로그는 hide시킬수도 있겟죠)

 

여기까지 초보자가 2개의 다이얼로그를 링크 시키는 방법에 대해 알려 드렸습니다 

 

제가 만든 방법 말고도 다른 쉬운 방법이 있으시면 댓글 부탁드립니다



출처: http://asus200.tistory.com/entry/MFC-2개의-다이얼로그-링크-시키는-방법 [람보의 세상살이]

 

 

 

=================================

=================================

=================================

 

 

 모달리스 다이얼로그 생성 및 삭제 방법

 

 


1. new로 CDialog 클래스를 베이스 클래스로 하는 클래스의 인스턴스를 생성한다.

2. Create 함수로 다이얼로그를 생성한다.

3. ShowWindow( SW_SHOW ) 함수로 윈도우가 화면에 보이게 만든다. ( 다이얼로그 리소스에 스타일이 보이기로 설정되어 있으면 이 함수를 호출하지 않아도 되는데 걍 호출해준다. 괜히 화면에 안보여서 헤메지 말자)

4. 여기까지가 모달리스 다이얼로그 생성 화면이다.


주의 모달리스 다이얼로그에서는 EndDialog가 실행되면 안된다.

OnOK, OnCancel 함수에서는 EndDialog 함수를 알아서 호출하게 돼는데 이 함수들도 재정의 해서 베이스 클래스의 OnOK, OnCancel 함수를 호출하지 않도록 한다.


모달리스 다이얼로그 종료하기

1. DestroyWindow 함수를 호출하여 윈도우를 없앤다.

2. delete 로 CDialog 클래스를 베이스 클래스로 하는 클래스의 인스턴스를 삭제한다.


이래처럼 해주면 메모리 릭도 없어진다.


실제 코드는 다음과 같이 해주면 된다.

 

view plaincopy to clipboardprint?

  1. CDialog *pDlg = new CDialog( );  
  2.   
  3.   
  4. if ( pDlg )  
  5. {  
  6.     pDlg->Create( IDD_TEST );    // IDD_TEST 는 리소스에 등록된 다이어로그 ID  
  7.     pDlg->ShowWindow( SW_SHOW ); // 혹시 모르니깐 화면에 보여지게 속성 변경  
  8. }  
  9.   
  10. // 여기까지가 모달리스 다이얼로그 윈도우 보이기  
  11.   
  12. // 여기서부터는 모달리스 다이얼로그 종료하기  
  13.   
  14. if ( pDlg )  
  15. {  
  16.     pDlg->DestroyWindow( );  
  17.     delete pDlg;  
  18.     pDlg = NULL;  
  19. }  

 

 

=================================

=================================

=================================

 

 

 

출처: http://heart4u.co.kr/tblog/318

 

 

들어가기 앞서. MFC 책 펼친지 이틀밖에 되지 않아서 이게 정답이 아닐 수 있습니다. 

본 편은 버튼 클릭시 다이얼로그 띄우는 방법에 대하여 소개합니다.

 

버튼 클릭시 다이얼로그 띄우는방법은 다른분들도 글 올려두셨던데 글로만 써놓으셔가지고 저같은 초보들은 알아보기 힘들기에 차라리 내가 만들어 올리자 해서 만들어 올립니다.

 

 

STEP1. 새로운 MFC 프로젝트를 생성하여 "리소스 뷰"에서 새로운 Dialog를 생성합니다.

             아래 스크린샷과 같이 Dialog 삽입 버튼을 클릭합니다.

 

 

 STEP2. 새로만든 Dialog 창에 "새로 띄우는 다이얼로그 입니다." 라고 입력하였습니다. [띄어쓰기가 틀렸네요;; 무시해주세요;]

 

 

 STEP3. 다이얼로그 창을 선택한 후 오른쪽버튼을 클릭하시면 "클래스 추가"를 클릭하여 새로운 클래스를 등록합니다.

 

 

 STEP4. 새로운 클래스 등록창에 저는 클래스 이름 항에 "NewDialog"로 입력하였습니다.

입력후 보시면 헤더파일인 .h 파일 부분을 보시면 "NewDialog.h"로 생성 될것이라고 보입니다. 기억해주시기 바랍니다.

그리고 마침을 눌러줍니다.

 

 

STEP5.  엄마다이얼로그로 가셔서 버튼을 생성하여 줍니다.

버튼 이름은 자유롭게 하시고 버튼의 Edit모드로 들어가기 위하여 버튼을 더블클릭하여 줍니다. 

 

 

STEP6.  아래 스크린샷은 버튼 클릭하여 edit모드로 들어온 모습입니다.

아래와 같이 타이핑하여 줍시다.

NewDialog dlg;

dlg.DoModal(); 

 

타이핑 하시고 보면 아마 빨간 물결이 NewDialog쪽에 하이라이트 되어 있을건데 헤더파일을 include시켜주지 않아서 뜨지 않은것입니다. 신경쓰지마시고 STEP7로 넘어갑시다.

 

 

 

 STEP7.  그 위로 쭉 올려주시면 헤더파일 인클루드가 보입니다.

 아래 스크린샷처럼 "NewDialog.h"를 include시켜 줍니다.

 #include "NewDialog.h"

 

그리고 내려와서 보시면 아까 NewDialog에 물결표시 하이라이트된 부분이 사라져있을 것입니다.

 

 

 

FIN. 이제 빌드하여 확인합니다. 버튼을 클릭하여 보시면 새로운 창이 뜨는것을 확인 할 수 있습니다.

 

 

 



출처: http://as1202.tistory.com/317 [세상속 나만의 무인도]

 

 

=================================

=================================

=================================

 

 

 

출처: http://hot2364928.tistory.com/33

 

 

 

 DialogToDialog.zip

 

 

MFC 다이얼로그에서 다이얼로그 생성하는 법을 알려드리겠습니다~

 

구조를 설명하면,

 

부모의 다이얼로그가 있습니다.

 

거기서 버튼을 누르면 자식의 다이얼로그가 생성되는 구조입니다.

 

 

 

 

이런 식으로 MFC 를 생성해줍니다

 

저는 대화 상자 기반으로 생성했는데, 단일문서로 하던 다중 문서로 하던 상관없습니다.

 

 

 

설명은 대화 상자 기반으로 생성했을 때를 기준으로 하겠습니다.

 

 

 

 

 

그렇게 생성을 하고 디버그하면 저런 아무것도 없는 창이 뜹니다.

 

 

 

이제, 다이얼로그를 생성시킬 버튼을 만들겠습니다.

 

오른쪽 도구 상자에서 버튼을 끌어다놓고, ID 나 이름은 자유롭게 지어주세요

 

일단 여기까지하고, 버튼을 클릭하면 나오게 될 다이얼로그를 만들겠습니다.

 

 

 

 

리소스 추가 - 다이얼로그 를 선택합니다.

 

그리고나면 아까와 같이 빈 다이얼로그가 나옵니다. 

 

 

 

 

 

그리고 위와같이 디자인 합니다.

 

하나는 이름 : 메세지 , ID : IDMESSAGE

 

다른 하나는 이름 : 종료 , ID : IDEXIT

 

로 했습니다.

 

저는 기본적으로 나오는 확인 , 취소 버튼을 수정해서 만들었습니다.

 

 

 

그다음에 다이얼로그 아무데나 더블클릭하면 MFC 클래스 추가 마법사가 나옵니다.

 

여기서 클래스 이름만 설정해주시고 확인 누르시면 클래스가 하나 생성됩니다.

 

(저는 Message_Dlg 로 했습니다)

 

그리고 난 뒤, 다시 다이얼로그로 돌아가서

 

메세지 , 종료 버튼을 각각 더블클릭해서 함수를 생성합니다.

 

 

 

 

그리고 OnBnClickedMessage 에는 MessageBox("Sample","Hi");

 

OnBnClickedExit 에는 OnOK 를 추가시켜 줍니다.

 

메세지를 클릭했을 때에는, MessageBox 를

 

종료를 클릭했을 때에는 종료시켜주는 겁니다.



출처: http://hot2364928.tistory.com/33 [굳]

 

 

 

=================================

=================================

=================================

 

 

 

출처: http://codegeneration.tistory.com/15

 

 

참,,

많이도 했었는데 할때마다 책본다.. 이런,, 망할 기억력..

모달리스 대화상자는 윈도우 창 선택이 자유로운 다이얼로그이다.

모달 대화상자는 (dlg.DoModel == ID_OK) 이런식으로 생성 시키고 종료하는데

모달 대화상자가 없어질때까지 부모 클래스 다이얼로그를 선택할 수 없다는 단점이 있다. 물론, 단점이라기보단 그런 기능

예를 들어 파일 열기 같은 CFileDialog 가 이런 경우라 하겠다.

모달리스는 생성후 닫지 않아도 부모 클래스 다이얼로그를 선택할 수 있는 것이다.

거두 절미 하고,

모달리스는 먼저, 띄우고자 하는 다이얼로그 리소스와 클래스를 만든뒤

생성하고자 하는 클래스로 이동해서

해더파일에 다음과 같이 클래스를 등록해주고.

/// 생성할 버튼이 있는 다이얼로그의 헤더파일을 등록해주고, 멤버 변수로 선언해준다.

view sourceprint?

01.#incldue "MotherDlg.h"

02. 

03.#include "ModelessDlg.h"

04. 

05.class CModelessDlg;

06. 

07.class CMotherDlg:public CDialg

08. 

09.{

10. 

11....

12. 

13.public :

14. 

15.CModelessDlg* m_pDlg;

16. 

17....

18. 

19. 

20./// MotherDlg.h 의 생성할 버튼에서는 동적으로 생성하기 위해 아래와 같이 해준다.

21. 

22.void CMotherDlg::OnBnClickedModeless()

23.{

24. 

25.if (m_pDlg!= NULL)

26.{

27.m_pDlg->SetFocus();

28.}

29.else

30.{

31.m_pDlg= CModelessDlg;

32.m_pDlg->Create(IDD_MODELESS_DLG,this);

33.m_pDlg->ShowWindow(SW_SHOW);

34.}

35. 

36.}

37. 

38.//동적이게 하기 위해서는 다음과 같이 모달리스 대화 상자의 cpp 파일에 다음을 추가한다.

39.// 종료하기 위한 확인 버튼, 취소 버튼 또는 사용자가 만든 버튼에 아래와 같이 윈도우 종료와

40. 

41....

42. 

43.void CModelessDlg::OnBnClickedOnCancel()

44.{

45.DestroyWindow();

46.}

47....

48. 

49./// 부모 쪽에서 생성한 모달리스 다이얼로그의 멤버 변수를 NULL 로 만들어준다.

50. 

51.void CModelessDlg::PostNcDestroy()

52.{

53.CMotherDlg*)GetActiveWindow())->m_pDlg= NULL;

54.delete this; // 이것을 해야 함. PostNcDestroy 함수는 다이얼로그가 종료되면서

55. 

56.//  최종적으로 날리는 메시지여서 여기에서 this를 지워야 합니다.

57.CDialog::PostNcDestroy();

58.}



출처: http://codegeneration.tistory.com/15 [Code Generation]

 

 

=================================

=================================

=================================

 

 

 

출처: http://bigmark.tistory.com/7

 

 

1. 부모 다이얼로그 생성

2. 자식 다이얼로그 생성

- 자식 다이얼로그 속성창에서 style은 child, border는 NONE 으로 설정 변경

3. 부모 다이얼로그의 헤더파일에서 해당 자식 다이얼로그 변수 포인터로 생성

CChildDlg *m_pChildDlg;


4. 부모 다이얼로그의 OnInitDialog에서

m_pChildDlg = new CChildDlg;
m_pChildDlg->Create( CChildDlg::IDD, this );
m_pChildDlg->ShowWindow( SW_SHOW );
m_pChildDlg->MoveWindow( rcDlg ); // 크기는 알아서 맞게 지정

이렇게 하면 자식 다이얼로그가 부모 다이얼로그에 붙는다.

출처: http://bigmark.tistory.com/7 [마크의 맥시멈 라이프]

 

 

 

=================================

=================================

=================================

 

 

 

출처: http://blog.naver.com/PostView.nhn?blogId=chaose21c&logNo=150133862259

 

 

[MDI] 다른 종류의 View(뷰)를 띄우자

 

 MFC는 다일로그 기반의 프로그램만 개발해 왔다. 좀 더 개발의 폭을 넓히기 위해 MDI 쪽을 다시 살펴보게 되었다.

 

SDI 및 MDI구조의 설명을 이포스트에서는 따로 다루지 않을 것이다. 다만 아래 예제를 통하여 그 구조를 살짝 엿볼 수는 있을 것이다.

 

이번 포스의 제목처럼 MDI에서 여러 종류의 뷰를 띄워보고 간단한 예제를 통하여 사용방법을 보여줄 것이다.

 

다름 방법으로 차일드 윈도를 생성하는 방법은 아래 링크를 참조하길 바란다.

 

http://nenunena.tistory.com/66

 

개발환경

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

OS : Windows 7

TOOL : Visual Studio 2008

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

 

1) 프로젝트 생성하기

step 1. 새 프로젝트

 

 

 

Step2. MFC 응용프로그램 마법사 시작

 

 

 

프로젝트 생성에 대한 설명을 보여주고 있다.

 

 

Step3. 응용프로그램 종류

 

 

 

위 그램에서 표시한 것 처럼 [ 다중문서 > 탭 문서 ] 의 체크를 해제한다.

프로젝트 스타일은 [ MFC 표준 ] 을 선택한다.

 

 

Step4. 복합문서 지원

 

 

 

[ 복합 문서 ] 에 관련된 내용을 다루지 않으므로 [ 다음 ] 을 선택한다.

 

 

Step5. 문서 템플릿 문자열

 

 

[ 문서 탬플릿 문자열 ] 은 기본 설정 값 그대로 사용한다. [ 다음 ] 을 선택한다.

 


Step6. 데이터베이스 지원
 

 

[ 데이터베이스 지원 ] 은 사용하지 않으므로 [ 다음 ] 을 선택한다.


 
Step7. 사용자 인터페이스 기능
 



 [ 사용자 인터페이스 기능 ] 은 기본 설정 값 그대로 사용한다. [ 다음 ] 을 선택한다.

 

 

Step8. 고급기능

 

 

 

 [ 고급 기능 ] 은 기본 설정 값 그대로 사용한다. [ 다음 ] 을 선택한다.

 

 

Step9. 생성된 클래스

 

 

 

[ 기본 클래스 ] 에서 View의 종류를 선택하면 프로젝트에 적용된다.

 

[ 생성된 ] 은 기본 설정 값 그대로 사용한다. [ 다음 ] 을 선택한다.

 

 

마법사를 통해 생성된 프로젝트를 컴파일 후 실행하면 아래와 같다.

 

 

 

 

 

 

2)  새 템플레이트 만들기

 

템플레이트에 등록 되어야할 클래스 아래 와 같다. 그리고 각 클래스 별 상세 설명은 다음 포스트에 하기로 한다.

 

- 프레임 클래스

- 도큐먼트 클래스

- 뷰 클래스

- 아이콘, 메뉴, 문자열 테이블

 

우리는 마법사를 통해 MidEx 프로젝트를 생성했고, CMainFrame, CChildFrame, CMidExApp, CMidExDoc, CMidExView 클래스가 생성 되었을 것이다. ( 각각의 생성된 이유와 기능은 SDI 또는 MDI 구조 참고)

 

 

그럼 먼저 아래와 같이 클래스를 생성한다.

 

( 클래스 추가는 [ 프로젝트 > 클래스 추가 ] 메뉴를 선택하여 추가한다. )

 

1.CFrameWnd를 상속받은 프레임 클래스 CFromFrameWnd 생성한다.



 

2.CFormView를 상속받은 View클래스 CFormViewEx 생성한다.

 

위 (1) 과  같이 MFC 클래스 마법사에서 클래스의 이름을 [ CFormViewEx ] 로하고 기본클래스를 [ CFormView ]로 하여 생성한다.

3.CDocument클래스를 상속받은 도큐먼트 클래스 CFormDoc 생성한다.

 

위 (1) 과  같이 MFC 클래스 마법사에서 클래스의 이름을 [ CFormDoc ] 로하고 기본클래스를 [ CDocument]로 하여 생성한다.

 

 

 

 다음은 CMdiExApp::InitInstance() 를 아래 내용이 있을 겁니다.

 

 

// ...

// 중간 생략

 

CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_MdiExTYPE,
  RUNTIME_CLASS(CMdiExDoc),
  RUNTIME_CLASS(CChildFrame), // 사용자 지정 MDI 자식 프레임입니다.
  RUNTIME_CLASS(CMdiExView));
 if (!pDocTemplate)
  return FALSE;
 AddDocTemplate(pDocTemplate);

 

// 이하 생략

// ...

 

 

위 내용을 그대로 복사하여 붙여넣기 한 다음, 아래 와 같이 수정합니다.

 

MultiDocTemplate* pDocTemplate2;
 pDocTemplate2 = new CMultiDocTemplate(IDR_MdiExTYPE,
  RUNTIME_CLASS(CFormDoc),
  RUNTIME_CLASS(CFormFrameWnd), // 사용자 지정 MDI 자식 프레임입니다.
  RUNTIME_CLASS(CFormViewEx));
 if (!pDocTemplate2)
  return FALSE;
 AddDocTemplate(pDocTemplate2);

 

아래와 같이 해당 코드를 주석처리합니다.

 

// CCommandLineInfo cmdInfo;

// ParseCommandLine(cmdInfo);

//// Dispatch commands specified on the command line

// if (!ProcessShellCommand(cmdInfo))

// return FALSE; 

위의 내용중에서 PareCommandLine라는 함수는 명령정보를 분석한다는 의미입니다. ProcessShellCommand함수는 명령정보에 따라서 쉘을 실행하는 형태입니다. 위의 것을 삭제하지 않으면 다중 템플레이트일경우 어느 템플레이트를 로드할것인가를 물어보게 됩니다. 우리는 처음에는 프로젝트를 만들때 자동으로 만들어진 템플레이트를 로드하고 그리고 메뉴에서 특정항목을 클릭하면 새로만든 템플레이트를 로드할려고 하기 때문에 위의 함수들이 수행되어서는 안되기 때문입니다.

다음 삭제후에 OnFileNew() 라는 함수를 새로 삽입합니다.

void CMdiExApp::OnFileNew()

{

// TODO: Add your command handler code here

} 

이함수를 다음과 같이 수정을 합니다.

void CMdiExApp::OnFileNew()

{

// TODO: Add your command handler code here

POSITION pos=GetFirstDocTemplatePosition();

CDocTemplate* pTemplate;

pTemplate=GetNextDocTemplate(pos);

pTemplate->OpenDocumentFile(NULL);

}

 

GetFristDocTemplatePosition()함수는 POSITION형의 위치 값을 리턴합니다. 이리턴된값은 템플레이트의 첫시작위치를 가르킵니다. Inistance에서 AddDocTemplate 등록한 템플레이트의 첫 시작위치라는 것입니다. 이것은 첫번째 템플레이트가 아닌 템플레이트의 시작점입니다. 여기에서 AddDocTemplate 에의해서 설정한 첫번째 템플레이트를 받고자 한다면 현재 위치에서 GetNextDocTemplate 함수를 사용하여 이동을한번 해야 합니다. 이렇게 함으로써 첫번째 위치를 얻을수 있습니다.

GetNextDocTemplate(pos); 함수를 실행하면 실제 템플레이트를 얻게 됩니다. 이템플레이트의 멤버함수이 OpenDocumentFile함수에 인자를 NULL 로 설정하면 File 에서 New항목을 설정한것과 같은 현상이 발생됩니다. 만일 OpenDocumentFile에 파일명을 주게 되면 이때는 File 의 Open항목을 선택한것과 같은 것이 됩니다.

InitInstance() 함수는 ProcessShellCommand 함수 대신에 OnFileNew()함수가 실행됨으로 다중템플레이트중에서 첫번째 등록한 템플레이트를 로드하게 되는 것입니다. 

 

 

이제 두번째 템플레이트를 로드하는 함수를 만들어 보겠습니다. 이함수를 만들기전에 메뉴 IDR_MAINFRAME 에 항목을 추가합니다. 추가하는 항목의 ID는 ID_ANOTHERVIEW 입니다. 이항목은 IDR_ANOTERFRAME 에서 File에 Newㅇ항목의 ID와 같은 것입니다. 이항목의 이름은 여러분이 원하는대로 설정하셔도 됩니다. 이항목을 선택하였을때는 두번째로 등록한 템플레이트가 실행됩니다. 메뉴에 이항목을 설정하고 이항목이 선택되었을대 실행하는 함수를 CMdiExApp에 만듭니다.(꼭 CMdiExApp 입니다. 혹시 다른 곳에 하시면 안됩니다) 이렇게 만들어진 함수는 다음과 같습니다.

 

void CMdiExApp::OnAnotherview()

{

// TODO: Add your command handler code here

}

위의 함수에 두번째 템플레이트를 로드하는 내용을 삽입한 OnAnotherView는 다음과 같습니다.

void CMdiExApp::OnAnotherview()

{

// TODO: Add your command handler code here

POSITION pos=GetFirstDocTemplatePosition();

CDocTemplate* pTemplate;

for(int i=0;i<2;i++)

pTemplate=GetNextDocTemplate(pos);

pTemplate->OpenDocumentFile(NULL);

}

 

 

 

아래는 최종 프로그램을 실행한 화면입니다.

 

 

 

 

 

=================================

=================================

=================================

 

 

 

출처: http://blog.naver.com/PostView.nhn?blogId=kilsu1024&logNo=110156301791&parentCategoryNo=14&categoryNo=&viewDate=&isShowPopularPosts=false&from=postView

 

 

다이얼로그 POPUP / CHILD 속성에 따른 '모달리스' 동작 형태 

[출처] 다이얼로그 POPUP / CHILD 속성에 따른 '모달리스' 동작 형태|작성자 콩이아부지

 

 

 

 

 

 

 

 

리소스에 생성된 Dialog를 모달리스로 동작시키는 경우

 

1. 부모 윈도우에 추가

    부모 윈도우에 추가 하기 위해서는 'WS_CHILD' 스타일이 지정 되어 있어야 한다.

 

2. 부모 윈도우 외부 영역에 띄우기

'WS_POPUP' 속정 

 

3. 내부/외부 영역 모두 띄우기

child/popup 사용하기 위해서는 리소스 에서 'POPUP' 스타일로 적용 시키여 한다.

그렇지 않고 'CHILD' 스타일로 적용하면 코드에서 'CHILD->POPUP'로 변경 하고자 할 경우 약간의 문제가 발생 한다. (오류 아님)

이상 현상) => 두개의 윈도우 창이 별개의 창으로 설정 된다

. (예) 부모창이 최소화/ 최대화를 클릭하여도 자식 팝업창은 영향 받지 않음 (윈도우 작업 표시줄에도 별도로 추가됨)

 

void CTestDlg::InitDlg()

{

CDialog dlg;

 

if(bChild) // 부모 영역 내

{

dlg.Create(IDD_TEST_DLG); 

dlg.ModifyStyle(WS_POPUP, WS_CHILD); // 스타일 수정 

dlg.SetParent(this);  //  부모 윈도우를 지정 하지 않으면 POPUP 창으로 부모 위에 위치함

}

else 부모 영역 외

{

dlg.Create(IDD_TEST_DLG);

dlg.ModifyStyle(WS_CHILD, WS_POPUP|WS_BORDER|WS_CAPTION);

dlg.SetParent(NULL);

}

 

dlg.ShowWindow(SW_SHOW);

}

[출처] 다이얼로그 POPUP / CHILD 속성에 따른 '모달리스' 동작 형태|작성자 콩이아부지

 

 

=================================

=================================

=================================

 

 

반응형


관련글 더보기

댓글 영역