(轉)wxWindows一些網文

轉)wxWindows一些網文

 1# 大 中 小 發表於 2005-4-26 20:57  只看該作者
(轉)wxWindows一些網文
最近看了Borland C++BuilderX的報道,發現這次的版本使用的是wxWindows做爲FrameWork。十分驚訝,因爲我在一年以前就使用wxWindows了。不過在當時,包括最近有關它的國內報道還是很少。
  wxWindows是一個C++的擴展庫。是一個OpenSource項目,而且支持多平臺。所以,你完全可以從OpenSource的網站上免費獲得各個平臺的版本和源代碼。而對於wxWindows的官方網站www.wxWindows.org我一年來從未一睹其芳容,——網站無法訪問。但是儘管如此,並不影響我們獲得它。這多虧了OpenSource的力量。
  wxWindows最吸引我的是它簡潔的代碼——幾行簡單的代碼,隨心所欲的派生。一個窗口就誕生了。一個用API要近100行的效果。用 wxWindows最多十幾行就可以解決問題。我想這也或許是Borland選擇它的原因之一吧。wxWindows對於各種常用控件和繁瑣的功能都分別封裝成了類。使用的時候只要加一行代碼就可以使用了。像

wxButton *p_b = new wxButton(frame,-1,"Button");

就是在frame窗口中繪製一個寫有Button的按鈕。以後的訪問只要使用

p_b->//要調用的函數

就可以對按鈕進行操作了。我想直接用API就沒有那麼方便了吧。其實在簡單的背後,wxWindows爲你默默的做了許多的工作。雖然你也可以在 wxWindows中對這些工作全面接手。但是,有些時候根本沒有必要那麼做。當然,如果你對wxWindows的控件不滿意的話,完全可以用 wxWindows派生出自己的控件。比如你對主窗口不滿意——只有一塊深灰色。你完全可以生成一個自己的主窗口,方法如下:

Class MyFrameublic wxFrame
{
public:
MyFrame(int width,int height);
};
MyFrame::MyFrame(int width,int height)
:wxFrame((wxFrame)*NULL,wxPoint(0,0),wxSize(width,height))
{
//你爲MyFrame所添加的控件等。
}

從上面的代碼,可以看出。wxWindows靈活的類管理。
  我鍾情於wxWindows的另一個理由是它與C++標準庫的兼容和健全的非窗口類。比如,在wxWindows中我最喜歡的是wxString,它是我見到的最健全的String類之一。它不但可以與wx完全兼容,也可以與C++標準兼容。在C++中,wxString更像一個靈活多變的Char 列。你可以像Char那樣使用它。而無需考慮內存的事先分配等問題。而且,在某些方面,它比char更強大。
  當然,對於多平臺的支持也是我喜歡它的原因。wxWindows有多平臺的版本。我使用的是MSW的。當然也有 Mac X11 GTK MGL等許多平臺的。如果你要讓你的代碼在其他的平臺上使用。那麼你只要在編譯的時候修改一下附帶的語句。將有關平臺的參數改變一下就可以了。對於代碼,只要沒有使用在特定平臺下的功能,就能不修改代碼直接使用。當然,wxWindows不只是對各個操作系統有支持。由於它是OpenSource的。所以,通常,其他非C++語言也會使用它的。比如 wxPython就是wxWindows對Python的版本。wxPerl是對Perl的版本。在這些不同的語言中的wxWindows,力求保持它原有的編程風格和思路,而且他們也做到了。所以,你會wxWindows就等於會了wxPython,wxPerl。說到這裏,我想說一些題外話。我也用 python+wxPython做一些桌面的小玩具,不僅如此,在我要用wxWindows開發界面的時候,會使用wxPython先事先寫好界面的代碼。然後,確定好後,再機械的灌到我的C++代碼中。由於Python是解釋性語言,所以與C++相比少了編譯,連接的開發週期。寫完代碼直接運行就可以了。所以,節省了不少的開發時間。這不失爲一種減少開發週期,加快開發速度的好方法。下面我們來看看wxPython和wxWindows在實現相同功能上有多大的相同。
//C++ Source
#include <wx/wx.h>

class MainApp:public wxApp
{
public:
virtual bool OnInit(void);
private:
wxFrame *mainFrame;
};
IMPLEMENT_APP(MainApp)

bool MainApp::OnInit(void)
{
mainFrame = new wxFrame((wxFrame*) NULL,-1,"Hello wxWindows");
mainFrame->Show(TRUE);
SetTopWindow(mainFrame);
return TRUE;
}


