오늘 SendMessage 의 Param 의 형태가 C++, Delphi 언어마다 다르다는 소리에 발끈해 뒤졌다. 도대체 API 함수인데 어떻게 다를 수가 있고, Delphi 는 포팅해서 쓴다는 소리는 뭐냐고, Windows 유닛에 뻔히 있는데 다른데 있다니...
글 아래의 자료는 거슬러 올라가며 관련 선언을 다 모아 놓은 것이니 참고하시길... 결론은 SendMessage 의 Param 은 둘다 32-bit unsigned integer 다.
무슨 에러가 났네 어쩌내 해대서 더 찾아봤더니... VCL 의 메세지 처리 프로시저의 매개변수인 TMessage 의 Param 들은 32-bit signed integer 형이다.
-2147483648..2147483647 signed 32-bit 0..4294967295 unsigned 32-bit
2147483647 이상의 값은 TMessage 로 받아보면 음수가 되는 것이다. 그 상황은 아마 signed 와 unsigned 를 비교해 놓고 안되네 어쩌네 한 것이겠지... 답답하다.
SendMessage 는 32비트의 자료를 안전하게 전송해 줬는데 자료 이용을 잘 못하고... 이 글을 보는 이들은 이런 실수 하지마시길...
피해가려면 VCL 의 메세지 맵을 쓰지 말고 CALLBACK 프로시저를 하나 만들어서 Sub-Classing 하세요. 직접 unsigned 형으로 받으면... 그래도 실수할 수 없겠지. ㅋ
// SendMessage WINUSERAPI LRESULT WINAPI SendMessageA(IN HWND hWnd, IN UINT Msg, IN WPARAM wParam, IN LPARAM lParam); WINUSERAPI LRESULT WINAPI SendMessageW(IN HWND hWnd, IN UINT Msg, IN WPARAM wParam, IN LPARAM lParam); #ifdef UNICODE #define SendMessage SendMessageW #else #define SendMessage SendMessageA #endif // !UNICODE
// TMessage typedef unsigned short Word; // 0..65535
#pragma pack(push, 1) struct TMessage { unsigned Msg; union { struct { Word WParamLo; Word WParamHi; Word LParamLo; Word LParamHi; Word ResultLo; Word ResultHi; }; struct { int WParam; int LParam; int Result; };
}; }; #pragma pack(pop)
// Define Cardinal 32-bit unsigned integer unsigned int typedef long [int]; When used to modify an int, it doubles the number of bytes available to store the integer value. 32-bit integer.
// SendMessage function SendMessage; external user32 name 'SendMessageA'; function SendMessageA; external user32 name 'SendMessageA'; function SendMessageW; external user32 name 'SendMessageW';