본문 바로가기
Visual C++(MFC)

MFC06. 대화상자

by 정양섭 2022. 3. 7.

   대화 상자 사용은 내용이 방대하여 여기에서 모든 내용을 설명할 수 없고 많이 쓰는 기능을 위주로 설명합니다. 대화 상자 사용은 Resource 사용에서 잠깐 언급했듯이 Resource 의 Dialog를 이용하여 대화 상자 모양을 설정합니다.

위 그림과 같이 Dialog 트리에서 마우스 오른쪽 버튼을 선택하여 생성된 팝업 메뉴에서 Insert Dialog를 실행하면 IDD_DIALOG1이라는 대화 상자(기본적으로 OK버튼과 Cancel버튼이 들어 있는 대화상자)가 생성됩니다.

Properties의 ID를 IDD_TEST_DIALOG라고 설정합니다.
좌측의 Toolbox를 선택하면 다음과 같이 화면에 나타납니다.

여러 가지 Control들이 지원되며 원하는 Control을 마우스 왼쪽 버튼을 이용하여 선택한 후 대화 상자의 필요한 위치에 마우스로 영역을 지정하면 그 선택된 Control이 삽입됩니다.
많이 사용하는 Control들을 간단히 설명하면 다음과 같습니다.
Static Text : 정적인 문자열을 삽입할 때 사용합니다.
Edit Box : Edit Box를 삽입합니다.
Group Box : Group Box를 삽입합니다. Visual Basic과는 달리 기능은 거의 없고 Group 모양만 표시합니다.
Button : Button을 삽입합니다.
Check Box : Check Box를 삽입합니다.
Radio Button : Radio Button을 삽입합니다.
Combo Box : Combo Box를 삽입합니다.
List Box : List Box를 삽입합니다.
Spin Control : Spin Control을 삽입합니다.
List Control : List Control을 삽입합니다.
위의 Control들 외에는 자주 사용하지 않고, 위의 사용법만 익히면 대부분 그냥 사용할 수 있을 것입니다. 다음 그림은 각 Control들을 삽입한 모양입니다.

  각 Control에서 마우스 왼쪽 버튼을 선택하여 Properties를 보면 다음과 같이 Property를 편집할 수 있도록 제공합니다.

위의 Properties의 내용은 Control 마다 그 모양이 조금씩 다릅니다. 모든 Control은 ID로 구분을 하므로 ID는 존재합니다. 각 ID에 ID만 보아도 Control의 기능을 알 수 있도록 이름을 설정합니다(여기서는 편의상 기본값을 사용합니다). Caption영역은 외부에 Text가 표시되는 Control의 경우 존재합니다. 그외 설정은 대부분 손댈 필요는 없고 각 Control 세부 설명에서 설정할 필요가 있는 부분은 다시 설명합니다.
화면 설계를 한 대화 상자를 더블클릭하면 다음과 같은 대화 상자가 생성됩니다.

Class name에 TestDialog를 입력하고 Base class에 CDialog를 선택한 후에 Finish를 선택하면 Class name에 입력한 Class 이름에 의해 파일이 생성되고(여기서는 TestDialog.cpp와 TestDialog.h 파일이 생성된다), 프로젝트에 추가가됩니다.

Edit Box, Check Box
Edit Box와 Check Box는 간단한 I/F로 그 설정 값을 변수와 연결할 수 있습니다.

변수와 연결하고자 하는 Edit box에서 마우스 오른쪽 버튼을 클릭하여 나타난 팝업메뉴에서 Add Variable을 선택하면 다음과 같이 대화 상자가 나타납니다.

Category를 Value로 선택하고 Variable type을 원하는 Type으로 설정한 후 Variable name을 입력하면 Edit box와 연결이 됩니다.
Check Box 또한 같은 방식으로 설정하고 Variable type는 BOOL 형태만 있습니다.

 

Spin
Spin의 경우 대부분 Edit Box의 Variable type를 int로 설정하여 삽입한 후 Edit Box옆에 붙여서 사용합니다. Spin은 위쪽 화살표와 아래쪽 화살표가 같이 있는데, 대부분 위쪽화살표를 누르면 Edit Box의 값이 1 증가하고 아래쪽 화살표를 누르면 EditBox의 값이 1 감소하도록 구성합니다. 즉 Edit Box와 연계되어 동작을 수행합니다.
따라서 연계하고자 하는 Edit Box 다음에 바로 Spin Control을 삽입해야 하고(탭 순서가 Edit Box 다음 바로 Spin Control), Spin Control의 Properties에서 설정을 몇 가지 해주어야 합니다.

Auto buddy : Check 해준다.
Set buddy integer : Check 해준다.
No thousands : Check 해준다.
Wrap : Check 해준다.
Alignment : Right로 선택합니다.

