리소스의 Menu란에 IDR_CONTEXTMENU를 추가한다.
빨강 : IDM_COLOR_RED
파랑 : IDM_COLOR_BLUE
녹색 : IDM_COLOR_GREEN
메인.cpp 소스코드
// test_ex.cpp : 응용 프로그램에 대한 진입점을 정의합니다.
//
#include "stdafx.h"
#include "test_ex.h"
#include <windows.h>
#include <commctrl.h>
#define MAX_LOADSTRING 100
// 전역 변수:
HINSTANCE g_hInst; // 현재 인스턴스입니다.
HWND g_hWndMenuBar; // 메뉴 모음 핸들입니다.
/// 추가내용 ////////////////////////////////////
HMENU g_hContextMenu;
/////////////////////////////////////////////////
// 이 코드 모듈에 들어 있는 함수의 정방향 선언입니다.
ATOM MyRegisterClass(HINSTANCE, LPTSTR);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
// 응용 프로그램 초기화를 수행합니다.
if (!InitInstance(hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable;
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TEST_EX));
// 기본 메시지 루프입니다.
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// 함수: MyRegisterClass()
//
// 목적: 창 클래스를 등록합니다.
//
// 설명:
//
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TEST_EX));
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = szWindowClass;
return RegisterClass(&wc);
}
//
// 함수: InitInstance(HINSTANCE, int)
//
// 목적: 인스턴스 핸들을 저장하고 주 창을 만듭니다.
//
// 설명:
//
// 이 함수를 통해 인스턴스 핸들을 전역 변수에 저장하고
// 주 프로그램 창을 만든 다음 표시합니다.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
TCHAR szTitle[MAX_LOADSTRING]; // 제목 표시줄 텍스트
TCHAR szWindowClass[MAX_LOADSTRING]; // 주 창 클래스 이름
g_hInst = hInstance; // 인스턴스 핸들을 전역 변수에 저장합니다.
// CAPEDIT 및 SIPPREF와 같은 모든 장치 특수 컨트롤을 초기화하기 위해
// 응용 프로그램을 초기화하는 동안 SHInitExtraControls를 한 번 호출해야 합니다.
SHInitExtraControls();
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_TEST_EX, szWindowClass, MAX_LOADSTRING);
/// 추가내용 ////////////////////////////////////
g_hContextMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CONTEXTMENU));
// g_hContextMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_MENU));
/////////////////////////////////////////////////
//이미 실행 중인 경우 창에 포커스를 둔 다음 끝냅니다.
hWnd = FindWindow(szWindowClass, szTitle);
if (hWnd)
{
// 맨 앞 자식 창에 포커스를 설정합니다.
// "| 0x00000001"을 사용하여 소유한 모든 창을 전경으로 보낸 다음
// 활성화합니다.
SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001));
return 0;
}
if (!MyRegisterClass(hInstance, szWindowClass))
{
return FALSE;
}
hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
// CW_USEDEFAULT를 사용하여 주 창을 만드는 경우 메뉴 모음의 높이는
// 고려되지 않습니다. 따라서 메뉴 모음이 있는 경우
// 창을 만든 후 창의 크기를 조정합니다.
if (g_hWndMenuBar)
{
RECT rc;
RECT rcMenuBar;
GetWindowRect(hWnd, &rc);
GetWindowRect(g_hWndMenuBar, &rcMenuBar);
rc.bottom -= (rcMenuBar.bottom - rcMenuBar.top);
MoveWindow(hWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, FALSE);
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// 함수: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 목적: 주 창의 메시지를 처리합니다.
//
// WM_COMMAND - 응용 프로그램 메뉴를 처리합니다.
// WM_PAINT - 주 창을 그립니다.
// WM_DESTROY - 종료 메시지를 게시하고 반환합니다.
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
/// 추가내용 ////////////////////////////////////
HBRUSH hbrush;
RECT rect;
static COLORREF s_color = RGB(255,255,255);
/////////////////////////////////////////////////
static SHACTIVATEINFO s_sai;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 메뉴의 선택 영역을 구문 분석합니다.
switch (wmId)
{
case IDM_HELP_ABOUT:
DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, About);
break;
/// 추가내용 ////////////////////////////////////
case IDM_COLOR_RED:
s_color = RGB(255, 0, 0);
InvalidateRect(hWnd, NULL, TRUE);
break;
case IDM_COLOR_BLUE:
s_color = RGB(0, 0, 255);
InvalidateRect(hWnd, NULL, TRUE);
break;
case IDM_COLOR_GREEN:
s_color = RGB(0, 255, 0);
InvalidateRect(hWnd, NULL, TRUE);
break;
/////////////////////////////////////////////////
case IDM_OK:
SendMessage (hWnd, WM_CLOSE, 0, 0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_CREATE:
SHMENUBARINFO mbi;
memset(&mbi, 0, sizeof(SHMENUBARINFO));
mbi.cbSize = sizeof(SHMENUBARINFO);
mbi.hwndParent = hWnd;
mbi.nToolBarId = IDR_MENU;
mbi.hInstRes = g_hInst;
if (!SHCreateMenuBar(&mbi))
{
g_hWndMenuBar = NULL;
}
else
{
g_hWndMenuBar = mbi.hwndMB;
}
// 셸 활성화 정보 구조 초기화
memset(&s_sai, 0, sizeof (s_sai));
s_sai.cbSize = sizeof (s_sai);
/// 추가내용 ///////////////////////////////////////////////
TBBUTTONINFO tbbi;
memset(&tbbi, 0, sizeof(tbbi));
tbbi.cbSize = sizeof(tbbi);
tbbi.dwMask = TBIF_TEXT;
tbbi.pszText = L"색깔";
SendMessage(SHFindMenuBar(hWnd), TB_SETBUTTONINFO, IDM_HELP, (LPARAM)&tbbi);
DrawMenuBar(g_hWndMenuBar);
////////////////////////////////////////////////////////////
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 여기에 그리기 코드를 추가합니다.
/// 추가내용 /////////////////////////////////////////////
GetClientRect(hWnd, &rect);
hbrush = CreateSolidBrush(s_color);
FillRect( hdc, &rect, hbrush);
DeleteObject(hbrush);
//////////////////////////////////////////////////////////
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
CommandBar_Destroy(g_hWndMenuBar);
PostQuitMessage(0);
break;
/// 추가내용 ////////////////////////////////////
case WM_LBUTTONDOWN:
{
SHRGINFO shrg;
HMENU hmenu;
shrg.cbSize = sizeof(shrg);
shrg.hwndClient = hWnd;
shrg.ptDown.x = LOWORD(lParam);
shrg.ptDown.y = HIWORD(lParam);
shrg.dwFlags = SHRG_RETURNCMD;
if (SHRecognizeGesture(&shrg) == GN_CONTEXTMENU) {
hmenu = GetSubMenu(g_hContextMenu, 1); //0과 1값들을 통해 메뉴 열을 선택해 가져옴
TrackPopupMenuEx(hmenu, TPM_LEFTALIGN, LOWORD(lParam), HIWORD(lParam), hWnd, NULL);
}
break;
}
/////////////////////////////////////////////////
case WM_ACTIVATE:
// 활성화 메시지를 셸에 알립니다.
SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE);
break;
case WM_SETTINGCHANGE:
SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// 정보 대화 상자의 메시지 처리기입니다.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
// [완료] 단추를 만들고 크기를 조정합니다.
SHINITDLGINFO shidi;
shidi.dwMask = SHIDIM_FLAGS;
shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN | SHIDIF_EMPTYMENU;
shidi.hDlg = hDlg;
SHInitDialog(&shidi);
}
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
case WM_CLOSE:
EndDialog(hDlg, message);
return TRUE;
}
return (INT_PTR)FALSE;
}
'Embedded > Windows CE' 카테고리의 다른 글
WinCE RAPI사용시 외부 SDK 헤더추가하는 법 (0) | 2007.09.21 |
---|---|
WinCE 라이브러리 추가 예제 (0) | 2007.09.20 |
WinCE 메뉴와 리소스 편집기 만들기 예제 (0) | 2007.09.20 |
PXA255에 Windows CE 4.2 수행과정 (0) | 2007.09.05 |