获取桌面窗口句柄

GetDesktopWindow获取的是顶层显示桌面句柄,也就是说,如果应用程序窗口在桌面上,那么它的窗口也算是所获取的窗口的一部分,如果使用GetDC(NULL)作图,则永远是在最顶层。

那么如何获取包含桌面图标的窗口句柄呢?

我们可以用Spy++来查看。


可以看出窗口层次为Progman->SHELLDLL_DefView->SysListView32。于是我们可以这样来获取我们想要的窗口句柄:

HWND hProgMan = ::FindWindow(L"ProgMan", NULL);
HWND hWndDesktop;
if(hProgMan)
{
	HWND hShellDefView = ::FindWindowEx(hProgMan, NULL, L"SHELLDLL_DefView", NULL);
	if(hShellDefView)
		hWndDesktop = ::FindWindowEx(hShellDefView, NULL, L"SysListView32", NULL);
}

然而在Windows7下还会发生另外一种情况(WindowsXP未测试):


其窗口层次为WorkerW-> SHELLDLL_DefView->SysListView32。而且WorkerW还不止一个。此时我们可以这样来获取句柄:

HWND hwndWorkerW=NULL;
HWND hShellDefView=NULL;
HWND hwndDesktop=NULL;
while(hwndDesktop==NULL)//必须存在桌面窗口层次
{
	hwndWorkerW=::FindWindowEx(0,hwndWorkerW,L"WorkerW",NULL);//获得WorkerW类的窗口
	if(hwndWorkerW==NULL)
		break;//未知错误
	hShellDefView=::FindWindowEx(hwndWorkerW,NULL,L"SHELLDLL_DefView",NULL);
	if (hShellDefView==NULL)
		continue;
	hwndDesktop=::FindWindowEx(hShellDefView,NULL,L"SysListView32",NULL);
}

注意:上述代码中没有用FindWindowW,这是因为我们需要指定从哪一个窗口往下查找。

 

在用以上方法获得的桌面窗口句柄上绘图,将会和桌面图标处于同一层次(即会被应用程序窗口覆盖),并且覆盖桌面图标。

 

那么什么时候会出现后一种情况呢?动态桌面(桌面壁纸定时更换)的环境下便会出现。但是当你在现行环境中更改了此设置后,这种现象并不会立即出现,要想让它“现出原形”,可以注销再登录,或者干脆重启。

 

我曾试过在动态桌面下绘图,情况会比较糟糕——我的桌面很卡。也可能是我的代码不好。

 

最后说明一点:这里获得的桌面窗口是一个ListView控件,可以用以ListView_开头的宏操作,具体可查看MSDN文档。

你可能感兴趣的:(VC++)