참고 : 탭 순서 바꾸기
탭 순서는 대화 상자의 기능이 아무리 좋아도 탭 순서(탭키를 눌렀을 때 옮겨 다니는 순서)가 잘 되어 있지 않으면 싸구려 프로그램 같고 또한 불편합니다. 탭 순서는 Control의 삽입 순서 대로되고 그 순서를 바꾸고자 한다면 대화 상자 디자인 창을 띄웠을 때 추가되는 메뉴인 Layout의 부메뉴 Tab Order(Ctrl+D)를 선택하면 대화 상자는 다음과 같이 탭 순서가 표시됩니다.

마우스로 Control을 선택하면 탭 순서가 바뀝니다(처음 선택한 Control은 1번, 두 번째 선택한 Control은 2번,.....). 참고로 Ctrl키를 누른 상황에서 마우스로 Control을 선택하면 그 번호는 바뀌지 않고 다음 선택하는 Control은 그 선택 Control을 기준으로 번호가 증가합니다. 탭 순서 바꾸기 기능으로 Edit Box와 Spin Control을 연계합니다.
Spin Control에서 위의 설정을 모두 해 주면 1가지 기능을 제외하면 모든 기능을 수행합니다. 그 1가지 기능은 위쪽 화살표 키를 눌렀을 때 값이 감소하고 아래쪽 화살표 기를 눌렀을 때 값이 증가하며(원 기능과 반대)Range가 무조건 0~100까지로 됩니다.
이것을 해결하기 위하여 Spin Control에서 마우스 오른쪽 버튼을 클릭하여 나타난 팝업메뉴에서 Add Variable을 선택하면 다음과 같이 대화 상자가 나타납니다.

Category를 Control로 선택하고 Variable type을 CSpinButtonCtrl로 설정한 후 Variable name을 m_SpinControl로 입력하면 Spin Control과 연결이 됩니다.
그 후 다음과 같이 Class View 탭을 선택한 후 WM_INITDIALOG 메시지와 연결되는 OnInitDialog함수를 생성합니다.

OnInitDialog 함수에서 다음과 같이 Range를 설정하면 그 문제는 해결이 됩니다.
        m_SpinControl.SetRange(1, 20);   //Range가 1~20일때
주의 : 위의 경우와 같이 생성된 Control에 변화를 줄 경우 Control이 생성된 후 설정을 해야만 합니다. 모든 Control이 생성된 후 호출되는 함수가 OnInitDialog입니다.

Button
Button은 삽입한 버튼을 마우스로 선택할 경우 실행되는 함수를 만들면 됩니다.


Radio Button
Radio Button은 여러개의 Radio Button 중 하나를 선택하도록 구성할 때 사용합니다. 따라서 여러개의 Radio Button을 하나의 변수와 연결해야만 합니다. Radio Button들을 하나의 변수로 연결하기 위해서는 그 Button들의 탭 순서가 순서 대로 설정되어야 하고, 가장 첫 Radio Button의 Properties에서 Group을 체크해야만 합니다.

Group을 체크한 후 마우스 우측 버튼을 선택하여 생성된 팝업메뉴에서 Add Variable을 선택하여 변수와 연결을 하면, 연결한 변수에 Radio Button을 선택한 값이( 순서대로 0, 1, ...) 입력됩니다.

Combo Box
  Combo Box는 주로 Radio Button의 기능과 비슷하게 여러 개의 선택항목중 하나를 선택할 때 사용합니다. Radio Button의 경우 항목이 작을 때 사용하고, Combo Box의 경우 항목이 많고 작은 공간에 그 기능을 구현하고자 할 때 사용합니다.
Combo Box의 Properties를 선택하면 다음과 같이 Data라는 항목이 하나 더 추가된 것을 알 수 있습니다.

여기에 선택할 데이터를 설정합니다. 데이터간 구분은 ;으로 해서 입력하면 됩니다(여기서는 COMBO1~COMBO5까지 입력했습니다, COMBO1;COMBO2;COMBO3;COMBO4;COMBO5;).
Type을 Dropdown에서 Droplist로 변경하였습니다. Dropdown은 선택도 가능하지만 Text를 입력할 수 도 있는 형태이며, Droplist는 선택만 가능한 형태입니다. 용도에 따라 선택하면 됩니다.

List Box
  List Box는 Combo Box와 기능상 거의 비슷합니다. 그러나 Combo Box는 선택항목의 갯수 및 문자열이 고정되어 있을 때 주로 사용하고, List Box는 그 선택항목이 가변일 때 주로 사용합니다. 따라서 List Box의 Properties에는 Data 탭이 존재하지 않고 Source에서 데이터 항목(선택 항목)들을 추가해야만 합니다. 참고로 Combo Box또한 Source에서 데이터 항목을 추가해서 사용할 수 있는데, 여기에서는 이 방법을 설명하지 않는다. 그러나 List Box와 거의 비슷하므로 도움말 만 조금 보면 구현하는 데 문제가 없을 것입니다.
