Programming Language/Windows API

메뉴 및 공용대화상자

D4tai1 2018. 10. 9.

1. 메뉴만들기

1) 리소스 파일

[1] 리소스파일 생성

- [리소스파일(우클릭) - 추가 - 리소스] 를 클릭한다.

 

[2] 메뉴리소스 추가

- Menu 리소스를 클릭하고 새로만들기를 누른다.

 

[3] 현재 프로젝트의 리소스 뷰에 접근

- 리소스를 만들면 .rc확장자를 가지는 리소스 파일이 생성되고 헤더파일에 Resource.h 파일이 만들어진다.

- [프로젝트명.rc] 파일을 더블클릭하면 현재 프로젝트의 리소스 뷰에 접근하게 된다.

 

[4] 메뉴리소스 확인

- 여러가지 리소스중에 우리가 만든 메뉴리소스를 더블클릭한다.

 

[5] 메뉴에 원하는 문자를 넣어 메뉴를 구성할 수 있다.

- [여기에 입력] 부분을 클릭하여 작성 후 Enter키를 누르면 저장된다.

 

[6] Popup - True

- FILE이라고 적은 것의 속성을 확인한다.

 

- 속성의 모양에 Popup을 보면 True로 체크되어 있다.

- 이 말은 이 캡션은 기능을 수행하는 것이 아닌 다른 캡션을 띄우는 역활을 한다는 말이다..

 

[7] Popup - False

- EXIT라고 적은 것의 속성을 확인한다.

 

- 속성의 모양에 Popup을 보면 False로 체크되어 있다.

- 이 말은 이 캡션은 누르면 특정 기능을 수행하는 역활을 한다는 말이다.

[8] ID속성

 - [7]번 그림에서 보면 [속성 - 기타 - ID] 에 보통 숫자가 적혀있다.

 - 이 숫자(정수)가 어떤 메뉴항목이 선택되었는지를 구분지어주며 윈도우메세지처리함수로 전달된다.

 - Popup이 True면 기능을 수행하는 것이 아니기 때문에 편집이 불가능하다.

 

 ※ [7]번 그림의 ID를 보면 ID_EXIT라고 적혀있다.

  - .rc 파일을 닫고 [헤더파일 - Resourec.h]을 열어서 내용을 확인한다.

 

  - 위 그림과 같이 Resource.h 파일에 ID에 적은 메세지가 정수로 들어가있다.

  - 이렇게 하는 이유는 컴퓨터는 숫자를 보고 해당하는 처리를 하겠지만

  사람은 숫자만 보고는 무슨동작을 하는지 가늠할 수 가 없다.

  - 그래서 숫자에 해당하는 기능에 맞게 ID를 부여한 것이다.

 

[9] Prompt

 - ID를 가진 메뉴의 도움말을 작성한다.

 

[10] Enable

 - 프로그램 실행 시 이 메뉴를 사용할 수 있는지 True나 False로 나타낸다.

 

[11] Separator

 - 메뉴구분선을 넣을지 True나 False로 나타낸다.

 - 기능수행과 무관하다.

 

2) 소스파일

 [1] resource.h 파일추가

  

  - [프로젝트명.h] 파일에 resoure.h파일을 추가한다.

 

 [2] 메뉴설정 필드에 메뉴리소스 추가

  - lpszMenuName 필드에 [메뉴리소스이름]을 넣어준다.

  - 메뉴리소스이름은 [1) - [4]]그림에서 확인할 수 있다.

 

 [3] 메세지처리함수의 소스

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	OPENFILENAME OFN;
	//OPENFILENAME 구조체는 commdlg.h에 정의되어 있다.
	//파일을 여는 대화상자의 구조체 변수 OPN을 생성한다.

	TCHAR str[100] = _T("");
	TCHAR lpstrFile[100] = _T("");
	//파일을 열기위해 선택하면 메세지박스를 띄울 예정이고,
	//이 파일이 맞는지 확인하는 문자열을 저장하기위한 임시변수이다.

	TCHAR filter[] = _T("Every File \0 *.*\0Text File \0 *.txt; *.doc\0");
	//OFN.lpstrFilter 필드에 열기대화상자에 나오는 필터를 지정한다,
	//모든파일은 *.* 형식
	//텍스트파일은 *.txt와 *.doc 형식
	//을 선택할 수 있다.
	//\0(NULL)을 넣어서 끊을 수 있고, ;(세미콜론)을 넣어서 추가할 수 있다.

	int wmId = LOWORD(wParam);
	//wParam의 하위 2바이트에는 발생된 이벤트의 메세지(ID)가 저장되어 있다.
	//LOWORD() 함수는 하위 2바이트를 추출하는 함수이다.
	//wmId는 윈도우메세지 ID값을 저장하는 변수이다.

	int answer;
	//메세지박스에서 누른 버튼의 ID값을 저장하는 정수변수이다.
	
	switch (message)
	{
	case WM_COMMAND:
		switch (wmId)
		{
		case ID_FILENEW:	//NEW를 눌렀다면? 
			MessageBox(hWnd, _T("새 파일을 여시겠습니까?"), _T("새 파일 선택"), MB_OKCANCEL);
			//OK와 CANCEL 만 선택이 가능한 메세지박스 호출
			break;

		case ID_FILEOPEN:	//OPEN을 눌렀다면?
			memset(&OFN, 0, sizeof(OPENFILENAME));
			//memset함수를 이용하여 구조체의 모든 공간을 0으로 채운다.

			OFN.lStructSize = sizeof(OPENFILENAME);
			//lStructSize 필드는 구조체의 크기를 넣는다.

			OFN.hwndOwner = hWnd;
			//hwndOwner 필드는 윈도우의 핸들값을 넣는다.

			OFN.lpstrFilter = filter;
			//lpstrFilter 필드는 위에서 정의한 필터 변수의 주소를 넣는다.

			OFN.lpstrFile = lpstrFile;
			//lpstrFile 필드는 위에서 정의한 파일이름 변수의 주소를 넣는다.

			OFN.nMaxFile = 100;
			//nMaxFile 필드는 파일이름의 최대길이 100으로 지정한다.

			OFN.lpstrInitialDir = _T(".");
			//대화상자에 가장 먼저 보여줄 폴더는 현재디렉토리로 지정한다.

			if (GetOpenFileName(&OFN) != 0) {
				//GetOpenFileName함수는 OFN구조체의 주소를 파라미터로 넣어서
				//정상적인 파일을 잘 선택했다면 1을 반환하여 아래 메세지를 출력한다.
				_stprintf_s(str, _T("%s 파일을 여시겠습니까?"), OFN.lpstrFile);
				MessageBox(hWnd, str, _T("열기 선택"), MB_OK);
			}
			break;

		case ID_EXIT:	//EXIT를 눌렀다면?
			answer = MessageBox(hWnd, _T("파일을 저장하고 끝내겠습니까?"), _T("끝내기 선택"), MB_YESNOCANCEL);
			if (answer == IDYES || answer == IDNO) {	//yes나 no가 눌렸다면 종료, cancle이 눌렸다면 아무 것도 안하기
				PostQuitMessage(0);
			}
			break;
		}
		
	case WM_PAINT:
	{
		PAINTSTRUCT ps;
		HDC hdc = BeginPaint(hWnd, &ps);
		// TODO: 여기에 hdc를 사용하는 그리기 코드를 추가합니다...
		EndPaint(hWnd, &ps);
	}
	break;

	case WM_DESTROY:
		PostQuitMessage(0);
		break;

	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

 

- 만약 OPENFILENAME 구조체에서 에러가 발생한다면 #include <commdlg.h>를 맨 위에 추가해주면 사용할 수 있다.

- 새로운 라인은 모두 주석처리해서 확인할 수 있다.

 

3) 시연

- NEW를 클릭한다.

 

- 메세지박스가 나오는 것을 확인할 수 있다.(새로 만들기의 메세지박스 내용이 이상하긴 하지만..)

- 아직은 파일 여는 동작에 대해 서술하지 않았기 때문에 파일이 열리지는 않는다.

 

- OPEN을 누르면 공용대화상자가 나오고 파일 형식은 지정한 파일 형식만 열 수 있다.

- 대화상자 오픈하는 것까지만 했고 파일입출력에 대해서는 추후에 서술할 예정이다.

 

- 예나 아니오를 누르면 종료되고 취소를 누르면 종료되지 않는다.

 


'Programming Language > Windows API' 카테고리의 다른 글

대화상자 생성  (0) 2018.12.09
리소스파일  (0) 2018.12.09
지렁이게임  (0) 2018.09.30
두더지잡기 게임  (0) 2018.09.30
입력된 방향키 확인  (0) 2018.09.30

댓글