以這麼說現在的人越來越妖精了,本來軟體嗎,要的是簡單穩定實用,但是看現在的趨勢是越來越多人注重界面的美化和和效果。比如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中添加以下類:
#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+中的一緻。
編譯運作:看結果:
是不是很帥:) 再看看景甜妹妹的效果:
綠色的我的桌面背景哈。
當然可以用在MFC中通過UpdateLayerAttribute函數也可以達到這個效果。但是我覺得有兩個缺點:
第一:如果你繪制了png圖檔,再繪制别的非png元素,該函數會失效
第二:也可以設定遮罩色混合,不過會出現毛邊,這是個很惡心的問題。
Juce做的很帥,這隻是它小功能之一,還有很多。後續我會放上demo。
回家吃飯了,有空再繼續。。。。
文中有些自己的了解,如果不對的地方,請給我提出來,但是不能說髒話哈,了解,了解。。。。