




下載本文檔
版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、 最近看了桌面天氣秀這款小軟件,其界面精致漂亮,而且可以透明顯示,還有個(gè)特別有趣的功能就是能讓窗體固定在桌面上并且鼠標(biāo)可以“穿透”而窗體不受任何影響,這就是帶著些許神秘的“有影無(wú)形”的功能。 事實(shí)上要實(shí)現(xiàn)這種“有影無(wú)形”的功能,很簡(jiǎn)單,我相信聰明的您一定很快會(huì)想到怎么做。幾句代碼就可以搞定,給你點(diǎn)提示,只有在2000以上的Win操作系 統(tǒng)才支持(當(dāng)然如果你有足夠的時(shí)間可以完全可以在98上實(shí)現(xiàn))。那么今天我們主要討論一下窗體的半透明顯示,其實(shí),如果僅僅要實(shí)現(xiàn)窗體的半透明顯示,很簡(jiǎn) 單,Upd
2、ateLayeredWindow調(diào)用就可以了,網(wǎng)上去搜一下幾乎都是貼的這個(gè)函數(shù)怎么怎么實(shí)現(xiàn)窗體的半透明,在往下就沒(méi)了,比如此函數(shù)有個(gè)缺 陷,就是經(jīng)過(guò)此函數(shù)處理過(guò)的窗體,其上面的控件都透明了。諸如此類(lèi)的問(wèn)題至少到現(xiàn)在我在網(wǎng)上沒(méi)找到一個(gè)讓人感覺(jué)滿(mǎn)意的解決方案。 記得在一個(gè)所謂專(zhuān)業(yè)的C#網(wǎng)站上看到一篇題為“XP下透明窗體的完美實(shí)現(xiàn)”,當(dāng)時(shí)看了還真高興一陣子,可是把代碼下下來(lái)一看,又是被忽悠了,里面就調(diào)用了 UpdateLayeredWindow函數(shù)實(shí)現(xiàn)透明然后加個(gè)旋轉(zhuǎn)顯示,這樣子就算完美了,我暈!這個(gè)函數(shù)查查資料誰(shuí)不會(huì)??磥?lái)還是
3、自己動(dòng)手,不知道有心 的朋友注意到?jīng)]有,在桌面天氣秀里,打開(kāi)設(shè)置,然后快速拖動(dòng),會(huì)看到上面的窗體明顯脫離,這就是多層窗口留下的尾巴。下面的透明窗體是背景,上面的窗體承 載控件。在拖動(dòng)下層窗體的時(shí)候讓上層窗體跟著一起動(dòng)。對(duì)于小軟件來(lái)說(shuō),效果還可以。事實(shí)上,今天我實(shí)現(xiàn)的也和這個(gè)思路差不多,不過(guò)我這個(gè)上下兩層窗體是父 子關(guān)系,它們各施其職,但是又沒(méi)有拖動(dòng)時(shí)留下的尾巴(窗口移動(dòng)的處理),我把這些功能都封裝在一起了,只需要簡(jiǎn)單地把你要在透明窗體上顯示的窗體傳過(guò)去以 及透明處理的圖片就OK了。限于篇幅下面給繪制函數(shù)以及調(diào)用示例:bool DrawAlpha(Image* pBgImg, HWND hWnd
4、) 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;
5、160;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 = :GetWindowD
6、C(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 dwE
7、xStyle = :GetWindowLong(hWnd, GWL_EXSTYLE); if (dwExStyle & 0x80000) != 0x80000) :SetWindowLong(hWnd, GWL_EXSTYLE, dwExStyle 0x80000); CString strTitle; m_alWnd.GetWindowText(strTitle); Gdiplus:Font
8、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
9、, &ptWinPos, &sizeWindow, hdcMemory, &ptSrc, 0, &m_alBlend, ULW_ALPHA); graph.ReleaseHDC(hdcMemory); :ReleaseDC(hWnd,hdcScreen); hdcScreen = NULL; :ReleaseDC(hWnd,hdcTemp); hdcTemp = NULL; DeleteObject(hBitMap); &
10、#160;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();本篇演示實(shí)現(xiàn)仿QQ界面的中間客戶(hù)區(qū)。QQ是可以調(diào)整界面透明度的,但是調(diào)整了透明度卻連中間客戶(hù)區(qū)也變得半透明了??蛻?hù)區(qū)畢竟是軟件最重要的部分,
11、是要 與用戶(hù)交互的,透明了就影響操作了,因此這里的客戶(hù)區(qū)不學(xué)QQ,始終不透明。要實(shí)現(xiàn)不透明控件,只能創(chuàng)建一個(gè)彈出窗口,遮住主界面的客戶(hù)區(qū)域,然后設(shè)定與 主界面連動(dòng),即始終跟著主窗口移動(dòng)及調(diào)整尺寸。這個(gè)方法并不是很好,但卻幾乎是唯一的方法。為什么說(shuō)幾乎是唯一的方法呢?的確存在著另外的解決方案,但是 這個(gè)方法太麻煩了,在此討論一下這個(gè)方法。 fV>d_6Lf ph5i2U0 實(shí) 現(xiàn)半透明窗體,不透明控件,應(yīng)該有不少朋友碰到過(guò)這個(gè)問(wèn)題:為什么設(shè)定了窗口透明,窗口上的子窗口及控件也變得透明了?這個(gè)是受系統(tǒng)限制的,創(chuàng)建一個(gè)窗 口,這個(gè)窗口區(qū)域就相當(dāng)于一塊畫(huà)布,最終系統(tǒng)要在這
12、塊畫(huà)布上繪制出窗口標(biāo)題,客戶(hù)區(qū),控件等等,而窗口和控件繪制時(shí)的GetDC,BeginPaint等 不過(guò)是獲取到了跟自己相關(guān)的這塊畫(huà)布的一部分,在限定的區(qū)域內(nèi)繪制,最終是畫(huà)到這塊畫(huà)布上,系統(tǒng)最后顯示窗口就是在桌面上顯示這塊畫(huà)布,透明度也是認(rèn)這塊 畫(huà)布,因此上面的子窗口及控件也一起變得透明了。另建一個(gè)彈出式窗口,相當(dāng)于創(chuàng)建了另一塊畫(huà)布,就不受主窗口的透明度限制。 dX/7n= <!> nA 知 道了原因,現(xiàn)在來(lái)討論如何不創(chuàng)建彈出式窗口,實(shí)現(xiàn)不透明控件。透明窗口有兩種實(shí)現(xiàn)方法,一種是調(diào)用 SetLayeredWindowAttributes,設(shè)定統(tǒng)一的窗口透明度,
13、既整個(gè)窗口采用同樣的透明度,QQ2009和這里的演示程序采用的就是這 個(gè)方法,這個(gè)方法不創(chuàng)建彈出窗口是無(wú)法實(shí)現(xiàn)不透明控件的,因?yàn)橄胍丶煌该?,就必須在控件區(qū)域采用不同的透明 度,SetLayeredWindowAttributes無(wú)法做到,只能通過(guò)調(diào)用另一個(gè)函數(shù)UpdateLayeredWindow來(lái)實(shí)現(xiàn)可指定不同區(qū) 域不同透明度的窗口,API代碼大致如下: 37kFbRx Ny7*MZ- C/C+ code HDC hdc,hMemDC; TSewq4K RECT rc; 0ex.S_Oj4 &
14、#160; IXtG 36O GetWindowRect(hWnd,&rc); M;<!C%K> uFSU|SDd. POINT ptSrc = 0,0; _x(hlHFk POINT ptWinPos = rc.left,rc.top; GgY8>u SIZE szWin = rc.right-rc.left,rc.bottom-rc.top;
15、0; !0?o3,of- BLENDFUNCTION stBlend = AC_SRC_OVER, 0,255,AC_SRC_ALPHA; U=yvi8 !gWxVGv hdc = GetWindowDC(m_hWnd); &Iy58 hMemDC = CreateCompatibleDC(hdc); OQP;5 #K SelectObject(hMemDC,hbmp);
16、 /hbmp為整個(gè)窗口貼圖 aXj UDu7 UpdateLayeredWindow(hWnd,hdc,&ptWinPos,&szWin,hMemDC,&ptSrc,0,&stBlend,ULW_ALPHA); gNP1UH4m 8%B_nVc ,zxRDI 最 關(guān)鍵的部分就是SelectObject(hMemDC,hbmp);實(shí)現(xiàn)不同區(qū)域不同透明度,全在這個(gè)選入設(shè)備的hbmp的圖象數(shù)據(jù),Wind
17、ows的 32位色圖像的像素?cái)?shù)據(jù)是COLORREF類(lèi)型,0x00bbggrr格式,關(guān)鍵就在最高位的字節(jié)0x00,UpdateLayeredWindow是認(rèn) 這個(gè)字節(jié)來(lái)設(shè)定透明度,0x00為全透明,0xFF為不透明,這個(gè)字節(jié)的集合有個(gè)專(zhuān)門(mén)名稱(chēng)叫ALPHA通道。設(shè)定hbmp圖象每一個(gè)像素的這個(gè)最高位字節(jié) 數(shù)據(jù),就可以實(shí)現(xiàn)像素級(jí)別的透明度。網(wǎng)上應(yīng)該能搜到大把利用PNG圖片實(shí)現(xiàn)半透明窗口的例子,因?yàn)镻NG圖片是可以帶ALPHA通道的,解碼PNG圖片, 自然就有了ALPHA通道,即設(shè)定了這個(gè)最高位字節(jié),就不需要用代碼來(lái)一個(gè)個(gè)像素指定透明度了。實(shí)現(xiàn)這樣的半透明窗口是這樣一個(gè)過(guò)程:首先要用雙緩沖,創(chuàng) 建與窗
18、口相同大小的內(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,那些最常用的BitBlt,TextOut,FillRect等等都是忽略ALPHA通道的,繪制過(guò)后這些區(qū)域的 ALPHA值都變成了0,即全透明。因此想要實(shí)現(xiàn)不透明控件,就要實(shí)現(xiàn)所有控件的自繪,使控件繪制到內(nèi)存圖象上,常規(guī)GDI操作過(guò)后再設(shè)定這些區(qū)域的 ALPHA值為0xFF。是不是頭大了?這個(gè)方法
19、太麻煩了,而且僅僅是為了在半透明窗口上實(shí)現(xiàn)不透明控件這樣一個(gè)效果,代價(jià)太大,因此并不實(shí)用。 QQ2009所用的DirectUI應(yīng)該能很容易實(shí)現(xiàn)這個(gè)效果,但是并沒(méi)實(shí)現(xiàn),估計(jì)跟執(zhí)行效率有關(guān),因?yàn)檫@種像素級(jí)透明的程序在繪制時(shí)很耗時(shí),調(diào)整窗口大 小時(shí)可能會(huì)有延遲現(xiàn)象,在速度慢一點(diǎn)的機(jī)器上更是明顯。 C8|Ls(4Ck *1>)P8# 現(xiàn) 在來(lái)講模仿QQ的客戶(hù)區(qū),有很多種方法,這里選用相對(duì)比較簡(jiǎn)單的方法,有更好的解決方案歡迎留言討論。首先是上部的搜索欄,當(dāng)然是子類(lèi)化EDIT控件進(jìn)行 自繪,處理WM_NCCALCSIZE消息加大其非客戶(hù)區(qū),畫(huà)個(gè)外方內(nèi)圓的邊框。在編輯框輸入內(nèi)容
20、后會(huì)有個(gè)自繪的下拉列表出來(lái),這個(gè)其實(shí)跟點(diǎn)了“更改外 觀(guān)”按鈕后出現(xiàn)的界面調(diào)色對(duì)話(huà)框是一樣的,不過(guò)是把那對(duì)話(huà)框改一下表現(xiàn)形式,然后搬到編輯框下面,就不演示了,還有右邊會(huì)出現(xiàn)清除和執(zhí)行按鈕,又是貼圖, 屬于非典型編輯框功能,也不演示了,有興趣的可以自己完成。 VI4mEq,V Jkj7ty.J 然 后是側(cè)邊欄,看起來(lái)是TAB控件的功能,其實(shí)用工具欄更簡(jiǎn)單一些,添加TBSTYLE_BUTTON|TBSTYLE_CHECKGROUP類(lèi)型的按鈕就 跟TAB控件的效果差不多。怎么繪制前面一篇已經(jīng)講過(guò)了,收起和展開(kāi)只是隱藏和顯示而已。最重要的好友列表部分,這個(gè)要用到TAB控件了,調(diào)整
21、窗口尺寸時(shí) 3個(gè)標(biāo)簽的寬度是跟著變的,這個(gè)需要?jiǎng)?chuàng)建TAB控件時(shí)指定TCS_FIXEDWIDTH窗口類(lèi)型,子類(lèi)化后在WM_SIZE消息里發(fā)送 TCM_SETITEMSIZE消息調(diào)整標(biāo)簽的寬度。標(biāo)簽需要自繪,鼠標(biāo)點(diǎn)擊上面的下拉箭頭會(huì)彈出菜單,這個(gè)需要在WM_LBUTTONDOWN消息里判 斷一下,子類(lèi)化后其實(shí)想干什么都行,只是麻煩一點(diǎn)罷了:)點(diǎn)擊標(biāo)簽后下面列表子窗口的滑動(dòng)效果切換也很簡(jiǎn)單,把兩個(gè)窗口并排然后連續(xù)移動(dòng)就可以,不過(guò)因?yàn)?刷新的關(guān)系,可能會(huì)有重影,如果想要更好的效果,應(yīng)該是把子窗口截圖,然后用雙緩沖繪制出滑動(dòng)效果,這里就簡(jiǎn)單一點(diǎn),不用這個(gè)方法了。 nyHt/T *| hd/j 好 友列表,群列表和最近聯(lián)系人列表是用ListBox
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 易錯(cuò)點(diǎn)20 中國(guó)精神-備戰(zhàn)2021年中考道德與法治一輪復(fù)習(xí)易錯(cuò)題
- 【鄭州】2025年中國(guó)(河南)自由貿(mào)易試驗(yàn)區(qū)鄭州片區(qū)管委會(huì)招聘10人筆試歷年典型考題及考點(diǎn)剖析附帶答案詳解
- 無(wú)紙化測(cè)試活動(dòng)方案
- 文聯(lián)年會(huì)活動(dòng)方案
- 春季防火活動(dòng)方案
- 新年活動(dòng)放煙花活動(dòng)方案
- 新沂麻辣燙活動(dòng)方案
- 新公司揭牌策劃方案
- 新會(huì)文化嘉年華活動(dòng)方案
- 春季捐衣活動(dòng)方案
- Unit 3 Same or Different?Section A 課件 人教版英語(yǔ)八年級(jí)上冊(cè)
- 2024年中級(jí)人民法院勞動(dòng)審判輔助人員招聘考試筆試試題(含答案)
- 2025年廣東省高考語(yǔ)文試卷(含標(biāo)準(zhǔn)答案)
- 中國(guó)熱射病診斷與治療指南(2025版)
- 公共藝術(shù)裝置項(xiàng)目管理流程
- 2025年下半年佛山市南海區(qū)建筑工程質(zhì)量檢測(cè)站招考編外工作人員易考易錯(cuò)模擬試題(共500題)試卷后附參考答案
- GB/T 45610-2025煤矸石回填塌陷區(qū)復(fù)墾技術(shù)規(guī)程
- 中醫(yī)基礎(chǔ)執(zhí)業(yè)醫(yī)師考試試題及答案
- 2025-2030年中國(guó)寫(xiě)字樓行業(yè)市場(chǎng)深度調(diào)研及前景趨勢(shì)與投資研究報(bào)告
- 人教版(2024)七年級(jí)下冊(cè)英語(yǔ)Unit 8 Once upon a Time單元集體備課教案(共5課時(shí))
- 診所托管合同協(xié)議
評(píng)論
0/150
提交評(píng)論