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