Juce之旅-第一個例子(圖形窗口)


以這么說現在的人越來越妖精了,本來軟件嗎,要的是簡單穩定實用,但是看現在的趨勢是越來越多人注重界面的美化和和效果。比如IM類軟件,QQ,飛信還有土的掉渣的MSN等,前兩天看了一下YahooUI,覺得不錯,ICQ的界面也可以。Windows上界面技術基本都是DirectUI或者近似於DirectUI,而迅雷7使用了WPF做界面,很漂亮,雖然有很多bug,不過可以理解。WPF估計是未來donet平台的主流開發技術了。這樣做就給用戶慣了個壞毛病,如果你的軟件不夠漂亮,就會引來很多非議或者干脆扔掉不用。呵呵, 沒有辦法。其實我的工作本身和界面美化沒什么關系,純粹出於興趣。研究過很多流行的庫,不過問題是開源的很難作出好的效果,效果不錯的卻不開源,當然我不是說不能用純win32或者MFC做出牛X的界面哈,只是一種權衡而已,國內現在有很多公司比如UIPower,UIEasy還有直接叫DirectUI的公司,都是收費的,而且價格不是一般的貴。記得在東軟的時候,項目中買了一個Skin++的授權,MD7千一個,呵呵。其實Skin++先前版本的原理很簡單,采用的是子類化和鈎子而已,當然這也是Win32窗體系列美化的經典做法了。如果哪位哥們有興趣可以聯系我,我們也開發個,而且免費。呵呵。

 

     Ok,廢話少說,回到正題上來吧,說說Juce,這是個很不錯的庫,源碼非常簡練,而且注釋完備,很容易看懂,整個體系就是DirectUI的思路,我一直覺得這東西就是一個精簡版的Qt。我不得不說Jules大哥是個牛人也是好人,有什么問題一封郵件,他立馬回你,而且Juce社區國外用戶很活躍,Juce庫也不斷地完善的和強大。聽Jules大哥說,會加入Skin的功能,Great!

 

     來看第一個例子,我們給他取個名字叫“SuperJucer”吧,該例子的功能就是利用png文件創建一個不規則窗口,估計大家對這個很熟悉了,想想QQ寵物哈,一個小企鵝笨笨的在你的工具欄走來走去,是不是很有意思。而該類就是一個超人叔叔,出現在你的桌面上,沒有windows土里吧唧的邊框和XXX按鈕,哈哈!

 

先看圖片哈:這就是我們要制作的窗口,超人叔叔。

 

第二個圖片:景甜妹妹

 

Ok,素材准備好了,我們就用這兩幅圖片做個異形窗口哈:

 

第一步: 在VS2008中創建一個Win32的空項目,取名SuperJucer,創建好之后,該工程下面只有三個空的文件夾:header,source,resource. 要的就是干凈。

 

第二步: 添加兩個文件SuperJucer.h和SuperJucer.cpp.這就是我們的代碼文件。

 

第三步:設置包含路徑及鏈接庫路徑,請看我第一篇的翻譯哈。

 

第四步:在頭文件SuperJucer.h中添加以下類:

 

 

[cpp]  view plain  copy
 
  1. #ifndef __SUPERJUCER__  
  2. #define __SUPERJUCER__  
  3. #include "../../juce.h"  
  4. namespace ProjectInfo  
  5. {  
  6.     const char* const  projectName    = "SuperJucer";  
  7.     const char* const  versionString  = "1.0.0";  
  8.     const int          versionNumber  = 0x10000;  
  9. }  
  10. //==============================================================================  
  11. class MainAppWindow   : public Component  
  12. {  
  13. public:  
  14.     //==============================================================================  
  15.     MainAppWindow();  
  16.     ~MainAppWindow();  
  17.     void closeButtonPressed();  
  18.     virtual void paint (Graphics& g);  
  19.     void mouseDown (const MouseEvent& e)  
  20.     void mouseDrag (const MouseEvent& e)   
  21.     juce_UseDebuggingNewOperator  
  22.      
  23. private:  
  24.     MainAppWindow (const MainAppWindow&);  
  25.     MainAppWindow& operator= (const MainAppWindow&);  
  26.     ComponentDragger dragger;  
  27.     Image* m_testWindowBK;  
  28. };  
  29. #endif  // __SUPERJUCER__  

 

 

