市場營銷VC多媒體編程_第1頁
市場營銷VC多媒體編程_第2頁
市場營銷VC多媒體編程_第3頁
市場營銷VC多媒體編程_第4頁
市場營銷VC多媒體編程_第5頁
已閱讀5頁,還剩72頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、 HYPERLINK /nicolas16/article/details/一五88688 置頂 VC多媒體編程分類: HYPERLINK /nicolas16/article/category/208295 軟件開發(fā) 2007-04-28 14:09 14021人閱讀 HYPERLINK l comments 評論(8) HYPERLINK javascript:void(0); o 收藏 收藏 HYPERLINK l report o 舉報 舉報 HYPERLINK /tag/details.html?tag=%e7%bc%96%e7%a8%8b 編程 HYPERLINK /tag/det

2、ails.html?tag=null null HYPERLINK /tag/details.html?tag=microsoft microsoft HYPERLINK /tag/details.html?tag=windows windows HYPERLINK /tag/details.html?tag=gdi%2b gdi+ HYPERLINK /tag/details.html?tag=%e6%96%87%e6%a1%a3 文檔-VC多媒體編程-Visual C+中基于多文檔視窗模型的重疊圖象拼接技術(shù)摘要圖象拼接是在全景視頻系統(tǒng)、地理信息系統(tǒng)等應(yīng)用中經(jīng)常遇到的一個問題,本文基于網(wǎng)格匹

3、配的方法對邊界部分有重疊的圖象提出了一種行之有效的對準(zhǔn)算法,并通過平滑因子對圖象實現(xiàn)了無縫拼接。并應(yīng)用文檔視窗模型實現(xiàn)了該算法,并完成了位圖文件的顯示、存儲等操作,具有一定的普遍意義。關(guān)鍵詞:圖象拼接,算法,重疊圖象,文檔視窗,位圖文件,圖象顯示文章正文一、多文檔視窗模型概述MFC的AppWizard可以生成三種類型的應(yīng)用程序:基于對話框的應(yīng)用、單文檔應(yīng)用(SDI)和多文檔應(yīng)用(MDI)。三種應(yīng)用中,以多文檔應(yīng)用(MDI)最為復(fù)雜,其功能也最強大。當(dāng)我們用AppWizard生成一個多文檔應(yīng)用時,系統(tǒng)由CMultiDocTemplate自動生成了一個從Cdocument類繼承的文檔類,一個從Cv

4、iew類繼承的視窗類,一個從CMDIChildWnd類繼承的框架類。當(dāng)我們每次建立一個新的文檔時,程序根據(jù)文檔模板生成一個新實例,這些我們均可不用關(guān)心AppWizard已經(jīng)自動生成了代碼。但如果我們要在程序中使用多個不同的文檔類時,則需自己建立文檔模板并控制文檔實例的建立。假設(shè)我們要向一基于多文檔的工程MDI中增加一Test的文檔。具體步驟如下:1、用Clazard建立一個框架類CTestFrame基類選CMDIChildWnd。2、用Clazard建立一個文檔類CTestDoc基類選CDocument。3、用Clazard建立一個文檔類CTestView基類選CView。4、將三個類的頭文件

5、加入應(yīng)用類CMDIApp中。5、創(chuàng)建新文檔模板,在CMDIApp:InitInstance()函數(shù)中加入如下代碼 CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_TESTTYPE, RUNTIME_CLASS(CTestDoc), RUNTIME_CLASS(CTestFrame), RUNTIME_CLASS(CTestView); AddDocTemplate(pDocTemplate); 6、定義一菜單項ID號為ID_NEWTEST,利用Clazard將其處理函數(shù)加入應(yīng)用類(或主框架類)

