今天在QQ群里有人問(wèn)怎樣實(shí)現(xiàn)將自己的窗口嵌入桌面,讓它和桌面融為一體,就像很多桌面日歷軟件那樣。
我當(dāng)時(shí)想到的就是建立一個(gè)Child Window,將他的父窗口設(shè)置成桌面Shell窗口就可以了。但是后來(lái)想想覺(jué)得不對(duì),因?yàn)楹芏嘧烂嫒諝v窗口都有半透明和陰影效果,明顯是用Layered Window實(shí)現(xiàn)的,而大家知道Layered Window一定要用Pop Up Window才能實(shí)現(xiàn)的。
那么如何用Pop up Window實(shí)現(xiàn)這種效果呢? 這里關(guān)鍵的一點(diǎn)就是要將該窗口的Owner設(shè)置成桌面的Shell 窗口。
很多以為Pop Up Window的Owner窗口只能在Create時(shí)關(guān)聯(lián), 建立后沒(méi)法動(dòng)態(tài)修改,實(shí)際上微軟是有接口讓我們改的,只是他們不建議我們動(dòng)態(tài)改,因?yàn)檫@樣會(huì)影響窗口的層次關(guān)系,尤其是對(duì)于Modal Dialog。
我們將窗口Owner改成桌面Shell窗口的代碼如下:
BOOL CheckParent(HWND hWnd)
{
static HWND s_hWndOldParent = NULL;
HWND hWndProgram = NULL;
HWND hWndShellDLL = NULL;
hWndProgram = FindWindow(_T("Progman"), _T("Program Manager"));
if(hWndProgram != NULL)
{
hWndShellDLL = FindWindowEx(hWndProgram, NULL, _T("SHELLDLL_DefView"), NULL);
}
if(hWndShellDLL != NULL
&& hWndShellDLL != s_hWndOldParent)
{
SetWindowLong(hWnd, GWL_HWNDPARENT, (LONG)hWndShellDLL);
s_hWndOldParent = hWndShellDLL;
return TRUE;
}
return FALSE;
}
另外還有一個(gè)問(wèn)題是一般Pop up窗口在Show出來(lái)時(shí)會(huì)顯示在最上面,而我們是要讓它顯示在最下面, 所以要設(shè)置下Z-Order:
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
CheckParent(hWnd);
SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_SHOWWINDOW);
這樣上面的代碼就實(shí)現(xiàn)了的窗口永遠(yuǎn)在桌面上,即使你點(diǎn)“顯示桌面”或是WIN+D,也不受影響。
另外,如果你要讓你的窗口在激活時(shí)也不會(huì)跑到其他窗口上面,只要?jiǎng)?chuàng)建時(shí)設(shè)置WS_EX_NOACTIVATE屬性就可以了。
還有個(gè)問(wèn)題是桌面Shell有可能重啟,比如我們Kill掉Explorer.exe進(jìn)程,所以我們最好一開(kāi)始就啟一個(gè)定時(shí)器,然后不停調(diào)用
CheckParent(HWND hWnd)。
測(cè)試代碼下載: source code
posted on 2012-05-03 22:07
Richard Wei 閱讀(8651)
評(píng)論(8) 編輯 收藏 引用 所屬分類(lèi):
windows desktop