- Today
- Total
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 재능이의 돈버는 일기
- StresslessLife
- K_JIN2SM
- 소소한 일상
- My Life Style & Memory a Box
- Blog's generation
- 공감 스토리
- 취객의 프로그래밍 연구실
- Love Me
- Dream Archive
- 세상에 발자취를 남기다 by kongmingu
- hanglesoul
- 카마의 IT 초행길
- 느리게.
- 미친듯이 즐겨보자..
- Joo studio
- Gonna be insane
- 악 다 날아갔어!! 갇대밋! 왓더...
- xopowo05
- 맑은공기희망운동
- 엔지니어 독립운동
- 혁준 블로그
- Simple in Complex with Simple
- 무의식이 의식을 지배한다
드럼치는 프로그래머
[API/MFC] 윈도우, 윈도우 클래스, WNDCLASS 구조체 , WNDCLASSEX, SetClassLong, GetClassLong, GetClassLongPtr, SetClassLongPtr 본문
[API/MFC] 윈도우, 윈도우 클래스, WNDCLASS 구조체 , WNDCLASSEX, SetClassLong, GetClassLong, GetClassLongPtr, SetClassLongPtr
드럼치는한동이 2010. 2. 16. 16:24[윈도우의 정의]
- 프로그램이 출력 결과를 내 보내고 사용자로부터 입력을 받아들이는 화면상의 사격영역
[윈도우 클래스]
정의 : 모든 윈도우들은 윈도우 클래스로부터 만들어 진다. 윈도우 클래스는 윈도우를 만들기
위한 형틀이며 생성될 윈도우의 여러가지 특징들을 모아놓은 구조체이다.
[윈도우 클래스의 종류]
1. 시스템 전역 클래스
- 운영체제가 부팅될 때 등록되며 주로 컨트롤을 만들때 사용된다.
ex) button, edit, scrollbar, listbox 등
2. 응용 프로그램 전역 클래스
- dll에 의하여 등록되며 프로세스의 모든 모듈에서 이 클래스를 사용할수 있다.
- 커스텀 컨트롤을 위한 클래스를 DLL에서정의하면 프로그램에서는 DLL을 로드해서 이
클래스를 사용할 수 있다. 클래스 스타일에 GS_GLOBALCLASS 스타일을 지정해야 한다.
3. 응용 프로그램 로컬 클래스
- 응용 프로그램 자신이 메인 윈도우나 차일드 또는 커스텀 컨트롤을 맏늘기 위해 프로그램 선두에서 등록한
클래스이며 프로그램 내부에서 사용된다.ㄴ
[WNDCLASS 구조체]
typedef struct tagWNDCLASSA {
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
} WNDCLASSA, *PWNDCLASSA, NEAR *NPWNDCLASSA, FAR *LPWNDCLASSA;
위와 같이 되어 있다... 각 구조체 멤버에 대한 설명은..
-------------------------------
----- lpszClassName -----
등록하고자 하는 윈도우 클래스의 이름을 나타낸다.
------------------------------
----- hInstance -----
이 윈도우 클래스를 등록한 응용 프로그램의 인스턴스 핸들이다.
메인 윈도우를 만들때 WinMain으로 전달된 hInstance 인수를 그대로 대입하면 된다.
------------------------------
----- lpFnWndProc -----
메시지 처리 함수를 지정한다. 이 클래스로 부터 만들어진 윈도우에 메시지가 전달되며
이 멤버가 지정하는 함수로 메시지가 전달되어 윈도우의 고유의 처리를 하게 된다.
------------------------------
----- hCursor -----
클래스 커서를 지정한다.
--------------------
----- hIcon -----
클래스 아이콘을 지정한다.
--------------------
----- hbrBackground -----
윈도우의 작업영역을 칠할 배경 브러시를 지정한다.
---------------
----- lpszMenuName -----
이 클래스로부터 만들어진 윈도우가 사용할 메뉴를 지정한다. 메뉴는 윈도우 클래스에서뿐만 아니라
CreateWindow 함수에서 개별 윈도우를 만들때 지정할수도 있다. CreateWindow 함수에서 지정하면
lpszMenuName 에서 지정한 메뉴는 무시된다.
-------------------------
----- sytle -----
윈도우 클래스의 스타일을 지정한다.
--------------------
----- cbClsExtra -----
윈도우 클래스에서 사용하고자 하는 여분의 메모리양을 바이트 단위로 지정한다.
운영체제는 윈도우 클래스를 등록할 때 이 멤버가 지정하는 만큼의 메모리를 추가로 할당한다.
SetClassLong(Ptr); GetClassLong(Ptr); 등의 함수로 이 메모리를 사용한다.
-----------------------------------
----- cbWndExtra -----
cbClsExtra와 유사하되 개별 윈도우에서 사용하고자 하는 여분의 메모리양을 지정한다. 운영체제는
CreateWindow로 개별 윈도우를 만들 때마다 이 멤버가 지정하는 만큼의 메모리를 추가로 할당한다.
응용프로그램에서는 GetWindowLong(Ptr), SetWindowLong(Ptr) 등의 함수로 이 메모리를 사용한다.
-------------------------
[WNDCLASSEX]
WNDCLASS 구조체에 확장버전인 WNDCLASSEX 구조체는 두가지가 더 추가되었는데
하나는 UINT sbSize 구조체 사이즈를 지정하는 멤버이고 (버전확인을 위해) 또 하나는
HICON hIconSm; 으로 작은 아이콘을 지정할때 사용한다.
구조체 멤버는
typedef struct tagWNDCLASSEXA {
UINT cbSize;
/* Win 3.x */
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
/* Win 4.0 */
HICON hIconSm;
} WNDCLASSEXA, *PWNDCLASSEXA, NEAR *NPWNDCLASSEXA, FAR *LPWNDCLASSEXA;
위와 같다..
sbSize는 구조체 자체를 sizeof(); 로 대입하면되고.. 새로 생긴 작은아이콘 hIconSm 은
WndClassEx.hIconSm = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICON1),
IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),LR_DEFAULTCOLOR);
클래스 멤버를 초기화후 등록할때는
ATOM RegisterClassEx(CONST WNDCLASSEX *lpwcs): 라는 함수로 등록해야 한다고한다....
-----------------------------------
[ GetClassLong, SetClassLong, GetClassLongPtr, SetClassLongPtr ]
DWORD GetClassLong(HWND hWnd, int nIndex);
DWORD SetClassLong(HWND hWnd, int nIndex, LONG dwNewLong);
LONG_PTR GetClassLongPtr(HWND hWnd, int nIndex);
ULONG_PTR SetClassLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong);
WNDCLASS(EX) 의 구조체 값은 윈도우 클래스를 등록할 때 정해지지만 등록된 후에도 수정할 수 있다.
그러한 방법을 제공하는 함수가 위의 함수들이다.
하지만 위에 GetClassLong, SetClassLong 두 함수는 과거에 많이 썻지만 최근 64비트 호환이 되지 않으므로
요즘에는 잘 쓰지않고 아래 두 함수 GetClassLongPtr, SetClassLongPtr 가 가장 많이 쓰인다고 한다.
함수인자의 첫번째와 세번째는 딱 봐도 무슨의미 인지 알겠지만 두번째 인자 nIndex는 클래스구조체의 값과 매치되는데 아래와 같다.
GCL_MENUNAME
GCL_HBRBACKGROUND
GCL_HCURSOR
GCL_HICON
GCL_HMODULE
GCL_CBWNDEXTRA
GCL_CBCLSEXTRA
GCL_WNDPROC
GCL_STYLE
GCW_ATOM
GCL_HICONSM
딱봐도 구조체와 대응된다는것 알수 있다.
해당 구조체의 값을 변경하는 인덱스는 위와 같은 인자를 주면 가능하다.
그러면 정말로 프로그램 실행중에 윈도우 클래스를 바꺼서 윈도우에 변화를 주는 예제를 만들어보자
※ 64비트호환 버전인 GetClassLongPtr , SetClassLongPtr 함수 사용시 위의 인자값에서 GCL 다음 P를 하나 더 붙여야 한다.
GCL_HBRBACKGROUND 의 경우 GCLP_HBRBACKGROUND 라고 해야 64비트 호환 함수 인자로 할수 있다.
하지만 독자의 컴퓨터에서는 SetClassLongPtr 함수가 이상하게 사용이 안됬다. 컴파일 에러가 났다. 이유는 모르겠다.
--------------- 윈도우 실행도중 클래스를 바꾸는 에제 SetClassLong 함수 사용 ---------------------
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass = TEXT("First"); //윈도우 이름 및 타이틀바에 등록할 문자열
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
g_hInst = hInstance;
//------------ 아래 부분은 윈도우 클래스를 설정해주는 것이다. --------------------
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor = LoadCursor(NULL,IDC_ARROW);
WndClass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
WndClass.hInstance = hInstance;
WndClass.lpfnWndProc = WndProc;
WndClass.lpszClassName = lpszClass;
WndClass.lpszMenuName = NULL;
WndClass.style = CS_HREDRAW | CS_VREDRAW;
//------------ 위 부분은 윈도우 클래스를 설정해주는 것이다. --------------------
RegisterClass(&WndClass); // <-- 여기서는 위에서 설정한 클래스를 등록한다.
hWnd = CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,NULL,(HMENU)NULL,hInstance,NULL); // 설정하고 등록한 윈도우를 생성한다.
ShowWindow(hWnd,nCmdShow); //생성한 윈도우를 출력..(이 함수를 호출하지않으면 윈도우가 보이지 않는다.)
while(GetMessage(&Message,NULL,0,0)) //사용자가 종료하기 전까지 반복해서 메세지 처리를 호출한다.
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) //여기서 실제로 메시지를 처리한다.
{
static HBRUSH hRed, hGreen, hBlue;
static HBRUSH NowBrush;
switch(iMessage)
{
case WM_CREATE:
hRed = CreateSolidBrush(RGB(255,0,0));
hGreen = CreateSolidBrush(RGB(0,255,0));
hBlue = CreateSolidBrush(RGB(0,0,255));
NowBrush = hRed;
return 0;
case WM_LBUTTONDOWN:
if(NowBrush == hRed) NowBrush = hGreen;
else if(NowBrush == hGreen) NowBrush = hBlue;
else if(NowBrush == hBlue) NowBrush = hRed;
SetClassLong(hWnd,GCL_HBRBACKGROUND,(LONG)NowBrush);
InvalidateRect(hWnd,NULL,TRUE);
return 0;
case WM_DESTROY:
DeleteObject(hRed);
DeleteObject(hGreen);
DeleteObject(hBlue);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd,iMessage,wParam,lParam); //프로그래머가 처리하지 않은 나머지 동작을 기본처리로 넘긴다.
}
-------------------------------------------------------------------------------------------
위의 코드를 실행하면 마우스를 왼쪽 클릭할때마다 윈도우 배경색이 바뀌는 것을 볼수 있다.^^;
하지만 독자의 컴퓨터에서는 SetClassLongPtr 함수가 이상하게 사용이 안됬다. 컴파일 에러가 났다. 이유는 모르겠다.
그래서 32비트 SetClassLong 버전을 썼다.-_-ㅋㅋ
[출처] [11장] 윈도우, 윈도우 클래스, WNDCLASS 구조체 , WNDCLASSEX, SetClassLong, GetClassLong, GetClassLongPtr, SetClassLongPtr,|작성자 어른아이
'★─Programing > ☆─API | MFC' 카테고리의 다른 글
[API/MFC] CFileDialog 불러오기 저장하기 (0) | 2011.04.18 |
---|---|
[API/MFC] 'const char [11]'에서 'LPCTSTR'(으)로 변환할 수 없습니다. (0) | 2010.02.26 |
[API/MFC] WndProc ( 윈도우 프로시저 ( Window Procedure ) ) (0) | 2009.02.25 |
[API/MFC] 메시지 루프 ( 메시지 구동 시스템 ( Message Driven System ) ) (0) | 2009.02.25 |
[API/MFC] 윈도우 클래스 ( WNDCLASS, CreateWindow ) (0) | 2009.02.25 |