728x90
300x250

[MFC] 윈도우 프로그래밍 기초 - 대화 상자 만들기

 

이번에는 윈도우 프로그래밍 기초로 "대화 상자 만들기"에 대해서 소개하고자 합니다.

 


1. 프로젝트 만들기

 

 

 

 새 프로젝트 -> 이름 : MFCModal, 확인 클릭

 

 

 대화 상자 기반에 체크한 후 마침을 누릅니다.

 

 

 Welcome to 대화상자 월드

 


2. 소스 코드 살펴보기

 

 

 


2-1. 응용 프로그램 클래스

 

앞전에 http://yyman.tistory.com/494 ([MFC] 윈도우 프로그래밍 기초 - 팝업메뉴 만들기(리소스의 이해))의 글에서는
SDI 기반으로 응용 프로그램을 작성했습니다.

 

SDI는 Single Document Interface의 약자로서 단일 Document를 의미합니다.

하지만, 이번에 살펴볼 대화상자는 SDI기반과는 다른 구조로 되어있음을 소개하고자 합니다.

 

SDI 기반에서는

 

CDocument, CView 

 

로 구성되어 있었습니다.

 

하지만, 대화상자에서는

CDialogi 클래스 대체되고, 공통 클래스는 CWinApp

 

로 구성됩니다.

 

MFCModal.cpp를 열어보면,

// MFCModal.cpp : 응용 프로그램에 대한 클래스 동작을 정의합니다.
//

#include "stdafx.h"
#include "MFCModal.h"
#include "MFCModalDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CMFCModalApp

BEGIN_MESSAGE_MAP(CMFCModalApp, CWinApp)
     ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()


// CMFCModalApp 생성

CMFCModalApp::CMFCModalApp()
{
          // 다시 시작 관리자 지원
         m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;

         // TODO: 여기에 생성 코드를 추가합니다.
         // InitInstance에 모든 중요한 초기화 작업을 배치합니다.
}


// 유일한 CMFCModalApp 개체입니다.

CMFCModalApp theApp;


// CMFCModalApp 초기화

BOOL CMFCModalApp::InitInstance()
{
          // 응용 프로그램 매니페스트가 ComCtl32.dll 버전 6 이상을 사용하여 비주얼 스타일을
          // 사용하도록 지정하는 경우, Windows XP 상에서 반드시 InitCommonControlsEx()가 필요합니다.
          // InitCommonControlsEx()를 사용하지 않으면 창을 만들 수 없습니다.
          INITCOMMONCONTROLSEX InitCtrls;
          InitCtrls.dwSize = sizeof(InitCtrls);
          // 응용 프로그램에서 사용할 모든 공용 컨트롤 클래스를 포함하도록
          // 이 항목을 설정하십시오.
          InitCtrls.dwICC = ICC_WIN95_CLASSES;
          InitCommonControlsEx(&InitCtrls);

          CWinApp::InitInstance();


          AfxEnableControlContainer();

          // 대화 상자에 셸 트리 뷰 또는
          // 셸 목록 뷰 컨트롤이 포함되어 있는 경우 셸 관리자를 만듭니다.
          CShellManager *pShellManager = new CShellManager;

          // MFC 컨트롤의 테마를 사용하기 위해 "Windows 원형" 비주얼 관리자 활성화
          CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));

 

          SetRegistryKey(_T("로컬 응용 프로그램 마법사에서 생성된 응용 프로그램"));

          CMFCModalDlg dlg;
          m_pMainWnd = &dlg;
          INT_PTR nResponse = dlg.DoModal();
      

          if (nResponse == IDOK)
          {
             // TODO: 여기에 [확인]을 클릭하여 대화 상자가 없어질 때 처리할
            //  코드를 배치합니다.
          }
          else if (nResponse == IDCANCEL)
          {
                 // TODO: 여기에 [취소]를 클릭하여 대화 상자가 없어질 때 처리할
                 //  코드를 배치합니다.
          }
          else if (nResponse == -1)
         {
               TRACE(traceAppMsg, 0, "경고: 대화 상자를 만들지 못했으므로 응용 프로그램이 예기치 않게 종료됩니다.\n");
               TRACE(traceAppMsg, 0, "경고: 대화 상자에서 MFC 컨트롤을 사용하는 경우 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS를 수행할 수 없습니다.\n");
         }

           // 위에서 만든 셸 관리자를 삭제합니다.
          if (pShellManager != NULL)
         {
             delete pShellManager;
         }

         // 대화 상자가 닫혔으므로 응용 프로그램의 메시지 펌프를 시작하지 않고  응용 프로그램을 끝낼 수 있도록 FALSE를
         // 반환합니다.
        return FALSE;
}

 

