==================================================================================================
서론 : 각 차일드 윈도우를 구별할 경우 특정 차일드의 정보를 저장하는 배열 첨자를 찾을 수 없는데,
이는 핸들이 운영체제가 발급하는 것이라서 그렇다.
ID를 이용하면 될 것 같지만 이것도 차일드 윈도우 같은 경우
필요에 따라서 동적으로 생성, 소멸을 하기 때문에 ID의 연속성을 확보하기 어렵다.
해결책 : 차일드별로 다른 정보를 저장할 수 있는 모종의 장치가 필요 → 여분의 메모리를 사용한다.
( ※ 윈도우 프로퍼티 : 여분의 메모리와 같은 용도 - 여분의 메모리보다 유연하고 편리한 방법 )
cbClsExtra - 윈도우 클래스를 등록할 때 여분의 메모리 할당 (byte)
cbWndExtra - 윈도우를 만들때 여분의 메모리 할당 (byte)
여분의 메모리가 일반적인 전역변수나 정적변수와 다른 점은 윈도우별로 할당되고 관리되며,
핸들이 다르면 실제로 엑세스되는 대상도 달라진다는 점이다.
사용 : ( ..Window..() - 윈도우별, ..Class..() - 윈도우 클래스별 )
GetWindow(Class)LongPtr(HWND hwnd, int nIndex)
SetWindow(Class)LongPtr(HWND hwnd, int nIndex, LONG dwnewlong)
( nIndex = 여분의 메모리 시작주소 오프셋. nIndex = 0 : 첫번째 여분의 메모리를 사용한다는 의미 )
단점 및 제약사항 : 기존에 존재하는 윈도우를 서브 클래싱한 경우는 여분의 메모리를 함부로 사용할 수
없다. 다른 동료 개발자나 오랜 시간이 흐른 뒤에 장문(?)의 소스코드를 봤을 때
기존의 윈도우가 여분 메모리를 어떤 사용 용도로 사용하고 있으며 남은 용량이
얼마인지 알아내기 어렵기 때문이다. ( OOP에서 private member와 유사 )
→ 프로퍼티 사용 !!
------------------------------------------------------------------------------------
[예제 : 윈도우즈 API 정복 1권]
==================================================================================================
[실행화면]
- 초기 화면
- 마우스 왼쪽 버튼을 클릭할 경우
- 크기를 줄일 경우
- 크기를 다시 크게 할 경우
==================================================================================================
[소스코드]
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hInstance;
int APIENTRY WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
HWND hwnd;
MSG message;
WNDCLASS wndclass;
static char lpszMainClass[] = TEXT("MainWindow");
g_hInstance = 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 = lpszMainClass;
wndclass.lpszMenuName = NULL;
wndclass.style = CS_HREDRAW | CS_HREDRAW;
RegisterClass(&wndclass);
wndclass.cbWndExtra = 4; // 여분의 메모리 지정 (최대 40Byte) : 각 차일드를 구별하는 용도
// - 여기서는 ㅇor x 구별 용도
wndclass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
wndclass.hCursor = LoadCursor(NULL, IDC_CROSS);
wndclass.lpfnWndProc = ChildProc;
wndclass.lpszClassName = TEXT("ChildsCls");
RegisterClass(&wndclass);
hwnd = CreateWindow (
lpszMainClass,
lpszMainClass,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
(HMENU) 0,
hInstance,
NULL
);
ShowWindow(hwnd, nShowCmd);
while(GetMessage(&message, NULL, 0, 0)) // 메시지 루프
{
TranslateMessage(&message);
DispatchMessage(&message);
}
return (int)message.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
{
int x, y;
switch(message)
{
case WM_CREATE : for(x=0; x<300; x+=100) // x 좌표
{
for(y=0; y<300; y+=100) // y 좌표
{
CreateWindow (
TEXT("ChildsCls"),
NULL,
WS_CHILD | WS_VISIBLE,
x,
y,
100,
100,
hwnd, // 부모 윈도우 핸들 등록
(HMENU) NULL,
g_hInstance,
NULL
);
}
}
return 0;
case WM_DESTROY : PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wp, lp);
}
LRESULT CALLBACK ChildProc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
{
HDC hdc;
PAINTSTRUCT ps;
switch(message)
{
case WM_CREATE : SetWindowLong(hwnd, 0, TRUE);
return 0;
case WM_LBUTTONDOWN : // !GetWindowLong(hwnd, 0) : TRUE → FALSE , FALSE → TRUE
SetWindowLong(hwnd, 0, !GetWindowLong(hwnd, 0));
// 강제로 WM_PAINT 메시지를 발생시킴
InvalidateRect(hwnd, NULL, TRUE);
return 0;
case WM_PAINT : hdc = BeginPaint(hwnd, &ps);
if(GetWindowLong(hwnd, 0)) // TRUE
{
// ㅇ(동그라미) 그리기
Ellipse(hdc, 10, 10, 90, 90);
}
else // FALSE
{
// X(엑스)자 그리기
MoveToEx(hdc, 10, 10, NULL);
LineTo(hdc, 90, 90);
MoveToEx(hdc, 10, 90, NULL);
LineTo(hdc, 90, 10);
}
EndPaint(hwnd, &ps);
return 0;
}
return DefWindowProc(hwnd, message, wp, lp);
}
==================================================================================================
'IT_Programming > MFC · API' 카테고리의 다른 글
[API] 사용자 정의 메시지 핸들러 & 메시지 크래커 (0) | 2009.07.29 |
---|---|
[API] 윈도우 프로퍼티 (Window Property) (0) | 2009.07.24 |
[API] 윈도우 창에 글 출력하기 (0) | 2009.07.22 |
[펌_API] 변수의 타입 (0) | 2009.07.14 |
작업 표시줄에서 프로그램 안보이게 하기 (0) | 2009.05.12 |