『Lena's by ☆볶기!!』: Restart !!

Rorolena
[API] 리소스 활용
이번 포스팅에선 API의 리소스를 작성하는 방법에 관하여 포스팅 해보겠습니다.

이번 포스팅에서 소개해드릴
리소스 활용방법은 6가지 입니다.

1. 엑셀레이터
2. 커서
3. 대화상자
4. 아이콘
5. 메뉴
6. 문자열 테이블

이번 포스팅은 좀길어 지겠지만
굉장히 간단함으로 가벼이 한번 주욱
읽어보시면 쉽게 이해가 가시리라 생각합니다.

엑셀레이터)_
엑셀레이터는 단축키를 쉽게 관리하기 위한 자원입니다.
[리소스 추가방법]
엑셀레이터를 추가하는 방법을 포스팅 하겠습니다.
만... 그전에 리소스를 추가하는 방법에 관하여
먼저 소개를 해야겠죠?

먼저 해당 프로젝트에서 오른쪽 마우스를 클릭하시면
추가 -> 리소스가 있습니다.


그럼 아래와 같은 리소스를 추가하기 위한
준비된 선택 창이 하나추가됩니다.


저도 이대사가 해보고 싶었습니다.
참쉽죠? ㅋㅋ

우리는 여기서 엑셀레이터를
추가 할 것이기 때문에 엑셀레이터를 선택해줍니다.

[엑셀레이터 추가하기]
위에서 엑셀레이터를 추가하시면
아래와 같이 뜨는데요

보이는 바와같이 작성 해주시면됩니다.

추가적 설명을 드리자면
보조키와 키를 설정해서
조합키를 만드실수 있습니다.

여기까지 리소스 추가 방법이고요
아래부턴 소스부분에서 추가해줘야 할 부분입니다.

5가지 부분을 작성 해주셔야 하는대요
먼저 작성해주신 리소스를
사용하기위한 해더 추가
입니다.

아마 리소스를 추가하시고 나시면
resource.h라는 해더가 생기실탠대
이를 소스의 상단에 다음과같이 작성해주시면 됩니다.
#include "resource.h"

다음은 winmain 부분입니다.

HACCEL hAccel;
hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));

while (GetMessage(&Message,NULL,0,0)) {
if(!TranslateAccelerator(hWnd, hAccel, &Message))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
}

먼저 엑셀레이터 변수를 하나 만들어주시고
그다음 거기로 만드신 엑셀레이터를 로드합니다.

그후 메세지루프 도는 곳에 if 문을 걸어서
if(!TranslateAccelerator(hWnd, hAccel, &Message))

위와 같이 조건을 걸으시면
엑셀레이터를 사용하실수 있습니다.
자 여기서 끝이면 먼가 허전하죠

이번엔 해당 윈도우 프로시져에 부분으로
WM_COMMAD: 메세지에 다음과 같이
입력하시면 조건별로 사용하실수 있습니다.

이때 wParam에 들어오는 ID는
아까 엑셀레이터에 작성해주신 ID로 들어옵니다.

case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDE_MENU1:
MessageBox(hWnd, TEXT("Menu1 입니다."), TEXT("안내"), MB_OK);
break;
case IDE_MENU2:
MessageBox(hWnd, TEXT("Menu2 입니다."), TEXT("안내"), MB_OK);
break;
case IDE_ABOUT:
DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)About);
break;
case IDE_EXIT:
DestroyWindow(hWnd);
break;
}
return 0;

커서)_
여기서는 우리 눈에 보이는 커서를
만드는 윈도우내에서는 바꿔도록 해보겠습니다.
[커서 추가하기]
커서를 추가하시면 아마 이런 모습이 될겁니다.

 

이미지 처럼 집적 그리 셔도 상관 없구요
저는 참고로 전에 만들어둔것을 가져왔습니다.
(참고로 그리는건 256 color 밖에 안되서 다른대서 만들어 가져오시길 권장합니다.)

이제 소스적인 부분을 설명해 드리겠습니다.

아주 간단합니다.
winmain 부분에서 윈도우 클레스 부분중
다음부분을 아래와 같이 작성
하시면 됩니다.

WndClass.hCursor=LoadCursor(hInstance,MAKEINTRESOURCE(IDC_CURSOR1));

대화상자)_
대화상자는 사용자와 윈도우간의 준비된 인터페이스 입니다,
[대화상자 추가하기]
대화상자 추가 방법은 설명이 다소 길을수 있습니다.
하지만 일단 어렵지 않으니 주욱 읽어주시기 바랍니다.

먼저 리소스 추가에 Dialog에서
적절한 대화상자를 선택
해주기 바랍니다.
(참고로 전 IDD_PROPPAGE_MEDIUM을 선택했습니다.)

그럼 아래와 같이 뜨는데요
아 아래 스샷은 재가좀 추가 수정한 모습입니다.
 

이것으로 끝이면 편하겠지만 몇 가지 더 설정을 해야합니다.
대화상자의 속성에 보면 6가지 정도 수정 하셔야 하는데요
1. ID를 원하시는 ID명으로 수정
2. 동작의 Disabled를 Ture에서 False로 수정
3. 모양의 Border를 Dialog Frame으로 수정
4. 모양의 Caption도 원하시는 이름으로 수정
5. 모양의 Style을 Overlapped 혹은 Popup으로 수정
6. 모양의 System Menu를 True로 수정

이후에는 대화상자에 원하시는대로 추가 해보시면 됩니다.
이를 위한 적당한 도구들이 도구 상자 안에 들어있습니다.
 