6、,在其處理函數(shù)CMDIApp:OnNewtest()函數(shù)中加入如下代碼POSITION curTemplatePos = GetFirstDocTemplatePosition(); while(curTemplatePos != NULL) /取下一個文檔模板指針 CDocTemplate* curTemplate =GetNextDocTemplate(curTemplatePos); CString str; curTemplate-GetDocString(str, CDocTemplate:docName); /取文檔名稱 if(str = _T(Test) /判斷當(dāng)前文檔文檔是否T

7、est類 curTemplate-OpenDocumentFile(NULL); /創(chuàng)建新的文檔實例 return; 這樣我們就建立了一個新的文檔類。注意在5中創(chuàng)建文檔模板時我們用到了一文檔類型資源IDR_TESTTYPE,該資源ID在資源文件中定義如下(未包括圖標(biāo)和菜單的定義):STRINGTABLE PRELOAD DISCARDABLE BEGIN . IDR_TESTTYPE/nTest/nTest/n/n/nMDI.Document/nTest Document END 文檔類型標(biāo)識包括七個子串,包括窗口標(biāo)題、文檔名稱、文件擴展名等。在6中curTemplate-GetDocStri

8、ng(str, CDocTemplate:docName);取的就是第二個子串,文檔名稱。文檔建立之后我們就可以對其進行操作了。當(dāng)然文檔類和視窗類,文檔類和主窗口類,以及不同文檔類之間進行通信也是較為復(fù)雜的,并非幾句話就能說清楚,如不熟悉文檔視窗的讀者請參看其它有關(guān)資料。二、重疊圖象拼接技術(shù)1算法思想在實現(xiàn)全景視頻(Panoramic Video)系統(tǒng)、地理信息系統(tǒng)(GIS)及其它一些應(yīng)用的過程中,我們通常會碰到這樣的一個問題,就是要把幾幅小的圖象拼接成一幅大的圖象。為了能讓計算機自動對準(zhǔn)圖象我們要求待拼接的圖象邊界有部分重疊,計算機正是利用這些信息進行匹配對準(zhǔn)。匹配算法的總體思想是既要保證對

9、準(zhǔn)的精度,又要保證運算量不至過大。這里算法利用了圖象的自身特性,既在一般圖象中,相鄰的象素點的灰度值相差不大。因此,可在第二幅圖象的邊界取一個網(wǎng)格,然后將網(wǎng)格在第一幅圖象上移動,計算所有網(wǎng)格點的兩幅圖象對應(yīng)象素點的RGB值的差的平方和。記錄最小的值的網(wǎng)格位置,即認(rèn)為是最佳匹配位置。(如圖1)為了減小運算量,我們將匹配分為兩個步驟,第一步是粗略匹配,在該階段網(wǎng)格每次水平或垂直移動一個網(wǎng)格間距。在完成粗略匹配之后,我們在當(dāng)前最佳匹配點處進行精確匹配,在該階段以當(dāng)前最佳匹配點為中心,網(wǎng)格向上下、左右各移動一個小步長。初始步長為粗略拼接時移動步長的一半,即為半個網(wǎng)格間距。不斷的與當(dāng)前最小平方和進行比較

10、,如果比當(dāng)前值優(yōu),就替換當(dāng)前最佳匹配點。循環(huán)進行這個過程每次步長減半,直到水平步長和垂直步長均為0為止。2算法描述procedure ImageMatching 輸入FirstImage; 輸入SecondImage; /獲得兩幅圖象的大小Height1=GetImageHeight(FirstImage); Height2=GetImageHeight(SecondImage); Width1=GetImageWidth(FirstImage); Width2=GetImageWidth(SecondImage); / 從第二幅圖象取網(wǎng)格匹配模板SecondImageGrid = GetSe

11、condImageGrid(SecondImage); / 粗略匹配,網(wǎng)格在第一幅圖象中先從左向右移動,再從下到上移動,每次移動一個網(wǎng)格間距,Step_Width 或Step_Height,當(dāng)網(wǎng)格移出重疊區(qū)域后結(jié)束y=Heitht1-GridHeight; MinValue = MaxInteger; While ( yHeight1-OverlapNumber)/當(dāng)網(wǎng)格移出重疊部分后結(jié)束 x=Grid_Width/2; /當(dāng)網(wǎng)格位于第一幅圖象的最左邊時,A點的橫坐標(biāo)。 While ( x(Width1-Grid_Width/2) ) FirstImageGrid=GetImgaeGrid(F

12、irstImgaeGrid, x, y); differ=CaculateDiff(FirstImgaeGrid, SecondImageGrid);/計算象素值差的平 /方和 if (differ0 & Step_Width0)/當(dāng)水平步長和垂直步長均減為零時結(jié)束 if(Step_Height=0)/當(dāng)僅有垂直步長減為零時,將其置為1 Step_Height=1; If(Step_Width=0) /當(dāng)僅有水平步長減為零時,將其置為1 Step_Width=1; temp_x = BestMatch_x; temp_y = BestMatch_y; for ( i= -1; i1; i+)

13、for( j= -1; j1; j+) if (i=0&j!=0)|(i!=0&j=0) FirstImageGrid=GetImgaeGrid(FirstImgaeGrid, temp_x+i*Step_Width, temp_y +j*Step_Height); differ=CaculateDiff(FirstImgaeGrid, SecondImageGrid); if (differ3(1)假設(shè)位數(shù)組的起始指針為lpStartBits屏幕坐標(biāo)(x,y)在的象素值的指針可用下式計算。lpBits=lpStartBits + (WidthBytes*(Height-y-1) + x*bi

14、BitCount);(2) 其中WidthBytes為(1)式計算的值,Height為圖象的高度。3、不同文檔類之間的數(shù)據(jù)交換的實現(xiàn)不同文檔類之間的數(shù)據(jù)交換我們可以通過應(yīng)用程序類或主窗口類作為媒介進行。在文檔類或視窗類可通過AfxGetApp()或AfxGetMainWnd()獲得應(yīng)用類和主窗口類的指針,在應(yīng)用類和主窗口類則可以通過獲得文檔模板來獲得文檔類的指針來訪問文檔類的數(shù)據(jù)。這樣我們可以通過應(yīng)用類或主窗口類的成員變量進行數(shù)據(jù)交換了。4、圖象的平滑連接當(dāng)找到最佳匹配點后,隨后的工作將是把兩幅圖象合成一幅圖象。對于重疊部分,我們?nèi)绻皇呛唵蔚娜〉谝环鶊D象或第二幅圖象的數(shù)據(jù),會造成圖象的模糊和

15、明顯的邊界,這是不能容忍的。即使取兩幅圖象的平均值,效果也不能令人滿意。為了能使拼接區(qū)域平滑,保證圖象質(zhì)量,我們采用了漸入漸出的方法,即在重疊部分由第一幅圖象慢慢過渡到第二幅圖象,很自然我們可以想到設(shè)一漸變因子為0dget_Width(&hmWidth); pPic-get_Height(&hmHeight); double fX,fY; fX = (double)pDC-GetDeviceCaps(HORZRES)*(double)hmWidth/(double)pDC-GetDeviceCaps(HORZSIZE)*100.0); fY = (double)pDC-GetDeviceCap

