VC++调用UpdateLayeredWindow实现半透明窗体【转】
半年沒碰MFC了 , 感覺是那么的陌生 , 忘記了絕大部分函數(shù)了....?你說我現(xiàn)在都有點(diǎn)學(xué)這忘哪,以后能跟的上技術(shù)的發(fā)展嘛?
????? 注意:由于代碼有點(diǎn)長(zhǎng),直接放在這里顯得冗長(zhǎng),所以,如果需要源碼的朋友請(qǐng)發(fā)郵件或留言,代碼只是互相學(xué)習(xí)之用,由于本人水平有限,如果您覺得不好,望理解,且不要有攻擊性的言行,謝謝!)
??????? 首先看看我做的效果,有點(diǎn)像Vista的效果,而且解決了控件不能顯示的問題,注意上層是一個(gè)子窗體,用來承載窗體控件:
? ? ?
???????? 最近看了桌面天氣秀這款小軟件,其界面精致漂亮,而且可以透明顯示,還有個(gè)特別有趣的功能就是能讓窗體固定在桌面上并且鼠標(biāo)可以“穿透”而窗體不受任何影響,這就是帶著些許神秘的“有影無形”的功能。
???????? 事實(shí)上要實(shí)現(xiàn)這種“有影無形”的功能,很簡(jiǎn)單,我相信聰明的您一定很快會(huì)想到怎么做。幾句代碼就可以搞定,給你點(diǎn)提示,只有在2000以上的Win操作系統(tǒng)才支持(當(dāng)然如果你有足夠的時(shí)間可以完全可以在98上實(shí)現(xiàn))。那么今天我們主要討論一下窗體的半透明顯示,其實(shí),如果僅僅要實(shí)現(xiàn)窗體的半透明顯示,很簡(jiǎn)單,UpdateLayeredWindow調(diào)用就可以了,網(wǎng)上去搜一下幾乎都是貼的這個(gè)函數(shù)怎么怎么實(shí)現(xiàn)窗體的半透明,在往下就沒了,比如此函數(shù)有個(gè)缺陷,就是經(jīng)過此函數(shù)處理過的窗體,其上面的控件都透明了。諸如此類的問題至少到現(xiàn)在我在網(wǎng)上沒找到一個(gè)讓人感覺滿意的解決方案。
?????? 記得在一個(gè)所謂專業(yè)的C#網(wǎng)站上看到一篇題為“XP下透明窗體的完美實(shí)現(xiàn)”,當(dāng)時(shí)看了還真高興一陣子,可是把代碼下下來一看,又是被忽悠了,里面就調(diào)用了UpdateLayeredWindow函數(shù)實(shí)現(xiàn)透明然后加個(gè)旋轉(zhuǎn)顯示,這樣子就算完美了,我暈!這個(gè)函數(shù)查查資料誰不會(huì)。看來還是自己動(dòng)手,不知道有心的朋友注意到?jīng)]有,在桌面天氣秀里,打開設(shè)置,然后快速拖動(dòng),會(huì)看到上面的窗體明顯脫離,這就是多層窗口留下的尾巴。下面的透明窗體是背景,上面的窗體承載控件。在拖動(dòng)下層窗體的時(shí)候讓上層窗體跟著一起動(dòng)。對(duì)于小軟件來說,效果還可以。事實(shí)上,今天我實(shí)現(xiàn)的也和這個(gè)思路差不多,不過我這個(gè)上下兩層窗體是父子關(guān)系,它們各施其職,但是又沒有拖動(dòng)時(shí)留下的尾巴(窗口移動(dòng)的處理),我把這些功能都封裝在一起了,只需要簡(jiǎn)單地把你要在透明窗體上顯示的窗體傳過去以及透明處理的圖片就OK了。限于篇幅下面給繪制函數(shù)以及調(diào)用示例:
bool?DrawAlpha(Image*?pBgImg,?HWND?hWnd)
{
???if?(!::IsWindow(hWnd))?return?false;
???CWndDecorate?wndDecor(hWnd);
???//wndDecor.SetAlpha((255 * 20) / 100);
???//wndDecor.ShowOnDesk();
???RECT?rcWnd;
???::GetWindowRect(hWnd,?&rcWnd);
???int?nWid?=?rcWnd.right?-?rcWnd.left;
???int?nHei?=?rcWnd.bottom?-?rcWnd.top;
???HDC?hdcTemp?=?::GetWindowDC(hWnd);
???HDC?hdcMemory?=?::CreateCompatibleDC(hdcTemp);
???HBITMAP?hBitMap?=?CreateCompatibleBitmap(hdcTemp,?nWid,?nHei);
???SelectObject(hdcMemory,?hBitMap);
???HDC?hdcScreen?=?::GetWindowDC(hWnd);
???POINT?ptWinPos?=?{rcWnd.left,?rcWnd.top};
???Graphics?graph(hdcMemory);
???Point?points[]?=?{Point(0,?0),Point(nWid,?0),Point(0,?nHei)};
???graph.DrawImage(pBgImg,?points,3);
???SIZE?sizeWindow={nWid,?nHei};
???POINT?ptSrc={0,0};
???DWORD?dwExStyle?=?::GetWindowLong(hWnd,?GWL_EXSTYLE);
???if?((dwExStyle?&?0x80000)?!=?0x80000)
???{
????::SetWindowLong(hWnd,?GWL_EXSTYLE,?dwExStyle?^?0x80000);
???}
???CString?strTitle;
???m_alWnd.GetWindowText(strTitle);
???Gdiplus::Font???font(L"宋體",12,FontStyleBold,UnitPixel);
???StringFormat???strFormat;
???SolidBrush???brush(Color(0xff,0,0,0));
???graph.DrawString(strTitle,?-1,?&font,?PointF(32,30),&strFormat,?&brush);
???::UpdateLayeredWindow(hWnd,?hdcScreen,?&ptWinPos,?&sizeWindow,?hdcMemory,?&ptSrc,?0,?&m_alBlend,?ULW_ALPHA);
???graph.ReleaseHDC(hdcMemory);
???::ReleaseDC(hWnd,hdcScreen);
???hdcScreen?=?NULL;
???::ReleaseDC(hWnd,hdcTemp);
???hdcTemp?=?NULL;
???DeleteObject(hBitMap);
???DeleteDC(hdcMemory);
???hdcMemory?=?NULL;
???return?true;
}
調(diào)用示例:
CWndAlpha<CMainDlg>?wndAl;wndAl.InitAlpha(L"C:\\bg.png",?NULL,?rcMargin,?true);
m_pMainWnd?=?wndAl.GetMainWnd();
wndAl.DoModal();
很簡(jiǎn)單吧,就這么幾行代碼就可以實(shí)現(xiàn)背景透明而且又可以隨意編輯你自己的子控件了。下面是我生成的示例圖,大家欣賞一下了,歡迎留言討論,如果有需要的請(qǐng)留言!謝謝!
原文轉(zhuǎn)載自:http://rohna.w.blog.163.com/blog/static/145741652009023534832/
總結(jié)
以上是生活随笔為你收集整理的VC++调用UpdateLayeredWindow实现半透明窗体【转】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《认清C++语言》的random_shu
- 下一篇: ARP欺骗:先认识再防御