• <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

            厚積薄發(fā). 勤為槳,思為帆

               :: 首頁(yè) :: 新隨筆 ::  :: 聚合  :: 管理 ::
              73 隨筆 :: 4 文章 :: 22 評(píng)論 :: 0 Trackbacks

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

            為什么用VC6,只不過(guò)此文專門針對(duì)VC6而已。

            創(chuàng)建項(xiàng)目

            點(diǎn)擊菜單:File -> New... 創(chuàng)建一個(gè)"Win32 Application" Project,項(xiàng)目名稱為"wxProject",點(diǎn)擊OK按鈕,

            在下一步的提示中選擇"An Empty Project",點(diǎn)擊Finish按鈕完成項(xiàng)目的創(chuàng)建。

            以下的設(shè)置和操作可能有一些繁瑣,但這是一勞永逸的事情。只要你完成了第一個(gè)空白工程,以后再需要?jiǎng)?chuàng)建工程時(shí)復(fù)制一份就可以了。

             

            設(shè)置項(xiàng)目屬性

            以下四個(gè)編譯配置并不要求都必須設(shè)置好,如果您不打算使用Unicode,那么不用設(shè)置"Win32 Unicode Debug"和"Win32 Unicode Release",如果您僅僅想調(diào)試程序而非發(fā)布,則只需設(shè)置相應(yīng)的"Debug"不用設(shè)置"Release"。最簡(jiǎn)單的情況下,只需設(shè)置"Win32 Debug"。

            還有一點(diǎn)要注意,您需要事先編譯出相應(yīng)版本的 wxWidgets 庫(kù)文件。如"Win32 Unicode Debug"需要 Unicode+Debug 版本的 wxWidgets 庫(kù)。(wxWidgets 各種版本庫(kù)均可通過(guò) \build\msw\wx.dsw 進(jìn)行編譯)。

            點(diǎn)擊菜單:Project -> Settings... 打開項(xiàng)目屬性設(shè)置對(duì)話框。

            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 

            進(jìn)行以下操作之前,請(qǐng)先通過(guò)菜單 Build -> Configurations... 增加兩個(gè)編譯配置"Win32 Unicode Debug"和"Win32 Unicode Release"(分別復(fù)制于"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 

             

            設(shè)置wxWidgets目錄

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

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

            Include files:

            \include

            \include\msvc

            Library files:

            \lib\vc_lib

            Source files:

            \src

            這一設(shè)置是針對(duì)VC全局的,以后再用VC創(chuàng)建wxWigets程序,就不用設(shè)置這些路徑了。

             

            創(chuàng)建wxWidgets預(yù)編譯頭文件

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

            點(diǎn)擊菜單 File -> New...,新建一個(gè)C/C++頭文件 wx_pch.h,其內(nèi)容如下:

            #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中基本上就是這樣子,我只是簡(jiǎn)單的增加了一行"#include "(為了使用XRC文件)。

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

             

            創(chuàng)建wxApp子類

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

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

            app.h

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

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

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

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

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

            // 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

            增加頭文件包含(此頭文件將在下面創(chuàng)建MainFrame類時(shí)創(chuàng)建):#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 的內(nèi)容如下(其中經(jīng)過(guò)手工改寫的地方已用黃色背景突出顯示):

            #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;
            }

             

            創(chuàng)建wxFrame子類

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

            下面對(duì)VC生成的類代碼進(jìn)行相應(yīng)的修改:

            mainframe.h

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

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

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

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

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

            #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

            修改構(gòu)造函數(shù)的定義:

            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 的內(nèi)容如下(其中經(jīng)過(guò)手工改寫的地方已用黃色背景突出顯示):

            #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()
            {
            }

             

            至此,一個(gè)wxWidget的空白Project已經(jīng)創(chuàng)建完畢


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

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

            此數(shù)據(jù)全部是靜態(tài)鏈接wxWidgets的結(jié)果。動(dòng)態(tài)鏈接的話,EXE的大小沒(méi)有意義——?jiǎng)e忘了wxWidgets的版DLLs的大小總共約4到5M(Release版)。

             

            添加子控件

            向 wxFrame 或 wxDialog 中添加子控件是比較容易的,只需在其子類的構(gòu)造函數(shù)中 new 相應(yīng)的子控件就可以了。

            這是最簡(jiǎn)單的情況:

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

            沒(méi)錯(cuò),只要"new"一下就搞定了,控件會(huì)自動(dòng)出現(xiàn)在wxFrame中。這是運(yùn)行結(jié)果:


            如果界面再?gòu)?fù)雜一些,上面這種方法就行不通了,我們需要引入"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, _("測(cè)試按鈕"), 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);
            }

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


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

            enum CtrlID
            {
               
            ID_TEXTCTRL, ID_BUTTON
            };

             

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

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

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

             

            處理事件

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

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

            作為示例,我們來(lái)處理上圖中"測(cè)試按鈕"被按下的事件。

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

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

            private:
               
            void OnButtonClick( wxCommandEvent& event);

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

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

            下面需要在 mainframe.cpp 中填寫"事件表(EVENT_TABLE)",以便我們的"事件處理函數(shù)(方法)"能在適當(dāng)?shù)臅r(shí)機(jī)(即事件觸發(fā)時(shí))被調(diào)用:

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

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

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



             

            如何處理其它事件?

            說(shuō)白了,關(guān)鍵要知道兩點(diǎn):事件處理函數(shù)(方法)的參數(shù)是什么類型,填寫參數(shù)表時(shí)用哪一個(gè)宏(EVT_*)。

            再補(bǔ)充一點(diǎn):要知道"什么控件"在"什么時(shí)機(jī)"會(huì)觸發(fā)"什么事件"。

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

            建議看一下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頁(yè))中對(duì)事件處理時(shí)所涉及的事件類型(wxXXXEvent)和事件宏(EVT_*)有比較好的總結(jié),建議看一下,最好打印出來(lái)放在手邊,以便隨時(shí)參考。

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

             

            更進(jìn)一步

            了解 Sizer,熟悉界面設(shè)計(jì):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 上找第三方的控件/庫(kù):http://www.wxwidgets.org/contrib2.htm#classes

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

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

            posted on 2008-11-05 00:55 kenlistian 閱讀(1675) 評(píng)論(0)  編輯 收藏 引用 所屬分類: wxwidgets
            久久国产精品99久久久久久老狼 | 精品久久久久久国产潘金莲| 国产69精品久久久久9999APGF | 久久受www免费人成_看片中文| 亚洲精品无码久久久| 久久精品中文字幕一区| 热re99久久6国产精品免费| 亚洲精品乱码久久久久久| 亚洲国产精品婷婷久久| 日本精品久久久久久久久免费| 中文字幕无码免费久久| 久久午夜电影网| 精品国产乱码久久久久软件| 久久国产热精品波多野结衣AV| 91精品国产色综久久| 亚洲午夜久久久影院| 国内精品久久久久久久亚洲| 99久久国产综合精品女同图片| 久久青草国产手机看片福利盒子| 国产精品久久久久免费a∨| 久久精品国产99国产电影网| 久久国产欧美日韩精品免费| 久久精品国产99国产电影网| 久久国产免费直播| 亚洲日韩欧美一区久久久久我| 国产一久久香蕉国产线看观看| 国产免费久久精品99re丫y| 国产成人久久精品二区三区| av午夜福利一片免费看久久| 久久婷婷国产剧情内射白浆| 久久se精品一区二区影院| 国产精品久久久久久一区二区三区| 模特私拍国产精品久久| 精品国产青草久久久久福利 | 久久综合色区| 久久精品无码一区二区三区日韩| 久久99精品国产99久久| 狠狠久久亚洲欧美专区| 久久精品午夜一区二区福利| 久久亚洲精精品中文字幕| 囯产精品久久久久久久久蜜桃 |