16、s(VERTRES)*(double)hmHeight/(double)pDC-GetDeviceCaps(VERTSIZE)*100.0); if(FAILED(pPic-Render(*pDC,0,0,(DWORD)fX,(DWORD)fY,0,hmHeight,hmWidth,-hmHeight,NULL) AfxMessageBox(渲染圖像失敗!); pPic-Release(); else AfxMessageBox(從流中裝載圖像失??!); 其中,顯示工作主要是由IPicture接口對象的Render函數(shù)來完成的,該函數(shù)主要用來將圖片的指定部分畫到指定的設(shè)備環(huán)境的指定位置。原型如

17、下:HRESULT Render( HDC hdc, /渲染圖像用的設(shè)備環(huán)境句柄long x, /在hdc上的水平坐標(biāo)long y, /在hdc上的垂直坐標(biāo)long cx, /圖像寬度long cy, /圖像高度OLE_XPOS_HIMETRIC xSrc, /在源圖像上的水平偏移OLE_YPOS_HIMETRIC ySrc, /在源圖像上的垂直偏移OLE_XSIZE_HIMETRIC cxSrc,/在源圖像上水平拷貝的數(shù)量OLE_YSIZE_HIMETRIC cySrc,/在源圖像上垂直拷貝的數(shù)量LPCRECT prcWBounds /指向目標(biāo)圖元設(shè)備環(huán)境句柄的指針); 小結(jié):到此為止,通過

18、上述代碼已經(jīng)能夠在程序的客戶區(qū)內(nèi)顯示JPEG、GIF等標(biāo)準(zhǔn)的圖像了,但對于有多幀圖片(即有動畫)的GIF格式的圖像,目前還只能顯示第一幀,如要完整的顯示GIF 動畫的全過程,還需要外部Active X控件的支持。-Visual C+實現(xiàn)Flash動畫播放摘要:本文通過在VC中將外格式文件內(nèi)嵌為VC的內(nèi)部資源,使其在程序運行過程中從資源動態(tài)釋放到臨時文件,從而實現(xiàn)VC對Flash動畫的播放。引言 Flash動畫由于可以很方便地把用戶的想象通過動畫顯現(xiàn)出來,使原本只屬于專業(yè)制作人員的動畫制作變的異乎尋常的快捷、方便。由于Flash制作的動畫在層次、內(nèi)容、表現(xiàn)形式等諸多方面均比較出色,因此在網(wǎng)絡(luò)上得

19、到迅猛的發(fā)展,更有不少廠商用Flash在互聯(lián)網(wǎng)上做起了廣告和產(chǎn)品演示,效果絲毫不比視頻的差,而體積則要小的多。Flash不僅在網(wǎng)絡(luò)上有廣泛的應(yīng)用,在普通的應(yīng)用程序中也可以借助Flash實現(xiàn)一些VC、Delphi等編程語言所難以實現(xiàn)的特效,比如在一些演示版的程序中完全可以將程序運行前的閃屏用Flash來制作。本文下面將通過對內(nèi)嵌資源的動態(tài)釋放來實現(xiàn)VC對Flash動畫的播放,并給出了部分實現(xiàn)代碼。內(nèi)嵌資源的動態(tài)釋放 Flash動畫在此是作為程序的一個模塊,雖然也可以以文件的形式作為一個外部資源來使用,但為了避免因外部模塊遺失而造成程序的非正常運行,可將由Flash 5.0預(yù)先制作好格式的文件以資

20、源的形式打包到應(yīng)用程序中去,而在程序運行時再將其從資源恢復(fù)到文件,使用完畢再通過程序?qū)⑵鋸拇疟P刪除。在導(dǎo)入資源時由格式文件并非VC的標(biāo)準(zhǔn)資源,所以在導(dǎo)入時需要在Resource type欄指定資源類型,特別需要注意的是在此必須要包含引號。加入到資源后可以通過資源視圖看到導(dǎo)入資源是以二進制形式保存的,一但加入就不能再通過資源視圖對其進行編輯了。在使用資源前首先要將其動態(tài)從應(yīng)用程序中釋放到文件中才可對資源做進一步的使用??上韧ㄟ^宏MAKEINTRESOURCE()將資源標(biāo)識號IDR轉(zhuǎn)換成字符串Name,再分別通過FindResource()、LoadResource()函數(shù)查找、裝載該資源到內(nèi)存:

21、CString Type=;HRSRC res=FindResource (NULL,Name,Type); HGLOBAL gl=LoadResource (NULL,res); 當(dāng)資源加載到內(nèi)存后,還要通過對資源內(nèi)存的鎖定來返回指向資源內(nèi)存的地址的指針,并籍此實現(xiàn)資源從內(nèi)存到磁盤的保存,至于存盤的操作則由文件函數(shù)CreateFile()、和WriteFile()來完成:LPVOID lp=LockResource(gl); /返回指向資源內(nèi)存的地址的指針。CString filename=Temp; /保存的臨時文件名/ CREATE_ALWAYS為不管文件存不存在都產(chǎn)生新文件。fp= C

22、reateFile(filename ,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL); DWORD a; /sizeofResource 得到資源文件的大小if (!WriteFile (fp,lp,SizeofResource (NULL,res),&a,NULL) return false; CloseHandle (fp); /關(guān)閉句柄FreeResource (gl); /釋放內(nèi)存通過上述代碼,可資源從應(yīng)用程序中提取并釋放到臨時文件Temp中,在此后只對此臨時文件操作,與程序內(nèi)嵌資源無關(guān)。 Flash動畫的播放格式的Flash動畫通常主要應(yīng)用在網(wǎng)

23、頁上,也就是說IE瀏覽器本身可以支持Flash動畫的播放。這樣就不必再單獨編寫用于播文件的代碼,從而大大減少編程的工作量。在VC + 6.0中新增了一個從CView派生的、用于處理網(wǎng)頁的視類CHtmlView,由于該類是以Internet Explorer為后臺支持,因此在創(chuàng)建工程時只需在最后一步指定視類從CHtmlView派生就可以使程序不編一行代碼而具備IE瀏覽器的網(wǎng)頁顯示能力。程序剛生成的時候缺省的連接主頁是為微軟公司的主頁,需要對此修改,使程序在執(zhí)行時立即顯示剛才提取出來的Flash臨時文件Temp。顯示缺省主頁的代碼是在視類的初始化函數(shù)中進行的:void CEmbedModuleVi

24、ew:OnInitialUpdate() CHtmlView:OnInitialUpdate(); Navigate2(_T(xxmicrosoftx),NULL,NULL); 顯然要將Navigate2()函數(shù)的第一個參數(shù)改成Temp的存放路徑。剛才在釋放資源到文件時并沒有指定絕對路徑,因此釋放出來的資源文件應(yīng)當(dāng)和應(yīng)用程序處于同一目錄。但是在此處如果不寫明絕對路徑是無法顯示該臨時文件的。獲取該臨時文件的絕對路徑可用如下方法實現(xiàn):先獲取應(yīng)用程序本身的絕對路徑,然后去處應(yīng)用程序全名(程序名和擴展名)此時得到的是應(yīng)用程序和臨時文件所處文件夾的路徑,最后只需在此基礎(chǔ)上加上臨時文件的文件名Temp即可

25、得到臨時文件的全路徑。下面是實現(xiàn)的主要代碼:/獲取應(yīng)用程序的全路徑char exeFullPathMAX_PATH; GetModuleFileName(NULL,exeFullPath,MAX_PATH); /將其格式化為字符串m_TempFile.Format(%s,exeFullPath); /去掉應(yīng)用程序的全名(一五為應(yīng)用程序文件全名的長度)exeFullPathm_TempFile.GetLength()-一五=/; /得到應(yīng)用程序所在路徑m_TempFile.Format(%s,exeFullPath); /得到臨時文件的全路徑m_TempFile+=Temp; 最后將得到的臨時文

26、件的全路徑m_TempFile作為參數(shù)傳遞給Navigate2()即可在程序運行時把Flash動畫作為主頁而顯示(如上圖所示)。由于臨時文件Temp是在程序運行過程中從應(yīng)用程序的資源中提取出來的,因此在程序退出之前需要將其刪除。一般是在消息WM_DESTORY的響應(yīng)函數(shù)里通過DeleteFile()函數(shù)來加以實現(xiàn)的。小結(jié)本文通過對CHtmlView和內(nèi)嵌資源的動態(tài)釋放實現(xiàn)了Flash動畫在VC程序中的播放,并對資源的動態(tài)釋放作了較為清晰的描述。通過類似的方法,可以將動態(tài)鏈接庫、HTML文件等程序模塊作為資源嵌入其中,在使用時再動態(tài)釋放到臨時文件,這樣可有效避免文件模塊過多時的雜亂以及程序模塊丟

27、失導(dǎo)致程序非正常運行等情況的發(fā)生。本文所述程序在Windows 98下,由Microsoft Visual C+ 6.0編譯通過。Flash動畫由 Macromedia Flash 5.0制作,所需瀏覽器支持為Internet Explorer 6.0。-用RealPlayer控件制作的播放器本文介紹如何插入RealPlay控件實現(xiàn)媒體文件的播放,代碼運行效果圖如左:下面簡要介紹一下具體實現(xiàn)步驟:一、建立基于對話框的程序二、在對話框內(nèi)添加RealPlayer G2 control的ActiveX控件(工程-添加工程-compontent and controls-registed Active

28、X controls )。三、在對話框內(nèi)添加源程序內(nèi)所示的按鈕和靜態(tài)文本分別用于控制打開播放等控制及顯示歌曲信息其ID號如源程序四、用MFC映射各按鈕消息void CSunapplerealplayerDlg:OnOpen() char szFileFilter= RM File(*.rm)|*.rm| Mp3 File(*.mp3)|*.mp3| MPEG File(*.mpeg)|*.mpeg| Media File(*.asf)|*.asf| Video File(*.dat)|*.dat| MPGA File(*.mpga)|*.mpga| Wave File(*.wav)|*.wav

29、| AVI File(*.avi)|*.avi| Movie File(*.mov)|*.mov| Mid File(*.mid;*,rmi)|*.mid;*.rmi| Wma File(*.wma)|*.wma| All File(*.*)|*.*|; CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,szFileFilter); if(dlg.DoModal()=IDOK) CString PathName=dlg.GetPathName(); PathName.MakeUpper(); m_player-SetSource(PathName)

30、; m_player-DoPlay(); SetDlgItemText(IDC_STATIC1,m_player-GetAuthor(); SetDlgItemText(IDC_STATIC2,m_player-GetTitle(); SetDlgItemText(IDC_x,m_player-Getx(); SetDlgItemText(IDC_SOURCE,m_player-GetSource(); void CSunapplerealplayerDlg:OnPlay() SetDlgItemText(IDC_STATIC1,m_player-GetAuthor(); SetDlgItem

31、Text(IDC_STATIC2,m_player-GetTitle(); SetDlgItemText(IDC_x,m_player-Getx(); SetDlgItemText(IDC_SOURCE,m_player-GetSource(); m_player-DoPlay(); UpdateData(false); SetTimer(1,20,NULL); void CSunapplerealplayerDlg:OnTimer(UINT nIDEvent) if(0&isRepeat) m_player-DoPlay(); CDialog:OnTimer(nIDEvent); void

32、CSunapplerealplayerDlg:OnClose() /添加此代碼時不要忘了在stdafx.h開頭處添加前兩行AnimateWindow(GetSafeHwnd(),1000,AW_HIDE|AW_BLEND); KillTimer(0); / /此處采用DestroyWindow關(guān)閉窗口/多謝杜修杏老師指點/ this-DestroyWindow(); void CSunapplerealplayerDlg:OnFullscreen() m_player-DoPause(); m_player-SetFullScreen(); m_player-DoPlay(); void CS

33、unapplerealplayerDlg:OnMp3down() ShellExecute(NULL,_T(open),NULL,NULL,TRUE); void CSunapplerealplayerDlg:OnPause() m_player-DoPause(); void CSunapplerealplayerDlg:OnStop() m_player-DoStop(); KillTimer(0); void CSunapplerealplayerDlg:OnRepeat() m_player-SetLoop(true); if(isRepeat) isRepeat=FALSE; Set

34、DlgItemText(IDC_REPEAT,循環(huán)); else isRepeat=TRUE; SetDlgItemText(IDC_REPEAT,正常); void CSunapplerealplayerDlg:OnLower() / TOD Add your control notification handler code here short volume=m_player-GetVolume(); m_player-DoPause(); m_player-SetVolume(volume-100); m_player-DoPlay(); void CSunapplerealplaye

35、rDlg:OnUpper() / TOD Add your control notification handler code here short volume=m_player-GetVolume(); m_player-DoPause(); m_player-SetVolume(volume+100); m_player-DoPlay(); void CSunapplerealplayerDlg:OnFloat() /TOD Add your command handler code here ShellExecute(NULL,_T(open),NULL,NULL,TRUE); voi

36、d CSunapplerealplayerDlg:OnPetroleum() / TOD Add your command handler code here ShellExecute(NULL,_T(open),x,NULL,NULL,TRUE); 五、映射WM_CTLCOLOR消息,用于控制文本顯示的顏色HBRUSH CSunapplerealplayerDlg:OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) HBRUSH hbr = CDialog:OnCtlColor(pDC, pWnd, nCtlColor); if(nCtlColo

37、r=CTLCOLOR_STATIC) if(pWnd.GetDlgCtrlID()=IDC_VOLUME) pDC.SetTextColor(RGB(165,一八2,222); pDC.SetBkMode(TRANSPARENT); return (HBRUSH) m_brush.GetSafeHandle(); if(pWnd.GetDlgCtrlID()=IDC_STATIC1|pWnd.GetDlgCtrlID()=IDC_STATIC2 |pWnd.GetDlgCtrlID()=IDC_SOURCE|pWnd.GetDlgCtrlID()=IDC_x) pDC.SetTextColor

38、(RGB(0,0,255); pDC.SetBkMode(TRANSPARENT); return (HBRUSH) m_brush.GetSafeHandle(); if(pWnd.GetDlgCtrlID()=IDC_STATIC|pWnd.GetDlgCtrlID()=IDC_INFO) pDC.SetTextColor(RGB(255,0,0); pDC.SetBkMode(TRANSPARENT); return (HBRUSH) m_brush.GetSafeHandle(); / TOD Return a different brush if the default is not

39、 desired return hbr; 六、在APP類里的initInstance()里添加下面函數(shù)改變對話框背景。SetDialogBkColor(RGB(206,227,99); 七、為了美觀我們的外形可引入CButtonXP類,將個按鈕類型設(shè)置為CButtonXP 好了,應(yīng)該大功告成了!調(diào)試一下吧!本程序在調(diào)試過程中要多謝杜修杏老師的指點-Visual C+編程控制鼠標(biāo)鼠標(biāo)是現(xiàn)在計算機的標(biāo)準(zhǔn)配置,很多軟件都有控制鼠標(biāo)的功能,比如,有的保密軟件可以使鼠標(biāo)移動限制在一定范圍以內(nèi),有的可以模擬鼠標(biāo)的點擊,有的可以使鼠標(biāo)自己移動。要實現(xiàn)以上的功能,必須使用Windows的API函數(shù)。我們以下面

40、的程序例子,來說明如何控制鼠標(biāo)。我們使用Visual C+6.0來寫這個程序。打開Visual C+6.0,使用MFC AppWizard新建1個基于對話框的工程,工程名為Mouse,在對話框上加上2個button控件,一個標(biāo)題為控制鼠標(biāo)移動范圍,另外1個的標(biāo)題是釋放鼠標(biāo)在MFC Clazard中添加兩個當(dāng)我們使用鼠標(biāo)單擊這兩個控件時響應(yīng)的函數(shù),標(biāo)題為控制鼠標(biāo)移動范圍的控件的響應(yīng)函數(shù)代碼為: /首先使用GetWindowRect獲得這個程序窗口的范圍CRect rect;this-GetWindowRect(&rect);/然后使用ClipCursor函數(shù)把鼠標(biāo)控制在這個范圍以內(nèi),這個函數(shù)的功

41、能就是控制鼠標(biāo)的范圍。ClipCursor(&rect);標(biāo)題為釋放鼠標(biāo)的控件的響應(yīng)函數(shù)代碼為: ClipCursor(NULL); 這行代碼非常簡單,就是使鼠標(biāo)可以自由移動,不受限制。把以上程序編譯好了以后運行,點下控制鼠標(biāo)移動范圍按鈕,鼠標(biāo)就只能在這個窗口的范圍以內(nèi)活動,離不開這個窗口了,點下釋放鼠標(biāo)按鈕,鼠標(biāo)就恢復(fù)正常了。知道了如何控制鼠標(biāo)范圍,該講講如何移動鼠標(biāo)了。移動鼠標(biāo)非常簡單,只需要一個API函數(shù)SetCursorPos,這個函數(shù)有2個參數(shù),第1個參數(shù)是屏幕的x坐標(biāo),第2個參數(shù)是屏幕的y坐標(biāo),它可以把鼠標(biāo)移動到指定的坐標(biāo)上去。模擬鼠標(biāo)的點擊功能也非常簡單,比如模擬點鼠標(biāo)右鍵,可以

42、使用下面兩行代碼: mouse_event(MOUSEEVENTF_RIGHTDOWN,0,0,0,0); mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0); mouse_event函數(shù)的功能就是模擬鼠標(biāo)點擊,第1行代碼是模擬按下鼠標(biāo)右鍵,第2行代碼是模擬鼠標(biāo)右鍵彈起,這兩行代碼就模擬了1次點擊鼠標(biāo)右鍵的操作,如果想模擬點鼠標(biāo)左鍵的操作,只要以上兩行代碼中的MOUSEEVENTF_RIGHTDOWN和MOUSEEVENTF_RIGHTUP參數(shù)換成MOUSEEVENTF_LEFTDOWN和MOUSEEVENTF_LEFTUP就可以了。鼠標(biāo)的模擬操作講完了。以上的程

43、序在Windows98下,使用Visual V+6.0編譯成功,調(diào)試正常。本期知識點:控制鼠標(biāo)的API函數(shù)。-用VC實現(xiàn)圖象漸顯和漸隱摘要圖象的漸顯/漸隱被廣泛運用與圖象處理和多媒提娛樂軟件。本文基于windows的調(diào)色板動畫和時間碼技術(shù)設(shè)計了通用的圖象漸顯和漸隱算法,并實現(xiàn)了其visual c+程序編碼。關(guān)鍵詞漸顯、漸隱、調(diào)色板、調(diào)色板動畫、時間碼圖象的漸顯/漸隱是十分重要的圖象效果,廣泛運用于圖象處理和多媒提娛樂軟件。漸顯/漸隱算法設(shè)計的最大困難是速度控制,包括定時和快速改變圖象中各象素的顏色。如采用普通的全圖掃描算法,則速度較慢,很難真正體現(xiàn)漸顯/漸隱效果。利用windows(3.x.9

44、5/98/nt)操作系統(tǒng)特殊的調(diào)色板管理和時間碼定時機制能設(shè)計出有效的圖象漸顯/漸隱算法。windows提供一種被稱為調(diào)色板動畫(palette animation)的顏色處理技術(shù),它通過快速改變顏色調(diào)色板中所選取的表項中的顏色能模擬顏色的變化。設(shè)置時間碼,定時調(diào)用該技術(shù)使圖象顏色漸變就能實現(xiàn)圖象的漸顯和漸隱。一、調(diào)色板動畫在visual c+中實現(xiàn)調(diào)色板動畫依賴于mfc類庫提供的cpalette類和cdc類中的若干成員函數(shù),其基本步驟如下:調(diào)用cpalette:createpalette(lplogpalette lplogpalette)函數(shù)創(chuàng)建邏輯調(diào)色板,注意將參數(shù)lplogpalett

45、e所指向的各顏色表項結(jié)構(gòu)的peflags域設(shè)置為pc_reserved,以防止其它窗口同該調(diào)色板匹配顏色。;調(diào)用cdc:selectpalette和cdc:realizepalette函數(shù)選擇和實現(xiàn)所創(chuàng)建的邏輯調(diào)色板;調(diào)用cpalette:animatepalette函數(shù)改變顏色,實現(xiàn)調(diào)色板動畫;動畫完成后應(yīng)恢復(fù)系統(tǒng)調(diào)色板。cpalette:animatepalette是其中最關(guān)鍵的函數(shù),其原型如下:void animatepalette( uint nstartindex, / 起始的表項號uint nnumentries, / 變化的表項數(shù)lppaletteentry lppalettec

46、olors ); / 邏輯調(diào)色板表項指針lppalettecolors為指向paletteentry結(jié)構(gòu)的指針,其中存儲著邏輯調(diào)色板將要更新的顏色信息。paletteentry結(jié)構(gòu)定義如下:typedef struct tagpaletteentry / pe byte pered; byte pegreen; byte peblue; byte peflags; paletteentry; pered、pegreen、peblue分別表示邏輯調(diào)色板項的r、g、b顏色分量值。peflags 應(yīng)被置為pc_reserved 。nstartindex為lppalettecolors中將變化的起始表

47、項號,nnumentries 為lppalettecolors中將變化的表項數(shù)。二、時間碼定時cwnd:settimer函數(shù)可設(shè)置一個系統(tǒng)時間碼,并指定每經(jīng)過一定的時間間隔使windows系統(tǒng)發(fā)送一個wm_timer消息到窗口的消息隊列中。窗口在每當(dāng)接收到相應(yīng)的wm_timer消息時做一定的處理,便實現(xiàn)了定時處理。通常應(yīng)在窗口的消息循環(huán)中接受和處理wm_timer消息,這樣將很難編制通用的定時操作。通用的定時操作應(yīng)將定時處理封裝在一個函數(shù)中,而不與其它的代碼糾纏在一起。筆者實現(xiàn)這一技術(shù)的技巧是,在循環(huán)操作中截獲窗口消息,如消息為指定的時間碼消息,則進行定時處理;否則分發(fā)消息給窗口消息處理機制。

48、如果定時操作已結(jié)束,則修改循環(huán)標(biāo)志,退出循環(huán)。具體的代碼如下: / 設(shè)置時間碼,pwnd為處理定時操作的窗口對象指針pwnd-settimer(0 x100, utimeout, null); / 屏蔽鼠標(biāo)操作,使定時操作不受影響pwnd-setcapture(); / 開始定時操作bool bdone = false; msg msg; while (! bdone) if (:peekmessage(&msg, null, 0, 0, pm_remove) if (msg.message = wm_timer & msg. wparam = 0 x100) . 定時操作代碼. / 如定時操

49、作完成,則設(shè)置循環(huán)標(biāo)志,結(jié)束操作if (定時操作完成) bdone = true; :translatemessage(&msg); :dispatchmessage(&msg); / 釋放鼠標(biāo):releasecapture(); / 刪除時間碼pwnd-killtimer(0 x100); . 函數(shù)peekmessage截獲窗口消息,translatemessage和dispatchmessage函數(shù)解釋和分發(fā)除指定時間碼消息之外的所有消息,以避免丟失消息。三、漸顯漸顯就是將顯示顏色由黑色(rgb(0, 0, 0))逐漸變化為圖象各象素的顏色的過程。開始時調(diào)用cpalette:getpale

50、tteentries函數(shù)保存圖象調(diào)色板的各邏輯表項信息,然后調(diào)用cpalette:setpaletteentries函數(shù)將邏輯調(diào)色板中各邏輯表項的pered、pegreen、peblue置為0,定時調(diào)用cpalette:animatepalette,每次將各邏輯表項的pered、pegreen、peblue值增加一個變化量,直到它們分別等于圖象邏輯調(diào)色板中各邏輯表項的pered、pegreen、peblue值。下面的函數(shù)fadein通過對調(diào)色板顏色表項中的各顏色分量值先設(shè)為0,然后進行遞增,直到所有顏色值都恢復(fù)成原調(diào)色板中顏色值來實現(xiàn)漸顯。/ 圖象漸顯效果/ 參數(shù):/ pwnd 顯示圖象的窗口

51、/ ppal 調(diào)色板指針/ ndeta 各顏色分量的減小量/ utimeout 時間的變化量void fadein(cwnd *pwnd, cpalette *ppal, int ndeta, uint utimeout) / 保留原來的調(diào)色板顏色表項int ntotalcolors = ppal-getentrycount(); paletteentry palettecolors0256; ppal-getpaletteentries(0, ntotalcolors, palettecolors0); / 先將調(diào)色板表項中各顏色分量置為0 paletteentry palettecolor

52、s1256; for (int i=0; isetpaletteentries(0, ntotalcolors, palettecolors1);ppal-animatepalette(0, ntotalcolors, palettecolors1);/ 設(shè)置時間碼pwnd-settimer(0 x100, utimeout, null); / 開始漸顯pwnd-setcapture(); bool bdone = false; msg msg; while (! bdone) if (:peekmessage(&msg, null, 0, 0, pm_remove) if (msg.mess

53、age = wm_timer & msg.wparam = 0 x100) cclientdc dc(pwnd); cpalette *poldpal = dc.selectpalette(ppal, false); dc.realizepalette(); / 遞增各顏色分量paletteentry palettecolors256; ppal-getpaletteentries(0, ntotalcolors, palettecolors); bool bredzero=false;bool bgreenzero=false; bool bbluezero=false; for (int

54、i=0; intotalcolors; +i) if (palettecolorsi.pered + ndeta palettecolors0i.pered) palettecolorsi.pered += ndeta; bredzero = false; else if (palettecolorsi.pered + 1 palettecolors0i.pered) palettecolorsi.pered+; bredzero = false; else bredzero = true; if (palettecolorsi.pegreen + ndeta palettecolors0i.

55、pegreen) palettecolorsi.pegreen += ndeta; bgreenzero = false; else if (palettecolorsi.pegreen + 1 palettecolors0i.pegreen) palettecolorsi.pegreen+; bgreenzero = false; else bgreenzero = true; if (palettecolorsi.peblue + ndeta palettecolors0i.peblue) palettecolorsi.peblue += ndeta; bbluezero = false;

56、 else if (palettecolorsi.peblue +1 animatepalette(0, ntotalcolors, palettecolors); :translatemessage(&msg); :dispatchmessage(&msg); :releasecapture(); pwnd-killtimer(0 x100); / 恢復(fù)原始調(diào)色板ppal-setpaletteentries(0, ntotalcolors, palettecolors0); ppal-animatepalette(0, ntotalcolors, palettecolors0); 四、漸隱漸

57、隱就是將顯示顏色由圖象各象素的顏色逐漸變化為黑色(rgb(0, 0, 0))的過程,即定時調(diào)用cpalette:animatepalette,每次將各邏輯表項的pered、pegreen、peblue值減小一個變化量,直到它們都為0。下面的函數(shù)fadeout通過對調(diào)色板顏色表項中的各顏色分量值進行遞減,直到所有顏色值都變成0(即黑色)來實現(xiàn)漸隱。/ 圖象漸隱效果/ 參數(shù):/ pwnd 顯示圖象的窗口/ ppal 調(diào)色板指針/ ndeta 各顏色分量的減小量/ utimeout 時間的變化量void fadeout(cwnd *pwnd, cpalette *ppal, int ndeta, u

58、int utimeout) / 保留原來的調(diào)色板顏色表項int ntotalcolors = ppal-getentrycount(); paletteentry palettecolors0256; ppal-getpaletteentries(0, ntotalcolors, palettecolors0); / 設(shè)置時間碼pwnd-settimer(0 x100, utimeout, null); / 開始漸隱pwnd-setcapture(); bool bdone = false; msg msg; while (! bdone) if (:peekmessage(&msg, nul

59、l, 0, 0, pm_remove) if (msg.message = wm_timer & msg.wparam = 0 x100) cclientdc dc(pwnd); cpalette *poldpal = dc.selectpalette(ppal, false); dc.realizepalette(); paletteentry palettecolors256;ppal-getpaletteentries(0, ntotalcolors, palettecolors); bool bredzero=false;bool bgreenzero=false; bool bblu

60、ezero=false; / 遞減顏色分量for (int i=0; i ndeta) palettecolorsi.pered -= ndeta; bredzero = false; else if (palettecolorsi.pered 1) palettecolorsi.pered-; bredzero = false; else bredzero = true; if (palettecolorsi.pegreen ndeta) palettecolorsi.pegreen -= ndeta; bgreenzero = false; else if (palettecolorsi.

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論