VC++UpdateLayeredWindow實(shí)現(xiàn)半透明窗體_第1頁
VC++UpdateLayeredWindow實(shí)現(xiàn)半透明窗體_第2頁
VC++UpdateLayeredWindow實(shí)現(xiàn)半透明窗體_第3頁
VC++UpdateLayeredWindow實(shí)現(xiàn)半透明窗體_第4頁
VC++UpdateLayeredWindow實(shí)現(xiàn)半透明窗體_第5頁
已閱讀5頁,還剩3頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

最近看了桌面天氣秀這款小軟件其界面精致漂亮而且可以透明顯示還有個(gè)特別有趣的功能就是能讓窗體固定在桌面上并且鼠標(biāo)可以“穿透”而窗體不受任何影響這就是帶著些許神秘的“有影無形”的功能。事實(shí)上要實(shí)現(xiàn)這種“有影無形”的功能很簡單我相信聰明的您一定很快會(huì)想到怎么做。幾句代碼就可以搞定給你點(diǎn)提示只有在2000以上的Win操作系統(tǒng)才支持當(dāng)然如果你有足夠的時(shí)間可以完全可以在98上實(shí)現(xiàn)。那么今天我們主要討論一下窗體的半透明顯示其實(shí)如果僅僅要實(shí)現(xià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)。對于小軟件來說效果還可以。事實(shí)上今天我實(shí)現(xiàn)的也和這個(gè)思路差不多不過我這個(gè)上下兩層窗體是父子關(guān)系它們各施其職但是又沒有拖動(dòng)時(shí)留下的尾巴窗口移動(dòng)的處理我把這些功能都封裝在一起了只需要簡單地把你要在透明窗體上顯示的窗體傳過去以及透明處理的圖片就OK了。限于篇幅下面給繪制函數(shù)以及調(diào)用示例boolDrawAlphalmagepBglmgHWNDhWndif::IsWindowhWndreturnfalseCWndDecoratewndDecorhWnd//wndDecor.SetAlpha25520/100//wndDecor.ShowOnDeskRECTrcWnd::GetWindowRecthWndrcWndintnWidrcWnd.right-rcWnd.leftintnHeircWnd.bottom-rcWnd.topHDChdcTemp::GetWindowDChWndHDChdcMemory::CreateCompatibleDChdcTempHBITMAPhBitMapCreateCompatibleBitmaphdcTempnWidnHeiSelectObjecthdcMemoryhBitMapHDChdcScreen::GetWindowDChWndPOINTptWinPosrcWnd.leftrcWnd.topGraphicsgraphhdcMemoryPointpointsPoint00PointnWid0Point0nHeigraph.DrawImagepBgImgpoints3SIZEsizeWindownWidnHeiPOINTptSrc00DWORDdwExStyle::GetWindowLonghWndGWL_EXSTYLEifdwExStyle0x800000x80000::SetWindowLonghWndGWL_EXSTYLEdwExStyle0x80000CStringstrTitlem_alWnd.GetWindowTextstrTitleGdiplus::FontfontL宋體12FontStyleBoldUnitPixelStringFormatstrFormatSolidBrushbrushColor0xff000graph.DrawStringstrTitle-1fontPointF3230strFormatbrush::UpdateLayeredWindowhWndhdcScreenptWinPossizeWindowhdcMemoryptSrc0m_alBlendULW_ALPHAgraph.ReleaseHDChdcMemory::ReleaseDChWndhdcScreenhdcScreenNULL::ReleaseDChWndhdcTemphdcTempNULLDeleteObjecthBitMapDeleteDChdcMemoryhdcMemoryNULLreturntrue調(diào)用示例:CWndAlphawndAlwndAl.InitAlphaLC:bg.pngNULLrcMargintruem_pMainWndwndAl.GetMainWndwndAl.DoModal本篇演示實(shí)現(xiàn)仿QQ界面的中間客戶區(qū)。QQ是可以調(diào)整界面透明度的但是調(diào)整了透明度卻連中間客戶區(qū)也變得半透明了??蛻魠^(qū)畢竟是軟件最重要的部分是要與用戶交互的透明了就影響操作了因此這里的客戶區(qū)不學(xué)QQ始終不透明。要實(shí)現(xiàn)不透明控件只能創(chuàng)建一個(gè)彈出窗口遮住主界面的客戶區(qū)域然后設(shè)定與主界面連動(dòng)即始終跟著主窗口移動(dòng)及調(diào)整尺寸。這個(gè)方法并不是很好但卻幾乎是唯一的方法。為什么說幾乎是唯一的方法呢的確存在著另外的解決方案但是這個(gè)方法太麻煩了在此討論一下這個(gè)方法。實(shí)現(xiàn)半透明窗體不透明控件應(yīng)該有不少朋友碰到過這個(gè)問題為什么設(shè)定了窗口透明窗口上的子窗口及控件也變得透明了這個(gè)是受系統(tǒng)限制的創(chuàng)建一個(gè)窗口這個(gè)窗口區(qū)域就相當(dāng)于一塊畫布最終系統(tǒng)要在這塊畫布上繪制出窗口標(biāo)題客戶區(qū)控件等等而窗口和控件繪制時(shí)的GetDCBeginPaint等不過是獲取到了跟自己相關(guān)的這塊畫布的一部分在限定的區(qū)域內(nèi)繪制最終是畫到這塊畫布上系統(tǒng)最后顯示窗口就是在桌面上顯示這塊畫布透明度也是認(rèn)這塊畫布因此上面的子窗口及控件也一起變得透明了。另建一個(gè)彈出式窗口相當(dāng)于創(chuàng)建了另一塊畫布就不受主窗口的透明度限制。知道了原因現(xiàn)在來討論如何不創(chuàng)建彈出式窗口實(shí)現(xiàn)不透明控件。透明窗口有兩種實(shí)現(xiàn)方法一種是調(diào)用SetLayeredWindowAttributes設(shè)定統(tǒng)一的窗口透明度既整個(gè)窗口采用同樣的透明度QQ2009和這里的演示程序采用的就是這個(gè)方法這個(gè)方法不創(chuàng)建彈出窗口是無法實(shí)現(xiàn)不透明控件的因?yàn)橄胍丶煌该骶捅仨氃诳丶^(qū)域采用不同的透明度SetLayeredWindowAttributes無法做到只能通過調(diào)用另一個(gè)函數(shù)UpdateLayeredWindow來實(shí)現(xiàn)可指定不同區(qū)域不同透明度的窗口API代碼大致如下C/CcodeHDChdchMemDCRECTrcGetWindowRecthWndrcPOINTptSrc00POINTptWinPosrc.leftrc.topSIZEszWinrc.right-rc.leftrc.bottom-rc.topBLENDFUNCTIONstBlendAC_SRC_OVER0255AC_SRC_ALPHAhdcGetWindowDCm_hWndhMemDCCreateCompatibleDChdcSelectObjecthMemDChbmp//hbmp為整個(gè)窗口貼圖UpdateLayeredWindowhWndhdcptWinPosszWinhMemDCptSrc0stBlendULW_ALPHA最關(guān)鍵的部分就是SelectObjecthMemDChbmp實(shí)現(xiàn)不同區(qū)域不同透明度全在這個(gè)選入設(shè)備的hbmp的圖象數(shù)據(jù)Windows的32位色圖像的像素?cái)?shù)據(jù)是COLORREF類型0x00bbggrr格式關(guān)鍵就在最高位的字節(jié)0x00UpdateLayeredWindow是認(rèn)這個(gè)字節(jié)來設(shè)定透明度0x00為全透明0xFF為不透明這個(gè)字節(jié)的集合有個(gè)專門名稱叫ALPHA通道。設(shè)定hbmp圖象每一個(gè)像素的這個(gè)最高位字節(jié)數(shù)據(jù)就可以實(shí)現(xiàn)像素級別的透明度。網(wǎng)上應(yīng)該能搜到大把利用PNG圖片實(shí)現(xiàn)半透明窗口的例子因?yàn)镻NG圖片是可以帶ALPHA通道的解碼PNG圖片自然就有了ALPHA通道即設(shè)定了這個(gè)最高位字節(jié)就不需要用代碼來一個(gè)個(gè)像素指定透明度了。實(shí)現(xiàn)這樣的半透明窗口是這樣一個(gè)過程首先要用雙緩沖創(chuàng)建與窗口相同大小的內(nèi)存圖象然后在這個(gè)內(nèi)存圖象上繪制窗口的各個(gè)部分標(biāo)題欄背景等等一般是用PNG圖片實(shí)現(xiàn)這樣就不用逐個(gè)像素指定透明度了最后把這個(gè)內(nèi)存圖象繪制到窗口。想實(shí)現(xiàn)不透明控件就要把控件區(qū)域的ALPHA通道值設(shè)為0xFF然而不幸的是幾乎所有的GDI操作除了TransparentBlt那些最常用的BitBltTextOutFillRect等等都是忽略ALPHA通道的繪制過后這些區(qū)域的ALPHA值都變成了0即全透明。因此想要實(shí)現(xiàn)不透明控件就要實(shí)現(xiàn)所有控件的自繪使控件繪制到內(nèi)存圖象上常規(guī)GDI操作過后再設(shè)定這些區(qū)域的ALPHA值為0xFF。是不是頭大了這個(gè)方法太麻煩了而且僅僅是為了在半透明窗口上實(shí)現(xiàn)不透明控件這樣一個(gè)效果代價(jià)太大因此并不實(shí)用。QQ2009所用的DirectUI應(yīng)該能很容易實(shí)現(xiàn)這個(gè)效果但是并沒實(shí)現(xiàn)估計(jì)跟執(zhí)行效率有關(guān)因?yàn)檫@種像素級透明的程序在繪制時(shí)很耗時(shí)調(diào)整窗口大小時(shí)可能會(huì)有延遲現(xiàn)象在速度慢一點(diǎn)的機(jī)器上更是明顯。現(xiàn)在來講模仿QQ的客戶區(qū)有很多種方法這里選用相對比較簡單的方法有更好的解決方案歡迎留言討論。首先是上部的搜索欄當(dāng)然是子類化EDIT控件進(jìn)行自繪處理WM_NCCALCSIZE消息加大其非客戶區(qū)畫個(gè)外方內(nèi)圓的邊框。在編輯框輸入內(nèi)容后會(huì)有個(gè)自繪的下拉列表出來這個(gè)其實(shí)跟點(diǎn)了“更改外觀”按鈕后出現(xiàn)的界面調(diào)色對話框是一樣的不過是把那對話框改一下表現(xiàn)形式然后搬到編輯框下面就不演示了還有右邊會(huì)出現(xiàn)清除和執(zhí)行按鈕又是貼圖屬于非典型編輯框功能也不演示了有興趣的可以自己完成。然后是側(cè)邊欄看起來是TAB控件的功能其實(shí)用工具欄更簡單一些添加TBSTYLE_BUTTONTBSTYLE_CHECKGROUP類型的按鈕就跟TAB控件的效果差不多。怎么繪制前面一篇已經(jīng)講過了收起和展開只是隱藏和顯示而已。最重要的好友列表部分這個(gè)要用到TAB控件了調(diào)整窗口尺寸時(shí)3個(gè)標(biāo)簽的寬度是跟著變的這個(gè)需要?jiǎng)?chuàng)建TAB控件時(shí)指定TCS_FIXEDWIDTH窗口類型子類化后在WM_SIZE消息里發(fā)送TCM_SETITEMSIZE消息調(diào)整標(biāo)簽的寬度。標(biāo)簽需要自繪鼠標(biāo)點(diǎn)擊上面的下拉箭頭會(huì)彈出菜單這個(gè)需要在WM_LBUTTONDOWN消息里判斷一下子類化后其實(shí)想干什么都行只是麻煩一點(diǎn)罷了:點(diǎn)擊標(biāo)簽后下面列表子窗口的滑動(dòng)效果切換也很簡單把兩個(gè)窗口并排然后連續(xù)移動(dòng)就可以不過因?yàn)樗⑿碌年P(guān)系可能會(huì)有重影如果想要更好的效果應(yīng)該是把子窗口截圖然后用雙緩沖繪制出滑動(dòng)效果這里就簡單一點(diǎn)不用這個(gè)方法了。好友列表群列表和最近聯(lián)系人列表是用ListBox控件實(shí)現(xiàn)本來不需要子類化不過ListBox不支持鼠標(biāo)移到選項(xiàng)上的高亮功能因此還是實(shí)現(xiàn)了子類化處理WM_MOUSEMOVE消息進(jìn)行判斷。好友列表里面是有“我的好友”“陌生人”“黑名單”等分類的這些分類選項(xiàng)的高度與用戶項(xiàng)的高度不同因此創(chuàng)建控件時(shí)需要指定LBS_OWNERDRAWVARIABLE類型還有ListBox控件默認(rèn)是會(huì)計(jì)算控件高度并調(diào)整尺寸適應(yīng)列表項(xiàng)的高度不會(huì)在客戶區(qū)顯示不完整的列表選項(xiàng)這個(gè)功能我們不需要因此還需指定LBS_NOINTEGRALHEIGHT類型不自動(dòng)調(diào)整高度再指定一下LBS_HASSTRINGSLBS_NOTIFYWS_VSCROLL常規(guī)類型然后就是在父窗口的WM_DRAWITEM消息里進(jìn)行列表選項(xiàng)的自繪了。加入選項(xiàng)時(shí)需要指定選項(xiàng)的高度為了區(qū)分分類選項(xiàng)和用戶信息選項(xiàng)通過發(fā)送LB_SETITE

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論