| 1 | \chapter{Porting from wxWidgets 1.xx}\label{porting} |
| 2 | |
| 3 | This addendum gives guidelines and tips for porting applications from |
| 4 | version 1.xx of wxWidgets to version 2.0. |
| 5 | |
| 6 | The first section offers tips for writing 1.xx applications in a way to |
| 7 | minimize porting time. The following sections detail the changes and |
| 8 | how you can modify your application to be 2.0-compliant. |
| 9 | |
| 10 | You may be worrying that porting to 2.0 will be a lot of work, |
| 11 | particularly if you have only recently started using 1.xx. In fact, |
| 12 | the wxWidgets 2.0 API has far more in common with 1.xx than it has differences. |
| 13 | The main challenges are using the new event system, doing without the default |
| 14 | panel item layout, and the lack of automatic labels in some controls. |
| 15 | |
| 16 | Please don't be freaked out by the jump to 2.0! For one thing, 1.xx is still available |
| 17 | and will be supported by the user community for some time. And when you have |
| 18 | changed to 2.0, we hope that you will appreciate the benefits in terms |
| 19 | of greater flexibility, better user interface aesthetics, improved C++ conformance, |
| 20 | improved compilation speed, and many other enhancements. The revised architecture |
| 21 | of 2.0 will ensure that wxWidgets can continue to evolve for the foreseeable |
| 22 | future. |
| 23 | |
| 24 | {\it Please note that this document is a work in progress.} |
| 25 | |
| 26 | \section{Preparing for version 2.0}\label{portingpreparing} |
| 27 | |
| 28 | Even before compiling with version 2.0, there's also a lot you can do right now to make porting |
| 29 | relatively simple. Here are a few tips. |
| 30 | |
| 31 | \begin{itemize} |
| 32 | \item {\bf Use constraints or .wxr resources} for layout, rather than the default layout scheme. |
| 33 | Constraints should be the same in 2.0, and resources will be translated. |
| 34 | \item {\bf Use separate wxMessage items} instead of labels for wxText, wxMultiText, |
| 35 | wxChoice, wxComboBox. These labels will disappear in 2.0. Use separate |
| 36 | wxMessages whether you're creating controls programmatically or using |
| 37 | the dialog editor. The future dialog editor will be able to translate |
| 38 | from old to new more accurately if labels are separated out. |
| 39 | \item {\bf Parameterise functions that use wxDC} or derivatives, i.e. make the wxDC |
| 40 | an argument to all functions that do drawing. Minimise the use of |
| 41 | wxWindow::GetDC and definitely don't store wxDCs long-term |
| 42 | because in 2.0, you can't use GetDC() and wxDCs are not persistent. |
| 43 | You will use wxClientDC, wxPaintDC stack objects instead. Minimising |
| 44 | the use of GetDC() will ensure that there are very few places you |
| 45 | have to change drawing code for 2.0. |
| 46 | \item {\bf Don't set GDI objects} (wxPen, wxBrush etc.) in windows or wxCanvasDCs before they're |
| 47 | needed (e.g. in constructors) - do so within your drawing routine instead. In |
| 48 | 2.0, these settings will only take effect between the construction and destruction |
| 49 | of temporary wxClient/PaintDC objects. |
| 50 | \item {\bf Don't rely} on arguments to wxDC functions being floating point - they will |
| 51 | be 32-bit integers in 2.0. |
| 52 | \item {\bf Don't use the wxCanvas member functions} that duplicate wxDC functions, such as SetPen and DrawLine, since |
| 53 | they are going. |
| 54 | \item {\bf Using member callbacks} called from global callback functions will make the transition |
| 55 | easier - see the FAQ |
| 56 | for some notes on using member functions for callbacks. wxWidgets 2.0 will banish global |
| 57 | callback functions (and OnMenuCommand), and nearly all event handling will be done by functions taking a single event argument. |
| 58 | So in future you will have code like: |
| 59 | |
| 60 | {\small |
| 61 | \begin{verbatim} |
| 62 | void MyFrame::OnOK(wxCommandEvent& event) |
| 63 | { |
| 64 | ... |
| 65 | } |
| 66 | \end{verbatim} |
| 67 | }% |
| 68 | |
| 69 | You may find that writing the extra code to call a member function isn't worth it at this stage, |
| 70 | but the option is there. |
| 71 | \item {\bf Use wxString wherever possible.} 2.0 replaces char * with wxString |
| 72 | in most cases, and if you use wxString to receive strings returned from |
| 73 | wxWidgets functions (except when you need to save the pointer if deallocation is required), there should |
| 74 | be no conversion problems later on. |
| 75 | \item Be aware that under Windows, {\bf font sizes will change} to match standard Windows |
| 76 | font sizes (for example, a 12-point font will appear bigger than before). Write your application |
| 77 | to be flexible where fonts are concerned. |
| 78 | Don't rely on fonts being similarly-sized across platforms, as they were (by chance) between |
| 79 | Windows and X under wxWidgets 1.66. Yes, this is not easy... but I think it is better to conform to the |
| 80 | standards of each platform, and currently the size difference makes it difficult to |
| 81 | conform to Windows UI standards. You may eventually wish to build in a global 'fudge-factor' to compensate |
| 82 | for size differences. The old font sizing will still be available via wx\_setup.h, so do not panic... |
| 83 | \item {\bf Consider dropping wxForm usage}: |
| 84 | wxPropertyFormView can be used in a wxForm-like way, except that you specify a pre-constructed panel |
| 85 | or dialog; or you can use a wxPropertyListView to show attributes in a scrolling list - you don't even need |
| 86 | to lay panel items out. |
| 87 | |
| 88 | Because wxForm uses a number of features to be dropped in wxWidgets 2.0, it cannot be |
| 89 | supported in the future, at least in its present state. |
| 90 | \item {\bf When creating a wxListBox}, put the wxLB\_SINGLE, wxLB\_MULTIPLE, wxLB\_EXTENDED styles in the window style parameter, and put |
| 91 | zero in the {\it multiple} parameter. The {\it multiple} parameter will be removed in 2.0. |
| 92 | \item {\bf For MDI applications}, don't reply on MDI being run-time-switchable in the way that the |
| 93 | MDI sample is. In wxWidgets 2.0, MDI functionality is separated into distinct classes. |
| 94 | \end{itemize} |
| 95 | |
| 96 | \section{The new event system}\label{portingeventsystem} |
| 97 | |
| 98 | The way that events are handled has been radically changed in wxWidgets 2.0. Please |
| 99 | read the topic `Event handling overview' in the wxWidgets 2.0 manual for background |
| 100 | on this. |
| 101 | |
| 102 | \subsection{Callbacks} |
| 103 | |
| 104 | Instead of callbacks for panel items, menu command events, control commands and other events are directed to |
| 105 | the originating window, or an ancestor, or an event handler that has been plugged into the window |
| 106 | or its ancestor. Event handlers always have one argument, a derivative of wxEvent. |
| 107 | |
| 108 | For menubar commands, the {\bf OnMenuCommand} member function will be replaced by a series of separate member functions, |
| 109 | each of which responds to a particular command. You need to add these (non-virtual) functions to your |
| 110 | frame class, add a DECLARE\_EVENT\_TABLE entry to the class, and then add an event table to |
| 111 | your implementation file, as a BEGIN\_EVENT\_TABLE and END\_EVENT\_TABLE block. The |
| 112 | individual event mapping macros will be of the form: |
| 113 | |
| 114 | \begin{verbatim} |
| 115 | BEGIN_EVENT_TABLE(MyFrame, wxFrame) |
| 116 | EVT_MENU(MYAPP_NEW, MyFrame::OnNew) |
| 117 | EVT_MENU(wxID_EXIT, MyFrame::OnExit) |
| 118 | END_EVENT_TABLE() |
| 119 | \end{verbatim} |
| 120 | |
| 121 | Control commands, such as button commands, can be routed to a derived button class, |
| 122 | the parent window, or even the frame. Here, you use a function of the form EVT\_BUTTON(id, func). |
| 123 | Similar macros exist for other control commands. |
| 124 | |
| 125 | \subsection{Other events} |
| 126 | |
| 127 | To intercept other events, you used to override virtual functions, such as OnSize. Now, while you can use |
| 128 | the OnSize name for such event handlers (or any other name of your choice), it has only a single argument |
| 129 | (wxSizeEvent) and must again be `mapped' using the EVT\_SIZE macro. The same goes for all other events, |
| 130 | including OnClose (although in fact you can still use the old, virtual form of OnClose for the time being). |
| 131 | |
| 132 | \section{Class hierarchy}\label{portingclasshierarchy} |
| 133 | |
| 134 | The class hierarchy has changed somewhat. wxToolBar and wxButtonBar |
| 135 | classes have been split into several classes, and are derived from wxControl (which was |
| 136 | called wxItem). wxPanel derives from wxWindow instead of from wxCanvas, which has |
| 137 | disappeared in favour of wxScrolledWindow (since all windows are now effectively canvases |
| 138 | which can be drawn into). The status bar has become a class in its own right, wxStatusBar. |
| 139 | |
| 140 | There are new MDI classes so that wxFrame does not have to be overloaded with this |
| 141 | functionality. |
| 142 | |
| 143 | There are new device context classes, with wxPanelDC and wxCanvasDC disappearing. |
| 144 | See \helpref{Device contexts and painting}{portingdc}. |
| 145 | |
| 146 | \section{GDI objects}\label{portinggdiobjects} |
| 147 | |
| 148 | These objects - instances of classes such as wxPen, wxBrush, wxBitmap (but not wxColour) - |
| 149 | are now implemented with reference-counting. This makes assignment a very cheap operation, |
| 150 | and also means that management of the resource is largely automatic. You now pass {\it references} to |
| 151 | objects to functions such as wxDC::SetPen, not pointers, so you will need to dereference your pointers. |
| 152 | The device context does not store a copy of the pen |
| 153 | itself, but takes a copy of it (via reference counting), and the object's data gets freed up |
| 154 | when the reference count goes to zero. The application does not have to worry so much about |
| 155 | who the object belongs to: it can pass the reference, then destroy the object without |
| 156 | leaving a dangling pointer inside the device context. |
| 157 | |
| 158 | For the purposes of code migration, you can use the old style of object management - maintaining |
| 159 | pointers to GDI objects, and using the FindOrCreate... functions. However, it is preferable to |
| 160 | keep this explicit management to a minimum, instead creating objects on the fly as needed, on the stack, |
| 161 | unless this causes too much of an overhead in your application. |
| 162 | |
| 163 | At a minimum, you will have to make sure that calls to SetPen, SetBrush etc. work. Also, where you pass NULL to these |
| 164 | functions, you will need to use an identifier such as wxNullPen or wxNullBrush. |
| 165 | |
| 166 | \section{Dialogs and controls}\label{portingdialogscontrols} |
| 167 | |
| 168 | \wxheading{Labels} |
| 169 | |
| 170 | Most controls no longer have labels and values as they used to in 1.xx. Instead, labels |
| 171 | should be created separately using wxStaticText (the new name for wxMessage). This will |
| 172 | need some reworking of dialogs, unfortunately; programmatic dialog creation that doesn't |
| 173 | use constraints will be especially hard-hit. Perhaps take this opportunity to make more |
| 174 | use of dialog resources or constraints. Or consider using the wxPropertyListView class |
| 175 | which can do away with dialog layout issues altogether by presenting a list of editable |
| 176 | properties. |
| 177 | |
| 178 | \wxheading{Constructors} |
| 179 | |
| 180 | All window constructors have two main changes, apart from the label issue mentioned above. |
| 181 | Windows now have integer identifiers; and position and size are now passed as wxPoint and |
| 182 | wxSize objects. In addition, some windows have a wxValidator argument. |
| 183 | |
| 184 | \wxheading{Show versus ShowModal} |
| 185 | |
| 186 | If you have used or overridden the {\bf wxDialog::Show} function in the past, you may find |
| 187 | that modal dialogs no longer work as expected. This is because the function for modal showing |
| 188 | is now {\bf wxDialog:ShowModal}. This is part of a more fundamental change in which a |
| 189 | control may tell the dialog that it caused the dismissal of a dialog, by |
| 190 | calling {\bf wxDialog::EndModal} or {\bf wxWindow::SetReturnCode}. Using this |
| 191 | information, {\bf ShowModal} now returns the id of the control that caused dismissal, |
| 192 | giving greater feedback to the application than just true or false. |
| 193 | |
| 194 | If you overrode or called {\bf wxDialog::Show}, use {\bf ShowModal} and test for a returned identifier, |
| 195 | commonly wxID\_OK or wxID\_CANCEL. |
| 196 | |
| 197 | \wxheading{wxItem} |
| 198 | |
| 199 | This is renamed wxControl. |
| 200 | |
| 201 | \wxheading{wxText, wxMultiText and wxTextWindow} |
| 202 | |
| 203 | These classes no longer exist and are replaced by the single class wxTextCtrl. |
| 204 | Multi-line text items are created using the wxTE\_MULTILINE style. |
| 205 | |
| 206 | \wxheading{wxButton} |
| 207 | |
| 208 | Bitmap buttons are now a separate class, instead of being part of wxBitmap. |
| 209 | |
| 210 | \wxheading{wxMessage} |
| 211 | |
| 212 | Bitmap messages are now a separate class, wxStaticBitmap, and wxMessage |
| 213 | is renamed wxStaticText. |
| 214 | |
| 215 | \wxheading{wxGroupBox} |
| 216 | |
| 217 | wxGroupBox is renamed wxStaticBox. |
| 218 | |
| 219 | \wxheading{wxForm} |
| 220 | |
| 221 | Note that wxForm is no longer supported in wxWidgets 2.0. Consider using the wxPropertyFormView class |
| 222 | instead, which takes standard dialogs and panels and associates controls with property objects. |
| 223 | You may also find that the new validation method, combined with dialog resources, is easier |
| 224 | and more flexible than using wxForm. |
| 225 | |
| 226 | \section{Device contexts and painting}\label{portingdc} |
| 227 | |
| 228 | In wxWidgets 2.0, device contexts are used for drawing into, as per 1.xx, but the way |
| 229 | they are accessed and constructed is a bit different. |
| 230 | |
| 231 | You no longer use {\bf GetDC} to access device contexts for panels, dialogs and canvases. |
| 232 | Instead, you create a temporary device context, which means that any window or control can be drawn |
| 233 | into. The sort of device context you create depends on where your code is called from. If |
| 234 | painting within an {\bf OnPaint} handler, you create a wxPaintDC. If not within an {\bf OnPaint} handler, |
| 235 | you use a wxClientDC or wxWindowDC. You can still parameterise your drawing code so that it |
| 236 | doesn't have to worry about what sort of device context to create - it uses the DC it is passed |
| 237 | from other parts of the program. |
| 238 | |
| 239 | You {\bf must } create a wxPaintDC if you define an OnPaint handler, even if you do not |
| 240 | actually use this device context, or painting will not work correctly under Windows. |
| 241 | |
| 242 | If you used device context functions with wxPoint or wxIntPoint before, please note |
| 243 | that wxPoint now contains integer members, and there is a new class wxRealPoint. wxIntPoint |
| 244 | no longer exists. |
| 245 | |
| 246 | wxMetaFile and wxMetaFileDC have been renamed to wxMetafile and wxMetafileDC. |
| 247 | |
| 248 | \section{Miscellaneous} |
| 249 | |
| 250 | \subsection{Strings} |
| 251 | |
| 252 | wxString has replaced char* in the majority of cases. For passing strings into functions, |
| 253 | this should not normally require you to change your code if the syntax is otherwise the |
| 254 | same. This is because C++ will automatically convert a char* or const char* to a wxString by virtue |
| 255 | of appropriate wxString constructors. |
| 256 | |
| 257 | However, when a wxString is returned from a function in wxWidgets 2.0 where a char* was |
| 258 | returned in wxWidgets 1.xx, your application will need to be changed. Usually you can |
| 259 | simplify your application's allocation and deallocation of memory for the returned string, |
| 260 | and simply assign the result to a wxString object. For example, replace this: |
| 261 | |
| 262 | {\small |
| 263 | \begin{verbatim} |
| 264 | char* s = wxFunctionThatReturnsString(); |
| 265 | s = copystring(s); // Take a copy in case it is temporary |
| 266 | .... // Do something with it |
| 267 | delete[] s; |
| 268 | \end{verbatim} |
| 269 | } |
| 270 | |
| 271 | with this: |
| 272 | |
| 273 | {\small |
| 274 | \begin{verbatim} |
| 275 | wxString s = wxFunctionThatReturnsString(); |
| 276 | .... // Do something with it |
| 277 | \end{verbatim} |
| 278 | } |
| 279 | |
| 280 | To indicate an empty return value or a problem, a function may return either the |
| 281 | empty string (``") or a null string. You can check for a null string with wxString::IsNull(). |
| 282 | |
| 283 | \subsection{Use of const} |
| 284 | |
| 285 | The {\bf const} keyword is now used to denote constant functions that do not affect the |
| 286 | object, and for function arguments to denote that the object passed cannot be changed. |
| 287 | |
| 288 | This should not affect your application except for where you are overriding virtual functions |
| 289 | which now have a different signature. If functions are not being called which were previously, |
| 290 | check whether there is a parameter mismatch (or function type mismatch) involving consts. |
| 291 | |
| 292 | Try to use the {\bf const} keyword in your own code where possible. |
| 293 | |
| 294 | \section{Backward compatibility}\label{portingcompat} |
| 295 | |
| 296 | Some wxWidgets 1.xx functionality has been left to ease the transition to 2.0. This functionality |
| 297 | (usually) only works if you compile with WXWIN\_COMPATIBILITY set to 1 in setup.h. |
| 298 | |
| 299 | Mostly this defines old names to be the new names (e.g. wxRectangle is defined to be wxRect). |
| 300 | |
| 301 | \section{Quick reference}\label{portingquickreference} |
| 302 | |
| 303 | This section allows you to quickly find features that |
| 304 | need to be converted. |
| 305 | |
| 306 | \subsection{Include files} |
| 307 | |
| 308 | Use the form: |
| 309 | |
| 310 | \begin{verbatim} |
| 311 | #include <wx/wx.h> |
| 312 | #include <wx/button.h> |
| 313 | \end{verbatim} |
| 314 | |
| 315 | For precompiled header support, use this form: |
| 316 | |
| 317 | \begin{verbatim} |
| 318 | // For compilers that support precompilation, includes "wx.h". |
| 319 | #include <wx/wxprec.h> |
| 320 | |
| 321 | #ifdef __BORLANDC__ |
| 322 | #pragma hdrstop |
| 323 | #endif |
| 324 | |
| 325 | // Any files you want to include if not precompiling by including |
| 326 | // the whole of <wx/wx.h> |
| 327 | #ifndef WX_PRECOMP |
| 328 | #include <stdio.h> |
| 329 | #include <wx/setup.h> |
| 330 | #include <wx/bitmap.h> |
| 331 | #include <wx/brush.h> |
| 332 | #endif |
| 333 | |
| 334 | // Any files you want to include regardless of precompiled headers |
| 335 | #include <wx/toolbar.h> |
| 336 | \end{verbatim} |
| 337 | |
| 338 | \subsection{IPC classes} |
| 339 | |
| 340 | These are now separated out into wxDDEServer/Client/Connection (Windows only) and wxTCPServer/Client/Connection |
| 341 | (Windows and Unix). Take care to use wxString for your overridden function arguments, instead of char*, as per |
| 342 | the documentation. |
| 343 | |
| 344 | \subsection{MDI style frames} |
| 345 | |
| 346 | MDI is now implemented as a family of separate classes, so you can't switch to MDI just by |
| 347 | using a different frame style. Please see the documentation for the MDI frame classes, and the MDI |
| 348 | sample may be helpful too. |
| 349 | |
| 350 | \subsection{OnActivate} |
| 351 | |
| 352 | Replace the arguments with one wxActivateEvent\& argument, make sure the function isn't virtual, |
| 353 | and add an EVT\_ACTIVATE event table entry. |
| 354 | |
| 355 | \subsection{OnChar} |
| 356 | |
| 357 | This is now a non-virtual function, with the same wxKeyEvent\& argument as before. |
| 358 | Add an EVT\_CHAR macro to the event table |
| 359 | for your window, and the implementation of your function will need very few changes. |
| 360 | |
| 361 | \subsection{OnClose} |
| 362 | |
| 363 | The old virtual function OnClose is now obsolete. |
| 364 | Add an OnCloseWindow event handler using an EVT\_CLOSE event table entry. For details |
| 365 | about window destruction, see the Windows Deletion Overview in the manual. This is a subtle |
| 366 | topic so please read it very carefully. Basically, OnCloseWindow is now responsible for |
| 367 | destroying a window with Destroy(), but the default implementation (for example for wxDialog) may not |
| 368 | destroy the window, so to be sure, always provide this event handler so it is obvious what's going on. |
| 369 | |
| 370 | \subsection{OnEvent} |
| 371 | |
| 372 | This is now a non-virtual function, with the same wxMouseEvent\& argument as before. However |
| 373 | you may wish to rename it OnMouseEvent. Add an EVT\_MOUSE\_EVENTS macro to the event table |
| 374 | for your window, and the implementation of your function will need very few changes. |
| 375 | However, if you wish to intercept different events using different functions, you can |
| 376 | specify specific events in your event table, such as EVT\_LEFT\_DOWN. |
| 377 | |
| 378 | Your OnEvent function is likely to have references to GetDC(), so make sure you create |
| 379 | a wxClientDC instead. See \helpref{Device contexts}{portingdc}. |
| 380 | |
| 381 | If you are using a wxScrolledWindow (formerly wxCanvas), you should call |
| 382 | PrepareDC(dc) to set the correct translation for the current scroll position. |
| 383 | |
| 384 | \subsection{OnMenuCommand} |
| 385 | |
| 386 | You need to replace this virtual function with a series of non-virtual functions, one for |
| 387 | each case of your old switch statement. Each function takes a wxCommandEvent\& argument. |
| 388 | Create an event table for your frame |
| 389 | containing EVT\_MENU macros, and insert DECLARE\_EVENT\_TABLE() in your frame class, as |
| 390 | per the samples. |
| 391 | |
| 392 | \subsection{OnPaint} |
| 393 | |
| 394 | This is now a non-virtual function, with a wxPaintEvent\& argument. |
| 395 | Add an EVT\_PAINT macro to the event table |
| 396 | for your window. |
| 397 | |
| 398 | Your function {\it must} create a wxPaintDC object, instead of using GetDC to |
| 399 | obtain the device context. |
| 400 | |
| 401 | If you are using a wxScrolledWindow (formerly wxCanvas), you should call |
| 402 | PrepareDC(dc) to set the correct translation for the current scroll position. |
| 403 | |
| 404 | \subsection{OnSize} |
| 405 | |
| 406 | Replace the arguments with one wxSizeEvent\& argument, make it non-virtual, and add to your |
| 407 | event table using EVT\_SIZE. |
| 408 | |
| 409 | \subsection{wxApp definition} |
| 410 | |
| 411 | The definition of OnInit has changed. Return a bool value, not a wxFrame. |
| 412 | |
| 413 | Also, do {\it not} declare a global application object. Instead, use the macros |
| 414 | DECLARE\_APP and IMPLEMENT\_APP as per the samples. Remove any occurrences of IMPLEMENT\_WXWIN\_MAIN: |
| 415 | this is subsumed in IMPLEMENT\_APP. |
| 416 | |
| 417 | \subsection{wxButton} |
| 418 | |
| 419 | For bitmap buttons, use wxBitmapButton. |
| 420 | |
| 421 | \subsection{wxCanvas} |
| 422 | |
| 423 | Change the name to wxScrolledWindow. |
| 424 | |
| 425 | \subsection{wxDialogBox} |
| 426 | |
| 427 | Change the name to wxDialog, and for modal dialogs, use ShowModal instead of Show. |
| 428 | |
| 429 | \subsection{wxDialog::Show} |
| 430 | |
| 431 | If you used {\bf Show} to show a modal dialog or to override the standard |
| 432 | modal dialog {\bf Show}, use {\bf ShowModal} instead. |
| 433 | |
| 434 | \wxheading{See also} |
| 435 | |
| 436 | \helpref{Dialogs and controls}{portingdialogscontrols} |
| 437 | |
| 438 | \subsection{wxForm} |
| 439 | |
| 440 | Sorry, this class is no longer available. Try using the wxPropertyListView or wxPropertyFormView class |
| 441 | instead, or use .wxr files and validators. |
| 442 | |
| 443 | \subsection{wxPoint} |
| 444 | |
| 445 | The old wxPoint is called wxRealPoint, and wxPoint now uses integers. |
| 446 | |
| 447 | \subsection{wxRectangle} |
| 448 | |
| 449 | This is now called wxRect. |
| 450 | |
| 451 | \subsection{wxScrollBar} |
| 452 | |
| 453 | The function names have changed for this class: please refer to the documentation for wxScrollBar. Instead |
| 454 | of setting properties individually, you will call SetScrollbar with several parameters. |
| 455 | |
| 456 | \subsection{wxText, wxMultiText, wxTextWindow} |
| 457 | |
| 458 | Change all these to wxTextCtrl. Add the window style wxTE\_MULTILINE if you |
| 459 | wish to have a multi-line text control. |
| 460 | |
| 461 | \subsection{wxToolBar} |
| 462 | |
| 463 | This name is an alias for the most popular form of toolbar for your platform. There is now a family |
| 464 | of toolbar classes, with for example wxToolBar95, wxToolBarMSW and wxToolBarSimple classes existing |
| 465 | under Windows 95. |
| 466 | |
| 467 | Toolbar management is supported by frames, so calling wxFrame::CreateToolBar and adding tools is usually |
| 468 | enough, and the SDI or MDI frame will manage the positioning for you. The client area of the frame is the space |
| 469 | left over when the menu bar, toolbar and status bar have been taken into account. |
| 470 | |