#Python Source
from wxPython.wx import *

class MainApp(wxApp):
def OnInit(self):
  mainFrame=wxFrame(NULL,-1,"Hello wxWindows")
  mainFrame.Show(true)
  self.SetTopWindow(mainFrame)
  return true
app=MainApp(0)
app.MainLoop()

從上面的代碼,我們可以看到。對於wxWindows和wxPython的界面實現方法幾乎是相同的。不同的只是在有關變量的聲明,和C++與Python自身的語法不同。
  接下來,說說wxWindows支持的C++的IDE環境。既然Borland C++BuildX已經使用了wxWindows那麼Borland的C++編譯器應該支持吧。其實,事實也是如此。Borland C++ 4.5和5.0都支持。對於使用最廣的VC的IDE環境自然也必須支持了。支持的有1.5,4.0,5.0和6.0。當然,其實.Net下也可以使用 wxWindows。至少我使用下來沒有問題。另外,使用GCC的Dev-CPP也對它有很好的支持,甚至還爲wxWindows專門打了一個包。直接使用Dev-CPP的包管理就可以安裝並使用了。以上只是一些可以使用wxWindows的IDE環境,還有很多,在此不一一介紹了。有關更多的介紹,可以看看wxWindows的自帶文檔,在裏面有詳細的介紹和對於不同環境的安裝方法。
  對於wxWindows中值得稱讚的是它的說明文檔。可以這樣說,它的自帶的文檔從教程到查詢文檔一應俱全。要知道,作爲一個開源項目,免費維護的項目,文檔能夠如此詳細和完整真是難得。所以,在沒有中文文檔的時候,我就是閱讀這些英文文檔來學習的。而且,直到現在,我每次看這些文檔的時候都會有許多新的感悟。而且,另一個值得說明的是,wxWindows 2.4.0,wxWindows 2.4.1等這些不同版本的wxWindows雖然之間有很多的改進。但是,使用的介紹文檔等幾乎沒有改變。這也正說明了它語法的穩定。不至於一個新的版本會造成過去代碼的不可用。所以,你完全不用擔心你的代碼由於版本的問題,會造成他人在閱讀和編譯上的困難。
  對於,多平臺的運行機制。我想我也要簡單介紹一下。畢竟我想這個也是我們需要關注的問題。如果,你仔細看看wxWindows的include/wx 目錄,你會看到有諸如 msw unix 等目錄。其實,在你導入wxWindows文件的時候,wxWindows會更具不同的平臺選擇不同的文件。下面是 include/wx/button.h中63行的一段代碼。

#if defined(__WXUNIVERSAL__)
    #include "wx/univ/button.h"
#elif defined(__WXMSW__)
    #include "wx/msw/button.h"
#elif defined(__WXMOTIF__)
    #include "wx/motif/button.h"
#elif defined(__WXGTK__)
    #include "wx/gtk/button.h"
#elif defined(__WXMAC__)
    #include "wx/mac/button.h"
#elif defined(__WXPM__)
    #include "wx/os2/button.h"
#elif defined(__WXSTUBS__)
    #include "wx/stubs/button.h"
#endif

由上面的代碼,可以看到,如果你向編譯器傳送的是__WXMSW__的時候,button.h會從msw文件夾中繼續導入button.h。這就是 wxWindows支持多平臺的方法。所以,wxWindows的運行機制,更像是一個解釋器的運行機制。不論平臺如何改變,編寫的人無需考慮平臺的問題,解釋器會更具不同的平臺,將相同的代碼轉換成不同的命令。
  當然,世界上的任何事物都是由兩面性的,像wxWindows也有它的缺點。首先,使用wxWindows的界面,往往體積比較大,基本在1M以上。而且,會隨界面的複雜而上升。不過,這主要取決於你使用的頭文件的多少。通常不會有突變的情況。當然,這也不是不可以改變的。如果用ZIP等壓縮一下的話,通常都會只有原來的50%或者更低30%我像,這或許是取決於編譯器和代碼自身的問題。應該可以解決的。另外,wxWindows的簡化也會給使用的人帶來不少的麻煩。比如:

wxNotebook *p_note = new wxNotebook(frame,-1);
p_note->AddPage(new wxPanel(frame,-1),"1");
p_note->AddPage(new wxPanel(frame,-1),"2");
p_note->DeletPage(0);