만약 도구 상자가 보이지 않으신다면 아래와 같이
보기에서 도구 상자를 선택해주시면 나옵니다.
단축키로는 Ctrl + Alt + X 입니다.
 

이제 수정이 끝낮다고 생각하고
소스적인 부분을 설명 드리겠습니다.

여기서부터 대화 상자에 대한 이해가 조금 필요한데요
필요한것들을 소스로 명세하면 다음과 같습니다.

HINSTANCE g_hInst;

g_hInst = hInstance;

LRESULT CALLBACK About(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
switch (iMessage)
{
case WM_INITDIALOG:
return TRUE; case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDCANCEL:
EndDialog(hDlg, IDCANCEL);
break;
}
return TRUE;
}
return FALSE;
}

DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)About);

참으로 필요한것이 많아 보입니다.

하나 하나 설명을 드리자면 먼저 인스턴스 인데요
HINSTANCE g_hInst;
g_hInst = hInstance;

대화상자에 대화상자를 가진 인스턴스 핸들을
지정해주기 위해서 필요
합니다.
그래서 전역으로 인스턴스를 하나 만드시고
winmain의 인스턴스를 전역 인스턴스로
저장
을 해둡니다.

다음으로 작성 한것은 대화상자를 구동히가 위한 콜백 함수입니다.
LRESULT CALLBACK About(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam)

윈도우의 콜백 함수처럼 동일한 메세지 루프를 주고 받는데요
그중 몇몇 메세지는 윈도우 메세지와 틀립니다.

그중 하나가 WM_INITDIALOG로써
윈도우의 WM_CREATE같은 역활
을 합니다.

대화상자속 메세지중 IDCANCEL 이부분은
대화상자를 종료할때 사용하는 메세지중 하나입니다.

마지막으로 대화상자를 띄우기위한 실질적 코드입니다.
DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)About);
인자를 설명 해드리면 다음과 같습니다.
첫번째 인자: 대화상자를 가진 인스턴스 핸들(전역인스턴스)
두번째 인자: 위에서 작성한 대화상자 ID
세번째 인자: 대화상자를 소유할 부모 윈도우 핸들(hWnd)
네번째 인자: 대화상자의 프로시저 이름(위의 About 콜백 함수)


아이콘)_
이번엔 만드는 프로그램의 아이콘을 지정해도록 하겠습니다.
[아이콘 추가하기]
아이콘 추가방법은 위의 커서 추가방법과 매우 유사합니다.

 

이것도 이미지처럼 그리셔도 됩니다만
가져오시는걸 권장합니다.

소스적인 부분을 설명드리면

이번엔 winmain의 윈도우 클레스 부분중
다음 부분을 아래와같이 작성
하시면 됩니다.

WndClass.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));

메뉴)_
윈도우 프로그램들중 상단에 메뉴가 있는 프로그램들을 보신적이 많으실 겁니다.
이번엔 그 메뉴를 추가해보도록 하겠습니다.
[메뉴 추가하기]
먼저 메뉴를 추가 해주시면 다음과 같이 뜨는데요


그대로 작성해주시면 됩니다.

이때 이름을 작성하실때 단축키 같은것을
명시해주고 십다
고 생각하시면
문자사이에 \t 를 작성해주시면
\t 이후 문자는 오른쪽으로 정렬
이됩니다.

그 후 만들어주신 메뉴들에 ID를 부여 해야겠죠
아래와 같이 속성에서 ID 부분을 작성하시면 됩니다.


추가 사항으로 속성 창이 안보이실경우
마우스 왼쪽을 클릭하시면 속성을 선택하실수 있습니다.
 

이제 소스적 부분을 설명 드리면 이것도 간단합니다.
winmain의 윈도우 클레스 부분에서 아래와 같이 작성하시면 됩니다.

WndClass.lpszMenuName=MAKEINTRESOURCE(IDR_MENU1);

위와 같이 작성 후에는 위의 엑셀레이터와 마찬가지로
다음과같이 작성하시면 해당 이벤트를 검출하여 작업을 지정하실수 있습니다.

case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDE_MENU1:
MessageBox(hWnd, TEXT("Menu1 입니다."), TEXT("안내"), MB_OK);
break;
case IDE_MENU2:
MessageBox(hWnd, TEXT("Menu2 입니다."), TEXT("안내"), MB_OK);
break;
case IDE_ABOUT:
DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)About);
break;
case IDE_EXIT:
DestroyWindow(hWnd);
break;
}

참고로 위와 소스가 같은것은
단축키와 해당 메뉴가 동일하게 작동을 하기 위해서
동일한 ID를 주었기 때문
입니다.
ID가 다르면 다르게 작동할것 입니다.

문자열 테이블)_
문자열 테이블은 문자열을 쉽게 관리하기 위한 자원입니다.
[문자열 테이블 추가하기]
문자열 테이블 추가하기는 위의 엑셀레이터 추가 방법과 유사합니다.

 

문자열 테이블은 ID명과 ID Number와 문자열로 이루어져있습니다.
이때 문자열에는 ascii코드가 적용 됨으로 \n등을
사용하여 문단 나누기를 입력하실수 있습니다.

이제 소스적 부분을 설명해 드리면
3자기 정도만 하시면됩니다.

TCHAR sMent[100];
LoadString(g_hInst, IDS_MENT, sMent, 100);

GetClientRect(hWnd, &rt);
DrawText(hdc, sMent, strlen(sMent), &rt, DT_CENTER);

각각 문자열 변수해당 변수로 문자열 로드
로드한 문자열을 출력하는 과정이 되겠습니다.

이번 포스팅의 결과물은 다음과 같습니다.