먼저 소개한 방법에 예상되는 문제.


pthis 가 static으로 선언되어 있기 때문에 인스턴스가 여러개 생성될 경우 제대로 처리되지 않으리라 본다.


여러개의 인스턴스가 생성되어도 문제 없이 처리되도록 모든 인스턴스의 필요한 정보(hwnd 와 this 포인터)를

저장하고 필요할 때 꺼내오면 될듯..


해서..

STL의 map을 이용 간단하가 목록을 만들고, 거기서 찾아내는 코드를 만들었다.






#include <map>


std::map <HWND, ULONG> classMap;



LRESULT CALLBACK WinClassProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)

{

LRESULT result;

std::map<HWND, ULONG>::iterator it = classMap.find(hWnd); // 성능에 영향을 줄 것으로 예상됨.


if (it == classMap.end())

{

if (msg == WM_NCCREATE)

{

// CreateWindows/Ex() 함수의 마지막 인자는 무조건 this 포인터로 넘겨줘야 한다. 이걸 빼먹으면 동작하지 않음.

ULONG userdata = (ULONG)(((CREATESTRUCT*)lParam)->lpCreateParams);


// 여기서 종료되면 CreateWindow/Ex 함수에서 this 포인터를 안 넘긴 것임.

assert(userdata != 0);


// CreateWindow 함수가 리턴되기 전에 WM_CREATE가 처리 될 때 아직 생성 안된 hWnd를 사용하기 위해 필요함

((MyClass*)userdata)->m_hWnd = hWnd;


std::pair<HWND, ULONG> one(hWnd, userdata);

classMap.insert(one);

}


result = DefWindowProc(hWnd, msg, wParam, lParam);

}

else

{

    // virtual 선언으로 상속된 클래스의 함수가 호출된다.

result = ((MyClass*)(it->second))->WndProc(hWnd, msg, wParam, lParam);

}


return result;

}



코드는 깔끔한데 메세지가 발생할 때마다 map에서 find()를 수행하니 성능 저하가 제법 클것으로 예상된다.

또, MyClass 대신 template를 사용하면 더 깔끔해질듯하나... 내가 사용할줄 모른다. 




많이들 쓰는 듯...




class MyClass;



LRESULT CALLBACK WndProc( HWND hHwnd, UINT msg, WPARAM wParam, LPARAM lParam )

{

LRESULT result;

static MyClass *pthis = (MyClass*) GetWindowLong( hWnd, GWL_USERDATA );


if ( pthis == NULL && msg == WM_NCCREATE )

{

void *userdata = (void*)( ((CREATESTRUCT*) lParam)->lpCreateParam );

SetWindowLong( hWnd, GWL_USERDATA, userdata );

result = DefWindowProc( hWnd, msg, wParam, lParam );

}

else

{

if ( this )

result = pthis->MyWndProc( hWnd, msg, wParam, lParam );

else

result = DefWindowProc( hWnd, msg, wParam, lParam );

}


return result;

}


class MyClass

{

public:

CreateWindow( ... )

{

wc.lpfnWndProc = WndProc;

RegiserWindow( &wc );

m_hWnd = CreateWindowEx( /* */, this );

}


LRESULT MyWndProc( hWnd, msg, wParam, lParam );


protected:

m_hWnd;

}


를 나 나름대로 재 해석한 것..

- stack, queue, circular queue, tree, btree등.
- 모두 double linked list로 구현
- tree는 아직 완료 안됨

- vs2005에서 작성했지만 모두 C 코드임
   (몇가지만 손보면 리눅스에서도 테스트 가능하리라 봄)

%%%
그냥 심심하던 차에 책이 눈에 띄이길래...


- malloc을 사용할 수 없는 환경에서 linked list를 사용하고자 만듦.
- 크기가 큰 구조체를 가지는 자료 구조에서 삽입/삭제가 빈번할 경우 유용하지 않을까??

- but!! 약간(?)의 추가적인 메모리 사용이 부수적으로 생긴다.
배열 크기만큼의 포인터 (next 용), 리스트 관리용 자료구조와 포인터 등..




다 필요할 때가 있겠지...

+ Recent posts