如果,你沒有使用過或者剛使用wxWindows,一定會以爲這個代碼會造成內存泄漏。因爲,沒有顯式刪除new生成的內存空間。最初我也是這樣想的,但是後來才發現。wxWindows會自動爲你在DeletPage(0)時刪除new佔用的空間。對於用慣C++的人來說,這的確會造成一些混亂。不過,這也是wxWindows的好心被人誤解了吧。最後的問題是wxWindows在某些方面的不靈活。比如,要設計一個不規則的窗口就幾乎是不太可能的。而且,不如wxTextCtrl中的右鍵菜單是英文的,修改他的確也有些麻煩。以上是我使用wxWindows時發現的一些問題。不過,既然Borland 使用了wxWindows。我想wxWindows會越來越更完善的。
  最後,感謝各位的閱讀。希望各位前輩能爲小生的文章多多指教。我想以後wxWindows不只是C++BuildX的專利。你也可以在你喜歡的IDE中使用wxWindows。


STUDIO軟件開發組 
 
 


 2# 大 中 小 發表於 2005-4-26 20:57  只看該作者
wxWindows  Frame程序簡化版

前幾天給出了一個最簡單的Hello World 程序, 由於這幾天我還在學習wxWindows, 所以把今天做的第一個Frame框架程序寫出來,給大家分享.

1.  新建一個Win32 Application,名字爲Frame,然後選擇Empty Project,點Finish完成.
2.  Insert 一個Class, Class Type爲Generic Class,名字爲 CMyApp ,基類信息中Deviced From 填入wxApp,類別爲Public(默認),彈出對話框點OK.
3.  在ClassView中雙擊CMyApp的構造函數CMyApp(),在MyApp.cpp中加入#include "wx/wx.h"
4.  在ClassView中右鍵單擊CMyApp,選擇添加成員函數,加入一個Public的virtual bool OnInit()成員函數.
5.  修改CMyApp的OnInit()如下
    bool CMyApp::OnInit()
    {
     wxFrame *frame = new wxFrame((wxFrame*) NULL, -1, _T("我的第一個框架窗口"),wxPoint(100,100),wxSize(400,300));
     // 創建狀態欄
     frame->CreateStatusBar();
     frame->SetStatusText(_T("狀態欄就緒"));
     // 顯示窗口
     frame->Show(TRUE);
     SetTopWindow(frame);
     return true;
    }
6.  在CMyApp:CMyApp(){}前面加入IMPLEMENT_APP(CMyApp),看下面:
    IMPLEMENT_APP(CMyApp)
    CMyApp::CMyApp()
    {
   
    }
7   這個時候你如果點編譯按鈕的話,會出現一個致命錯誤(Fatal Error)
    fatal error C1083: Cannot open include file: 'wx/setup.h': No such file or directory
    怎麼解決?看下面
8.  設置好Settings
    win32 Debug配置
    C++選項卡
    預處理定義爲: _DEBUG,WIN32,_WINDOWS,_MT,WINVER=0x400,_wxUSE_GUI,__WXDEBUG__,WXDEBUG=1
    額外包含頭文件目錄爲: $(WXWIN)/lib/mswd
    預編譯頭文件選擇 Automatic use of precompiled headers
    Code Generation 中的Use Runtime library 選擇 Debug MultiThreaded DLL
    Link選項卡
    在對象代碼模塊最後,添加comctl32.lib rpcrt4.lib wsock32.lib wxmswd.lib , 這4個庫
////////////////////////
//源文件附在後面
//////////////////
// MyApp.h: interface for the CMyApp class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_MYAPP_H__08DC4B2E_BCC2_48EC_A02A_D82513125055__INCLUDED_)
#define AFX_MYAPP_H__08DC4B2E_BCC2_48EC_A02A_D82513125055__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CMyApp : public wxApp 
{
public:
virtual bool OnInit();
CMyApp();
virtual ~CMyApp();

};
DECLARE_APP(CMyApp)
#endif // !defined(AFX_MYAPP_H__08DC4B2E_BCC2_48EC_A02A_D82513125055__INCLUDED_)
//-------------------------------------------------------------------------
// MyApp.cpp: implementation of the CMyApp class.
//
//////////////////////////////////////////////////////////////////////
#include "wx/wx.h"
#include "MyApp.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_APP(CMyApp)
CMyApp::CMyApp()
{

}

CMyApp::~CMyApp()
{

}

bool CMyApp::OnInit()
{
wxFrame *frame = new wxFrame((wxFrame*) NULL, -1, _T("我的第一個框架窗口"),wxPoint(100,100),wxSize(400,300));
// 創建狀態欄
frame->CreateStatusBar();
frame->SetStatusText(_T("狀態欄就緒"));
// 顯示窗口
frame->Show(TRUE);
SetTopWindow(frame);
return true;
}

 