이처럼 코드가 구성되어 있습니다.

 


2-2) 대화 상자 클래스

 

MFCModelDlg.cpp 소개

 


// MFCModalDlg.cpp : 구현 파일
//

#include "stdafx.h"
#include "MFCModal.h"
#include "MFCModalDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 응용 프로그램 정보에 사용되는 CAboutDlg 대화 상자입니다.

class CAboutDlg : public CDialogEx
{
         public:
                  CAboutDlg();

                 // 대화 상자 데이터입니다.
                 enum { IDD = IDD_ABOUTBOX };

         protected:
                 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 지원입니다.

// 구현입니다.
         protected:
                 DECLARE_MESSAGE_MAP()
};

 

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{

 

}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
          CDialogEx::DoDataExchange(pDX);
}

 

 

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CMFCModalDlg 대화 상자

 

CMFCModalDlg::CMFCModalDlg(CWnd* pParent /*=NULL*/)
 : CDialogEx(CMFCModalDlg::IDD, pParent)
{
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

 

void CMFCModalDlg::DoDataExchange(CDataExchange* pDX)
{
           CDialogEx::DoDataExchange(pDX);
}

 

BEGIN_MESSAGE_MAP(CMFCModalDlg, CDialogEx)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
END_MESSAGE_MAP()


// CMFCModalDlg 메시지 처리기

BOOL CMFCModalDlg::OnInitDialog()
{
            CDialogEx::OnInitDialog();

            // 시스템 메뉴에 "정보..." 메뉴 항목을 추가합니다.

            // IDM_ABOUTBOX는 시스템 명령 범위에 있어야 합니다.
            ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
            ASSERT(IDM_ABOUTBOX < 0xF000);

 

            CMenu* pSysMenu = GetSystemMenu(FALSE);

 

            if (pSysMenu != NULL)
            {
                     BOOL bNameValid;
                     CString strAboutMenu;
                     bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
                     ASSERT(bNameValid);
         

                     if (!strAboutMenu.IsEmpty())
                     {
                                 pSysMenu->AppendMenu(MF_SEPARATOR);
                                 pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
                     }
            }

 

            // 이 대화 상자의 아이콘을 설정합니다.  응용 프로그램의 주 창이 대화 상자가 아닐 경우에는
            //  프레임워크가 이 작업을 자동으로 수행합니다.

 

            SetIcon(m_hIcon, TRUE);   // 큰 아이콘을 설정합니다.
            SetIcon(m_hIcon, FALSE);  // 작은 아이콘을 설정합니다.

 

            // TODO: 여기에 추가 초기화 작업을 추가합니다.

            return TRUE;  // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.


}

void CMFCModalDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }
 else
 {
  CDialogEx::OnSysCommand(nID, lParam);
 }
}

// 대화 상자에 최소화 단추를 추가할 경우 아이콘을 그리려면
//  아래 코드가 필요합니다.  문서/뷰 모델을 사용하는 MFC 응용 프로그램의 경우에는
//  프레임워크에서 이 작업을 자동으로 수행합니다.

void CMFCModalDlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.

  SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

  // 클라이언트 사각형에서 아이콘을 가운데에 맞춥니다.
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;

  // 아이콘을 그립니다.
  dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  CDialogEx::OnPaint();
 }
}

// 사용자가 최소화된 창을 끄는 동안에 커서가 표시되도록 시스템에서
//  이 함수를 호출합니다.
HCURSOR CMFCModalDlg::OnQueryDragIcon()
{
 return static_cast<HCURSOR>(m_hIcon);
}

 

 

눈 여겨 봐야할 부분만 블록으로 칠해놨습니다.

DoDataExchange() 함수와 OnInitDialog() 함수는 대화상자에서 중요한 역할을 합니다.

실제로 다음 장 글에서 컨트롤 배치와 실습을 통해 변화를 관찰하면 될 것 같습니다.

반응형

+ Recent posts