ListBox에서 마우스 오른쪽 버튼을 선택하여 생성된 팝업메뉴에서 Add Variable을 선택하면 다음과 같은 대화 상자가 생성됩니다.

Category를 Control로 선택하고 Variable name에 m_List라고 입력합니다.
OnInitDialog함수에 다음과 같이 추가하면 ListBox1~ListBox5의 5개 항목이 추가됩니다.
        const TCHAR *szListForm[] = {"ListBox1", "ListBox2", "ListBox3", "ListBox4", "ListBox5"};
        for(int i = 0; i < 5; i++)
                m_List.AddString(szListForm[i]);

List Control
  List Control은 탐색기에서 파일을 표시하는 형태를 말합니다. 보기 설정에 따라 큰 아이콘, 작은 아이콘, 자세히 등 다르게 표시할 수 있습니다. 그러나 대부분 대화 상자에서 사용하는 List Control은 탐색기에서 보기 설정을 자세히로 했을 경우 나타나는 모양을 주로 사용하므로 여기서는 그 모양만을 다룬다. List Control은 사용법도 다소 복잡할 뿐만 아니라 선택은 첫 번째 칼럼으로만 가능하므로 구현을 하여도 다소 불편합니다. 따라서 필자는 구현 방법도 간단하게 만들고, 모든 칼럼에서 다 선택이 가능하도록 하는 Class를 제작하여 제공합니다.
주로 사용하는 함수는 다음과 같습니다.
        //Column Title 설정
        void SetFieldTitle(TCHAR** pTitle, int* width, int nCount);
        //Column Style이 Text일 경우 Align 설정
        void SetColumnTextAlign(int nCol, int fmt);
        //Item을 삽입합니다.  삽입시에도 첫번째 Column만 이함수 사용
        int InsertItemString(int nItemId, int nSubItemId, LPCTSTR str);
        //Item을 설정합니다.
        void SetItemString(int nItemId, int nSubItemId, LPCTSTR str);
제공되는 Class의 이름은 ListCtrlEx.cpp 및 ListCtrlEx.h로 이 Class를 사용하기 위해서는 다음과 같이 몇가지 설정을 해주어야 합니다.

ListCtrl을 선택하고 나타난 Properties 화면에서 View를 Report로 설정하고, Owner draw fixed를 True로 설정합니다.
다음은 Add Variable을 실행하여 List Control의 ID와 변수 연결시 Category를 Control로 선택하고 연결 변수를 m_ListCtrl이라고 입력합니다.
대화 상자의 .h 파일을 열어 보면 CListCtrl m_ListCtrl;이 추가된 것을 볼 수 있을 것입니다. 여기에서 ListCtrlEx.h를 include 해 주고 CListCtrl m_ListCtrl; 대신 CListCtrlEx m_ListCtrl;를 입력합니다.
그후 OnInitDialog 함수에 다음과 같이 추가하면 (ListCtrl1-1 ListCtrl1-2 ListCtrl1-3) ~ (ListCtrl5-1 ListCtrl5-2 ListCtrl5-3)의 Column 3개 Row 5개인 ListCtrl 항목이 추가됩니다.

        //Column Title 설정
        const TCHAR *szListCtrlTitle[] = {"Column 1", "Column 2","Column 3"};
        int nWidthForm[] = {100, 100, 100};
        m_ListCtrl.SetFieldTitle((char**)szListCtrlTitle, nWidthForm, 3);

        //각 항목에 데이타 설정
        CString strBuffer;
        for(i = 0; i < 5; i++){
                for(j = 0; j < 3; j++){
                        strBuffer.Format("ListCtrl%d-%d", i+1, j+1);
                        if(j==0)        //Column의 처음일 경우
                                m_ListCtrl.InsertItemString(i, j, strBuffer);
                        else
                                m_ListCtrl.SetItemString(i, j, strBuffer);
                }
        }

대화 상자 호출
 마지막으로 대화 상자를 화면상에 나타내기 위해서 다음과 같이 호출하면 됩니다.

CTestDialog dlg;
//대화상자 변수 초기화 루틴
if(!dlg.DoModal()!=IDOK)
    return ;
//대화상자 설정값 읽어 오는 루틴


CListCtrlEx Class 파일 다운로드

ListCtrlEx.zip
0.00MB


예제 프로그램 다운로드

ResourceDemo.zip
0.04MB


 

'Visual C++(MFC)' 카테고리의 다른 글

MFC08. View에서 깜박임 문제 해결  (0) 2022.03.07
MFC07. Doc-View 구조  (0) 2022.03.07
MFC05. RESOURCE  (0) 2022.03.07
MFC04. GUI(Graphic User Interface)  (0) 2022.03.07
MFC03. ClassView 사용법  (0) 2022.03.07