[MFC] 윈도우 프로그래밍 기초 - 팝업메뉴 만들기(리소스의 이해)

 

오늘 실습은 팝업 메뉴 만드는 방법에 대해 실습할 계획입니다.

실습과 더불어 간단하게 리소스의 큰 그림을 이해할 수 있도록 작성하였습니다.

 

 

 

 출력 결과

 


1. 프로젝트 생성하기

 

1. Visual Studio 2013을 켭니다.

2. 새 프로젝트를 만듭니다.

 

 

프로젝트 명은 Lecture로 하겠습니다.

 

3. 다음은 MFC 프로그램에 대한 기본 환경 설정입니다.

아래와 같이 설정하고 마침을 누르겠습니다.

 

 


2. 리소스 뷰에 대한 설명(숲 그리기)

 

2-1. 리소스란?

사전적 의미로 자원이란 의미를 가지고 있습니다.

전쟁으로 비유하면,

 

 

 

리소스는 위의 그림과 같은 관계가 될 수 있습니다.

 

Figure 2-1. <Source And Resource> - Relational Model

 

 

소스코드와 리소스는 각각 컴파일되어서, 소스코드는 *.obj로 변환되고, 리소스 파일은 *.rc로 컴파일이 됩니다.

이들이 Link 단계에서 결합 후에 Execution File로서 결합됩니다.

 

이번 실습에서의 큰 그림은 아래와 같이 소개할 수 있습니다.

 

 

2-2. 리소스 뷰

 

앞서 설명한 이야기를 이해하였으면, 실제 리소스가 MFC에서 어떻게 사용되는지 소개하겠습니다.

프로젝트를 앞서 생성했으면, 왼쪽에 리소스 뷰란 탭을 클릭하면 아래와 같은 창을 살펴볼 수 있습니다.

 

 

 

 

 리소스 뷰

 리소스 파일의 위치 (솔루션 탐색기)

 

리소스 파일 생성에 관해 말씀드리면, MFC 라이브러리를 이용하지 않는 프로그램이면 이용하면 리소스에 대해 관리가 될 수 있다고 보이나 MFC를 이용한 파일이면 굳이 자동으로 생성되는 만큼 별도로 추가 구성을 할 필요가 없습니다.

 

.rc라는 파일은 즉, 다수의 리소스를 모아놓은 하나의 집합이라고 정의할 수 있습니다.

 

2-3. 리소스 식별 접두어 (관례)

* 사용자 정의 리소스 식별 매크로의 접두어

 

설명

접두어

아이콘

IDI_

커서

IDC_

비트맵

IDB_

문자열 항목

IDS_ 또는 IDM_

메뉴

IDR_

메뉴 항목

IDM_

엑셀러레이터

IDR_

엑셀러레이터 키

IDM_

도구 모음

IDR_ 

도구 모음 버튼

IDM_

대화 상자

IDD_

컨트롤

IDC_

 

* MFC 내장 리소스 식별 매크로의 접두어

 

설명

접두어

아이콘 

AFX_IDI_

커서

AFX_IDC_

비트맵

AFX_IDB_

버전

VS_VERSION

문자열 항목

AFX_IDS_ 또는 ID_

메뉴 항목

ID_

엑셀러레이터

AFX_IDR_

엑셀러레이터 키

ID_

도구 모음 버튼

ID_

대화 상자

AFX_IDD_

컨트롤

AFX_IDC_ 또는 ID_

 

2-4. 리소스 뷰 간단하게 살펴보기

 

 


3. 실습(팝업 메뉴 만들기)

 

이번 실습은 "팝업 메뉴 만들기"라는 주제로 실습을 하겠습니다.

 

3-1. 메뉴 만들기

 

 

리소스 추가를 클릭합니다.

 

 

Menu를 선택하고 새로 만들기(N)을 클릭합니다.

 

 

 

3-2. 아래와 같이 메뉴를 꾸며주기.

 

 

 

 

 

 메뉴 구성하기

 리소스뷰 - 방금 만든 메뉴 리소스 ID 변경 -> IDR_POPUP

 

