]> git.saurik.com Git - wxWidgets.git/blame - samples/mfc/mfctest.cpp
GetClientAreaOrigin should be public
[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//
31// (1) You need to set wxUSE_MFC to 1 in include/wx/msw/setup.h, which switches
32// off some debugging features and also removes the windows.h inclusion
33// in wxprec.h (MFC headers don't like this to have been included previously).
22431134 34// Set to 'Use MFC in a shared DLL' or add _AFXDLL to preprocessor settings.
be5a51fb 35// Then recompile wxWidgets and this sample.
3f8e5072 36//
22431134 37// (2) I can't get the sample to link and run using a static MFC library, only the DLL
3f8e5072
JS
38// version. Perhaps someone else is a wizard at working out the required settings
39// in the wxWin library and the sample; then debugging the assert problem may be
40// easier.
f6bcfd97 41//
be5a51fb
JS
42// (3) Compiling wxWidgets in DLL mode currently includes windows.h, so you must only
43// try linking wxWidgets statically.
bbf1f0e5
KB
44
45// For compilers that support precompilation, includes "wx/wx.h".
46#include "wx/wxprec.h"
47
48#ifdef __BORLANDC__
49#pragma hdrstop
50#endif
51
bbf1f0e5 52#include "wx/wx.h"
bbf1f0e5 53
f6bcfd97 54#if defined(_WINDOWS_) || !wxUSE_MFC
75d1935a 55#error "Sorry, you need to edit include/wx/msw/setup.h, set wxUSE_MFC to 1, and recompile the library."
818e52c2
JS
56#endif
57
bbf1f0e5
KB
58#ifdef new
59#undef new
60#endif
61
62#include "stdafx.h"
63
64#ifdef DrawText
65#undef DrawText
66#endif
67
68#include "resource.h"
69
70#include "mfctest.h"
71
bbf1f0e5
KB
72/////////////////////////////////////////////////////////////////////////////
73
74// theApp:
75// Just creating this application object runs the whole application.
76//
77CTheApp theApp;
78
be5a51fb 79// wxWidgets elements
bbf1f0e5
KB
80
81// Define a new application type
82class MyApp: public wxApp
83{ public:
22431134
JS
84bool OnInit(void);
85wxFrame *CreateFrame(void);
86};
bbf1f0e5 87
bbf1f0e5
KB
88class MyCanvas: public wxScrolledWindow
89{
22431134 90public:
bbf1f0e5
KB
91 MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size);
92 void OnPaint(wxPaintEvent& event);
93 void OnMouseEvent(wxMouseEvent& event);
22431134 94 DECLARE_EVENT_TABLE()
bbf1f0e5
KB
95};
96
97class MyChild: public wxFrame
98{
22431134 99public:
bbf1f0e5
KB
100 MyCanvas *canvas;
101 MyChild(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size, const long style);
102 ~MyChild(void);
22431134 103
bbf1f0e5
KB
104 void OnQuit(wxCommandEvent& event);
105 void OnNew(wxCommandEvent& event);
106 void OnActivate(wxActivateEvent& event);
22431134
JS
107
108 DECLARE_EVENT_TABLE()
bbf1f0e5
KB
109};
110
111// For drawing lines in a canvas
112long xpos = -1;
113long ypos = -1;
114
bbf1f0e5
KB
115// ID for the menu quit command
116#define HELLO_QUIT 1
117#define HELLO_NEW 2
118
119DECLARE_APP(MyApp)
120IMPLEMENT_APP(MyApp)
121
122/////////////////////////////////////////////////////////////////////////////
123
124// CMainWindow constructor:
125// Create the window with the appropriate style, size, menu, etc.
126//
127CMainWindow::CMainWindow()
128{
2f6c54eb
VZ
129 LoadAccelTable( "MainAccelTable" );
130 Create( NULL, "Hello Foundation Application",
131 WS_OVERLAPPEDWINDOW, rectDefault, NULL, "MainMenu" );
bbf1f0e5
KB
132}
133
134// OnPaint:
135// This routine draws the string "Hello, Windows!" in the center of the
136// client area. It is called whenever Windows sends a WM_PAINT message.
137// Note that creating a CPaintDC automatically does a BeginPaint and
138// an EndPaint call is done when it is destroyed at the end of this
139// function. CPaintDC's constructor needs the window (this).
140//
141void CMainWindow::OnPaint()
142{
2f6c54eb
VZ
143 CString s = "Hello, Windows!";
144 CPaintDC dc( this );
145 CRect rect;
22431134 146
2f6c54eb
VZ
147 GetClientRect( rect );
148 dc.SetTextAlign( TA_BASELINE | TA_CENTER );
149 dc.SetTextColor( ::GetSysColor( COLOR_WINDOWTEXT ) );
150 dc.SetBkMode(TRANSPARENT);
151 dc.TextOut( ( rect.right / 2 ), ( rect.bottom / 2 ),
22431134 152 s, s.GetLength() );
bbf1f0e5
KB
153}
154
155// OnAbout:
156// This member function is called when a WM_COMMAND message with an
157// IDM_ABOUT code is received by the CMainWindow class object. The
158// message map below is responsible for this routing.
159//
160// We create a ClDialog object using the "AboutBox" resource (see
161// hello.rc), and invoke it.
162//
163void CMainWindow::OnAbout()
164{
2f6c54eb
VZ
165 CDialog about( "AboutBox", this );
166 about.DoModal();
bbf1f0e5
KB
167}
168
169void CMainWindow::OnTest()
170{
be5a51fb 171 wxMessageBox("This is a wxWidgets message box.\nWe're about to create a new wxWidgets frame.", "wxWidgets", wxOK);
22431134 172 wxGetApp().CreateFrame();
bbf1f0e5
KB
173}
174
175// CMainWindow message map:
176// Associate messages with member functions.
177//
178// It is implied that the ON_WM_PAINT macro expects a member function
179// "void OnPaint()".
180//
181// It is implied that members connected with the ON_COMMAND macro
182// receive no arguments and are void of return type, e.g., "void OnAbout()".
183//
184BEGIN_MESSAGE_MAP( CMainWindow, CFrameWnd )
22431134
JS
185//{{AFX_MSG_MAP( CMainWindow )
186ON_WM_PAINT()
187ON_COMMAND( IDM_ABOUT, OnAbout )
188ON_COMMAND( IDM_TEST, OnTest )
189//}}AFX_MSG_MAP
bbf1f0e5
KB
190END_MESSAGE_MAP()
191
192/////////////////////////////////////////////////////////////////////////////
193// CTheApp
194
195// InitInstance:
196// When any CTheApp object is created, this member function is automatically
197// called. Any data may be set up at this point.
198//
199// Also, the main window of the application should be created and shown here.
200// Return TRUE if the initialization is successful.
201//
202BOOL CTheApp::InitInstance()
203{
2f6c54eb 204 SetDialogBkColor(); // hook gray dialogs (was default in MFC V1)
22431134 205
bbf1f0e5 206 wxEntry((WXHINSTANCE) m_hInstance, (WXHINSTANCE) m_hPrevInstance, m_lpCmdLine, m_nCmdShow, FALSE);
22431134
JS
207
208#if START_WITH_MFC_WINDOW
209 // Demonstrate creation of an initial MFC main window.
2f6c54eb
VZ
210 m_pMainWnd = new CMainWindow();
211 m_pMainWnd->ShowWindow( m_nCmdShow );
212 m_pMainWnd->UpdateWindow();
22431134 213#else
be5a51fb
JS
214 // Demonstrate creation of an initial wxWidgets main window.
215 // Wrap wxWidgets window in a dummy MFC window and
22431134 216 // make the main window.
bbf1f0e5
KB
217 if (wxTheApp && wxTheApp->GetTopWindow())
218 {
219 m_pMainWnd = new CDummyWindow((HWND) wxTheApp->GetTopWindow()->GetHWND());
220 }
22431134
JS
221#endif
222
2f6c54eb 223 return TRUE;
bbf1f0e5
KB
224}
225
226int CTheApp::ExitInstance()
227{
22431134
JS
228 // OnExit isn't called by CleanUp so must be called explicitly.
229 wxTheApp->OnExit();
230 wxApp::CleanUp();
231
232 return CWinApp::ExitInstance();
bbf1f0e5
KB
233}
234
be5a51fb 235// Override this to provide wxWidgets message loop
bbf1f0e5
KB
236// compatibility
237
238BOOL CTheApp::PreTranslateMessage(MSG *msg)
239{
22431134
JS
240 if (wxTheApp && wxTheApp->ProcessMessage((WXMSG*) msg))
241 return TRUE;
242 else
243 return CWinApp::PreTranslateMessage(msg);
bbf1f0e5
KB
244}
245
246BOOL CTheApp::OnIdle(LONG lCount)
247{
248 if (wxTheApp)
249 return wxTheApp->ProcessIdle();
250 else
251 return FALSE;
252}
253
254/*********************************************************************
be5a51fb 255* wxWidgets elements
22431134
JS
256********************************************************************/
257
bbf1f0e5
KB
258bool MyApp::OnInit(void)
259{
22431134
JS
260#if !START_WITH_MFC_WINDOW
261
262 // Exit app when the top level frame is deleted
263 SetExitOnFrameDelete(TRUE);
264
265 (void) CreateFrame();
266#endif
267
268 return TRUE;
bbf1f0e5
KB
269}
270
271wxFrame *MyApp::CreateFrame(void)
272{
22431134
JS
273 MyChild *subframe = new MyChild(NULL, "Canvas Frame", wxPoint(10, 10), wxSize(300, 300),
274 wxDEFAULT_FRAME_STYLE);
275
be5a51fb 276 subframe->SetTitle("wxWidgets canvas frame");
22431134
JS
277
278 // Give it a status line
279 subframe->CreateStatusBar();
280
281 // Make a menubar
282 wxMenu *file_menu = new wxMenu;
283
284 file_menu->Append(HELLO_NEW, "&New MFC Window");
285 file_menu->Append(HELLO_QUIT, "&Close");
286
287 wxMenuBar *menu_bar = new wxMenuBar;
288
289 menu_bar->Append(file_menu, "&File");
290
291 // Associate the menu bar with the frame
292 subframe->SetMenuBar(menu_bar);
293
294 int width, height;
295 subframe->GetClientSize(&width, &height);
296
297 MyCanvas *canvas = new MyCanvas(subframe, wxPoint(0, 0), wxSize(width, height));
298 canvas->SetCursor(wxCursor(wxCURSOR_PENCIL));
299 subframe->canvas = canvas;
300 subframe->Show(TRUE);
301
302 // Return the main frame window
303 return subframe;
bbf1f0e5
KB
304}
305
306BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
307 EVT_PAINT(MyCanvas::OnPaint)
308 EVT_MOUSE_EVENTS(MyCanvas::OnMouseEvent)
309END_EVENT_TABLE()
310
311// Define a constructor for my canvas
312MyCanvas::MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size):
22431134 313wxScrolledWindow(parent, -1, pos, size)
bbf1f0e5
KB
314{
315}
316
317// Define the repainting behaviour
318void MyCanvas::OnPaint(wxPaintEvent& event)
319{
320 wxPaintDC dc(this);
22431134 321
f5e5bd66 322 dc.SetFont(* wxSWISS_FONT);
17b74d79 323 dc.SetPen(* wxGREEN_PEN);
bbf1f0e5
KB
324 dc.DrawLine(0, 0, 200, 200);
325 dc.DrawLine(200, 0, 0, 200);
22431134 326
17b74d79
JS
327 dc.SetBrush(* wxCYAN_BRUSH);
328 dc.SetPen(* wxRED_PEN);
bbf1f0e5
KB
329 dc.DrawRectangle(100, 100, 100, 50);
330 dc.DrawRoundedRectangle(150, 150, 100, 50, 20);
22431134 331
bbf1f0e5
KB
332 dc.DrawEllipse(250, 250, 100, 50);
333 dc.DrawSpline(50, 200, 50, 100, 200, 10);
334 dc.DrawLine(50, 230, 200, 230);
335 dc.DrawText("This is a test string", 50, 230);
336}
337
338// This implements a tiny doodling program! Drag the mouse using
339// the left button.
340void MyCanvas::OnMouseEvent(wxMouseEvent& event)
341{
342 wxClientDC dc(this);
17b74d79 343 dc.SetPen(* wxBLACK_PEN);
3f8e5072 344 wxPoint pos = event.GetPosition();
bbf1f0e5
KB
345 if (xpos > -1 && ypos > -1 && event.Dragging())
346 {
3f8e5072 347 dc.DrawLine(xpos, ypos, pos.x, pos.y);
bbf1f0e5 348 }
3f8e5072
JS
349 xpos = pos.x;
350 ypos = pos.y;
bbf1f0e5
KB
351}
352
353BEGIN_EVENT_TABLE(MyChild, wxFrame)
354 EVT_MENU(HELLO_QUIT, MyChild::OnQuit)
355 EVT_MENU(HELLO_NEW, MyChild::OnNew)
356 EVT_ACTIVATE(MyChild::OnActivate)
357END_EVENT_TABLE()
358
359MyChild::MyChild(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size, const long style):
22431134 360wxFrame(frame, -1, title, pos, size, style)
bbf1f0e5 361{
22431134 362 canvas = NULL;
bbf1f0e5
KB
363}
364
365MyChild::~MyChild(void)
366{
367}
368
369void MyChild::OnQuit(wxCommandEvent& event)
370{
371 Close(TRUE);
372}
373
374void MyChild::OnNew(wxCommandEvent& event)
375{
376 CMainWindow *mainWin = new CMainWindow();
377 mainWin->ShowWindow( TRUE );
378 mainWin->UpdateWindow();
379}
22431134 380
bbf1f0e5
KB
381void MyChild::OnActivate(wxActivateEvent& event)
382{
22431134
JS
383 if (event.GetActive() && canvas)
384 canvas->SetFocus();
bbf1f0e5
KB
385}
386
bbf1f0e5 387// Dummy MFC window for specifying a valid main window to MFC, using
be5a51fb 388// a wxWidgets HWND.
bbf1f0e5
KB
389CDummyWindow::CDummyWindow(HWND hWnd):CWnd()
390{
22431134 391 Attach(hWnd);
bbf1f0e5
KB
392}
393
394// Don't let the CWnd destructor delete the HWND
395CDummyWindow::~CDummyWindow(void)
396{
22431134 397 Detach();
bbf1f0e5
KB
398}
399