創(chuàng)建分層窗口,實(shí)現(xiàn)圖像漸變_第1頁
創(chuàng)建分層窗口,實(shí)現(xiàn)圖像漸變_第2頁
創(chuàng)建分層窗口,實(shí)現(xiàn)圖像漸變_第3頁
創(chuàng)建分層窗口,實(shí)現(xiàn)圖像漸變_第4頁
創(chuàng)建分層窗口,實(shí)現(xiàn)圖像漸變_第5頁
已閱讀5頁,還剩1頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、6/6創(chuàng)建分層窗口,實(shí)現(xiàn)圖像漸變有沒有方法創(chuàng)建一個半透明的窗口,并將該窗口上發(fā)生的所有鼠標(biāo)事件都傳遞到桌面或另一個應(yīng)用窗口處理? Scott Stringam當(dāng)然可以,并且相當(dāng)容易.你只要創(chuàng)建一個“分層窗口”即可。我寫了一個小程序叫 lws 來示范如何做。你可以下載源代碼。為了創(chuàng)建分層窗口,你需要擴(kuò)展式樣 W_EX_LAYEE,此外,為了能在透明窗口上進(jìn)行鼠標(biāo)點(diǎn)擊,你還需要 WSETRNARENT 擴(kuò)展式樣.在窗口創(chuàng)建之后,你可以同時設(shè)置兩個式樣,MFC 代碼如下: inCMainae:OnCrate(.。.) .。 diyStyx(0, WS_ELAYRED|WS_E_TRNSPAN); M

2、odifySle 和MdfyStylE 是專用的 MFC CWd方法,其作用顧名思義。如果你用 語言編寫,那么得調(diào)用 GtWindoLo(GWL_EXTE) 來獲取擴(kuò)展式樣,然后必須調(diào)用 StWindwLog(GW_XSYLE)來設(shè)置式樣。其效果與odifytyle(Ex)一樣。當(dāng)然,你也可以在創(chuàng)建窗口的時候使用此式樣。 一旦創(chuàng)建了分層窗0口,你便可以調(diào)用 SeLrWindowAtbut來設(shè)置透明度??捎玫姆謱哟翱趯傩灾皇?LWAAL,它就是用來調(diào)整透明度的,取值范圍從 0(完全透明)到 255(不透明)。要得到半透明的效果,可以這樣調(diào)用 SetLaeredWndottibus:/in CM

3、inFame::CeSetLaeredWinowAtributes(0,255 050, _APHA);這里我用乘法來表示一般公式;你可以僅用 128,因?yàn)槟鞘?5的一半(四舍五入)。你還可以用專門的顏色作為透明色。此時,你得用 WCOLORKEY作為屬性,在第一個參數(shù)中指定 CLOEF。Window 會讓所有像素顏色都呈透明。注意前面的代碼段假設(shè)你是從 Wd 派生對象中調(diào)用。如果用 C語言,你得使用 ::SLayeredindowtriutes,它帶有一個額外的參數(shù) HWN. 你可以用分層窗口來進(jìn)行動畫和其它轉(zhuǎn)換效果的處理;詳細(xì)細(xì)節(jié)請參考文檔中的“分層窗口部分。我正在寫一個幻燈顯示程序,該程

4、序要顯示JPEG圖像序列。我使用了 2002年三月刊專欄文章中的 CPictre 類來繪制圖像(參見:C+ QA: oYo Hav aLicene fr tht GI? PreSbcassWndow, EOFin MFC, andMre)。那個程序運(yùn)行得很好。但我現(xiàn)在想添加從某一張圖像到下一張圖像的漸變特性。我在網(wǎng)頁中用轉(zhuǎn)換效果可以做到。那么是否有辦法從程序代碼中實(shí)現(xiàn)圖像漸變特性?Bbline借助 COM 確實(shí)可以在 IE 中實(shí)現(xiàn)轉(zhuǎn)換效果。這些效果包括漸變、擦除,框入、框出、棒狀等等在iectX 中都支持。具體細(xì)節(jié)已經(jīng)超出了本文的討論范圍,所以我只能讓你去看相關(guān)文檔,其內(nèi)容參見“ternt D

5、eveloptSDK”中的“ng rnsfomsin C+”。你需要熟悉 COM 以及一些基本的 DrectX 知識,如:表層(suraces)和轉(zhuǎn)換(trnsfrms)(XSurace 和DXransform)。如果你僅僅是想實(shí)現(xiàn)圖像到圖像的漸變,我可以給你示范如何用 GDI+ 函數(shù)AlhBend 來實(shí)現(xiàn),微軟的老大們在 MFC 中已經(jīng)對之進(jìn)行了足夠友好的包裝,CDC::AlpaBlnd.lpBed 中的alh 是一個圖形學(xué)術(shù)語。它表示位圖使用3個字節(jié)來說明一個像素:每個字節(jié)分別表示 紅、綠、藍(lán)的值.由于 32位的 RD 有4個字節(jié),多余的這個字節(jié)常被用作“alpha hannel”,用于指

