'서브클래싱'에 해당되는 글 2건
- 2010.02.11 DLL에서 WndProc 메시지 처리하는 방법
- 2009.05.26 서브클래싱
2010. 2. 11. 18:04
DLL에서 WndProc 메시지 처리하는 방법
2010. 2. 11. 18:04 in Programmings/Windows Programming
응용 프로그램에서 특정 DLL을 사용할 때, 해당하는 DLL에서 윈도우즈 메시지를 처리해야 할 경우가 있다.
한참을 고민했네.. 메시지를 후킹해서 필요한 녀석만 처리를 하게끔 해야하나?? -_-;
의외로 간단한 방법이 있었다.
그것을 '서브클래싱(SubClassing)' 이라고 부르는 것 같다.
DLL의 초기화 하는 적절한 부분에 다음과 같이 서브클래싱을 해준다.
본인의 경우 다음과 같이...
SetWindowLongPtr() 함수를 통해 메시지를 처리할 윈도우 프로시저를 기존의 응용프로그램의 것에서 DLL의
것으로 옮긴다.
DLL 내부에 만들어 놓은 윈도우 프로시저(WndProc)에서 처리하고자 하는 메시지만 처리하도록 하고 그 외의 것은
CallWindowProc()함수를 통해 기존의 응용프로그램의 윈도우 프로시저가 처리하도록 한다.
WNDPROC oldProc;
...
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
...
switch(msg)
{
...
}
return CallWindowProc(oldProc, hwnd, msg, wp, lp);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
...
switch(fdwReason)
{
case DLL_PROCESS_ATTACH :
...
oldProc = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG)WndProc);
}
}
...
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
...
switch(msg)
{
...
}
return CallWindowProc(oldProc, hwnd, msg, wp, lp);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
...
switch(fdwReason)
{
case DLL_PROCESS_ATTACH :
...
oldProc = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG)WndProc);
}
}
SetWindowLongPtr() 함수를 통해 메시지를 처리할 윈도우 프로시저를 기존의 응용프로그램의 것에서 DLL의
것으로 옮긴다.
DLL 내부에 만들어 놓은 윈도우 프로시저(WndProc)에서 처리하고자 하는 메시지만 처리하도록 하고 그 외의 것은
CallWindowProc()함수를 통해 기존의 응용프로그램의 윈도우 프로시저가 처리하도록 한다.
'Programmings > Windows Programming' 카테고리의 다른 글
warning C4995: 'xxx' : name was marked as #pragma deprecated (0) | 2010.04.27 |
---|---|
"응용 프로그램 구성이 올바르지 않기 때문에..." 해결 방안 (0) | 2010.04.27 |
아스키코드(ASCII CODE)와 유티코드(UNICODE) (0) | 2009.10.09 |
GetLastError() (0) | 2009.07.16 |
WinIO (0) | 2009.06.23 |
2009. 5. 26. 10:51
서브클래싱
2009. 5. 26. 10:51 in Programmings/Windows Programming
서브클래싱(SubClassing)이란 윈도우 프로시저로 전달되는 메시지를 중간에 가로채는 방법이다. 중간에서 메시지를 조작하게 됨으로써 윈도우의 모양을 변경하거나 동작을 감시하거나 하는 작업을 할 수 있게 되는 것이다.
윈도우는 CreateWindow()를 통해 만들어진다. 이 때 CreateWindow()의 첫번 째 인수인 윈도우 클래스에서 윈도우 생성에 필요한 정보를 구하게 되는데, 그 중 가장 중요한 것이 메시지를 처리하는 윈도우 프로시저의 번지(lpfnWndProc)이다. 이는 윈도우 클래스에 보관되는 것이 아니고 윈도우별로 별도로 보관된다.
윈도우는 메시지를 받게 되면 해당 윈도우의 윈도우 프로시저 번지를 조사한 후 조사된 번지로 메시지를 보내고 메시지를 받은 윈도우 프로시저는 이 메시지를 받아 해당 윈도우에서 작성한 코드대로 처리를 하게 된다.
이 때 윈도우 프로시저를 다른 윈도우 프로시저로 변경을 한다면, 모든 메시지는 새로 만든 윈도우 프로시저로 전달이 될 것이다.
이렇게 새로 만들어진 윈도우 프로시저를 서브클래스 프로시저(SubClass Procedure)라고 한다.
윈도우 프로시저의 번지를 변경하기 전에 원래의 윈도우 프로시저 번지를 보관해 두고 서브클래스 프로시저에서 처리하지 않은 메시지는 반드시 원래 윈도우 프로시저로 전달하도록 해야한다.
서브클래스 프로시저를 등록하기 위해서는 아래와 같은 함수를 사용한다.
LONG_PTR SetWindowLongPtr( HWND hWnd,
int nIndex,
LONG_PTR dwNewLong )
hWnd - 프로시저를 바꾸려는 윈도우에 속한 클래스의 핸들
nIndex - MSDN 참고
GWL_EXSTYLE : Sets a new extended window style
GWL_STYLE : Sets a new Window style
GWLP_WNDPROC : Sets a new address for the window procedure.
GWLP_HINSTANCE : Sets a application instance handle.
...
dwNewLong - 대체할 값(프로시져)을 지정.
int nIndex,
LONG_PTR dwNewLong )
hWnd - 프로시저를 바꾸려는 윈도우에 속한 클래스의 핸들
nIndex - MSDN 참고
GWL_EXSTYLE : Sets a new extended window style
GWL_STYLE : Sets a new Window style
GWLP_WNDPROC : Sets a new address for the window procedure.
GWLP_HINSTANCE : Sets a application instance handle.
...
dwNewLong - 대체할 값(프로시져)을 지정.
예)
원래번지 = SetWindowLongPtr(변경 윈도우, GWLP_WNDPROC, 서브클래스 프로시져);
위와 같이 하면, 변경 윈도우로 보내지는 모든 메시지는 일단 서브클래스 프로시져로 전달 될 것이다.
변경 윈도우는 일반적인 윈도우가 될 수도 있고, 버튼, 에디트박스와 같은 윈도우도 될 수 있다. 버튼이나 에디트박스가 변경 윈도우가 될 경우 그 윈도우에서 처리하고 싶은 이벤트, 메시지에 관련된 부분을 서브클래스 프로시져에 넣어주면 된다.
추가로 서브클래스 프로시져를 작성한다.
LRESULT CALLBACK 프로시져(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
switch(iMessage){
case XXX:
...
break;
}
return CallWindowProc(원래번지, hWnd, iMessage, wParam, lParam);
}
CallWindowProc() 는 위 예제의 서브클래스의 case 에 속하지 않은 메시지를 처리하는 부분이다. 이 메시지들은 lpPrevWndFunc에 정의된 윈도우 프로시져로 보내저 처리가 될 것이다.
LRESULT CallWindowProc (WNDPROC lpPrevWndFunc,
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam )
lpPrevWndFunc - 서브클래스 등록(SetWindowLongPtr)시 리턴된 값으로 원래의 윈도우 프로시저(번지)
hWnd - 메시지를 받을 윈도우 프로시저의 핸들
Msg - 메시지 내용
wParam - 메시지의 추가적인 정보
lParam - 메시지의 추가적인 정보
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam )
lpPrevWndFunc - 서브클래스 등록(SetWindowLongPtr)시 리턴된 값으로 원래의 윈도우 프로시저(번지)
hWnd - 메시지를 받을 윈도우 프로시저의 핸들
Msg - 메시지 내용
wParam - 메시지의 추가적인 정보
lParam - 메시지의 추가적인 정보
예)
return CallWindowProc(원래번지, hWnd, iMessage, wParam, lParam);
윈도우즈 API 정복을 참고한 간단하게 본 서브클래스의 개념과 주요 함수들이다.
'Programmings > Windows Programming' 카테고리의 다른 글
레지스트리(Registry) (0) | 2009.05.29 |
---|---|
다른 윈도우에서의 GetFocus() 사용하기 (0) | 2009.05.28 |
GetWindowThreadProcessId() (0) | 2009.05.18 |
GetModuleFileNameEx() (0) | 2009.05.15 |
DllMain (0) | 2009.04.27 |