不过下载附带的源代码,编译无法成功,报告“RealChildWindowFromPoint()”未定义错误。找到两个解决方法如下,
typedef HWND (WINAPI *REALCHILDWINDOWFROMPOINT)(HWND hwndParent, POINT ptParentClientCoords);
RealWindowFromPoint(CPoint ptHitTest)
{
HMODULE hUser32 = ::LoadLibrary("User32.dll");
if (hUser32)
{
// note this function is not available under win95 so we also have a fallback
REALCHILDWINDOWFROMPOINT fnRealWndFromPoint = (REALCHILDWINDOWFROMPOINT)GetProcAddress(hUser32, "RealChildWindowFromPoint");
}
}
2. 使编译器以为在WIN98环境,很简单的解决办法,但风险在影响了整个项目的编译环境,没有其他复杂功能可以试试
#define WINVER 0x0500 /* version 5.0 */
gobr的文章(http://proxy3.zju88.net/agent/thread.do?id=VC-447ef74f-eaaf138a67271197a124c259cc530eee&page=0&bd=VC&bp=25&m=2)中提供了第3种方法,利用WM_NCHITTEST消息返回值,效果的确和RealChildWindowFromPoint 相同。
但还是有一个小问题,利用WM_NCHITTEST消息返回值获得窗口时,将鼠标拖动到文件管理器标题栏,这时目录树视图窗口被捕获,错误在于发送消息的SendMessage函数,返回的值误导了下面的判断条件,因为鼠标在标题栏,所以任何窗口中的子窗口都不可能成功捕获HITTEST坐标,即总应返回0。实际上返回值可能是 0x01,0x0B等。
uHitTest = SendMessage(hChildWnd, WM_NCHITTEST, 0, MAKELPARAM(pt.x,pt.y));
改用 DefWindowProc 函数则可以解决这个问题
uHitTest = ::DefWindowProc(hChildWnd,WM_NCHITTEST,0, MAKELPARAM(pt.x,pt.y));
为了获得和一样的效果,修改gobr的函数如下
typedef HWND (WINAPI *REALCHILDWINDOWFROMPOINT)
(HWND hwndParent, POINT ptParentClientCoords);
HWND RealWindowFromPoint(HWND hParentWnd, POINT pt)
{
HWND hChildWnd = NULL;
REALCHILDWINDOWFROMPOINT fnRealWndFromPoint;
if ( !hParentWnd )
{
return NULL;
}
if ( (hUser32 = ::LoadLibrary("User32.dll"))&&
(fnRealWndFromPoint = (REALCHILDWINDOWFROMPOINT)GetProcAddress(hUser32, "RealChildWindowFromPoint"))
)
{
hChildWnd = fnRealWndFromPoint(hParentWnd, pt);
}
// RealChildWindowFromPoint doesn't exist, might slower but can work
else
{
UINT uHitTest;
hChildWnd = GetWindow(hParentWnd,GW_CHILD);
// Iterator through the child windows
while ( hChildWnd )
{
// test whether pt in the child window ?
// uHitTest = SendMessage(hChildWnd, WM_NCHITTEST, 0, MAKELPARAM(pt.x,pt.y));
uHitTest = ::DefWindowProc(hChildWnd,WM_NCHITTEST,0, MAKELPARAM(pt.x,pt.y));
if ((int)uHitTest > 0 )
{
break; // find that window !! break loop
}
// look for next child window
hChildWnd = GetNextWindow(hChildWnd, GW_HWNDNEXT);
}
if( NULL == hChildWnd )
{
hChildWnd = hParentWnd; // if no window matched, will return hParentWnd;
}
}
if(hUser32)
{
::FreeLibrary(hUser32);
}
return hChildWnd;
}