作者Blog:http://blog.csdn.net/huyoo/ 
 
 


 3# 大 中 小 發表於 2005-4-26 22:11  只看該作者
將 MFC 應用程序移植到 Linux
http://www-128.ibm.com/developerworks/cn/linux/guitoolkit/l-mfc/
循序漸進使用 wxWindows 的指南

Markus Neifer
軟件開發人員
2002 年 4 月

將 Windows 應用程序移植到 Linux 不必涉及再培訓的痛苦經歷。Markus Neifer 演示瞭如何使用 wxWindows 移植 MFC,指導讀者使用 wxWindows 這一開放源碼工具箱,並循序漸進地向讀者介紹了一個完整的移植示例。
您可能仍然在維護用微軟基礎類庫(Microsoft Foundation Classes(MFC))構建的舊的 Windows 應用程序,而現在卻有客戶要求 Linux 版本,該怎麼辦呢?在您的團隊中可能有技術熟練的 MFC 開發人員,但如何達到加速 Linux 開發呢?別急;本文就是針對您這種情況而寫的。依靠 wxWindows(一種用於 C++ 和 Python 的可移植 GUI 工具箱)的幫助,我將以多文檔界面(Multiple Document Interface (MDI))文本編輯器爲例向您演示如何將僅 Windows 的 MFC 應用程序移植到 Linux。類似這樣的小型應用程序有助於我們將討論集中在移植框架的具體細節上,從而避免我們迷失在代碼的汪洋中。可以在本文後面的參考資料一節中獲取完整的 MFC 應用程序和 wxWindows 應用程序的源代碼。

文檔/視圖概述
我將演示的應用程序使用衆所周知的文檔/視圖體系結構,因爲它可以象大多數應用程序一樣處理文檔。即使您的應用程序不使用文檔/視圖體系結構,我也建議您讀下去。只要您已在轉向這種框架,您就可能想要添加這項功能。

在我的關於 wxWindows 的 前一篇文章中,曾經指出過 MFC 和 wxWindows 之間具有某些相似性。字符串類 CString 、 wxString 和事件系統之間都非常相似。但還不止這些相似性。wxWindows 工具箱還提供對文檔/視圖體系結構的類 MFC 支持。

我將從核心類的比較開始。下表列出了兩種框架的文檔/視圖體系結構所涉及的類。

表 1. 文檔/視圖類比較
類  MFC 類  wxWindows 類 
文檔(Document) CDocument wxDocument
視圖(View) CView wxView
編輯視圖(Edit view) CEditView n/a
模板類(Template class) CMultiDocTemplate wxDocTemplate
MDI 父框架(MDI parent frame) CMDIFrameWnd wxDocMDIParentFrame
MDI 子框架(MDI child frame) CMDIChildWnd wxDocMDIChildFrame
文檔管理器(Document manager) n/a wxDocManager


除編輯視圖類以外,每個 MFC 類都有其對應的 wxWindows 類。(最後一項中 MFC 的部分爲空,因爲 MFC 沒有獨立的文檔管理器類。由應用程序類 CWinApp 內部處理文檔。)下列 UML 圖演示了這些類之間的關係:

圖 1. MFC 類


圖 2. wxWindows 類


應用程序
每個框架都提供一個表示應用程序本身的類。MFC 應用程序類聲明瞭一個構造器、一個用於初始化的方法、一個用於事件處理的方法和一個消息映射表。您需要這個消息映射表聲明和事件處理方法,因爲應用程序的“about”對話框將由該類處理。

應用程序類:MFC

class CPortMeApp : public CWinApp
{
public:
    CPortMeApp();
    virtual BOOL InitInstance();
    afx_msg void OnAppAbout();
    DECLARE_MESSAGE_MAP()
};

 

