1. 程式人生 > >獲取桌面視窗控制代碼

獲取桌面視窗控制代碼

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文件。