天天看點

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按鈕,哈哈!

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

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

第二個圖檔:景甜妹妹

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

Ok,素材準備好了,我們就用這兩幅圖檔做個異形視窗哈:

第一步: 在VS2008中建立一個Win32的空項目,取名SuperJucer,建立好之後,該工程下面隻有三個空的檔案夾:header,source,resource. 要的就是幹淨。

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

第三步:設定包含路徑及連結庫路徑,請看我第一篇的翻譯哈。

第四步:在頭檔案SuperJucer.h中添加以下類:

#ifndef __SUPERJUCER__  

#define __SUPERJUCER__  

#include "../../juce.h"  

namespace ProjectInfo  

{  

    const char* const  projectName    = "SuperJucer";  

    const char* const  versionString  = "1.0.0";  

    const int          versionNumber  = 0x10000;  

}  

//==============================================================================  

class MainAppWindow   : public Component  

public:  

    //==============================================================================  

    MainAppWindow();  

    ~MainAppWindow();  

    void closeButtonPressed();  

    virtual void paint (Graphics& g);  

    void mouseDown (const MouseEvent& e)  

    void mouseDrag (const MouseEvent& e)   

    juce_UseDebuggingNewOperator  

private:  

    MainAppWindow (const MainAppWindow&);  

    MainAppWindow& operator= (const MainAppWindow&);  

    ComponentDragger dragger;  

    Image* m_testWindowBK;  

};  

#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影響性能:)

第五步 實作檔案

#include "MainWindow.h"  

MainAppWindow::MainAppWindow()  

    : Component (JUCEApplication::getInstance()->getApplicationName())  

        centreWithSize (500, 400);  

        setVisible (true);  

    addToDesktop( ComponentPeer::windowIsTemporary  | ComponentPeer::windowIsResizable , NULL );  

    m_testWindowBK = ImageFileFormat::loadFrom( File( "f://Program//juce//1.png") );  

MainAppWindow::~MainAppWindow()  

   delete m_testWindowBK ;  

   m_testWindowBK = NULL;  

void MainAppWindow::closeButtonPressed()  

    JUCEApplication::getInstance()->systemRequestedQuit();  

void MainAppWindow::paint( Graphics& g )  

    if (isOpaque())  

        g.fillAll (Colours::white);  

    else  

        g.fillAll (Colours::blue.withAlpha (0.0f));  

    g.drawImage( m_testWindowBK, 0, 0, 256,256, 0,0, 256,256 );  

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+中的一緻。

編譯運作:看結果:

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

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

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

綠色的我的桌面背景哈。

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

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

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

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

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

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

繼續閱讀