注:最初創建 MFC 應用程序時,我使用 Microsoft Visual Studio 所包含的應用程序嚮導來創建,但在我的代碼片段中,我將不給出由嚮導生成的、有時會使人迷惑的註釋( //{{AFX_MSG 及類似的東西)。完整的源代碼,請參閱 ZIP 壓縮文檔。

對應的 wxWindows 類看起來略微有些不同。它也聲明瞭一個構造器及一個用於初始化的方法,但卻不需要任何東西來處理消息。如同您隨後將看到的一樣,在主框架類中處理“about”對話框。

應用程序類:wxWindows

class PortedApp : public wxApp
{
  public:
    PortedApp();
    bool OnInit();
    int OnExit();
  protected:
    wxDocManager* m_docManager;
};


正如下面所描述的那樣,這個類需要一個 wxDocManager 屬性來處理在初始化方法 OnInit() 中創建的模板。應用程序退出時,清理方法 OnExit() 將刪除這個 wxDocManager 對象。

所有應用程序都需要其入口點(也稱爲 main() 或 WinMain() )。在實現這一點的方法上,兩種框架略微有些不同。在 MFC 中,象這樣創建應用程序類的靜態對象:


CPortMeApp theApp;

 

在 wxWindows 中,則象這樣使用 IMPLEMENT_APP() 宏:


IMPLEMENT_APP(PortedApp)

 

如果對該宏所做的事情感興趣,請查看頭文件 wx/app.h 中它的定義,在可下載的源代碼中找到該頭文件。基本上,它是爲所使用的平臺插入適當的入口點函數。創建了應用程序類的對象之後,需要對其進行初始化。對於 MFC,Microsoft 建議不使用應用程序對象的構造器來初始化對象。而是應該使用其 InitInstance() 方法。要執行任何清理,請實現 ExitInstance() 方法。

雖然應用程序初始化有很多事情要做,這裏我將只着重討論與文檔/視圖有關的代碼。要建立文檔/視圖框架, InitInstance() 方法必須創建一個 CMultiDocTemplate ,如下所示:

創建文檔/視圖代碼:MFC

CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(
    IDR_PORTMETYPE,
    RUNTIME_CLASS(CPortMeDoc),
    RUNTIME_CLASS(CChildFrame),
    RUNTIME_CLASS(CPortMeView));

 

wxWindows 應用程序提供 OnInit() 方法來做任何初始化工作,並提供 OnExit() 用於清理。要在 wxWindows 應用程序中建立文檔/視圖框架, OnInit() 方法必須象這樣創建 wxDocTemplate :

創建文檔/視圖代碼:wxWindows

m_docManager = new wxDocManager();

wxDocTemplate* pDocTemplate;
pDocTemplate = new wxDocTemplate(
    m_docManager, "Pom", "*.pom", "", "pom", "Pom Doc", "Text View",
    CLASSINFO(PortedDoc),
    CLASSINFO(PortedView));

 

MFC 和 wxWindows 所做的事情基本上相同。框架需要關於哪個文檔同哪個視圖有關以及這個組合處理哪種文檔的信息。類型包括文檔的描述性名稱以及這類文檔的文件擴展名。兩種框架都使用模板來處理這一問題(請注意這與標準 C++ 模板沒有什麼關係)。

MFC CMultiDocTemplate 也保存關於同文檔相關聯的子框架的信息,並且該模板被添加到管理該模板的應用程序對象中。wxWindows wxDocTemplate 額外需要一個管理模板的 wxDocManager 對象。請記住, wxDocManager 是 wxWindows 應用程序的應用程序類的一個屬性。

完成文檔/視圖框架初始化之後,就創建了應用程序的主框架。在 MFC 應用程序的 InitInstance() 方法中,按如下創建一個主框架:

創建主框架:MFC

CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
    return FALSE;

m_pMainWnd = pMainFrame;

pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow();

 

調用 pMainFrame->LoadFrame(IDR_MAINFRAME) 從資源文件裝入所有關於主框架的信息。

在 wxWindows 中,可以從資源文件建立菜單、對話框以及控件,或者可以在代碼中創建它們。我更喜歡在代碼中創建它們,但如果您願意將代碼同資源分離,就應該看一看 wxWindows 資源系統(請參閱 wxWindows 文檔中的主題概述)。

創建主框架:wxWindows

m_mainFrame = new MainFrame(m_docManager, (wxFrame*) NULL, "DocView Demo",
                            wxPoint(0, 0), wxSize(500, 400),
                            wxDEFAULT_FRAME_STYLE);

// Set up menu bar...

m_mainFrame->SetMenuBar(menu_bar);
m_mainFrame->Centre(wxBOTH);
m_mainFrame->Show(TRUE);

SetTopWindow(m_mainFrame);

 

在查看應用程序初始化完成後發生了什麼事情之前,讓我向您演示每個框架的文檔和視圖類。

文檔
文檔保存應用程序處理的基於文件的數據。它負責從文件裝入該數據,並在必要的時候將該數據保存迴文件。該 MFC 類的聲明類似於這樣:

文檔類聲明:MFC

class CPortMeDoc : public CDocument
{
  protected:
    CPortMeDoc();
    DECLARE_DYNCREATE(CPortMeDoc)

  public:
    virtual BOOL OnNewDocument();
    virtual void Serialize(CArchive& ar);

    virtual ~CPortMeDoc();
    DECLARE_MESSAGE_MAP()
};

 

請注意:該類有一個受保護(protected)的構造器。決不要直接創建該類的任何對象;相反,框架使用序列化來創建文檔。因此,需要使用 DECLARE_DYNCREATE() 宏。wxWindows 類的聲明類似於這樣:

文檔類聲明:wxWindows

class PortedDoc : public wxDocument
{
  public:
    virtual bool OnSaveDocument(const wxString& filename);
    virtual bool OnOpenDocument(const wxString& filename);
    virtual bool IsModified() const;
    virtual void Modify(bool mod);

  private:
    DECLARE_DYNAMIC_CLASS(PortedDoc)
};

 

DECLARE_DYNAMIC_CLASS() 宏是必需的,因爲 wxWindows 就象 MFC 一樣動態地創建該類的對象。

視圖
如果 MFC 應用程序處理文本文檔,那麼從 CEditView 派生視圖類是一個好主意。該類已經在其客戶機窗口內提供了基本的編輯功能和文本控件。這裏我遵循自己的建議,MFC 視圖類的聲明類似於這樣:

視圖類聲明:MFC

class CPortMeView : public CEditView
{
  protected:
    CPortMeView();
    DECLARE_DYNCREATE(CPortMeView)

  public:
    CPortMeDoc* GetDocument();
    virtual void OnDraw(CDC* pDC);
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

    virtual ~CPortMeView();
    DECLARE_MESSAGE_MAP()
};

 

在 wxWindows 中,(還)沒有專門的編輯視圖。但是創建您自己的編輯視圖卻很容易。只需在視圖框架內有一個由 wxTextCtrl 派生的文本控件。視圖類將控件和框架都當作類屬性來處理。因此 wxWindows 聲明類似於這樣:

視圖類聲明:wxWindows

class PortedView : public wxView
{
  public:
    MyTextCtrl* textsw;

    PortedView();

    bool OnCreate(wxDocument* doc, long flags);
    void OnDraw(wxDC* dc);
    bool OnClose(bool deleteWindow = TRUE);

  private:
    wxMDIChildFrame* CreateChildFrame(wxDocument* doc, wxView* view);

    wxFrame* frame;

    DECLARE_DYNAMIC_CLASS(PortedView)
};

 

除了常見的用於窗口創建、窗口重畫以及窗口關閉的事件處理程序之外,該類還有一個創建框架並填充其菜單欄的方法。

雖然擁有公共(public)屬性不是一個好主意,但是爲簡單起見,我在這裏還是這麼做。在您的應用程序中應該避免這麼做(我將在以後的版本中除去它)。

主框架
既然已經有了處理和顯示數據的文檔和視圖類,並且也有了處理文檔/視圖框架的應用程序類,現在需要一個主框架類來同用戶交互。同樣,兩種框架提供類似的功能,而實際實現有略微不同。MFC 主框架類將一個狀態欄和一個工具欄作爲屬性保存,同時 MFC 主框架類還提供一些方法來處理窗口創建,以及聲明消息映射表。請注意:該類是從 CMDIFrameWnd 派生而來的,因爲該應用程序有一個 MDI 界面。

主框架類:MFC

class CMainFrame : public CMDIFrameWnd
{
public:
        CMainFrame();
        virtual ~CMainFrame();

        virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

protected:
        CStatusBar  m_wndStatusBar;
        CToolBar    m_wndToolBar;

        afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

        DECLARE_MESSAGE_MAP()

private:
        DECLARE_DYNAMIC(CMainFrame)
};

 

wxWindows 主框架類將菜單作爲屬性保存,還具有創建其工具欄的方法,以及聲明一個事件表外加一個處理應用程序的 about 對話框的方法。因爲這個應用程序有一個 MDI 界面,所以該類是從 wxDocMDIParentFrame 派生而來。

主框架類:wxWindows

class MainFrame : public wxDocMDIParentFrame
{
  public:
    wxMenu* editMenu;

    MainFrame(wxDocManager* manager, wxFrame* frame, const wxString& title,
              const wxPoint& pos, const wxSize& size, long type);

    void OnAbout(wxCommandEvent& event);
    void RecreateToolbar();

  private:
    DECLARE_CLASS(MainFrame);
    DECLARE_EVENT_TABLE();
};

 

全部工作原理
移植完成了。我來回顧一下實現這一點所需做的事情。MFC 應用程序類(派生自 CWinApp )移植到派生自 wxApp 的應用程序類,包括初始化代碼。將 MFC 文檔類(派生自 CDocument )移植到派生自 wxDocument 的文檔類。將 MFC 視圖類(派生自 CView )移植到派生自 wxView 的文檔類。除了這些同文檔/視圖有關的類之外,將 MFC 主框架類(派生自 CMDIFrameWnd )移植到派生自 wxDocMDIParentFrame 的類。

在其目前的版本中,該應用程序已經能夠做很多工作。可以處理多個文本文件。可以打開、編輯並保存這些文件,並且應用程序保持最近打開文件的歷史記錄。如果不得不從頭編寫這些功能,那麼將需要更多行代碼 ― 更多行代碼意味着要測試和維護更多行。在兩種框架中,都使用了專門的命令標識符來處理常用的同文檔/視圖有關的命令。常用的文件命令是新建、打開和保存。常用的編輯命令是剪切、複製和粘貼。其它經常使用的命令有打印命令(這個應用程序中還沒有實現該命令)和幫助命令。下表列出了這兩種框架結構的文檔/視圖體系結構所包含的命令標識符。

表 2. 標準的命令標識符
MFC  wxWindows 
ID_FILE_OPEN wxID_OPEN
ID_FILE_CLOSE wxID_CLOSE
ID_FILE_NEW wxID_NEW
ID_FILE_SAVE wxID_SAVE
ID_FILE_SAVE_AS wxID_SAVEAS
ID_EDIT_CUT wxID_CUT
ID_EDIT_COPY wxID_COPY
ID_EDIT_PASTE wxID_PASTE
ID_APP_EXIT wxID_EXIT
ID_EDIT_UNDO wxID_UNDO
ID_EDIT_REDO wxID_REDO
ID_HELP_INDEX wxID_HELP
ID_FILE_PRINT wxID_PRINT
ID_FILE_PRINT_SETUP wxID_PRINT_SETUP
ID_FILE_PRINT_PREVIEW wxID_PREVIEW


窗口管理器
如果您對 Linux 開發真的很感興趣,則可能已經做了一些研究,發現 Linux 上有不同的窗口管理器。曾經是 MFC 開發人員的您可能覺得這很奇怪。在進行 Windows 開發時,您無須操心不同的窗口管理器,因爲只有一個窗口管理器。

開始 wxWindows 開發時,您可能想知道您的應用程序是否將運行在兩個主流的窗口管理器 ― K 桌面環境(K Desktop Environment (KDE))和 GNOME ― 之上。我已經在 Microsoft Windows NT 4.0、使用公共桌面環境(Common Desktop Environment (CDE))的 Sun Solaris 2.6 以及使用 KDE 的 Linux 2.2 上使用了 wxWindows 工具箱,沒有任何問題。由於 wxWindows 僅僅是一個建立在其它低級別 GUI 工具箱上的高級別層次,所以可以選擇如何構建 Linux 應用程序。可以使用 Motif 版本(或者還要更好一些的,免費 Lesstif)或者 wxWindows 的 GTK+ 版本。GTK+ 是 GNOME 使用的基礎窗口構件工具箱,但是它在 KDE 下也運行得非常好。我建議您使用 GTK+ 版本,因爲它通常更新,有許多開發人員對它進行開發,而且有用戶在使用它。因此,如果您希望獲得更多幫助,則可以求助於郵件列表或新聞組,詢問關於 GTK+ 版本的問題。

下面是前前後後的抓屏,可以讓您對移植的應用程序有一個大致的認識。

圖 3. 原始的 MFC 應用程序


圖 4. Windows 上的 wxWindows 應用程序


圖 5. Linux/KDE 上的 wxWindows 應用程序


真實的故事
wxWindows 工具箱不只是書呆子的另一個玩具。它成熟、穩定,並且人們在實際應用程序中用它來解決實際問題。

wxWindows 項目創始人 Julian Smart 目前致力於 Red Hat,他已經將 eCos 配置工具(eCos Configuration Tool)移植到了 wxWindows。eCos 配置工具是一個配置 eCos 嵌入式操作系統的圖形工具。人們已將最初的 MFC 應用程序移植到了 wxWindows,尤其是在 Linux 上(參閱 參考資料)。 SciTech Software 的人員也已經使用 wxWindows 來全部重新開發用於 SciTech Display Doctor 產品的前端 GUI。IBM 已經獲得了 SciTech Display Doctor 的一個專門版本的許可證,IBM 現在將其作爲 IBM 所有基於 OS/2 Warp 的操作系統(包括 Warp Client、Workspace On Demand 及 Warp Server for e-business)的主要顯示驅動程序來分發。SciTech Software 對 wxWindows 社區做出了積極的貢獻,它提交了擴展包 wxApplet、wxUniversal 和 wxMGL。使用 wxMGL,wxWindows 應用程序甚至可以運行在 DOS 和其它嵌入式操作系統之上,例如 QNX、RT-Target、SMX 等等。SciTech Software 全力資助 wxUniversal 和 wxMGL 項目(參閱 參考資料)。

結束語
本文演示了使用 wxWindows 工具箱將 MFC 文檔/視圖框架的 Windows 應用程序移植到 Linux 的基本原理。wxWindows 工具箱同 MFC 框架有一些相似性,從而幫助 MFC 開發人員可以達到加速 Linux 開發。有了這些基礎知識,您應該能夠將最棒的應用程序移植到 Linux。但不要忘了:wxWindows 不是隻能用於 Linux。也許該是考慮在其它 UNIX 或者甚至 Macintosh 上來運行您的應用程序一個版本的時候了。
 
UID
153489
帖子
622
精華
5
積分
1520
閱讀權限
50
來自
China
在線時間
6 小時
註冊時間
2004-9-16
最後登錄
2008-6-13
查看詳細資料
 TOP
 

hobby!

高級會員

 

發短消息
加爲好友
當前離線
 4# 大 中 小 發表於 2005-4-26 22:15  只看該作者
跨平臺C++程序開發的利器
跨平臺C++程序開發的利器
wxWindows原來叫做wxWidgets,是由Julian Smart於1992年還在英國愛丁堡大學人工智能應用研究所開始的一個項目。Julian Smart現在是Anthemion軟件公司的技術總監。1995年的時候,Markus Holzem發佈了一個移植到Xt (X Toolkit)的版本。1997年五月,Windows版本和GTK+版本被合併。

簡單地說,wxWidgets提供了用於可在多平臺上開發GUI應用程序的一整套簡單易學易用的API。wxWidgets支持的多平臺包括 Windows 3.1/95/98/NT/2000/XP、帶有Motif 1.2版本以上的Unix、帶有GTK+的Unix/Linux/*BSD、Mac等等。開發者只需要用自己使用的系統平臺的編譯器編譯源程序,並鏈接上相應的庫文件,生成的程序代碼即具有該平臺的外觀和界面。在這些GUI之上,wxWidgets還提供了在線幫助、網絡編程、流處理、多種常用圖形格式支持、數據庫支持、HTML察看和打印,等等各種強大的功能。

wxWidgets支持的Windows上的多種流行編譯器包括:

Visual C++ 1.5, 4.0, 5.0, 6.0
Borland C++ 4.5, 5.0
Borland C++ Builder 1.0, 3.0
Watcom C++ 10.6 (Win32)
Cygwin
MinGW32
Metrowerks CodeWarrior 4
wxWidgets的一大吸引力是它的wxWidgets 2 licence類型是屬於L-GPL (Library General Public Licence)的,也就是說,使用它開發的軟件並不要求一定得公開源碼。這樣,無論是免費軟件的開發者、GPL類型軟件開發者,還是純粹商業軟件開發者都可以免費使用這個軟件包。

相比之下,TrollTech的Qt似乎正是因爲此因素而影響了它的受接受程度,因爲用Qt開發商用軟件者所需交納的費用對於個人開發者來說還是比較昂貴的,而且分單平臺、二平臺、三平臺(即Qt/X11、Qt/Windows和Qt/Mac都包含在內了)三個不同產品包,又分Professional和 Enterprise不同Edition亦即不同價位,而且開發人員數不同價格也不同。

從這點說來,wxWidgets是絕對具有優勢的。

另外Qt似乎是起源於Linux上的開發,後來推展到Windows、Mac等其它平臺;而wxWidgets恰好相反,始於Windows,其後移植到Unix等其它平臺。不過這一點本人尚未深入去調查具體情況,所以姑且聽之吧。

http://www.silu.org/articles/article.php?articleid=9 
 

 


本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/skyremember/archive/2008/10/21/3117352.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章