follow my heart...
分类: C/C++
2006-08-24 10:01:55
这是我看到的最简单有效的入门教程了
wxWidgets formerly known as wxWindows is a framework for developing cross-platform GUI applications in C++. Julian Smart started the framework in 1992 at the Artificial Intelligence Applications Institute, University of Edinburgh. In 1995, a port to Xt was released by Markus Holzem. In May 1997, the Windows and the GTK+ ports were merged and put into a CVS repository.
wxWidgets gives you a single, easy-to-use API for writing GUI applications on multiple platforms. Link it with the appropriate library for your platform (Windows/Unix/Mac) and compiler (almost any popular C++ compiler), and your application will adopt the look and feel appropriate to that platform. On top of the great GUI functionality, wxWindows gives you: online help, network programming, streams, clipboard and drag and drop, multithreading, image loading and saving in a variety of popular formats, database support, HTML viewing and printing, and much more.
wxWidgets is a framework very much similar to MFC, except for a few negative points of its own. Those MFC programmers who are aware of the growing number of Linux users and who want to write cross platform GUI applications can use wxWidgets. With wxWidgets, it is very easy to use a framework based on C++ and it has a proven record of 13 years. In fact, wxWidgets is very stable and is supported on:
There are a number of options available for writing cross platform GUI development, like: JAVA, Mono.NET, Qt, etc. Java has failed to prove itself as an efficient alternative. Qt is good but commercial and nobody knows its future. Mono.NET seems to be good but is largely driven by Microsoft, it seems like a copy of the work done by Microsoft and it has not yet proved itself as a successful alternative. Also, people would not like to use an extra burden of layer for highly efficient software. As wxWidgets does not use any middle layer and uses only the native controls available on the platform, it gives a nice look and feel to the application.
wxRegEx
, wxFTP
, wxSplashScreen
, wxZipInputStream
, etc.
wxGenericDirCtrl
, wxCalendarCtrl
, wxDatePickerCtrl
, wxTipWindow
, wxStyledTextCtrl
, wxStaticPicture
, wxLEDNumberCtrl
, wxEditableListBox
, wxFoldPanelBar
, wxGIFAnimationCtrl
, wxSplashScreen
, OGL
(Object Graphics Library), FL
(Frame Layout), etc. is one of the main repository.
wxSMTP
, wxHTTP
, wxFTP
.
wxRarInputStream
.
wxDao
.
wxMozilla
, wxIE
.
MFC version | wxWidgets version |
---|---|
BEGIN_MESSAGE_MAP |
BEGIN_EVENT_TABLE |
END_MESSAGE_MAP |
END_EVENT_TABLE |
DECLARE_DYNAMIC |
DECLARE_CLASS |
DECLARE_DYNCreate |
DECLARE_DYMAMIC_CLASS |
IMPLEMENT_DYNAMIC |
IMPLEMENT_CLASS |
IMPLEMENT_DYNCreate |
IMPLEMENT_DYNAMIC_CLASS |
IsKindOf (RUNTIME_CLASS (CWindow)) |
IsKindOf (CLASSINFO(wxWindow)) |
Miscellaneous Classes | |
MFC version | wxWidgets version |
---|---|
CWinApp |
|
CObject |
|
CCmdTarget |
|
CCommandLineInfo |
|
CMenu |
, , |
CWaitCursor |
wxBusyCursor |
CDataExchange |
|
Window Classes | |
MFC version | wxWidgets version |
CFrameWnd |
|
CMDIFrameWnd |
|
CMDIChildWnd |
|
CSplitterWnd |
|
CToolBar |
|
CStatusBar |
|
CReBar |
, but see contrib/src/fl and , |
CPropertyPage |
|
CPropertySheet |
, |
Dialog Classes | |
MFC version | wxWidgets version |
CDialog |
|
CColorDialog |
|
CFileDialog |
|
CFindReplaceDialog |
|
CFontDialog |
|
CPageSetupDialog |
|
CPrintDialog |
|
Control Classes | |
MFC version | wxWidgets version |
CAnimateCtrl |
, wxAnimationCtrl |
CButton |
|
CBitmapButton |
|
CComboBox |
, |
CDateTimeCtrl |
|
CEdit |
|
CHotKeyCtrl |
None, but see Keybinder |
CListBox , CDragListBox |
|
CCheckListBox |
|
CListCtrl |
, |
CMonthCalCtrl |
|
CProgressCtrl |
|
CReBarCtrl |
None, but see contrib/src/fl and , |
CRichEditCtrl |
|
CScrollBar |
|
CSliderCtrl |
|
CSpinButtonCtrl |
, |
CStatic |
, , , |
CStatusBarCtrl |
|
CTabCtrl |
|
CToolBarCtrl |
|
CToolTipCtrl |
|
CTreeCtrl |
|
Graphics Classes | |
MFC version | wxWidgets version |
CBitmap |
, wxImage, , wxCursor |
CBrush |
|
CPen |
|
CFont |
|
CImageList |
wxImageList, |
CPalette |
|
CRgn |
|
CClientDC |
|
CMetaFileDC |
|
CPaintDC |
|
CWindowDC |
|
CDC |
, |
Data Structure Classes | |
MFC version | wxWidgets version |
CArray , CObArray , CPtrArray |
|
CStringArray |
|
CDWordArray , CByteArray , CUIntArray |
|
CList , CPtrList , CObList |
|
CStringList |
, |
CMap |
|
CString |
|
CPoint |
|
CRect |
|
CSize |
|
CTime |
|
CTimeSpan |
, |
COleVariant |
|
Internet Classes | |
MFC version | wxWidgets version |
CSocket |
|
CFtpConnection |
|
CHttpConnection |
|
Document/View Classes | |
MFC version | wxWidgets version |
CDocument |
wxDocument |
CView |
|
CDocTemplate , CSingleDocTemplate , CMultiDocTemplate |
|
Drag and Drop Classes | |
MFC version | wxWidgets version |
COleDataSource |
|
COleDropSource |
|
COleDropTarget |
|
File Classes | |
MFC version | wxWidgets version |
CFile |
, , |
CMemFile |
, |
CSocketFile |
, |
CRecentFileList |
|
Multithreading Classes | |
MFC version | wxWidgets version |
CWinThread |
|
CCriticalSection |
|
CMutex |
|
CSemaphore |
Starting with wxWidgets is really very easy. Just follow these steps:
Hello world is a classic example to start learning any new language. It gives an overview of the language without going deeper into it.
/*
* hworld.cpp
* Hello world sample by Robert Roebling
*/
#i nclude "wx/wx.h"
class MyApp: public wxApp
{
virtual bool OnInit();
};
class MyFrame: public wxFrame
{
public:
MyFrame(const wxString& title,
const wxPoint& pos, const wxSize& size);
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
DECLARE_EVENT_TABLE()
};
enum
{
ID_Quit = 1,
ID_About,
};
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_Quit, MyFrame::OnQuit)
EVT_MENU(ID_About, MyFrame::OnAbout)
END_EVENT_TABLE()
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame( "Hello World",
wxPoint(50,50), wxSize(450,340) );
frame->Show(TRUE);
SetTopWindow(frame);
return TRUE;
}
MyFrame::MyFrame(const wxString& title,
const wxPoint& pos, const wxSize& size)
: wxFrame((wxFrame *)NULL, -1, title, pos, size)
{
wxMenu *menuFile = new wxMenu;
menuFile->Append( ID_About, "&About..." );
menuFile->AppendSeparator();
menuFile->Append( ID_Quit, "E&xit" );
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append( menuFile, "&File" );
SetMenuBar( menuBar );
CreateStatusBar();
SetStatusText( "Welcome to wxWindows!" );
}
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close(TRUE);
}
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox("This is a wxWindows Hello world sample",
"About Hello World", wxOK | wxICON_INFORMATION, this);
}
"$(WXWIN)\include";"$(WXWIN)\contrib\include";"$(WXWIN)\lib\mswd"
And for the "Release" configuration add the following line:
"$(WXWIN)\include";"$(WXWIN)\contrib\include";"$(WXWIN)\lib\msw"
WIN32;_DEBUG;_WINDOWS;__WINDOWS__;__WXMSW__;__WXDEBUG__;WXDEBUG=1;
__WIN95__;__WIN32__;WINVER=0x0400;STRICT
And for the "Release" configuration, add the following line:
NDEBUG,WIN32,_WINDOWS,__WINDOWS__,__WXMSW__,__WIN95__,__WIN32__,
WINVER=0x0400,STRICT
Multi-threaded Debug DLL (/MDd)
And for the "Releasse" configuration as:
Multi-threaded DLL (/MD)
"$(WXWIN)\lib";"$(WXWIN)\contrib\lib";"$(WXWIN)\lib\vc_lib"
And for the "Release" configuration, add the following line:
"$(WXWIN)\lib";"$(WXWIN)\contrib\lib";"$(WXWIN)\lib\vc_lib"
wxmsw26d_core.lib wxbase26d.lib wxtiffd.lib wxjpegd.lib
wxpngd.lib wxzlibd.lib wxregexd.lib wxexpatd.lib
winmm.lib comctl32.lib rpcrt4.lib wsock32.lib oleacc.lib
kernel32.lib user32.lib gdi32.lib winspool.lib
comdlg32.lib advapi32.lib shell32.lib ole32.lib
oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
wxmsw26_core.lib wxbase26.lib wxtiff.lib wxjpeg.lib
wxpng.lib wxzlib.lib wxregex.lib wxexpat.lib
winmm.lib comctl32.lib rpcrt4.lib wsock32.lib oleacc.lib
odbc32.lib kernel32.lib user32.lib gdi32.lib
winspool.lib comdlg32.lib advapi32.lib shell32.lib
ole32.lib oleaut32.lib uuid.lib odbccp32.lib
You have successfully created your first "Hello World" program with wxWidgets:
Install the Visual C++ 2005 Express by following the instructions given in and then configure the platform SDK by following steps given in . After this, you need to change the following:
[Editor comment: Line breaks used to avoid scrolling.]
%program Files%\Microsoft Visual Studio 8\VC\VCProjectDefaults\
corewin_express.vsprops
to set "_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE
" as PreprocessorDefinitions
.
An example corewin_express.vsprops file:
Version="8.00" Name="Core Windows Libraries">
"kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib" />
"_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE" />
Then open the file $(WXWIN)\src\msw\main.cpp, search for the function 'DllMain
' and add the following lines:
#if _MSC_VER >= 1400 && _WINDLL
#undef _WINDLL
#endif
before the line:
#if defined(_WINDLL)
After you have configured your Visual Studio, the remaining steps are the same, simply follow the instructions given above for Visual Studio .NET, and open the wx.dsw file and compile the libraries for all the project configurations namely: Debug, Release, Debug DLL, Release DLL, Unicode Debug, Unicode Release, Unicode Debug DLL, Unicode Release DLL.
VC8 has also changed the way manifests are embedded in your executable. Your project will not be built if you include wx.manifest in your resource file. First, exclude the manifest from your resources by adding the define statement to your YourAppName.rc file:
#define wxUSE_NO_MANIFEST 1
Second, add these lines to your one of your source or header files to enable XP-Style common controls:
#if defined(__WXMSW__) && !defined(__WXWINCE__)
#pragma comment(linker, "\"/manifestdependency:type='win32'
name='Microsoft.Windows.Common-Controls' version='6.0.0.0'
processorArchitecture='X86' publicKeyToken='6595b64144ccf1df'\"")
#endif
Due to the large number of pictures and high downloading time, this section has been moved to a new article. Working with wxWidgets on Linux, can be found .
You have to include wxWidgets' header files, of course. This can be done on a file by file basis (such as #i nclude "wx/window.h"
) or using one global include (#i nclude "wx/wx.h"
). This is also useful on platforms that support precompiled headers such as all major compilers on the Windows platform:
// file name: hworld.cpp
//
// purpose: wxWidgets "Hello world"
//
// For compilers that support precompilation,
// includes "wx/wx.h".
#i nclude "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#i nclude "wx/wx.h"
#endif
Practically, every app should define a new class derived from wxApp
. By overriding wxApp
's OnInit()
, the program can be initialized, e.g. by creating a new main window.
class MyApp: public wxApp { virtual bool OnInit(); };
The main window is created by deriving a class from wxFrame
and giving it a menu and a status bar in its constructor. Also, any
class that wishes to respond to any "event" (such as mouse clicks or
messages from the menu or a button) must declare an event table using
the macro below. Finally, a way to react to such events must be done in
"handlers". In our sample, we react to two menu items, one for "Quit"
and one for displaying an "About" window. These handlers should not be virtual
:
class MyFrame: public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos,
const wxSize& size);
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
private:
DECLARE_EVENT_TABLE()
};
In order to be able to react to a menu command, it must be given a unique identifier such as a const
or an enum
.
enum
{
ID_Quit = 1,
ID_About,
};
We then proceed to actually implement an event table in which the
events are routed to their respective handler functions in the class MyFrame
.
There are predefined macros for routing all the common events, ranging
from the selection of a list box entry to a resize event when a user
resizes a window on the screen. If -1 is given as the ID, the given
handler will be invoked for any event of the specified type, so that
you could just add one entry in the event table for all menu commands
or all button commands etc. The origin of the event can still be
distinguished in the event handler as the (only) parameter in an event
handler is a reference to a wxEvent
object, which holds information about the event (such as the ID of and a pointer to the class, which caused the event).
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_Quit, MyFrame::OnQuit)
EVT_MENU(ID_About, MyFrame::OnAbout)
END_EVENT_TABLE()
As in all programs, there must be a "main" function. Under wxWidgets, main is implemented using this macro, which creates an application instance and starts the program:
IMPLEMENT_APP(MyApp)
As mentioned above, wxApp::OnInit()
is called upon
startup and should be used to initialize the program, maybe for showing
a "splash screen" and creating the main window (or several). The frame
should get a title bar text ("Hello World") and a position and start-up
size. One frame can also be declared as the top window. Returning TRUE
indicates a successful initialization:
bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame( "Hello World",
wxPoint(50,50), wxSize(450,340) );
frame->Show( TRUE );
SetTopWindow( frame );
return TRUE;
}
In the constructor of the main window (or later on) we create a menu with two menu items as well as a status bar to be shown at the bottom of the main window. Both have to be "announced" to the frame with the respective calls:
MyFrame::MyFrame(const wxString& title,
const wxPoint& pos, const wxSize& size)
: wxFrame((wxFrame *)NULL, -1, title, pos, size)
{
wxMenu *menuFile = new wxMenu;
menuFile->Append( ID_About, "&About..." );
menuFile->AppendSeparator();
menuFile->Append( ID_Quit, "E&xit" );
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append( menuFile, "&File" );
SetMenuBar( menuBar );
CreateStatusBar();
SetStatusText( "Welcome to wxWidgets!" );
}
Here are the actual event handlers. MyFrame::OnQuit()
closes the main window by calling Close()
. The parameter TRUE
indicates that other Windows have no veto power, such as after asking
"Do you really want to close?". If there is no other main window left,
the application will quit:
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close( TRUE );
}
MyFrame::OnAbout()
will display a small window i.e. a
Message box with some text in it. In this case, a typical "About"
window with information about the program:
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox( "This is a wxWidgets's Hello world sample",
"About Hello World", wxOK | wxICON_INFORMATION );
}
An event table is placed in an implementation file to tell wxWindows
how to map events to member functions. These member functions are not virtual
functions, but they are all similar in form: they take a single wxEvent
-derived argument, and have a void
return type.
Here's an example of an event table:
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU (wxID_EXIT, MyFrame::OnExit)
EVT_MENU (DO_TEST, MyFrame::DoTest)
EVT_SIZE ( MyFrame::OnSize)
EVT_BUTTON (BUTTON1, MyFrame::OnButton1)
END_EVENT_TABLE()
The first two entries map menu commands to two different member functions. The EVT_SIZE
macro doesn't need a window identifier, since normally you are only
interested in the current window's size events. (In fact, you could
intercept a particular window's size event by using EVT_CUSTOM
(wxEVT_SIZE
, ID, func).)
The EVT_BUTTON
macro demonstrates that the originating
event need not come from the window class implementing the event table
- if the event source is a button within a panel within a frame, this
will still work, because event tables are searched up through the
hierarchy of W