/
mfctest.cpp
376 lines (304 loc) · 10.4 KB
/
mfctest.cpp
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
/////////////////////////////////////////////////////////////////////////////
// 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) Define a class deriving from wxMFCWinApp and override its InitMainWnd()
// to create the main window in MFC code.
//
// This can be accomplished by setting START_WITH_MFC_WINDOW to 1 below.
#define START_WITH_MFC_WINDOW 0
// NOTES:
//
// * 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
//
// * 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
#ifndef _UNICODE
# define _UNICODE
#endif
#ifndef UNICODE
# define UNICODE
#endif
#include "stdafx.h"
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/evtloop.h"
#include "wx/nativewin.h"
#include "wx/spinctrl.h"
#include "wx/msw/mfc.h"
#include "resource.h"
#include "mfctest.h"
/////////////////////////////////////////////////////////////////////////////
// theApp:
// Just creating this application object runs the whole application.
//
SampleMFCWinApp theApp;
// wxWidgets elements
// Define a new application type inheriting from wxAppWithMFC
class MyApp: public wxAppWithMFC
{
public:
virtual bool OnInit() override;
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();
};
class MyPanel : public wxPanel
{
public:
MyPanel(wxWindow *parent, const wxPoint& pos)
: wxPanel(parent, wxID_ANY, pos)
{
wxSizer* const sizer = new wxFlexGridSizer(2, wxSize(5, 5));
sizer->Add(new wxStaticText(this, wxID_ANY, "Enter your &name:"),
wxSizerFlags().Center().Right());
m_textName = new wxTextCtrl(this, wxID_ANY);
m_textName->SetHint("First Last");
sizer->Add(m_textName, wxSizerFlags().Expand().CenterVertical());
sizer->Add(new wxStaticText(this, wxID_ANY, "And your &age:"),
wxSizerFlags().Center().Right());
m_spinAge = new wxSpinCtrl(this, wxID_ANY);
sizer->Add(m_spinAge, wxSizerFlags().Expand().CenterVertical());
wxStaticBoxSizer* const
box = new wxStaticBoxSizer(wxVERTICAL, this, "wxWidgets box");
box->Add(sizer, wxSizerFlags(1).Expand());
SetSizer(box);
// We won't be resized automatically, so set our size ourselves.
SetSize(GetBestSize());
}
private:
wxTextCtrl* m_textName;
wxSpinCtrl* m_spinAge;
};
// ID for the menu quit command
#define HELLO_QUIT 1
#define HELLO_NEW 2
wxDECLARE_APP(MyApp);
// Notice use of wxIMPLEMENT_APP_NO_MAIN() instead of the usual wxIMPLEMENT_APP!
wxIMPLEMENT_APP_NO_MAIN(MyApp);
// 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();
}
CMainWindow::CMainWindow()
{
LoadAccelTable( L"MainAccelTable" );
Create( nullptr, L"Hello Foundation Application",
WS_OVERLAPPEDWINDOW, rectDefault, nullptr, L"MainMenu" );
// Create a container representing the MFC window in wxWidgets window
// hierarchy.
m_containerWX = new wxNativeContainerWindow(m_hWnd);
// Now we can create children of this container as usual.
new MyPanel(m_containerWX, wxPoint(5, 5));
// An ugly but necessary workaround to prevent the container TLW from
// resizing the panel to fit its entire client area as it would do if it
// were its only child.
new wxWindow(m_containerWX, wxID_ANY, wxPoint(4, 4), wxSize(1, 1));
}
void CMainWindow::OnPaint()
{
CString s = "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( L"AboutBox", this );
about.DoModal();
}
void CMainWindow::OnTest()
{
wxMessageBox("This is a wxWidgets message box.\nWe're about to create a new wxWidgets frame.", "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()
/*********************************************************************
* wxWidgets elements
********************************************************************/
bool MyApp::OnInit()
{
if ( !wxApp::OnInit() )
return false;
#if !START_WITH_MFC_WINDOW
(void) CreateFrame();
#endif
return true;
}
wxFrame *MyApp::CreateFrame()
{
MyChild *subframe = new MyChild(nullptr, "Canvas Frame", wxPoint(10, 10), wxSize(300, 300),
wxDEFAULT_FRAME_STYLE);
subframe->SetTitle("wxWidgets canvas frame");
// Give it a status line
subframe->CreateStatusBar();
// Make a menubar
wxMenu *file_menu = new wxMenu;
file_menu->Append(HELLO_NEW, "&New MFC Window");
file_menu->Append(HELLO_QUIT, "&Close");
wxMenuBar *menu_bar = new wxMenuBar;
menu_bar->Append(file_menu, "&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)
{
MSWDisableComposited();
}
// 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("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 = nullptr;
}
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();
}