6、定像素的透明度.這個 alpha 值按照如下的公式來合并像素: R,G,blended = ?R,G,imag+ (1?? ,Bbakgrund當(dāng) a 為 0 時,你得到的是背景(圖像完全透明);當(dāng) alpha 為 1 時,你得到非透明圖像(完全不透明)。實(shí)際有透明效果的alh 值是一個 8位的字節(jié)表示的值,范圍從0-55,0 和 1 只是表示透明和非透明兩個極端。它們都是可用的 lh值,但大多數(shù)應(yīng)用程序不需要;多數(shù)應(yīng)用程序使用一個常量h 值來處理整個對象,如一幅圖像。例如,你可能想讓一幅特定的圖像以的透明度顯示。 Alphaled 函數(shù)類似老的 Bilt和 retc,但它僅僅實(shí)現(xiàn)漸變。發(fā)音為

7、“bli,這個術(shù)語是從古老的 PP10 BLT (塊轉(zhuǎn)移)指令派生而來,這個指令用于將大塊內(nèi)存從一個位置轉(zhuǎn)移到另一個位置。AlphBlen 的細(xì)節(jié)如 HYPERLINK” l”fig1” t ”_blank”Fgur 1所示,參數(shù)簡單明了,但是用Alphaled 來實(shí)現(xiàn)漸變很繁瑣,因?yàn)橹徽{(diào)用一次是不行的,必須重復(fù)調(diào)用來產(chǎn)生漸變效果,用一個定時器和 -55 之間不同的 apha值來控制.為了展示 AphaBlend 實(shí)際的工作過程,我編寫了一個程序 Bendw,該程序基于我的一個圖像查看程序,參見2002年月刊的專欄文章。BndVew 可以查看各種圖像文件(MP、J、IF 以及其它任何 DI+

8、支持的格式),但是當(dāng)你打開一幅新圖像時,原來的圖像會漸變成新圖像,如 Fg 所示。igr2 原圖像igure 漸變的圖像Figre 2 最終的圖像 為了將一幅圖像漸變?yōu)榱硪环?,你需要兩幅圖像,當(dāng)用戶打開一個新文檔時,MF 要做的第一件事情是銷毀舊的那個對象。所以你考慮在 MFC 加載新圖像前將舊圖像保存在某個地方。因?yàn)闈u變效果概念上屬于視圖處理(繪制圖像范疇),所以我把處理過程放在在視圖(Vw)中。也就是說在視圖中保存舊圖像.但視圖如何知道何時要保存圖像呢?你當(dāng)然得告訴它。幸運(yùn)的是,Dcumet具備一個方法,你可以用它來隨時通知視圖發(fā)生了什么。這個方法就是 Cocument::UpdateAV

9、s:/ i Doc: CitueDoc:OnOpenDcun(PCTSR lszPahName) pdateAllVies(NUL, PREOPENDO, ts); reurm_i.o(szathame);PREOPDO 是我自己的枚舉代碼,在 dc.中定義。當(dāng)你調(diào)用UpaeAllVws 時,將自己的“提示代碼”(一個32位整數(shù))隨一個指針傳遞到“提示對象”,該對象可以是任何COect派生的MFC 類。這里我傳的是文檔本身。注意我是在加載新圖像之前調(diào)用 pdtAllView,而舊圖像仍然有效。視圖處理通知消息保存該圖像:vodCPicreVie::OnUpate(Ciew* pSnde, PR

10、M lHint, Objt* pHint) (lHint=CPictureDoc:REPNDC) SaveDocImag(Cictuc)pHnt); 相同的 Upte 函數(shù)處理所有文檔的通知消息,所以你得檢查發(fā)送了哪個通知消息.一般情況下,提示代碼和提示對象背后的工作原理是文檔以提示方式提供信息,告訴視圖它需要更新屏幕的哪一部份。對于 ictrView 來說,如果提示代碼是 PREOPENDOC,那么 CPctureVe則調(diào)用一個輔助函數(shù) SaveocImae 來保存當(dāng)前圖像。 YELIN l fi3t _lank” gure 3 是SavecImage 的代碼,它創(chuàng)建一個位圖和內(nèi)存設(shè)備上下文

11、(DC),然后在內(nèi)存設(shè)備上下文中呈現(xiàn)圖像,在文檔摧毀原來圖像后有效地進(jìn)行漸變拷貝。 現(xiàn)在,當(dāng)用戶打開一個新文件,文檔通知視圖以及 OnUpae 處理例程以位圖形式保存圖像。漸變是怎么做出來的呢?它需要重復(fù)調(diào)用 Alphle 從老圖像漸變成新圖像.最顯而易見的方法是設(shè)置一個定時器。假設(shè)你想用三秒來漸變。為了用 100 步來實(shí)現(xiàn)漸變,你可以將定時期設(shè)置成 3000/10=30毫秒.但問題是ApaBlend實(shí)際上花了大量的時間來處理漸變。而且,所花的時間依賴于圖像的大小。較大的圖像漸變的時間較長。如果你使用定時器來做,最后得到的幻燈效果是較小的圖像更快,較大的圖像更慢-可能不是你想要的結(jié)果。 保持漸