解釋如下:

 

  • #include "../../juce.h"   
  • 這個就是包含juce庫文件,按照文檔說明,一般這行應放在stdafx.h中,理由很簡單,就是這個是全局要用的文件。
  • class MainAppWindow   : public Component  
  • 這行就是創建一個窗口類,繼承Component, Component是Juce的窗體基類。暫時知道就可以了,我會翻譯后續文檔。到時就明白。
  • void closeButtonPressed(); 
  • virtual void paint (Graphics& g);
  • void mouseDown (const MouseEvent& e)
  • void mouseDrag (const MouseEvent& e)
  • 這幾行就是實現一些窗口常用的事件處理函數,需要關閉窗口所以,所以要相應closeButtonPressed這個函數,要移動和拖拽窗口所以mouseDown和mouseDrag需要的。 
  • 而paint函數就是繪制函數,這個更需要了,因為我們需要把圖片繪制在窗體上,而該函數就是干這事的,至於什么時候調用,怎么調用這事框架關心的,暫時可以不管。
  • juce_UseDebuggingNewOperator
  • 這一行的意思是允許調new操作符,如果編寫過mfc程序,這個就好理解,你經常會在mfc文件中看到,#define _DEBUG_NEW_ NEW 類似的語句,這行就是這個功能。作用就是便於檢查內存泄露或者其他調試功能。
  • ComponentDragger dragger;
  • 負責窗體拖拽
  • Image* m_testWindowBK;
  • 保存背景圖片,在程序啟動的時候加載一次背景圖片,不要放在paint函數中加載哈,因為磁盤IO影響性能:)

第五步 實現文件

 

[cpp] view plain copy
 
  1. #include "MainWindow.h"  
  2. MainAppWindow::MainAppWindow()  
  3.     : Component (JUCEApplication::getInstance()->getApplicationName())  
  4. {  
  5.         centreWithSize (500, 400);  
  6.         setVisible (true);  
  7.     addToDesktop( ComponentPeer::windowIsTemporary  | ComponentPeer::windowIsResizable , NULL );  
  8.     m_testWindowBK = ImageFileFormat::loadFrom( File( "f://Program//juce//1.png") );  
  9. }  
  10. MainAppWindow::~MainAppWindow()  
  11. {  
  12.    delete m_testWindowBK ;  
  13.    m_testWindowBK = NULL;  
  14. }  
  15. void MainAppWindow::closeButtonPressed()  
  16. {  
  17.     JUCEApplication::getInstance()->systemRequestedQuit();  
  18. }  
  19. void MainAppWindow::paint( Graphics& g )  
  20. {  
  21.     if (isOpaque())  
  22.         g.fillAll (Colours::white);  
  23.     else  
  24.         g.fillAll (Colours::blue.withAlpha (0.0f));  
  25.       
  26.     g.drawImage( m_testWindowBK, 0, 0, 256,256, 0,0, 256,256 );  
  27.       
  28. }  

 

解釋如下:

  • centreWithSize (500, 400);
  • 是窗口出於桌面的正中,並且設置其大小為500*400
  • setVisible (true);
  • 是窗口可見
  • addToDesktop( ComponentPeer::windowIsTemporary  | ComponentPeer::windowIsResizable , NULL );
  • 將窗口添加到桌面,這里很有意思,因為MainAppWIndow窗口是直接繼承Component類,該類並不知道其父窗口是誰,所以你必須強行將他加到桌面系統的窗口隊列中。如果沒有這句,雖然進程在但是看不到窗口。
  • m_testWindowBK = ImageFileFormat::loadFrom( File( "f://Program//juce//1.png") );
  • 加載文件,ImageFileFormat是個封裝數據流或是文件,或是流到Image的類,直接這樣就可以加載文件,是不是很類似Gdi+中的Image::FromImage。呵呵。

繪制部分是最重要的,看代碼:

 

  • if (isOpaque())
  • 判斷該窗口是否透明,真是不透明,假是透明。怪異。
  •    g.fillAll (Colours::white);
  •    如果不透明,就直接填充白色
  • else
  •    g.fillAll (Colours::blue.withAlpha (0.0f));
  •    如果透明,就填充顏色藍色,並且將它透明度設為0.0f,1.0是不透明哈。目的就是讓窗口本身透明。哈哈,至於什么色無所謂了。主要是alpha通的為0
  • g.drawImage( m_testWindowBK, 0, 0, 256,256, 0,0, 256,256 );
  • 這是吧剛才的圖片畫上去,和Gdi+中的一致。

編譯運行:看結果:

是不是很帥:) 再看看景甜妹妹的效果:

綠色的我的桌面背景哈。

 

當然可以用在MFC中通過UpdateLayerAttribute函數也可以達到這個效果。但是我覺得有兩個缺點:

第一:如果你繪制了png圖片,再繪制別的非png元素,該函數會失效

第二:也可以設置遮罩色混合,不過會出現毛邊,這是個很惡心的問題。

 

Juce做的很帥,這只是它小功能之一,還有很多。后續我會放上demo。

回家吃飯了,有空再繼續。。。。

 

文中有些自己的理解,如果不對的地方,請給我提出來,但是不能說臟話哈,理解,理解。。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM