티스토리 뷰
1. File 메뉴 안에 팝업 메뉴를 코드로 추가한것
1
2
3
4
5
6
7
8
9
10 |
HMENU hMenu = CretaeMenu();
HMENU hMenuPopup = CreateMenu();
AppendMenu(hMenuPopup, MF_STRING, IDM_NEW, "&New");
AppendMenu(hMenuPopup, MF_STRING, IDM_OPEN, "&Open");
AppendMenu(hMenuPopup, MF_STRING, IDM_SAVE, "&Save");
AppendMenu(hMenuPopup, MF_STRING, IDM_SAVEAS, "Save &As...");
AppendMenu(hMenuPopup, MF_SEPARATOR, 0, "NULL");
AppendMenu(hMenuPopup, MF_STRING, IDM_EXIT, "E&xit");
AppendMenu(hMenu, MF_POPUP, (UINT)hMenuPopup, "&File"); |
cs |
2. 리소스 메뉴
A. 메뉴를 윈도우 클래스에 등록
1 |
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WIN32PROJECT1); |
cs |
B. 이벤트 처리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 |
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int iColorID[5] = { WHITE_BRUSH, LTGRAY_BRUSH, GRAY_BRUSH, DKGRAY_BRUSH, BLACK_BRUSH };
static int iSelection = IDM_WHITE;
HMENU hMenu;
switch (message)
{
case WM_COMMAND:
hMenu = GetMenu(hWnd);
switch (LOWORD(wParam))
{
case IDM_NEW:
case IDM_OPEN:
case IDM_SAVE:
case IDM_SAVEAS:
MessageBox(hWnd, TEXT("메뉴 클릭"), szWindowClass, MB_OK);
break;
case IDM_EXIT:
SendMessage(hWnd, WM_CLOSE, 0, 0L);
break; |
cs |
3. 팝업 메뉴
A. 메뉴 리소스
최상위 메뉴는 단 하나만 가질 수 있다.
1
2
3
4
5
6
7
8 |
IDC_WIN32PROJECT1 MENU
BEGIN
POPUP ""
{
POPUP "파일(&F)"
BEGIN
MENUITEM "새파일", IDM_NEW
|
cs |
B. 이벤트 처리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 |
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HMENU hMenu;
static int iColorID[5] = { WHITE_BRUSH, LTGRAY_BRUSH, GRAY_BRUSH, DKGRAY_BRUSH, BLACK_BRUSH };
static int iSelection = IDM_WHITE;
POINT pt;
switch (message)
{
case WM_CREATE:
hMenu = LoadMenu(hInst, MAKEINTRESOURCEW(IDC_WIN32PROJECT1)); // 리소스에서 메뉴 핸들 얻기
hMenu = GetSubMenu(hMenu, 0); // 팝업 메뉴 핸들 얻기
break;
case WM_RBUTTONDOWN:
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
ClientToScreen(hWnd, &pt);
TrackPopupMenu(hMenu, 0, pt.y, pt.y, 0, hWnd, NULL); // 팝업 메뉴 표시
break;
case WM_COMMAND:
hMenu = GetMenu(hWnd);
switch (LOWORD(wParam))
{
case IDM_START:
if (SetTimer(hWnd, 1, 1000, NULL));
{
EnableMenuItem(hMenu, IDM_START, MF_GRAYED); // 메뉴 비활성화
EnableMenuItem(hMenu, IDM_STOP, MF_ENABLED); // 메뉴 활성화
}
break; |
cs |
4. 기타 함수
DeleteMenu : 메뉴에서 기존 항목을 뗴어내고 완전히 없앤다
InsertMenu : 메뉴에 새 항목을 삽입
AppendMenu : 메뉴 끝에 새 항목을 추가
ModifyMenu : 항목 변경
RemoveMenu : 메뉴에서 기존 항목을 떼어냄
DrawMenuBar(hWnd) : 최상위 메뉴를 변경한 경우 메뉴바를 새로 그려줘야만 적용된다
HMENU hMenuPopup = GetSubMenu(hMenu, n인텍스) : 최상위 메뉴 안에서 인덱스(0부터 시작)로 메뉴 핸들 얻기
int iCount = GetMenuItemCount(hMenu) : 최상위나 팝업 메뉴 항목 수 얻기
int id = GetMenuItemID(hMenuPopup, n인덱스) : 팝업 메뉴의 인덱스에 해당되는 메뉴 항목의 ID 얻기
CheckMenuItem(hMenu, id, iCheck) : 메뉴 항목에 체크표시 유무
CheckMenuItem(hMenu, n인덱스, MF_CHECKED | MF_BYPOSITION) : 인덱스로 체크 표시 확인
EnableMenuItem() 은 MF_ENABLED, MD_DISABLED, MF_GRAYED 로 사용
n문자수 = GetmenuString(hMenu, id, p문자열, n최대문자수, iFlag)
iFlag 값 : MF_BYCOMMAND (ID가 메뉴 ID), MF_BYPOSITION (ID가 인덱스 번호)
iFlag = GetMenuState(hMenu, id, iFlag) : 메뉴 항목의 현재 플래그 얻기, 인수는 MF_BYCOMMAND, MF_BYPOSITION 만 올수 있고 리턴값은 모든 플래그의 조합이다. MF_DISABLED, MF_GAYED, MF_CHECKED, MF_MENUBREAK, MF_SEPARATOR
DestoryMenu(hMenu) : 메뉴 삭제
5. 시스템 메뉴
A. 메뉴 추가 (IDM_ABOUT 값은 0xF000 (61,440) 보다 크면 안된다. 크면 다른 시스템 메뉴와 충돌남
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 |
hInst = hInstance; // 인스턴스 핸들을 전역 변수에 저장합니다.
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
HMENU hMenu = GetSystemMenu(hWnd, FALSE); // 윈도우 클래스 만들때 시스템 메뉴에 메뉴 추가
AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
AppendMenu(hMenu, MF_STRING, IDM_ABOUT, TEXT("About..."));
AppendMenu(hMenu, MF_STRING, IDM_HELP, TEXT("Help..."));
AppendMenu(hMenu, MF_STRING, IDM_REMOVE, TEXT("삭제"));
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd); |
cs |
B. 시스템 메뉴 이벤트 처리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 |
switch (message)
{
case WM_SYSCOMMAND:
switch (LOWORD(wParam))
{
case IDM_ABOUT:
MessageBox(hWnd, TEXT("시스템메뉴/About"), szWindowClass, MB_OK);
break;
case IDM_HELP:
MessageBox(hWnd, TEXT("시스템메뉴/Help"), szWindowClass, MB_OK);
break;
case IDM_REMOVE:
GetSystemMenu(hWnd, TRUE);
break;
default: // 삽입하지 않으면 다른 메뉴 동작 안됨
return DefWindowProc(hWnd, message, wParam, lParam);
}
break; |
cs |
6. 조건에 따라 메뉴 항목 속정 변경
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 |
case WM_INITMENUPOPUP:
if (lParam == 1) // 최상위 메뉴 인덱스, File : 0, Edit:1, Help:2 (Edit 메뉴에서만 실행)
{ // Undo 실행할 수 있는 조건인지, 클립보드에 텍스트가 있는 경우 조건에 따라 메뉴 항목 설정
EnableMenuItem((HMENU)wParam, ID_EDIT_UNDO, SendMessage(hWndEdit, EM_CANUNDO, 0, 0) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem((HMENU)wParam, ID_EDIT_PASTE, IsClipboardFormatAvailable(CF_TEXT) ? MF_ENABLED : MF_GRAYED);
iSelect = SendMessage(hWndEdit, EM_GETSEL, 0, 0);
if (HIWORD(iSelect) == LOWORD(iSelect))
iEnable = MF_GRAYED;
else
iEnable = MF_ENABLED;
EnableMenuItem((HMENU)wParam, ID_EDIT_CUT, iEnable);
EnableMenuItem((HMENU)wParam, ID_EDIT_COPY, iEnable);
EnableMenuItem((HMENU)wParam, ID_EDIT_DELETE, iEnable);
return 0;
}
break; |
cs |