File: mfctest.cpp

package info (click to toggle)
wxpython3.0 3.0.2.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 482,760 kB
  • ctags: 518,293
  • sloc: cpp: 2,127,226; python: 294,045; makefile: 51,942; ansic: 19,033; sh: 3,013; xml: 1,629; perl: 17
file content (421 lines) | stat: -rw-r--r-- 11,271 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
/////////////////////////////////////////////////////////////////////////////
// Name:        mfctest.cpp
// Purpose:     Sample to demonstrate mixing MFC and wxWidgets code
// Author:      Julian Smart
// Copyright:   (c) Julian Smart
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

// This sample pops up an initial wxWidgets frame, with a menu item
// that allows a new MFC window to be created. Note that CDummyWindow
// is a class that allows a wxWidgets window to be seen as a CWnd
// for the purposes of specifying a valid main window to the
// MFC initialisation.
//
// You can easily modify this code so that an MFC window pops up
// initially as the main frame, and allows wxWidgets frames to be
// created subsequently.
//
// (1) Make MyApp::OnInit not create a main window.
// (2) Make MFC's InitInstance create a main window, and remove
//     creation of CDummyWindow.
//
// This can be accomplished by setting START_WITH_MFC_WINDOW to 1 below.

#define START_WITH_MFC_WINDOW 0

//
// IMPORTANT NOTES:
//
// (1) You may need to set wxUSE_MFC to 1 in include/wx/msw/setup.h but
//     normally this shouldn't be needed any longer, i.e. it works without
//     it for me (VZ)
//
// (2) You should link with MFC DLL, not static libraries: or, to use static
//     run-time libraries, use this command for both building wxWidgets and
//     the sample:
//
//     nmake -f makefile.vc BUILD=debug SHARED=0 DEBUG_RUNTIME_LIBS=0 RUNTIME_LIBS=static all
//
//     Unless the run-time library settings match for wxWidgets and MFC, you
//     will get link errors for symbols such as __mbctype, __argc, and __argv
//
// (3) If you see bogus memory leaks within the MSVC IDE on exit, in this
//     sample or in your own project, you must be using __WXDEBUG__ +
//     WXUSINGDLL + _AFXDLL
//     Unfortunately this confuses the MSVC/MFC leak detector. To do away with
//     these bogus memory leaks, add this to the list of link objects, make it
//     first: mfc[version][u]d.lib
//     -  [version] -> 42 or 70 or 80 etc
//     -  u if using Unicode

// Disable deprecation warnings from headers included from stdafx.h for VC8+
#ifndef _CRT_SECURE_NO_WARNINGS
    #define _CRT_SECURE_NO_WARNINGS
#endif

// Also define WINVER to avoid warnings about it being undefined from the
// platform SDK headers (usually this is not necessary because it is done by wx
// headers but here we include the system ones before them)
#ifndef WINVER
    #define WINVER 0x0600
#endif

#include "stdafx.h"

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include "wx/wx.h"
#endif

#include "wx/evtloop.h"

#include "resource.h"

#include "mfctest.h"

/////////////////////////////////////////////////////////////////////////////

// theApp:
// Just creating this application object runs the whole application.
//
CTheApp theApp;

// wxWidgets elements

// Define a new application type
class MyApp: public wxApp
{
public:
    virtual bool OnInit();

    // we need to override this as the default behaviour only works when we're
    // running wxWidgets main loop, not MFC one
    virtual void ExitMainLoop();

    wxFrame *CreateFrame();
};

class MyCanvas: public wxScrolledWindow
{
public:
    MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size);
    void OnPaint(wxPaintEvent& event);
    void OnMouseEvent(wxMouseEvent& event);
    wxDECLARE_EVENT_TABLE();
};

class MyChild: public wxFrame
{
public:
    MyChild(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size, const long style);
    virtual ~MyChild();

    void OnQuit(wxCommandEvent& event);
    void OnNew(wxCommandEvent& event);
    void OnActivate(wxActivateEvent& event);

    MyCanvas *canvas;

    wxDECLARE_EVENT_TABLE();
};

// ID for the menu quit command
#define HELLO_QUIT 1
#define HELLO_NEW  2

DECLARE_APP(MyApp)

// notice use of IMPLEMENT_APP_NO_MAIN() instead of the usual IMPLEMENT_APP!
IMPLEMENT_APP_NO_MAIN(MyApp)

