• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            kenlistian

            厚積薄發. 勤為槳,思為帆

               :: 首頁 :: 新隨筆 ::  :: 聚合  :: 管理 ::
              73 隨筆 :: 4 文章 :: 22 評論 :: 0 Trackbacks

            前言:wxWidgets 是跨平臺的GUI庫,用VC6會影響它的跨平臺性嗎?當然不會,我們只是用VC6充當編譯器和編輯器,只要編寫代碼時注意不使用Windows相關的特性,寫出的代碼仍然是跨平臺的,仍然是可以在其它操作系統下(如Linux)使用其它C++編譯器(如GCC)編譯并運行的。

            為什么用VC6,只不過此文專門針對VC6而已。

            創建項目

            點擊菜單:File -> New... 創建一個"Win32 Application" Project,項目名稱為"wxProject",點擊OK按鈕,

            在下一步的提示中選擇"An Empty Project",點擊Finish按鈕完成項目的創建。

            以下的設置和操作可能有一些繁瑣,但這是一勞永逸的事情。只要你完成了第一個空白工程,以后再需要創建工程時復制一份就可以了。

             

            設置項目屬性

            以下四個編譯配置并不要求都必須設置好,如果您不打算使用Unicode,那么不用設置"Win32 Unicode Debug"和"Win32 Unicode Release",如果您僅僅想調試程序而非發布,則只需設置相應的"Debug"不用設置"Release"。最簡單的情況下,只需設置"Win32 Debug"。

            還有一點要注意,您需要事先編譯出相應版本的 wxWidgets 庫文件。如"Win32 Unicode Debug"需要 Unicode+Debug 版本的 wxWidgets 庫。(wxWidgets 各種版本庫均可通過 \build\msw\wx.dsw 進行編譯)。

            點擊菜單:Project -> Settings... 打開項目屬性設置對話框。

            Win32 Debug:

            C/C++ General:

            Preprocessor definitions: WIN32,_DEBUG,__WXMSW__,__WXDEBUG__,_MBCS,_WINDOWS,NOPCH

            C/C++ Code Generation:

            Use run-time library: Debug Multithreaded DLL

            Link General:

            Object/library modules: wxmsw26d_xrc.lib wxmsw26d_html.lib wxmsw26d_adv.lib wxmsw26d_core.lib wxbase26d_xml.lib wxbase26d.lib wxtiffd.lib wxjpegd.lib wxpngd.lib wxzlibd.lib wxregexd.lib wxexpatd.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib wsock32.lib odbc32.lib 

            Win32 Release:

            C/C++ General:

            Preprocessor definitions: WIN32,NDEBUG,__WXMSW__,_MBCS,_WINDOWS,NOPCH

            C/C++ Code Generation:

            Use run-time library: Multithreaded DLL

            Link General:

            Object/library modules: wxmsw26_xrc.lib wxmsw26_html.lib wxmsw26_adv.lib wxmsw26_core.lib wxbase26_xml.lib wxbase26.lib wxtiff.lib wxjpeg.lib wxpng.lib wxzlib.lib wxregex.lib wxexpat.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib wsock32.lib odbc32.lib 

            進行以下操作之前,請先通過菜單 Build -> Configurations... 增加兩個編譯配置"Win32 Unicode Debug"和"Win32 Unicode Release"(分別復制于"Win32 Debug"和"Win32 Release")。

            Win32 Unicode Debug:

            C/C++ General:

            Preprocessor definitions: WIN32,_DEBUG,__WXMSW__,__WXDEBUG__,_UNICODE,_WINDOWS,NOPCH

            C/C++ Code Generation:

            Use run-time library: Debug Multithreaded DLL

            Link General:

            Object/library modules: wxmsw26ud_xrc.lib wxmsw26ud_html.lib wxmsw26ud_adv.lib wxmsw26ud_core.lib wxbase26ud_xml.lib wxbase26ud.lib wxtiffd.lib wxjpegd.lib wxpngd.lib wxzlibd.lib wxregexud.lib wxexpatd.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib wsock32.lib odbc32.lib 

            Win32 Unicode Release:

            C/C++ General:

            Preprocessor definitions: WIN32,NDEBUG,__WXMSW__,_UNICODE,_WINDOWS,NOPCH

            C/C++ Code Generation:

            Use run-time library: Multithreaded DLL

            Link General:

            Object/library modules: wxmsw26u_xrc.lib wxmsw26u_html.lib wxmsw26u_adv.lib wxmsw26u_core.lib wxbase26u_xml.lib wxbase26u.lib wxtiff.lib wxjpeg.lib wxpng.lib wxzlib.lib wxregexu.lib wxexpat.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib wsock32.lib odbc32.lib 

             

            設置wxWidgets目錄

            在前面的設置中,指定了wxWidgets的庫文件(*.lib),但VC可能并不知道到哪個目錄去尋找這些文件。同時,我們的源代碼中也要包含 (include)wxWidgets的頭文件,其頭文件所在目錄也需要指定。另外,為了更好的調試wx程序,最好把wxWidgets的源代碼所在目錄 也設置好。

            點擊菜單 Tools -> Options...,進入 Directories 頁,分別加入以下路徑(下面的表示wxWidgets安裝目錄)

            Include files:

            \include

            \include\msvc

            Library files:

            \lib\vc_lib

            Source files:

            \src

            這一設置是針對VC全局的,以后再用VC創建wxWigets程序,就不用設置這些路徑了。

             

            創建wxWidgets預編譯頭文件

            各個編譯器不同,有的支持預編譯頭文件,有的不支持,支持預編譯頭文件的,使用的語法也有所不同,如果在每個源文件中都重復的寫未免不爽,還是集中到一個頭文件中來比較好。但是注意,有了此文件并不決定或限制你使用還是不使用預編譯頭文件,用不用以及怎么用還是在你。

            點擊菜單 File -> New...,新建一個C/C++頭文件 wx_pch.h,其內容如下:

            #ifndef WX_PCH_H_INCLUDED
            #define WX_PCH_H_INCLUDED

            #if ( defined(USE_PCH) && !defined(WX_PRECOMP ) )
            #define WX_PRECOMP
            #endif // USE_PCH

            // basic wxWidgets headers
            #include <wx/wxprec.h>

            // for use xrc files
            #include <wx/xrc/xmlres.h>

            #ifdef __BORLANDC__
            #pragma hdrstop
            #endif

            #ifndef
            WX_PRECOMP
            #include <wx/wx.h>
            #endif

            #ifdef
            USE_PCH
            // put here all your rarely-changing header files

            #endif // USE_PCH

            #endif // WX_PCH_H_INCLUDED

            wxWidgets官方文檔是大概也是這樣推薦,Code::Blocks中基本上就是這樣子,我只是簡單的增加了一行"#include "(為了使用XRC文件)。

            以后,工程中的源文件,只要包含(include) wx_pch.h 文件就可以了。

             

            創建wxApp子類

            點擊菜單 Insert -> New Class...,新建一個名稱為"App"的類(類名稱可以隨意),考慮到代碼的跨平臺性,建議將其所在文件的名稱修改為全部使用小寫字母(如 app.h/app.cpp)。此操作將生成文件 app.h 和 app.cpp。

            VC在這里生成的類代碼顯然是不滿足我們的要求的,需要進行以下修改:

            app.h

            增加預編譯頭文件 wx_pch.h 的包含(以后創建的每個.h文件都要包含它):#include "wx_pch.h"

            指定App類的父類為wxApp:即將"class App"修改為"class App : public wxApp"

            為類增加虛方法OnInit()的聲明:virtual bool OnInit();

            在類聲明的下方增加 wxWidgets App 聲明:DECLARE_APP(App)

            最終 app.h 的內容如下(其中經過手工改寫的地方已用黃色背景突出顯示):

            // by: liigo.com

            #if
            !defined( AFX_APP_H__B4514AF3_2125_487B_BD66_AF638A80E73A__INCLUDED_)
            #define AFX_APP_H__B4514AF3_2125_487B_BD66_AF638A80E73A__INCLUDED_

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

            #include "wx_pch.h"

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

            DECLARE_APP(App )

            #endif // !defined(AFX_APP_H__B4514AF3_2125_487B_BD66_AF638A80E73A__INCLUDED_)

            app.cpp

            增加頭文件包含(此頭文件將在下面創建MainFrame類時創建):#include "mainframe.h"

            增加 OnInit() 方法的定義(其中用到的MainFrame類定義于mainframe.h,見后文):

            bool App::OnInit()
            {
                MainFrame* mainFrame = new MainFrame(NULL, _("MainFrame
            by liigo.com"));
               
            mainFrame->Show ();
               
            SetTopWindow(mainFrame);
               
            return true;
            }

            在類定義的上方增加 wxWidgets App 定義:IMPLEMENT_APP(App)

            最終 app.cpp 的內容如下(其中經過手工改寫的地方已用黃色背景突出顯示):

            #include "app.h"

            IMPLEMENT_APP (App)

            App:: App()
            {
            }

            App::~App()
            {
            }

            bool App::OnInit()
            {
               
            MainFrame* mainFrame = new MainFrame(NULL, _("MainFrame by liigo.com"));
               
            mainFrame-> Show();
               
            SetTopWindow(mainFrame);
               
            return true;
            }

             

            創建wxFrame子類

            點擊菜單 Insert -> New Class...,新建一個名稱為"MainFrame"的類(類名稱可以隨意),考慮到代碼的跨平臺性,建議將其所在文件的名稱修改為全部使用小寫字母 (如 mainframe.h/mainframe.cpp)。此操作將生成文件 mainframe.h 和 mainframe.cpp。

            下面對VC生成的類代碼進行相應的修改:

            mainframe.h

            增加預編譯頭文件的包含:#include "wx_pch.h"

            指定MainFrane類的父類為wxFrame:class MainFrame : public wxFrame

            修改構造函數的聲明:MainFrame(wxWindow* parent, const wxString& title);

            在類定義的末尾增加事件表聲明:DECLARE_EVENT_TABLE()

            最終 mainframe.h 的內容如下(其中經過手工改寫的地方已用黃色背景突出顯示):

            #if !defined(AFX_MAINFRAME_H__1BC90331_B69E_40F2_BDF7_197550D70F07__INCLUDED_ )
            #define AFX_MAINFRAME_H__1BC90331_B69E_40F2_BDF7_197550D70F07__INCLUDED_

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

            #include "wx_pch.h"

            class MainFrame : public wxFrame
            {
            public:
               
            MainFrame( wxWindow* parent, const wxString & title);
               
            virtual ~MainFrame();

               
            DECLARE_EVENT_TABLE()
            };
            #endif // !defined(AFX_MAINFRAME_H__1BC90331_B69E_40F2_BDF7_197550D70F07__INCLUDED_)

            mainframe.cpp

            修改構造函數的定義:

            MainFrame::MainFrame(wxWindow* parent, const wxString& title) : wxFrame(parent, wxID_ANY, title)
            {
               
            //wxTextCtrl* text = new wxTextCtrl(this, wxID_ANY, _("some text"));
            }

            增加事件表定義(BEGIN_EVENT_TABLE 與 END_EVENT_TABLE 之間保留空白,留待以后綁定事件):

            BEGIN_EVENT_TABLE(MainFrame, wxFrame)

            END_EVENT_TABLE()

            最終 mainframe.cpp 的內容如下(其中經過手工改寫的地方已用黃色背景突出顯示):

            #include "mainframe.h"

            BEGIN_EVENT_TABLE (MainFrame, wxFrame)

            END_EVENT_TABLE()


            MainFrame::MainFrame( wxWindow* parent, const wxString& title) : wxFrame (parent, wxID_ANY, title)
            {
                //wxTextCtrl* text = new wxTextCtrl(this, wxID_ANY, _("some text"));
            }

            MainFrame ::~MainFrame()
            {
            }

             

            至此,一個wxWidget的空白Project已經創建完畢


            編譯生成的 exe 文件的大小:

            可執行文件大小 Debug Release
            Unicode 3.78M 956K
            非Unicode 3.60M 932K

            此數據全部是靜態鏈接wxWidgets的結果。動態鏈接的話,EXE的大小沒有意義——別忘了wxWidgets的版DLLs的大小總共約4到5M(Release版)。

             

            添加子控件

            向 wxFrame 或 wxDialog 中添加子控件是比較容易的,只需在其子類的構造函數中 new 相應的子控件就可以了。

            這是最簡單的情況:

            MainFrame::MainFrame(wxWindow* parent, const wxString& title) : wxFrame(parent, wxID_ANY, title)
            {
               
            wxTextCtrl * text = new wxTextCtrl( this, wxID_ANY, _("some text"));
            }

            沒錯,只要"new"一下就搞定了,控件會自動出現在wxFrame中。這是運行結果:


            如果界面再復雜一些,上面這種方法就行不通了,我們需要引入"Sizer"(詳見http://www.wxwidgets.org/manuals/2.6.3/wx_sizeroverview.html(Sizer一覽)):

            MainFrame::MainFrame(wxWindow* parent, const wxString& title) : wxFrame(parent, wxID_ANY, title)
            {
                wxTextCtrl * textCtrl = new wxTextCtrl( this, ID_TEXTCTRL, _T("some text"), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
               
            wxButton * button = new wxButton(this , ID_BUTTON, _("測試按鈕"), wxDefaultPosition , wxDefaultSize, 0 );

               
            wxBoxSizer* vBoxSizer = new wxBoxSizer(wxVERTICAL);
               
            this ->SetSizer(vBoxSizer);

               
            vBoxSizer->Add (textCtrl, 1, wxALL|wxEXPAND, 5);
               
            vBoxSizer->Add(button, 0 , wxALIGN_CENTER_HORIZONTAL|wxALL|wxALIGN_BOTTOM, 5);
            }

            上面是多行編輯框控件,下面是按鈕控件,當窗口大小變化時,編輯框控件將在水平和垂直方向上自動擴展,而按鈕始終位于窗口底部居中。


            上述代碼中涉及的控件ID(ID_TEXTCTRL,ID_BUTTON)是我們在 mainframe.cpp 中自行定義的(定義控件ID的目的是為了下一步了事件處理):

            enum CtrlID
            {
               
            ID_TEXTCTRL, ID_BUTTON
            };

             

            參考文檔:http://www.wxwidgets.org/manuals/2.6.3/wx_sizeroverview.html(Sizer一覽)

            采用XML格式文件(XRC文件)定義程序界面也是不錯的方式,詳見:http://www.wxwidgets.org/manuals/2.6.3/wx_xrcoverview.html(基于XML的資源系統一覽)。

            無論如何,手工進行界面布局總是很繁雜,我們需要(可視化)工具的幫助:http://www.wxwidgets.org/apps2.htm

             

            處理事件

            在wxWidgets中處理事件,主要有兩個步驟:編寫"事件處理函數(方法)",填寫"事件表(EVENT_TABLE)"。

            事件處理函數(方法)視事件的不同而有所不同,但也有規律:沒有返回值,只有一個引用型參數(且一定是wxEvent的子類),不是虛方法(virtual method)。事件處理函數(方法)的名稱沒有特殊規定,可以自行命名。

            作為示例,我們來處理上圖中"測試按鈕"被按下的事件。

            根據wxWidgets文檔,要處理按鈕事件,需在自己的類中添加如下事件處理函數(方法):void MainFrame::OnButtonClick (wxCommandEvent &event)

            具體說來就是,在 mainframe.h 文件中的 MainFrame 類中增加新的 OnButtonClick() 方法聲明:

            private:
               
            void OnButtonClick( wxCommandEvent& event);

            并在 mainframe.cpp 文件中增加 OnButtonClick() 方法的定義:

            void MainFrame::OnButtonClick( wxCommandEvent &event)
            {
               
            //取編輯框中的文本并用信息框顯示出來
                wxString text = ((wxTextCtrl*)this-> FindWindow(ID_TEXTCTRL))->GetValue();
               
            wxMessageBox (text);
            }

            下面需要在 mainframe.cpp 中填寫"事件表(EVENT_TABLE)",以便我們的"事件處理函數(方法)"能在適當的時機(即事件觸發時)被調用:

            BEGIN_EVENT_TABLE(MainFrame, wxFrame )
               
            EVT_BUTTON(ID_BUTTON, MainFrame ::OnButtonClick)
            END_EVENT_TABLE()

            在這個事件表中,我們使用宏 EVT_BUTTON 指定了按鈕的ID,以及"事件處理函數(方法)"。

            注:上面一直講"事件處理函數(方法)",其實是"方法(method)"不是"函數(function)",只是"方法"這個詞在編程領域和在日 常生活中可以有不同的理解("方法"也可以理解為"方式"),我如果說成"事件處理方法",難免會產生歧義。當然,"事件處理函數(方法)"似乎也并不十 分合適,應稱為"事件處理'方法'"或"事件處理方法(method)"?再深究下去就有咬文嚼字的嫌疑了,聰明的讀者早已明白我的意思了吧?



             

            如何處理其它事件?

            說白了,關鍵要知道兩點:事件處理函數(方法)的參數是什么類型,填寫參數表時用哪一個宏(EVT_*)。

            再補充一點:要知道"什么控件"在"什么時機"會觸發"什么事件"。

            要知道這些,就需要對wxWidgets的事件處理有一個比較全面的了解。

            建議看一下wxWidgets官方文檔中的這篇文章:http://www.wxwidgets.org/manuals/2.6.3/wx_eventhandlingoverview.html(事件處理一覽)

            尤其是其中的 Event macros summary(事件宏概要)一段。

            電子書《Cross-Platform GUI Programming with wxWidgets》附錄9(Appendix I, 617頁)中對事件處理時所涉及的事件類型(wxXXXEvent)和事件宏(EVT_*)有比較好的總結,建議看一下,最好打印出來放在手邊,以便隨時參考。

            本文所涉及的完整源代碼可在此下載:http://liigo.diy.myrice.com/article/wxProject/wxProject.zip

             

            更進一步

            了解 Sizer,熟悉界面設計:http://www.wxwidgets.org/manuals/2.6.3/wx_sizeroverview.html

            了解 事件處理:http://www.wxwidgets.org/manuals/2.6.3/wx_eventhandlingoverview.html

            了解 wxWidgets 提供了哪些控件,它們各自的屬性、方法、事件,以及它們的用法。

            去 wxWidgets.org 上找第三方的控件/庫:http://www.wxwidgets.org/contrib2.htm#classes

            wxWiki 上找第三方的控件/庫:http://www.wxwidgets.org/wiki/index.php/Table_Of_Contents#Pages_about_classes.2C_functions_or_macros

            GUI庫嘛?無非就是控件(component)的使用:布局、操作、事件處理。

            posted on 2008-11-05 00:55 kenlistian 閱讀(1672) 評論(0)  編輯 收藏 引用 所屬分類: wxwidgets
            久久国产热这里只有精品| 久久久久成人精品无码中文字幕 | 国产精品久久久久天天影视| 97精品依人久久久大香线蕉97| 中文无码久久精品| 久久99精品国产99久久| 久久人人爽人人爽AV片| 波多野结衣AV无码久久一区| 成人综合伊人五月婷久久| 久久免费视频一区| WWW婷婷AV久久久影片| 午夜精品久久久内射近拍高清 | 久久香综合精品久久伊人| 国产精品美女久久久久| 久久国产香蕉一区精品| 久久精品国产亚洲av影院| 亚洲国产综合久久天堂| 香蕉久久一区二区不卡无毒影院| 婷婷久久综合九色综合九七| www.久久热| 久久综合精品国产二区无码| 欧美精品丝袜久久久中文字幕 | 一本色道久久HEZYO无码| 91精品国产高清久久久久久91| 久久露脸国产精品| 国产三级精品久久| 青青草国产精品久久| 久久久久久无码Av成人影院| 综合久久精品色| 亚洲婷婷国产精品电影人久久| 国产精品久久国产精麻豆99网站 | 久久午夜电影网| 久久无码人妻一区二区三区| 无夜精品久久久久久| 天天综合久久一二三区| 久久夜色撩人精品国产| 久久国产精品一区| 久久久久女教师免费一区| 国产精品99久久精品爆乳| 国产精品女同一区二区久久| 国产99久久久久久免费看|