3-3. 클래스 뷰의 CMainFrame 설정하기

WM_CONTEXTMENU라는 영역에 OnContextMenu를 생성하는 방법을 실습해보겠습니다.

 

 

 

 

 

 

<Add> OnContextMenu를 클릭하면

MainFrm.cpp과 MainFrm.h의 파일에 자동 생성되어 구현할 수 있는 상태로 코드가 생성됩니다.

즉, MainFrm.cpp의 함수 원형을 변경할 경우, MainFrm.h 쪽도 저장하셔야합니다.

 

(참고)

 

 

 

 기본 생성된 MainFrm.h의 OnContextMenu 원형 구조

 

 

 

 

 기본 생성된 MainFrm.cpp의 구현 구조

 

3-4. 코딩하기

 

 
void CMainFrame::OnContextMenu(CWnd *pWnd, CPoint point)
{
      CMenu popup;
      CMenu* pMenu;

      popup.LoadMenuW(IDR_POPUP);
      pMenu = popup.GetSubMenu(0);

      pMenu->TrackPopupMenu(TPM_LEFTALIGN || TPM_RIGHTBUTTON, point.x, point.y, this);

}

수정) MainFrm.cpp

 void CMainFrame::OnContextMenu(CWnd *pWnd, CPoint point);

수정) MainFrm.h

 

(참고) 팝업 메뉴 소스코드 분석

 

* < LoadMenu() >의 원형

 

* BOOL CMenu::LoadMenu(LPCTSTR lpszResourceName) 

 

메뉴 리소스를 읽어오는 함수를 의미합니다.

 

* < GetSubMenu() >의 원형

 

* CMenu *CMenu::GetSubMenu(int nPos) const 

 

GetSubMenu() 함수는 메뉴 표시줄에서 하위 메뉴를 구하는 함수입니다.

즉, 구하고자 하는 함수의 하위 메뉴는 0부터 시작함.

 

 

* <TrackPopupMenu() > 의 원형

 

* BOOL CMenu::TrackPopupMenu( UINT nFlags, int x, int y, CWnd *pWnd, LPCRECT lpRect = NULL ) 

 

uFlags에는 여러가지 조합으로 사용가능

인수 uFlags에는 여러 가지 값을 조합하여 설정할 수 있는데, 팝업 메뉴의 정렬과 동작 설정 값을 비트 OR 연산자로 연결해 지정할 수 있음.

 

<팝업 메뉴의 정렬 설정 값>

값 

내용 

TPM_LEFTALIGN

팝업 메뉴를 지정한 위치에서 좌측 정렬 

TPM_RIGHTALIGN

팝업 메뉴를 지정한 위치에서 우측 정렬 

TPM_CENTERALIGN

팝업 메뉴를 지정한 위치에서 가운데 정렬

TPM_TOPALIGN

팝업 메뉴를 지정한 위치에서 위쪽 정렬

TPM_BOTTOMALIGN

팝업 메뉴를 지정한 위치에서 바닥 정렬

TPM_VCENTERALIGN

팝업 메뉴를 지정한 위치에서 수직 중앙 정렬

 

<팝업 메뉴의 동작 설정 값>

 

내용

TPM_LEFTBUTTON

마우스 왼쪽 버튼 클릭시 메뉴 수행

TPM_RIGHTBUTTON

마우스 오른쪽 버튼 클릭시 메뉴 수행

TPM_NONOTIFY

메뉴 항목이 선택되었을 때 통지 메시지를 보내지 않음

TPM_RETURNCMD 

메뉴 항목이 선택되었을 때 선택된 메뉴 항목의 ID를 반환 

 

* int x, int y

-> Point의 좌표 (eg: point.x, point y)

 

* pWnd

pWnd는 팝업 메뉴를 소유하고 있는 윈도우를 지정해주면 됨.

-> pWnd

 

3-5. 컴파일 해보기

마우스 오른쪽 버튼을 클릭해보면, 아래와 같이 정상 동작함을 확인할 수 있습니다.

 

 

+ Recent posts