김성엽님의 블로그를 따라하고 있습니다.
Windows OS에는 멀티태스킹을 지원함(창 여러개 띄우는거)
프로그램이 엄청나게 중복될텐데 얘네를 어떻게 중복처리를 해서 간소화시킬까 라는 생각에서 나온 개념
Window Procedure
Window Procedure 공유하기
Window Class
Window Procedure를 공유하기 위한 정보 + 다양한 정보들이 있음.
매번 작업을 할때 마다 초기화를 해줘야한다.
여러 동일한 작업을 하는 Window라면 기본적으로 초기값이 동일함.
WNDCLASS 구조체에서 관리된다.
typedef struct tagWNDCLASS{
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCWSTR lpszMenuName;
LPCWSTR lpszClassName;
} WNDCLASS;
typedef const wchar_t *LPCWSTR
: LPCWSTR 자료형은 유니코드 문자열을 사용하기위한 포인터 형식의 자료형이다.const wchar_t *lpszClassName;
. 결국 이런모양이다.// 직접 문자열을 대입하는 경우
WNDCLASS wc;
wc.lpszClassName = L"Tipsware";
// 배열에 저장된값을 사용하는 경우
WNDCLASS wc;
wchar_t class_name[] = L"Tipsware";
wc.lpszClassName = class_name;
대,소문자 구분이 없다.
Window Procedure Address - lpfnWndProc
typedef LREUSLT (CALLBACK*WNDPROC)(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK MyProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
if(uMsg == WM_LBUTTONDOWN){
// 왼쪽 마우스버튼이 클릭되었을 때 처리하고싶은 작업을 적으면 됨
}
/*
DefWindowProc 함수는 Window OS가 발생하는 많은 메시지를
프로그래머가 전부 처리할수 없기때문에,
메시별 기본적인 상황을 처리할수 있도록
제공하는 API 함수이다.
*/
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
WNDCLASS wc;
wc.lpfnWndProc = MyProc; // MyProc 함수의 주소를 대입
Instance Handle - hInstance
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASS wc;
wc.hInstance = hInstance; // 첫 매개변수 값을 대입
...
}
Cursor - hCursor
WNDCLASS wc;
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
Logo Icon - hIcon
WNDCLASS wc;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
Background Brush - hbrBackground
WNDCLASS wc;
HBRUSH h_burch = CreateSolidBrush(RGB(0,255,255));
wc.hbrBackground = h_bursh;
WNDCLASS wc;
wc.hbrBackground = ::GetStockObject(WHITE_BRUSH); // 흰색채우기 속성 사용
더 간단히 색을 지정할 수 있다
GetSysColorBrush()를 사용하여 동작하기 때문에 다음과 같은 방법도 사용됨
WNDCLASS wc;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // 흰색채우기 속성 사용
Menu - lpszMenuName
WNDCLASS wc;
wc.lpszMenuName = L"MainMenu";
wc.lpszMenuName = NULL;
ClassStyle - style
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
Extra Class Memory - cbClsExtra
WNDCLASS wc;
wc.cbClsExtra = 0;
Extra Window Memory - cbWndExtra
WNDCLASS wc;
wc.cbWndExtra = 0;
WNDCLASS wc; // Window Class 등록을 위한 구조체
wc.cbClsExtra = 0; // 추가 메모리 사용 안함
wc.cbWndExtra = 0; // 추가 메모리 사용 안함
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); //메인 윈도우 배경색 지정
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 화살표 커서 사용
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 제목 표시줄의 LOGO ICON 사용
wc.hInstance = mh_instance; // 실행 인스턴스 핸들값 지정
wc.lpfnWndProc = MyProc; // 기본 메시지 처리 함수 지정
wc.lpszClassname = L"Tipsware"; // Window Class 이름 지정
wc.lpszMenuName = NULL; // 메뉴사용 안함
wc.style = CS_HREDRAW | CS_VREDRAW; // Window 그리기 특성 설정
Window Class 선언했으면 RegisterClass()
를 이용하여 OS 에 등록하자
RegisterClass(&wc); // wc에 저장도니 정보를 기준으로 'Window Class'등록
이렇게 등록한 WindowClass를 우리 프로그램에 생성하려면
CreateWindow()의 첫 매개변수를 WindowClass 이름을 넣어주면됨
HWND h_nwd = CreateWindow(L"Tipware", ...
이렇게 사용하면 되는데, 남이 만들었거나 윈도우OS에서 사용중엔 Window Class 또한 호출할 수 있다.
HWND h_nwd = CreateWidnow(L"Button", ...
컨트롤 관련 WindowClass 이름은
Button, ComboBox, Edit, ListBox, MDIClient, Static 등 이 있음
그외 특수한 목적으로 만들어진 WindowClass도 있으니 참고.
응용프로그램 방식
WM_LBUTTONDOWN // Window Message Left Button Down 줄임말
WM_RBUTTONUP // Window Message Right Button UP 줄임말
사용자가 정의해서 사용가능한데, 기존 Window 메시지와 중복되면 버그가 나서 보통 이렇게 사용함
#define WM_MY_MESAGE (WM_USER + 1)
메시지는 상태변화 뿐만 아니라 구체적인 상황까지 알려줌
도움말을 꼭 참조
해서 작업해야함.