学习"怎样编写一个类Spy++的搜索窗口程序" ”

  想写一个能帮我在“大家来找茬”中比较到不同的程序,首先就搜了捕捉游戏窗口的编程文章,"怎样编写一个类Spy++的搜索窗口程序" 帮助很大,作者提供的源代码相当不错,文章链接 http://www.vckbase.com/document/viewdoc/?id=636

  不过下载附带的源代码,编译无法成功,报告“RealChildWindowFromPoint()未定义错误。找到两个解决方法如下,

1. 在User32.dll查找这个函数,这个方法是 gobr的简化版本,没考虑确实没有这个API 函数的情况
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;
}


你可能感兴趣的:(user,null,iterator,编译器,文件管理器,winapi)