動畫窗口的實現-VC++實例一則
作者:陳萌 [email protected]
摘要:
本文通過對AnimateWindow函數的分析,介紹動畫窗口的實現原理,同時指出了在運用AnimateWindow函數時在編譯中會遇到的一些問題以及處理方法。
關鍵詞:動畫窗口,AnimateWindow,MSDN
一、引言
俗話說"佛靠金裝,人靠衣裝",一個好的軟件如果能配上精美的界面一定會讓更多的用戶認同它。喜歡上網的朋友對NetAnt(網絡螞蟻)這個軟件一定不會陌生,它的下載速度,斷點續傳的功能都給我們留下了深刻的印象,同時它的軟件界面也是相當棒的。在NetAnt的1.23版中,當下載任務完成或出錯時,在主窗口的中央會以動畫的方式展開一個窗口,報告當前下載的狀況;當用戶關閉窗口時,窗口又以收縮的方式關閉起來。那麼這個動畫窗口是怎樣實現的呢?下面我們就來討論一下在VC中如何實現這種動畫窗口。
二、編程原理
要實現這種動畫窗口的編程效果,主要用到Windows API中的AnimateWindow函數,通過在窗口的創建或消毀過程中運用該函數,來實現開啟和關閉程序時達到所希望的動畫窗口效果。AnimateWindow函數所提供的動畫效果十分豐富,我們可以在自己的程序中選擇各種不同的動畫效果,增強程序的趣味性。為使讀者對AnimateWindow函數有一個基本了解,我們先對該函數做一個簡單介紹:
函數原型:BOOL AnimateWindow(HWND hWnd,DWORD dwTime,DWord dwFlags)。
函數功能:該函數能在顯示與隱藏窗口時產生兩種特殊類型的動畫效果:滾動動畫和滑動動畫。
參數含義:
hWnd:指定產生動畫的窗口的句柄。 dwTime:指明動畫持續的時間(以微秒計),完成一個動畫的標准時間為200微秒。 dwFags:指定動畫類型。這個參數可以是一個或多個下列標志的組合。標志描述: AW_SLIDE:使用滑動類型。缺省則為滾動動畫類型。當使用AW_CENTER標志時,這個標志就被忽略。 AW_ACTIVATE:激活窗口。在使用了AW_HIDE標志後不能使用這個標志。 AW_BLEND:實現淡出效果。只有當hWnd為頂層窗口的時候才可以使用此標志。 AW_HIDE:隱藏窗口,缺省則顯示窗口。 AW_CENTER:若使用了AW_HIDE標志,則使窗口向內重疊,即收縮窗口;若未使用AW_HIDE標志,則使窗口向外擴展,即展開窗口。 AW_HOR_POSITIVE:自左向右顯示窗口。該標志可以在滾動動畫和滑動動畫中使用。當使用AW_CENTER標志時,該標志將被忽略。 AW_VER_POSITIVE:自頂向下顯示窗口。該標志可以在滾動動畫和滑動動畫中使用。當使用AW_CENTER標志時,該標志將被忽略。 AW_VER_NEGATIVE:自下向上顯示窗口。該標志可以在滾動動畫和滑動動畫中使用。當使用AW_CENTER標志時,該標志將被忽略。
返回值:如果函數成功,返回值為非零;如果函數失敗,返回值為零。在下列情況下函數將失敗:
窗口使用了窗口邊界;窗口已經可見仍要顯示窗口;窗口已經隱藏仍要隱藏窗口。
三、動畫窗口的實現
下面就以一個簡單的單文檔程序為例,說明如何在VC中使用AnimateWindow函數來實現打開和關閉程序時的動畫效果。基於多文檔與對話框的程序所用方法類似,本文就不一一介紹。筆者所使用的開發環境為:WindowsME,Visual C++6。
1、建立一個MFC AppWizard(exe)應用工程Animate。
在MFC AppWizard向導的第一步中選擇Single document,再點擊按鍵Finish->OK完成工程建立。
2、在CMainFrame::OnCreate函數中增加黑體加粗部分語句。
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct){ …… m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); AnimateWindow(GetSafeHwnd(),1000,AW_CENTER); return 0;}
3、使用MFC ClassWizard增加消息處理函數
使用ClassWizard在CMainFrame類中增加WM_CLOSE消息處理函數,並增加以下語句。
void CMainFrame::OnClose() { // TODO: Add your message handler code here and/or call default AnimateWindow(GetSafeHwnd(),1000,AW_HIDE|AW_CENTER); CFrameWnd::OnClose();}
四、編譯時出現的問題
在實現動畫窗口的程序時,筆者發現如果直接在VC中使用AnimateWindow函數,在編譯時會報告出錯。以上述程序為例,在編譯時系統會報告:
''AnimateWindow'' : undeclared identifier ''AW_HIDE'' : undeclared identifier ''AW_CENTER'' : undeclared identifIEr
通過錯誤提示可以看出是編譯系統認為AnimateWindow函數和AW_HIDE、AW_CENTER兩個參數沒有定義。因該函數是定義在Winuser.h頭文件中的,於時,筆者顯示地在程序中定義了對該頭文件的包含,編譯時卻仍然出現相同的錯誤。為什麼在VC中編譯不能通過呢?通過查閱MSDN筆者發現在MSDN中明確提到WindowsNT5.0和Windows98以上版本均支持該函數。通過筆者的研究發現,問題出在定義AnimateWindow函數的頭文件Winuser.h中,在VC安裝目錄下進入include子目錄,用EDIT打開Winuser.h文件,按F3鍵查找AnimateWindow,可以發現有兩處定義,一處是定義該函數中使用到的參數;另一處是該函數原型的定義。在這兩處定義中均出現了對Windows版本的條件判斷,#if (WINVER >= 0X500)……,原來問題出在這裡,我們目前所使用的各種Windows主版本號均為5點零以下,所以在VC中編譯上述程序時,編譯系統自然將AnimateWindow函數排除在外。因此為了在我們的程序中使用該函數,就得對其頭文件進行一些小小的修改,即將#if (WINVER >= 0X500)改為#if (WINVER >= 0X400),請注意兩處出現該函數定義的部分都要進行修改。
假如你不想修改Winuser.h,可以在工程裡的StdAfx.h文件靠前位置加上如下定義 #undef WINVER#define WINVER 0X500 具體可以參考源代碼
修改好頭文件後,編譯即可通過。
五、小結
實際上在AnimateWindow函數中包含了多種動畫效果,我們只須在程序中增加幾條語句,就能使得程序的開啟和關閉就得生動有趣。
另外,通過本例我們可以發現,盡管在MSDN中明確指出在Windows98中支持AnimateWindow函數,但是在實際編程時卻發現該函數在頭文件中的定義卻將版本控制在了5.0以上,筆者雖然不知道原因何在,但本文對此問題的解決無疑是一種比較新穎的作法,希望能夠對廣大讀者的工作起到拋磚引玉的效果。