]> git.saurik.com Git - wxWidgets.git/blame - samples/mdi/mdi.cpp
fix vertical mouse wheel event rotation value, sign was reversed in r74805
[wxWidgets.git] / samples / mdi / mdi.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: mdi.cpp
3// Purpose: MDI sample
4// Author: Julian Smart
d2824cdb 5// Modified by: 2008-10-31 Vadim Zeitlin: big clean up
c801d85f 6// Created: 04/01/98
d2824cdb
VZ
7// Copyright: (c) 1997 Julian Smart
8// (c) 2008 Vadim Zeitlin
526954c5 9// Licence: wxWindows licence
c801d85f
KB
10/////////////////////////////////////////////////////////////////////////////
11
c52d95b4
VZ
12// ===========================================================================
13// declarations
14// ===========================================================================
15
16// ---------------------------------------------------------------------------
17// headers
18// ---------------------------------------------------------------------------
19
c801d85f
KB
20// For compilers that support precompilation, includes "wx/wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
c52d95b4 24 #pragma hdrstop
c801d85f
KB
25#endif
26
27#ifndef WX_PRECOMP
c52d95b4
VZ
28 #include "wx/wx.h"
29 #include "wx/mdi.h"
c801d85f
KB
30#endif
31
012f2cb2 32#include "wx/toolbar.h"
c801d85f 33
e7092398 34#ifndef wxHAS_IMAGES_IN_RESOURCES
ea7fb468
VZ
35 #include "../sample.xpm"
36 #include "chart.xpm"
716b7364
RR
37#endif
38
d04d32c4
CE
39#include "bitmaps/new.xpm"
40#include "bitmaps/open.xpm"
41#include "bitmaps/save.xpm"
42#include "bitmaps/copy.xpm"
43#include "bitmaps/cut.xpm"
44#include "bitmaps/paste.xpm"
45#include "bitmaps/print.xpm"
46#include "bitmaps/help.xpm"
47
d2824cdb
VZ
48// replace this 0 with 1 to build the sample using the generic MDI classes (you
49// may also need to add src/generic/mdig.cpp to the build)
50#if 0
51 #include "wx/generic/mdig.h"
52 #define wxMDIParentFrame wxGenericMDIParentFrame
53 #define wxMDIChildFrame wxGenericMDIChildFrame
54 #define wxMDIClientWindow wxGenericMDIClientWindow
55#endif
d04d32c4 56
c801d85f
KB
57#include "mdi.h"
58
c52d95b4
VZ
59IMPLEMENT_APP(MyApp)
60
c52d95b4
VZ
61// ---------------------------------------------------------------------------
62// event tables
63// ---------------------------------------------------------------------------
64
65BEGIN_EVENT_TABLE(MyFrame, wxMDIParentFrame)
d2824cdb
VZ
66 EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
67 EVT_MENU(wxID_NEW, MyFrame::OnNewWindow)
9089cffb 68 EVT_MENU(MDI_FULLSCREEN, MyFrame::OnFullScreen)
d2824cdb 69 EVT_MENU(wxID_EXIT, MyFrame::OnQuit)
c52d95b4 70
1483e5db
VZ
71 EVT_MENU(wxID_CLOSE_ALL, MyFrame::OnCloseAll)
72
c52d95b4 73 EVT_CLOSE(MyFrame::OnClose)
c52d95b4
VZ
74END_EVENT_TABLE()
75
d2824cdb 76// Note that wxID_NEW and wxID_ABOUT commands get passed
c52d95b4
VZ
77// to the parent window for processing, so no need to
78// duplicate event handlers here.
79BEGIN_EVENT_TABLE(MyChild, wxMDIChildFrame)
d2824cdb 80 EVT_MENU(wxID_CLOSE, MyChild::OnClose)
c52d95b4 81 EVT_MENU(MDI_REFRESH, MyChild::OnRefresh)
f6bcfd97 82 EVT_MENU(MDI_CHANGE_TITLE, MyChild::OnChangeTitle)
3d8dea7e
VZ
83 EVT_MENU(MDI_CHANGE_POSITION, MyChild::OnChangePosition)
84 EVT_MENU(MDI_CHANGE_SIZE, MyChild::OnChangeSize)
85
c9f856af
VZ
86#if wxUSE_CLIPBOARD
87 EVT_MENU(wxID_PASTE, MyChild::OnPaste)
88 EVT_UPDATE_UI(wxID_PASTE, MyChild::OnUpdatePaste)
89#endif // wxUSE_CLIPBOARD
90
3d8dea7e
VZ
91 EVT_SIZE(MyChild::OnSize)
92 EVT_MOVE(MyChild::OnMove)
c52d95b4 93
d2824cdb 94 EVT_CLOSE(MyChild::OnCloseWindow)
c52d95b4
VZ
95END_EVENT_TABLE()
96
97BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
98 EVT_MOUSE_EVENTS(MyCanvas::OnEvent)
99END_EVENT_TABLE()
100
396e9eb8
VZ
101BEGIN_EVENT_TABLE(MyChild::EventHandler, wxEvtHandler)
102 EVT_MENU(MDI_REFRESH, MyChild::EventHandler::OnRefresh)
103END_EVENT_TABLE()
104
c52d95b4
VZ
105// ===========================================================================
106// implementation
107// ===========================================================================
c801d85f 108
c52d95b4
VZ
109// ---------------------------------------------------------------------------
110// MyApp
111// ---------------------------------------------------------------------------
c801d85f
KB
112
113// Initialise this in OnInit, not statically
c52d95b4 114bool MyApp::OnInit()
c801d85f 115{
45e6e6f8
VZ
116 if ( !wxApp::OnInit() )
117 return false;
118
c52d95b4 119 // Create the main frame window
c801d85f 120
d2824cdb 121 MyFrame *frame = new MyFrame;
c801d85f 122
d2824cdb
VZ
123 frame->Show(true);
124
125 return true;
126}
127
128// ---------------------------------------------------------------------------
129// MyFrame
130// ---------------------------------------------------------------------------
131
132// Define my frame constructor
133MyFrame::MyFrame()
134 : wxMDIParentFrame(NULL, wxID_ANY, "wxWidgets MDI Sample",
135 wxDefaultPosition, wxSize(500, 400))
136{
137 SetIcon(wxICON(sample));
c801d85f 138
c52d95b4 139 // Make a menubar
d2824cdb 140#if wxUSE_MENUS
c52d95b4 141 // Associate the menu bar with the frame
4f7cd56c 142 SetMenuBar(CreateMainMenubar());
d2824cdb 143
1483e5db
VZ
144
145 // This shows that the standard window menu may be customized:
146 wxMenu * const windowMenu = GetWindowMenu();
147 if ( windowMenu )
148 {
149 // we can change the labels of standard items (which also means we can
150 // set up accelerators for them as they're part of the label)
151 windowMenu->SetLabel(wxID_MDI_WINDOW_TILE_HORZ,
152 "&Tile horizontally\tCtrl-Shift-H");
153 windowMenu->SetLabel(wxID_MDI_WINDOW_TILE_VERT,
154 "&Tile vertically\tCtrl-Shift-V");
155
156 // we can also change the help string
157 windowMenu->SetHelpString(wxID_MDI_WINDOW_CASCADE,
158 "Arrange windows in cascade");
159
160 // we can remove some items
161 windowMenu->Delete(wxID_MDI_WINDOW_ARRANGE_ICONS);
162
163 // and we can add completely custom commands -- but then we must handle
164 // them ourselves, see OnCloseAll()
165 windowMenu->AppendSeparator();
166 windowMenu->Append(wxID_CLOSE_ALL, "&Close all windows\tCtrl-Shift-C",
167 "Close all open windows");
168
169 SetWindowMenu(windowMenu);
170 }
d2824cdb 171#endif // wxUSE_MENUS
c801d85f 172
8520f137 173#if wxUSE_STATUSBAR
d2824cdb 174 CreateStatusBar();
8520f137 175#endif // wxUSE_STATUSBAR
c801d85f 176
c801d85f 177
d2824cdb
VZ
178 m_textWindow = new wxTextCtrl(this, wxID_ANY, "A help window",
179 wxDefaultPosition, wxDefaultSize,
180 wxTE_MULTILINE | wxSUNKEN_BORDER);
c801d85f 181
6ceba174 182#if wxUSE_TOOLBAR
fa762db4 183 CreateToolBar(wxNO_BORDER | wxTB_FLAT | wxTB_HORIZONTAL);
81d66cf3 184 InitToolBar(GetToolBar());
6ceba174 185#endif // wxUSE_TOOLBAR
57a7b7c1 186
4219b5e7 187#if wxUSE_ACCEL
57a7b7c1
JS
188 // Accelerators
189 wxAcceleratorEntry entries[3];
d2824cdb
VZ
190 entries[0].Set(wxACCEL_CTRL, (int) 'N', wxID_NEW);
191 entries[1].Set(wxACCEL_CTRL, (int) 'X', wxID_EXIT);
192 entries[2].Set(wxACCEL_CTRL, (int) 'A', wxID_ABOUT);
57a7b7c1
JS
193 wxAcceleratorTable accel(3, entries);
194 SetAcceleratorTable(accel);
4219b5e7 195#endif // wxUSE_ACCEL
d2824cdb
VZ
196
197 // connect it only now, after creating m_textWindow
198 Connect(wxEVT_SIZE, wxSizeEventHandler(MyFrame::OnSize));
199}
200
201MyFrame::~MyFrame()
202{
203 // and disconnect it to prevent accessing already deleted m_textWindow in
204 // the size event handler if it's called during destruction
205 Disconnect(wxEVT_SIZE, wxSizeEventHandler(MyFrame::OnSize));
c801d85f
KB
206}
207
4f7cd56c
VZ
208#if wxUSE_MENUS
209/* static */
210wxMenuBar *MyFrame::CreateMainMenubar()
211{
212 wxMenu *menuFile = new wxMenu;
213
214 menuFile->Append(wxID_NEW, "&New window\tCtrl-N", "Create a new child window");
215 menuFile->AppendCheckItem(MDI_FULLSCREEN, "Show &full screen\tCtrl-F");
216 menuFile->Append(wxID_EXIT, "&Exit\tAlt-X", "Quit the program");
217
218 wxMenu *menuHelp = new wxMenu;
219 menuHelp->Append(wxID_ABOUT, "&About\tF1");
220
221 wxMenuBar *mbar = new wxMenuBar;
222 mbar->Append(menuFile, "&File");
223 mbar->Append(menuHelp, "&Help");
224
225 return mbar;
226}
227#endif // wxUSE_MENUS
228
c52d95b4
VZ
229void MyFrame::OnClose(wxCloseEvent& event)
230{
d2824cdb
VZ
231 unsigned numChildren = MyChild::GetChildrenCount();
232 if ( event.CanVeto() && (numChildren > 0) )
c52d95b4
VZ
233 {
234 wxString msg;
d2824cdb
VZ
235 msg.Printf("%d windows still open, close anyhow?", numChildren);
236 if ( wxMessageBox(msg, "Please confirm",
c52d95b4
VZ
237 wxICON_QUESTION | wxYES_NO) != wxYES )
238 {
239 event.Veto();
240
241 return;
242 }
243 }
244
245 event.Skip();
246}
247
248void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
c801d85f 249{
c52d95b4 250 Close();
c801d85f
KB
251}
252
e3e65dac 253void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
c801d85f 254{
d2824cdb
VZ
255 (void)wxMessageBox("wxWidgets 2.0 MDI Demo\n"
256 "Author: Julian Smart (c) 1997\n"
257 "Usage: mdi.exe", "About MDI Demo");
c801d85f
KB
258}
259
e3e65dac 260void MyFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event) )
c801d85f 261{
d2824cdb
VZ
262 // create and show another child frame
263 MyChild *subframe = new MyChild(this);
eb839c84 264 subframe->Show(true);
c801d85f
KB
265}
266
9089cffb
VZ
267void MyFrame::OnFullScreen(wxCommandEvent& event)
268{
269 ShowFullScreen(event.IsChecked());
270}
271
1483e5db
VZ
272void MyFrame::OnCloseAll(wxCommandEvent& WXUNUSED(event))
273{
274 for ( wxWindowList::const_iterator i = GetChildren().begin();
275 i != GetChildren().end();
276 ++i )
277 {
278 if ( wxDynamicCast(*i, wxMDIChildFrame) )
279 (*i)->Close();
280 }
281}
282
9298a1c2 283void MyFrame::OnSize(wxSizeEvent& event)
c52d95b4
VZ
284{
285 int w, h;
286 GetClientSize(&w, &h);
287
d2824cdb 288 m_textWindow->SetSize(0, 0, 200, h);
c52d95b4 289 GetClientWindow()->SetSize(200, 0, w - 200, h);
a9c824e9
JS
290
291 // FIXME: On wxX11, we need the MDI frame to process this
292 // event, but on other platforms this should not
293 // be done.
4219b5e7 294#ifdef __WXUNIVERSAL__
b9f933ab 295 event.Skip();
9298a1c2
VZ
296#else
297 wxUnusedVar(event);
a9c824e9 298#endif
c52d95b4
VZ
299}
300
6ceba174 301#if wxUSE_TOOLBAR
c52d95b4
VZ
302void MyFrame::InitToolBar(wxToolBar* toolBar)
303{
e21d8614
VZ
304 wxBitmap bitmaps[8];
305
306 bitmaps[0] = wxBitmap( new_xpm );
307 bitmaps[1] = wxBitmap( open_xpm );
308 bitmaps[2] = wxBitmap( save_xpm );
309 bitmaps[3] = wxBitmap( copy_xpm );
310 bitmaps[4] = wxBitmap( cut_xpm );
311 bitmaps[5] = wxBitmap( paste_xpm );
312 bitmaps[6] = wxBitmap( print_xpm );
313 bitmaps[7] = wxBitmap( help_xpm );
314
d2824cdb
VZ
315 toolBar->AddTool(wxID_NEW, "New", bitmaps[0], "New file");
316 toolBar->AddTool(1, "Open", bitmaps[1], "Open file");
317 toolBar->AddTool(2, "Save", bitmaps[2], "Save file");
c52d95b4 318 toolBar->AddSeparator();
d2824cdb
VZ
319 toolBar->AddTool(3, "Copy", bitmaps[3], "Copy");
320 toolBar->AddTool(4, "Cut", bitmaps[4], "Cut");
321 toolBar->AddTool(5, "Paste", bitmaps[5], "Paste");
c52d95b4 322 toolBar->AddSeparator();
d2824cdb 323 toolBar->AddTool(6, "Print", bitmaps[6], "Print");
c52d95b4 324 toolBar->AddSeparator();
d2824cdb 325 toolBar->AddTool(wxID_ABOUT, "About", bitmaps[7], "Help");
c52d95b4
VZ
326
327 toolBar->Realize();
c52d95b4 328}
6ceba174 329#endif // wxUSE_TOOLBAR
c52d95b4
VZ
330
331// ---------------------------------------------------------------------------
332// MyCanvas
333// ---------------------------------------------------------------------------
c801d85f
KB
334
335// Define a constructor for my canvas
c52d95b4 336MyCanvas::MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size)
eb839c84 337 : wxScrolledWindow(parent, wxID_ANY, pos, size,
3ebcfb76
VZ
338 wxSUNKEN_BORDER |
339 wxNO_FULL_REPAINT_ON_RESIZE |
340 wxVSCROLL | wxHSCROLL)
c801d85f 341{
ea92bb67 342 SetBackgroundColour(*wxWHITE);
d2824cdb
VZ
343 SetCursor(wxCursor(wxCURSOR_PENCIL));
344
345 SetScrollbars(20, 20, 50, 50);
c52d95b4 346
eb839c84 347 m_dirty = false;
c801d85f
KB
348}
349
350// Define the repainting behaviour
351void MyCanvas::OnDraw(wxDC& dc)
352{
c9f856af
VZ
353 if ( !m_text.empty() )
354 dc.DrawText(m_text, 10, 10);
355
c52d95b4
VZ
356 dc.SetFont(*wxSWISS_FONT);
357 dc.SetPen(*wxGREEN_PEN);
358 dc.DrawLine(0, 0, 200, 200);
359 dc.DrawLine(200, 0, 0, 200);
360
361 dc.SetBrush(*wxCYAN_BRUSH);
362 dc.SetPen(*wxRED_PEN);
363 dc.DrawRectangle(100, 100, 100, 50);
364 dc.DrawRoundedRectangle(150, 150, 100, 50, 20);
365
366 dc.DrawEllipse(250, 250, 100, 50);
c41ea66a 367#if wxUSE_SPLINES
c52d95b4 368 dc.DrawSpline(50, 200, 50, 100, 200, 10);
c41ea66a 369#endif // wxUSE_SPLINES
c52d95b4 370 dc.DrawLine(50, 230, 200, 230);
d2824cdb 371 dc.DrawText("This is a test string", 50, 230);
c52d95b4
VZ
372
373 wxPoint points[3];
374 points[0].x = 200; points[0].y = 300;
375 points[1].x = 100; points[1].y = 400;
376 points[2].x = 300; points[2].y = 400;
377
378 dc.DrawPolygon(3, points);
c801d85f
KB
379}
380
c52d95b4
VZ
381// This implements a tiny doodling program! Drag the mouse using the left
382// button.
c801d85f
KB
383void MyCanvas::OnEvent(wxMouseEvent& event)
384{
c52d95b4
VZ
385 wxClientDC dc(this);
386 PrepareDC(dc);
c801d85f 387
c52d95b4 388 wxPoint pt(event.GetLogicalPosition(dc));
c801d85f 389
d2824cdb
VZ
390 static long xpos = -1;
391 static long ypos = -1;
392
c52d95b4
VZ
393 if (xpos > -1 && ypos > -1 && event.Dragging())
394 {
395 dc.SetPen(*wxBLACK_PEN);
396 dc.DrawLine(xpos, ypos, pt.x, pt.y);
c801d85f 397
eb839c84 398 m_dirty = true;
c52d95b4 399 }
c801d85f 400
c52d95b4
VZ
401 xpos = pt.x;
402 ypos = pt.y;
403}
404
405// ---------------------------------------------------------------------------
406// MyChild
407// ---------------------------------------------------------------------------
408
d2824cdb
VZ
409unsigned MyChild::ms_numChildren = 0;
410
411MyChild::MyChild(wxMDIParentFrame *parent)
412 : wxMDIChildFrame
413 (
414 parent,
415 wxID_ANY,
416 wxString::Format("Child %u", ++ms_numChildren)
417 )
c801d85f 418{
d2824cdb
VZ
419 m_canvas = new MyCanvas(this, wxPoint(0, 0), GetClientSize());
420
421 SetIcon(wxICON(chart));
422
423 const bool canBeResized = !IsAlwaysMaximized();
424
4f7cd56c 425 // create our menu bar: it will be shown instead of the main frame one when
d2824cdb
VZ
426 // we're active
427#if wxUSE_MENUS
4f7cd56c
VZ
428 wxMenuBar *mbar = MyFrame::CreateMainMenubar();
429 mbar->GetMenu(0)->Insert(1, wxID_CLOSE, "&Close child\tCtrl-W",
430 "Close this window");
d2824cdb 431
4f7cd56c 432 wxMenu *menuChild = new wxMenu;
d2824cdb 433
4f7cd56c
VZ
434 menuChild->Append(MDI_REFRESH, "&Refresh picture");
435 menuChild->Append(MDI_CHANGE_TITLE, "Change &title...\tCtrl-T");
d2824cdb
VZ
436 if ( canBeResized )
437 {
4f7cd56c
VZ
438 menuChild->AppendSeparator();
439 menuChild->Append(MDI_CHANGE_POSITION, "Move frame\tCtrl-M");
440 menuChild->Append(MDI_CHANGE_SIZE, "Resize frame\tCtrl-S");
d2824cdb
VZ
441 }
442#if wxUSE_CLIPBOARD
4f7cd56c
VZ
443 menuChild->AppendSeparator();
444 menuChild->Append(wxID_PASTE, "Copy text from clipboard\tCtrl-V");
d2824cdb
VZ
445#endif // wxUSE_CLIPBOARD
446
4f7cd56c 447 mbar->Insert(1, menuChild, "&Child");
d2824cdb
VZ
448
449 // Associate the menu bar with the frame
4f7cd56c 450 SetMenuBar(mbar);
d2824cdb
VZ
451#endif // wxUSE_MENUS
452
453 // this should work for MDI frames as well as for normal ones, provided
454 // they can be resized at all
455 if ( canBeResized )
456 SetSizeHints(100, 100);
396e9eb8
VZ
457
458 // test that event handlers pushed on top of MDI children do work (this
459 // used to be broken, see #11225)
460 PushEventHandler(new EventHandler(ms_numChildren));
c801d85f
KB
461}
462
c52d95b4 463MyChild::~MyChild()
c801d85f 464{
396e9eb8
VZ
465 PopEventHandler(true);
466
d2824cdb 467 ms_numChildren--;
c801d85f
KB
468}
469
d2824cdb 470void MyChild::OnClose(wxCommandEvent& WXUNUSED(event))
c801d85f 471{
eb839c84 472 Close(true);
c52d95b4
VZ
473}
474
f6bcfd97
BP
475void MyChild::OnRefresh(wxCommandEvent& WXUNUSED(event))
476{
d2824cdb
VZ
477 if ( m_canvas )
478 m_canvas->Refresh();
f6bcfd97
BP
479}
480
fa762db4
VZ
481void MyChild::OnChangePosition(wxCommandEvent& WXUNUSED(event))
482{
483 Move(10, 10);
484}
485
486void MyChild::OnChangeSize(wxCommandEvent& WXUNUSED(event))
487{
488 SetClientSize(100, 100);
489}
490
f6bcfd97 491void MyChild::OnChangeTitle(wxCommandEvent& WXUNUSED(event))
c52d95b4 492{
e21d8614 493#if wxUSE_TEXTDLG
d2824cdb 494 static wxString s_title = "Canvas Frame";
f6bcfd97 495
d2824cdb
VZ
496 wxString title = wxGetTextFromUser("Enter the new title for MDI child",
497 "MDI sample question",
f6bcfd97 498 s_title,
fa762db4 499 GetParent()->GetParent());
f6bcfd97
BP
500 if ( !title )
501 return;
502
503 s_title = title;
504 SetTitle(s_title);
e21d8614 505#endif // wxUSE_TEXTDLG
c801d85f
KB
506}
507
508void MyChild::OnActivate(wxActivateEvent& event)
509{
d2824cdb
VZ
510 if ( event.GetActive() && m_canvas )
511 m_canvas->SetFocus();
c801d85f
KB
512}
513
fa762db4
VZ
514void MyChild::OnMove(wxMoveEvent& event)
515{
516 // VZ: here everything is totally wrong under MSW, the positions are
517 // different and both wrong (pos2 is off by 2 pixels for me which seems
518 // to be the width of the MDI canvas border)
519 wxPoint pos1 = event.GetPosition(),
520 pos2 = GetPosition();
d2824cdb 521 wxLogStatus("position from event: (%d, %d), from frame (%d, %d)",
fa762db4
VZ
522 pos1.x, pos1.y, pos2.x, pos2.y);
523
524 event.Skip();
525}
526
527void MyChild::OnSize(wxSizeEvent& event)
528{
529 // VZ: under MSW the size event carries the client size (quite
530 // unexpectedly) *except* for the very first one which has the full
531 // size... what should it really be? TODO: check under wxGTK
532 wxSize size1 = event.GetSize(),
533 size2 = GetSize(),
534 size3 = GetClientSize();
d2824cdb 535 wxLogStatus("size from event: %dx%d, from frame %dx%d, client %dx%d",
fa762db4
VZ
536 size1.x, size1.y, size2.x, size2.y, size3.x, size3.y);
537
538 event.Skip();
539}
540
d2824cdb 541void MyChild::OnCloseWindow(wxCloseEvent& event)
c801d85f 542{
d2824cdb 543 if ( m_canvas && m_canvas->IsDirty() )
c52d95b4 544 {
d2824cdb 545 if ( wxMessageBox("Really close?", "Please confirm",
c52d95b4
VZ
546 wxICON_QUESTION | wxYES_NO) != wxYES )
547 {
548 event.Veto();
c801d85f 549
c52d95b4
VZ
550 return;
551 }
552 }
c801d85f 553
c52d95b4 554 event.Skip();
c801d85f 555}
c9f856af
VZ
556
557#if wxUSE_CLIPBOARD
558
559#include "wx/clipbrd.h"
560
561void MyChild::OnPaste(wxCommandEvent& WXUNUSED(event))
562{
563 wxClipboardLocker lock;
564 wxTextDataObject data;
d2824cdb
VZ
565 m_canvas->SetText(wxTheClipboard->GetData(data)
566 ? data.GetText()
567 : wxString("No text on clipboard"));
c9f856af
VZ
568}
569
570void MyChild::OnUpdatePaste(wxUpdateUIEvent& event)
571{
572 wxClipboardLocker lock;
573 event.Enable( wxTheClipboard->IsSupported(wxDF_TEXT) );
574}
575
576#endif // wxUSE_CLIPBOARD