12、變時間為常量的方法是固定持續(xù)時間-假設(shè)為3,0 毫秒然后根據(jù)實(shí)際逝去的時間計(jì)算 alha 值,假設(shè)第一次迭代發(fā)生在t+2毫秒。那么你可以用的 aha 值為20255/300 = 1 (取最近似的一個整數(shù))。然后根據(jù)當(dāng)前時間計(jì)算的 alpha 值立即進(jìn)行另一次漸變。如果逝去的時間超過一半,你最終的 pha 值是 5。通過用實(shí)際逝去的時間計(jì)算 alpha值,你可以保證漸變總是按時完成,但缺點(diǎn)是較大的圖像無法平滑地完成漸變,因?yàn)樗鼈兊牡^程更少,在 Aphalend中花的時間更多。 所有這些實(shí)現(xiàn)難易程度不一。HPRLIN l ig3 _lank” Fgure3 和 HPERLK lfg4_blnk

13、”Figur4是詳細(xì)代碼。當(dāng) CPctVie:OUde獲得 REOEDC 通知時,保存舊圖像之后,它將數(shù)據(jù)成員 m_SrtTe 置為當(dāng)前時鐘時間.時鐘時間是自該進(jìn)程啟動后的“時鐘嘀嗒”數(shù)。每秒嘀嗒數(shù)為 CLCK_ERC(通常為 1,00)。當(dāng) Onpdte 返回時,控制傳回到文檔和 MFC,它調(diào)用視圖的nnitialpdate 函數(shù),該函數(shù)調(diào)用 Onpdate,它重畫窗口。最后,os向你的視圖發(fā)送 M_PIT 消息,MFC 通過調(diào)用視圖的虛擬 ODaw 方法處理該消息。這是 的基本常識:在某個視圖中,繪圖在ODraw 進(jìn)行,而不是 OnPaint 中.CPicueVie是這樣繪制的:void

14、CPictureVew::OnDr(CC* C) CPicture pic =/get curetcture if (m_atTie) / doblend else / ndr as nol pp-Rndr(pDC,c); 我省略了漸變的細(xì)節(jié),主要突出 CPicturView如何用 m_iSarime 作為標(biāo)志來確定是否漸變。以下是實(shí)現(xiàn)漸變需要的基本步驟。創(chuàng)建一個內(nèi)存 DC;在該內(nèi)存DC中繪制位圖;計(jì)算漸變的 alha 值;在該內(nèi)存 中 AlphaBlnd 位圖;將結(jié)果拷貝到屏幕(Blt);在畫面以外的內(nèi)存 DC 中進(jìn)行漸變?nèi)缓罂截惖狡聊贿@一步是很重要的;否則用戶將會看到一閃而過的中間圖像。因

15、為AlphBlen 需要設(shè)備上下文,而不是 CPture 對象,首先繪制新圖像(所以我調(diào)用CPictre:ende ),然后在其上漸變舊圖像要方便一些。所以我用的aph 值與先從舊的圖像開始顯示所用的ap 值相反轉(zhuǎn)(1ala),換句話說,不是先從舊圖像開始,然后在上面以越來越多的效果漸變新圖像。我是先從新圖像開始,然后在上面以越來越少的效果漸變舊圖像.很聰明,不是嗎?網(wǎng)格效果處理方法一樣.以下是計(jì)算 lpahBled a值的關(guān)鍵代碼行:italpha (clock() m_itarTi)* 255) BLEDDRATN; lpha =max(25alph,0); 漸變之后,如果計(jì)算的apha

16、值大于 0,那么就需要處理更多的漸變效果。所以O(shè)nDr 調(diào)用Invaidat(FALE) 在不擦除背景的情況下而重畫窗口。Winows 發(fā)送另一個 WMPAIN 消息-只是要等到當(dāng)前消息處理完成.這樣一來(使WMANT 為有效消息),沒有阻塞.在漸變期間,用戶仍然能使用應(yīng)用程序。你可以在漸變期間改變窗口大小來證明這一點(diǎn)。CPicreView在新的窗口尺寸下保持漸變。 如果算出的 a值為 ,漸變完成。計(jì)時器停止。這時,OnDrw調(diào)用輔助函數(shù) StopBleding,該函數(shù)刪除舊圖像并將_iStartTime 設(shè)置為 0,暗示 OnDrw 停止?jié)u變?,F(xiàn)在當(dāng)視圖需要繪制時,nDr通過調(diào)用 Pite:Rndr 進(jìn)行常規(guī)繪制,直接呈現(xiàn)新圖像,不發(fā)生漸變. 如果你使用活動模板庫(AT)Iag 類來保存圖像(而不是用 Picture,這是我很久以前實(shí)現(xiàn)的一個類,當(dāng)時 Image 還未出現(xiàn)),你可以用 CImge::AlphaBlend,不過用它來進(jìn)行漸變會產(chǎn)生一些開銷。如果你使用微軟的.NET框架,你可以用 Grahic.Drwma重載方法函數(shù)之一來進(jìn)行

溫馨提示

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

評論

0/150

提交評論