#ifdef _UNICODE
// In Unicode build MFC normally requires to manually change the entry point to
// wWinMainCRTStartup() but to avoid having to modify the project options to do
// it we provide an adapter for it.
extern "C" int wWinMainCRTStartup();

int WINAPI WinMain(HINSTANCE, HINSTANCE, char *, int)
{
    wWinMainCRTStartup();
}
#endif // _UNICODE

CMainWindow::CMainWindow()
{
    LoadAccelTable( wxT("MainAccelTable") );
    Create( NULL, wxT("Hello Foundation Application"),
        WS_OVERLAPPEDWINDOW, rectDefault, NULL, wxT("MainMenu") );
}

void CMainWindow::OnPaint()
{
    CString s = wxT("Hello, Windows!");
    CPaintDC dc( this );
    CRect rect;

    GetClientRect( rect );
    dc.SetTextAlign( TA_BASELINE | TA_CENTER );
    dc.SetTextColor( ::GetSysColor( COLOR_WINDOWTEXT ) );
    dc.SetBkMode(TRANSPARENT);
    dc.TextOut( ( rect.right / 2 ), ( rect.bottom / 2 ),
        s, s.GetLength() );
}

void CMainWindow::OnAbout()
{
    CDialog about( wxT("AboutBox"), this );
    about.DoModal();
}

void CMainWindow::OnTest()
{
    wxMessageBox(wxT("This is a wxWidgets message box.\nWe're about to create a new wxWidgets frame."), wxT("wxWidgets"), wxOK);
    wxGetApp().CreateFrame();
}

// CMainWindow message map:
// Associate messages with member functions.
//
// It is implied that the ON_WM_PAINT macro expects a member function
// "void OnPaint()".
//
// It is implied that members connected with the ON_COMMAND macro
// receive no arguments and are void of return type, e.g., "void OnAbout()".
//
BEGIN_MESSAGE_MAP( CMainWindow, CFrameWnd )
//{{AFX_MSG_MAP( CMainWindow )
ON_WM_PAINT()
ON_COMMAND( IDM_ABOUT, OnAbout )
ON_COMMAND( IDM_TEST, OnTest )
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CTheApp::InitInstance()
{
    if ( !CWinApp::InitInstance() )
        return FALSE;

    // TODO: cmd line parsing
    WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
    wxSetInstance(m_hInstance);
    wxApp::m_nCmdShow = m_nCmdShow;
    int argc = 0;
    wxChar **argv = NULL;
    wxEntryStart(argc, argv);
    if ( !wxTheApp || !wxTheApp->CallOnInit() )
        return FALSE;

#if START_WITH_MFC_WINDOW
    // Demonstrate creation of an initial MFC main window.
    m_pMainWnd = new CMainWindow();
    m_pMainWnd->ShowWindow( m_nCmdShow );
    m_pMainWnd->UpdateWindow();
#else
    // Demonstrate creation of an initial wxWidgets main window.
    // Wrap wxWidgets window in a dummy MFC window and
    // make the main window.
    if (wxTheApp && wxTheApp->GetTopWindow())
    {
        m_pMainWnd = new CDummyWindow((HWND) wxTheApp->GetTopWindow()->GetHWND());
    }
#endif

    return TRUE;
}

int CTheApp::ExitInstance()
{
#if !START_WITH_MFC_WINDOW
    delete m_pMainWnd;
#endif

    if ( wxTheApp )
        wxTheApp->OnExit();
    wxEntryCleanup();

    return CWinApp::ExitInstance();
}

// Override this to provide wxWidgets message loop compatibility
BOOL CTheApp::PreTranslateMessage(MSG *msg)
{
    wxEventLoop * const
        evtLoop = static_cast<wxEventLoop *>(wxEventLoop::GetActive());
    if ( evtLoop && evtLoop->PreProcessMessage(msg) )
        return TRUE;

    return CWinApp::PreTranslateMessage(msg);
}

BOOL CTheApp::OnIdle(LONG WXUNUSED(lCount))
{
    return wxTheApp && wxTheApp->ProcessIdle();
}

/*********************************************************************
* wxWidgets elements
********************************************************************/

bool MyApp::OnInit()
{
    if ( !wxApp::OnInit() )
        return false;

#if !START_WITH_MFC_WINDOW
    // as we're not inside wxWidgets main loop, the default logic doesn't work
    // in our case and we need to do this explicitly
    SetExitOnFrameDelete(true);

    (void) CreateFrame();
#endif

    return true;
}

