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