제가 이걸 구현하려고 참.. 많이도 고생했는데..-_- 얼마전에 구입한 책을 보니..나와있네요 -__-;
VCL에 보면 WndProc이 캡슐화 되어있죠?;
API로 그런것을 구현한겁니다 -_-a
출처는 OpenGL Game Programming이구요, 소스는-_-제가 쓰던거에서..
기본적인 작동 원리는,
1. WNDCLASS 구조체의 cbWndExtra = 4를 해서 4바이트 여분 메모리를 생성하구요
WNDCLASS WndClass;
WndClass.cbWndExtra = 4;
...
RegisterClass(&WndClass);
---------------------------------------------------------------------------------------
2. CreateWindow(Ex)의 '마지막 인자'에 클래스의 포인터를 주고요(원래는 CREATESTRUCT),
CreateWindowEx(0, WindowName.c_str(),WindowName.c_str(),WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,640,480,
NULL,(HMENU)NULL,Instance, (void *)POGLW_Iterator[0]); // 메인윈도 생성
POGLW_Iterator[0]이 클래스의 포인터입니다. 클래스 내에서 CreateWindow를 사용하는것이면,
this를 주면 됩니다.
---------------------------------------------------------------------------------------
3. static멤버인 WndProc에서는
LRESULT CALLBACK POpenGLWindows::WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
PMessage Messages(hWnd, Message, wParam, lParam); // TMessage와 비슷합니다. WndProc의 파라
//메터들이 들어있습니다....-_-a;
POpenGLWindows *POGLWnd = (POpenGLWindows*)GetWindowLong(hWnd, 0); // 0번째 오프셋이
//바로 여분의 메모리.
if( (POGLWnd == NULL) && (Message != WM_CREATE) ) // 여분의 메모리는 0으로 초기화됩니다.
{
return DefWindowProc(hWnd, Message, wParam, lParam);
}
else if((Message == WM_CREATE) && (POGLWnd == NULL))
{
// 이부분이 핵심 -_-;;;;;;;;
SetWindowLong(hWnd, 0, (LONG)((LPCREATESTRUCT)lParam)->lpCreateParams);
// CreateWindow 의 마지막인자로 준 포인터값은, lParam으로 넘어옵니다. 그걸 이용한것..-_-a
POGLWnd = (POpenGLWindows *)GetWindowLong(hWnd, 0);
POGLWnd->Handle = hWnd;
POGLWnd->WndProc(Messages);
}
else if(POGLWnd != NULL) POGLWnd->WndProc(Messages);
if(Messages.MsgNotProcessed) return DefWindowProc(hWnd, Message, wParam, lParam);
}
---------------------------------------------------------------------------------------
POGLWnd->WndProc(&Messages);
이게 바로 캡슐화된 프로시져구요, 이렇게하면.. 좋은점은..-_-a 그냥 클래스멤버에 접근이 편리한 정도..--
TForm::WndProc(TMessage &Message); 랑 모양이 똑같죠 ^-^(-_-..... 이상한거 해놓고 좋아하는..)
음 잘 전달이 되었을지..-_-a;;
제가 머리가 나쁜지-_- 이걸로 한참 고생을 했거든요..-_-;;;
그래서 함 올려봅니다;
|