void MyApp::ExitMainLoop()
{
    // instead of existing wxWidgets main loop, terminate the MFC one
    ::PostQuitMessage(0);
}

wxFrame *MyApp::CreateFrame()
{
    MyChild *subframe = new MyChild(NULL, wxT("Canvas Frame"), wxPoint(10, 10), wxSize(300, 300),
        wxDEFAULT_FRAME_STYLE);

    subframe->SetTitle(wxT("wxWidgets canvas frame"));

    // Give it a status line
    subframe->CreateStatusBar();

    // Make a menubar
    wxMenu *file_menu = new wxMenu;

    file_menu->Append(HELLO_NEW, wxT("&New MFC Window"));
    file_menu->Append(HELLO_QUIT, wxT("&Close"));

    wxMenuBar *menu_bar = new wxMenuBar;

    menu_bar->Append(file_menu, wxT("&File"));

    // Associate the menu bar with the frame
    subframe->SetMenuBar(menu_bar);

    int width, height;
    subframe->GetClientSize(&width, &height);

    MyCanvas *canvas = new MyCanvas(subframe, wxPoint(0, 0), wxSize(width, height));
    canvas->SetCursor(wxCursor(wxCURSOR_PENCIL));
    subframe->canvas = canvas;
    subframe->Show(true);

    // Return the main frame window
    return subframe;
}

wxBEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
    EVT_PAINT(MyCanvas::OnPaint)
    EVT_MOUSE_EVENTS(MyCanvas::OnMouseEvent)
wxEND_EVENT_TABLE()

// Define a constructor for my canvas
MyCanvas::MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size)
        : wxScrolledWindow(parent, -1, pos, size)
{
}

// Define the repainting behaviour
void MyCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
{
    wxPaintDC dc(this);

    dc.SetFont(* wxSWISS_FONT);
    dc.SetPen(* wxGREEN_PEN);
    dc.DrawLine(0, 0, 200, 200);
    dc.DrawLine(200, 0, 0, 200);

    dc.SetBrush(* wxCYAN_BRUSH);
    dc.SetPen(* wxRED_PEN);
    dc.DrawRectangle(100, 100, 100, 50);
    dc.DrawRoundedRectangle(150, 150, 100, 50, 20);

    dc.DrawEllipse(250, 250, 100, 50);
    dc.DrawLine(50, 230, 200, 230);
    dc.DrawText(wxT("This is a test string"), 50, 230);
}

// This implements a tiny doodling program! Drag the mouse using
// the left button.
void MyCanvas::OnMouseEvent(wxMouseEvent& event)
{
    static long s_xpos = -1;
    static long s_ypos = -1;

    wxClientDC dc(this);
    dc.SetPen(* wxBLACK_PEN);
    wxPoint pos = event.GetPosition();
    if (s_xpos > -1 && s_ypos > -1 && event.Dragging())
    {
        dc.DrawLine(s_xpos, s_ypos, pos.x, pos.y);
    }

    s_xpos = pos.x;
    s_ypos = pos.y;
}

wxBEGIN_EVENT_TABLE(MyChild, wxFrame)
    EVT_MENU(HELLO_QUIT, MyChild::OnQuit)
    EVT_MENU(HELLO_NEW, MyChild::OnNew)
    EVT_ACTIVATE(MyChild::OnActivate)
wxEND_EVENT_TABLE()

MyChild::MyChild(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size, const long style)
       : wxFrame(frame, -1, title, pos, size, style)
{
    canvas = NULL;
}

MyChild::~MyChild()
{
    if ( IsLastBeforeExit() )
        PostQuitMessage(0);
}

void MyChild::OnQuit(wxCommandEvent& WXUNUSED(event))
{
    Close(true);
}

void MyChild::OnNew(wxCommandEvent& WXUNUSED(event))
{
    CMainWindow *mainWin = new CMainWindow();
    mainWin->ShowWindow( TRUE );
    mainWin->UpdateWindow();
}

void MyChild::OnActivate(wxActivateEvent& event)
{
    if (event.GetActive() && canvas)
        canvas->SetFocus();
}

// Dummy MFC window for specifying a valid main window to MFC, using
// a wxWidgets HWND.
CDummyWindow::CDummyWindow(HWND hWnd)
{
    Attach(hWnd);
}

// Don't let the CWnd destructor delete the HWND
CDummyWindow::~CDummyWindow()
{
    Detach();
}