]> git.saurik.com Git - wxWidgets.git/blame - samples/mfc/mfctest.cpp
Allow compilation of samples to continue with wxUSE_DISPLAY set to 0 (the default)
[wxWidgets.git] / samples / mfc / mfctest.cpp
CommitLineData
7818a75c
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: mfctest.cpp
be5a51fb 3// Purpose: Sample to demonstrate mixing MFC and wxWidgets code
7818a75c
JS
4// Author: Julian Smart
5// Id: $Id$
6// Copyright: (c) Julian Smart
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
bbf1f0e5 9
be5a51fb 10// This sample pops up an initial wxWidgets frame, with a menu item
bbf1f0e5 11// that allows a new MFC window to be created. Note that CDummyWindow
be5a51fb 12// is a class that allows a wxWidgets window to be seen as a CWnd
bbf1f0e5
KB
13// for the purposes of specifying a valid main window to the
14// MFC initialisation.
15//
16// You can easily modify this code so that an MFC window pops up
be5a51fb 17// initially as the main frame, and allows wxWidgets frames to be
22431134 18// created subsequently.
bbf1f0e5 19//
22431134
JS
20// (1) Make MyApp::OnInit not create a main window.
21// (2) Make MFC's InitInstance create a main window, and remove
bbf1f0e5 22// creation of CDummyWindow.
22431134
JS
23//
24// This can be accomplished by setting START_WITH_MFC_WINDOW to 1 below.
25
26#define START_WITH_MFC_WINDOW 0
27
bbf1f0e5 28//
3f8e5072
JS
29// IMPORTANT NOTES:
30//
885ebd2b
VZ
31// (1) You may need to set wxUSE_MFC to 1 in include/wx/msw/setup.h but
32// normally this shouldn't be needed any longer, i.e. it works without
33// it for me (VZ)
3f8e5072 34//
4d3923a7
JS
35// (2) You should link with MFC DLL, not static libraries: or, to use static
36// run-time libraries, use this command for both building wxWidgets and
37// the sample:
38//
39// nmake -f makefile.vc BUILD=debug SHARED=0 DEBUG_RUNTIME_LIBS=0 RUNTIME_LIBS=static all
40//
41// Unless the run-time library settings match for wxWidgets and MFC, you will get
42// link errors for symbols such as __mbctype, __argc, and __argv
885ebd2b
VZ
43
44#include "stdafx.h"
bbf1f0e5
KB
45
46// For compilers that support precompilation, includes "wx/wx.h".
47#include "wx/wxprec.h"
48
49#ifdef __BORLANDC__
50#pragma hdrstop
51#endif
52
885ebd2b
VZ
53#ifndef WX_PRECOMP
54 #include "wx/wx.h"
bbf1f0e5
KB
55#endif
56
885ebd2b 57#include "wx/evtloop.h"
bbf1f0e5
KB
58
59#include "resource.h"
60
61#include "mfctest.h"
62
bbf1f0e5
KB
63/////////////////////////////////////////////////////////////////////////////
64
65// theApp:
66// Just creating this application object runs the whole application.
67//
68CTheApp theApp;
69
be5a51fb 70// wxWidgets elements
bbf1f0e5
KB
71
72// Define a new application type
73class MyApp: public wxApp
885ebd2b
VZ
74{
75public:
76 virtual bool OnInit();
77
78 wxFrame *CreateFrame();
22431134 79};
bbf1f0e5 80
bbf1f0e5
KB
81class MyCanvas: public wxScrolledWindow
82{
22431134 83public:
bbf1f0e5
KB
84 MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size);
85 void OnPaint(wxPaintEvent& event);
86 void OnMouseEvent(wxMouseEvent& event);
22431134 87 DECLARE_EVENT_TABLE()
bbf1f0e5
KB
88};
89
90class MyChild: public wxFrame
91{
22431134 92public:
bbf1f0e5 93 MyChild(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size, const long style);
885ebd2b
VZ
94 virtual ~MyChild();
95
bbf1f0e5
KB
96 void OnQuit(wxCommandEvent& event);
97 void OnNew(wxCommandEvent& event);
98 void OnActivate(wxActivateEvent& event);
885ebd2b
VZ
99
100 MyCanvas *canvas;
101
22431134 102 DECLARE_EVENT_TABLE()
bbf1f0e5
KB
103};
104
bbf1f0e5
KB
105// ID for the menu quit command
106#define HELLO_QUIT 1
107#define HELLO_NEW 2
108
109DECLARE_APP(MyApp)
bbf1f0e5 110
885ebd2b
VZ
111// notice use of IMPLEMENT_APP_NO_MAIN() instead of the usual IMPLEMENT_APP!
112IMPLEMENT_APP_NO_MAIN(MyApp)
bbf1f0e5 113
bbf1f0e5
KB
114CMainWindow::CMainWindow()
115{
2f6c54eb
VZ
116 LoadAccelTable( "MainAccelTable" );
117 Create( NULL, "Hello Foundation Application",
118 WS_OVERLAPPEDWINDOW, rectDefault, NULL, "MainMenu" );
bbf1f0e5
KB
119}
120
bbf1f0e5
KB
121void CMainWindow::OnPaint()
122{
2f6c54eb
VZ
123 CString s = "Hello, Windows!";
124 CPaintDC dc( this );
125 CRect rect;
885ebd2b 126
2f6c54eb
VZ
127 GetClientRect( rect );
128 dc.SetTextAlign( TA_BASELINE | TA_CENTER );
129 dc.SetTextColor( ::GetSysColor( COLOR_WINDOWTEXT ) );
130 dc.SetBkMode(TRANSPARENT);
131 dc.TextOut( ( rect.right / 2 ), ( rect.bottom / 2 ),
22431134 132 s, s.GetLength() );
bbf1f0e5
KB
133}
134
bbf1f0e5
KB
135void CMainWindow::OnAbout()
136{
2f6c54eb
VZ
137 CDialog about( "AboutBox", this );
138 about.DoModal();
bbf1f0e5
KB
139}
140
141void CMainWindow::OnTest()
142{
be5a51fb 143 wxMessageBox("This is a wxWidgets message box.\nWe're about to create a new wxWidgets frame.", "wxWidgets", wxOK);
22431134 144 wxGetApp().CreateFrame();
bbf1f0e5
KB
145}
146
147// CMainWindow message map:
148// Associate messages with member functions.
149//
150// It is implied that the ON_WM_PAINT macro expects a member function
151// "void OnPaint()".
152//
153// It is implied that members connected with the ON_COMMAND macro
154// receive no arguments and are void of return type, e.g., "void OnAbout()".
155//
156BEGIN_MESSAGE_MAP( CMainWindow, CFrameWnd )
22431134
JS
157//{{AFX_MSG_MAP( CMainWindow )
158ON_WM_PAINT()
159ON_COMMAND( IDM_ABOUT, OnAbout )
160ON_COMMAND( IDM_TEST, OnTest )
161//}}AFX_MSG_MAP
bbf1f0e5
KB
162END_MESSAGE_MAP()
163
bbf1f0e5
KB
164BOOL CTheApp::InitInstance()
165{
885ebd2b
VZ
166 if ( !CWinApp::InitInstance() )
167 return FALSE;
168
169 // TODO: cmd line parsing
170 WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
171 wxSetInstance(m_hInstance);
172 wxApp::m_nCmdShow = m_nCmdShow;
173 int argc = 0;
174 char **argv = NULL;
175 wxEntryStart(argc, argv);
176 if ( !wxTheApp || !wxTheApp->CallOnInit() )
177 return FALSE;
178
22431134
JS
179#if START_WITH_MFC_WINDOW
180 // Demonstrate creation of an initial MFC main window.
2f6c54eb
VZ
181 m_pMainWnd = new CMainWindow();
182 m_pMainWnd->ShowWindow( m_nCmdShow );
183 m_pMainWnd->UpdateWindow();
885ebd2b 184#else
be5a51fb
JS
185 // Demonstrate creation of an initial wxWidgets main window.
186 // Wrap wxWidgets window in a dummy MFC window and
22431134 187 // make the main window.
bbf1f0e5
KB
188 if (wxTheApp && wxTheApp->GetTopWindow())
189 {
190 m_pMainWnd = new CDummyWindow((HWND) wxTheApp->GetTopWindow()->GetHWND());
191 }
22431134 192#endif
885ebd2b 193
2f6c54eb 194 return TRUE;
bbf1f0e5
KB
195}
196
197int CTheApp::ExitInstance()
198{
cc3bb83d
VZ
199#if !START_WITH_MFC_WINDOW
200 delete m_pMainWnd;
201#endif
202
885ebd2b
VZ
203 if ( wxTheApp )
204 wxTheApp->OnExit();
205 wxEntryCleanup();
206
22431134 207 return CWinApp::ExitInstance();
bbf1f0e5
KB
208}
209
885ebd2b 210// Override this to provide wxWidgets message loop compatibility
bbf1f0e5
KB
211BOOL CTheApp::PreTranslateMessage(MSG *msg)
212{
885ebd2b
VZ
213 wxEventLoop *evtLoop = wxEventLoop::GetActive();
214 if ( evtLoop && evtLoop->PreProcessMessage(msg) )
22431134 215 return TRUE;
885ebd2b
VZ
216
217 return CWinApp::PreTranslateMessage(msg);
bbf1f0e5
KB
218}
219
885ebd2b 220BOOL CTheApp::OnIdle(LONG WXUNUSED(lCount))
bbf1f0e5 221{
885ebd2b 222 return wxTheApp && wxTheApp->ProcessIdle();
bbf1f0e5
KB
223}
224
225/*********************************************************************
be5a51fb 226* wxWidgets elements
22431134
JS
227********************************************************************/
228
885ebd2b 229bool MyApp::OnInit()
bbf1f0e5 230{
22431134
JS
231#if !START_WITH_MFC_WINDOW
232
233 // Exit app when the top level frame is deleted
234 SetExitOnFrameDelete(TRUE);
885ebd2b 235
22431134
JS
236 (void) CreateFrame();
237#endif
238
239 return TRUE;
bbf1f0e5
KB
240}
241
885ebd2b 242wxFrame *MyApp::CreateFrame()
bbf1f0e5 243{
22431134
JS
244 MyChild *subframe = new MyChild(NULL, "Canvas Frame", wxPoint(10, 10), wxSize(300, 300),
245 wxDEFAULT_FRAME_STYLE);
885ebd2b 246
be5a51fb 247 subframe->SetTitle("wxWidgets canvas frame");
885ebd2b 248
22431134
JS
249 // Give it a status line
250 subframe->CreateStatusBar();
885ebd2b 251
22431134
JS
252 // Make a menubar
253 wxMenu *file_menu = new wxMenu;
885ebd2b 254
22431134
JS
255 file_menu->Append(HELLO_NEW, "&New MFC Window");
256 file_menu->Append(HELLO_QUIT, "&Close");
885ebd2b 257
22431134 258 wxMenuBar *menu_bar = new wxMenuBar;
885ebd2b 259
22431134 260 menu_bar->Append(file_menu, "&File");
885ebd2b 261
22431134
JS
262 // Associate the menu bar with the frame
263 subframe->SetMenuBar(menu_bar);
885ebd2b 264
22431134
JS
265 int width, height;
266 subframe->GetClientSize(&width, &height);
885ebd2b 267
22431134
JS
268 MyCanvas *canvas = new MyCanvas(subframe, wxPoint(0, 0), wxSize(width, height));
269 canvas->SetCursor(wxCursor(wxCURSOR_PENCIL));
885ebd2b 270 subframe->canvas = canvas;
22431134
JS
271 subframe->Show(TRUE);
272
273 // Return the main frame window
274 return subframe;
bbf1f0e5
KB
275}
276
277BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
278 EVT_PAINT(MyCanvas::OnPaint)
279 EVT_MOUSE_EVENTS(MyCanvas::OnMouseEvent)
280END_EVENT_TABLE()
281
282// Define a constructor for my canvas
885ebd2b
VZ
283MyCanvas::MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size)
284 : wxScrolledWindow(parent, -1, pos, size)
bbf1f0e5
KB
285{
286}
287
288// Define the repainting behaviour
885ebd2b 289void MyCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
bbf1f0e5
KB
290{
291 wxPaintDC dc(this);
885ebd2b 292
f5e5bd66 293 dc.SetFont(* wxSWISS_FONT);
17b74d79 294 dc.SetPen(* wxGREEN_PEN);
bbf1f0e5
KB
295 dc.DrawLine(0, 0, 200, 200);
296 dc.DrawLine(200, 0, 0, 200);
885ebd2b 297
17b74d79
JS
298 dc.SetBrush(* wxCYAN_BRUSH);
299 dc.SetPen(* wxRED_PEN);
bbf1f0e5
KB
300 dc.DrawRectangle(100, 100, 100, 50);
301 dc.DrawRoundedRectangle(150, 150, 100, 50, 20);
885ebd2b 302
bbf1f0e5 303 dc.DrawEllipse(250, 250, 100, 50);
bbf1f0e5
KB
304 dc.DrawLine(50, 230, 200, 230);
305 dc.DrawText("This is a test string", 50, 230);
306}
307
308// This implements a tiny doodling program! Drag the mouse using
309// the left button.
310void MyCanvas::OnMouseEvent(wxMouseEvent& event)
311{
885ebd2b
VZ
312 static long s_xpos = -1;
313 static long s_ypos = -1;
314
bbf1f0e5 315 wxClientDC dc(this);
17b74d79 316 dc.SetPen(* wxBLACK_PEN);
3f8e5072 317 wxPoint pos = event.GetPosition();
885ebd2b 318 if (s_xpos > -1 && s_ypos > -1 && event.Dragging())
bbf1f0e5 319 {
885ebd2b 320 dc.DrawLine(s_xpos, s_ypos, pos.x, pos.y);
bbf1f0e5 321 }
885ebd2b
VZ
322
323 s_xpos = pos.x;
324 s_ypos = pos.y;
bbf1f0e5
KB
325}
326
327BEGIN_EVENT_TABLE(MyChild, wxFrame)
328 EVT_MENU(HELLO_QUIT, MyChild::OnQuit)
329 EVT_MENU(HELLO_NEW, MyChild::OnNew)
330 EVT_ACTIVATE(MyChild::OnActivate)
331END_EVENT_TABLE()
332
885ebd2b
VZ
333MyChild::MyChild(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size, const long style)
334 : wxFrame(frame, -1, title, pos, size, style)
bbf1f0e5 335{
22431134 336 canvas = NULL;
bbf1f0e5
KB
337}
338
885ebd2b 339MyChild::~MyChild()
bbf1f0e5 340{
cc3bb83d
VZ
341 if ( IsLastBeforeExit() )
342 PostQuitMessage(0);
bbf1f0e5
KB
343}
344
885ebd2b 345void MyChild::OnQuit(wxCommandEvent& WXUNUSED(event))
bbf1f0e5
KB
346{
347 Close(TRUE);
348}
349
885ebd2b 350void MyChild::OnNew(wxCommandEvent& WXUNUSED(event))
bbf1f0e5
KB
351{
352 CMainWindow *mainWin = new CMainWindow();
353 mainWin->ShowWindow( TRUE );
354 mainWin->UpdateWindow();
355}
22431134 356
bbf1f0e5
KB
357void MyChild::OnActivate(wxActivateEvent& event)
358{
22431134
JS
359 if (event.GetActive() && canvas)
360 canvas->SetFocus();
bbf1f0e5
KB
361}
362
bbf1f0e5 363// Dummy MFC window for specifying a valid main window to MFC, using
be5a51fb 364// a wxWidgets HWND.
cc3bb83d 365CDummyWindow::CDummyWindow(HWND hWnd)
bbf1f0e5 366{
22431134 367 Attach(hWnd);
bbf1f0e5
KB
368}
369
370// Don't let the CWnd destructor delete the HWND
885ebd2b 371CDummyWindow::~CDummyWindow()
bbf1f0e5 372{
22431134 373 Detach();
bbf1f0e5
KB
374}
375