// normally this shouldn't be needed any longer, i.e. it works without
// it for me (VZ)
//
-// (2) You should link with MFC DLL, not static libraries
+// (2) 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
+//
+// (3) 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
-// suppress warning about WINVER not being defined from MFC
+// 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 0x7000
+ #define WINVER 0x0600
#endif
#include "stdafx.h"
public:
virtual bool OnInit();
+ // we need to override this as the default behaviour only works when we're
+ // running wxWidgets main loop, not MFC one
+ virtual void ExitMainLoop();
+
wxFrame *CreateFrame();
};
// notice use of IMPLEMENT_APP_NO_MAIN() instead of the usual IMPLEMENT_APP!
IMPLEMENT_APP_NO_MAIN(MyApp)
+#ifdef _UNICODE
+// 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();
+}
+#endif // _UNICODE
+
CMainWindow::CMainWindow()
{
- LoadAccelTable( "MainAccelTable" );
- Create( NULL, "Hello Foundation Application",
- WS_OVERLAPPEDWINDOW, rectDefault, NULL, "MainMenu" );
+ LoadAccelTable( wxT("MainAccelTable") );
+ Create( NULL, wxT("Hello Foundation Application"),
+ WS_OVERLAPPEDWINDOW, rectDefault, NULL, wxT("MainMenu") );
}
void CMainWindow::OnPaint()
{
- CString s = "Hello, Windows!";
+ CString s = wxT("Hello, Windows!");
CPaintDC dc( this );
CRect rect;
void CMainWindow::OnAbout()
{
- CDialog about( "AboutBox", this );
+ CDialog about( wxT("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);
+ wxMessageBox(wxT("This is a wxWidgets message box.\nWe're about to create a new wxWidgets frame."), wxT("wxWidgets"), wxOK);
wxGetApp().CreateFrame();
}
wxSetInstance(m_hInstance);
wxApp::m_nCmdShow = m_nCmdShow;
int argc = 0;
- char **argv = NULL;
+ wxChar **argv = NULL;
wxEntryStart(argc, argv);
if ( !wxTheApp || !wxTheApp->CallOnInit() )
return FALSE;
int CTheApp::ExitInstance()
{
+#if !START_WITH_MFC_WINDOW
+ delete m_pMainWnd;
+#endif
+
if ( wxTheApp )
wxTheApp->OnExit();
wxEntryCleanup();
// Override this to provide wxWidgets message loop compatibility
BOOL CTheApp::PreTranslateMessage(MSG *msg)
{
- wxEventLoop *evtLoop = wxEventLoop::GetActive();
+ wxEventLoop * const
+ evtLoop = static_cast<wxEventLoop *>(wxEventLoop::GetActive());
if ( evtLoop && evtLoop->PreProcessMessage(msg) )
return TRUE;
bool MyApp::OnInit()
{
-#if !START_WITH_MFC_WINDOW
+ if ( !wxApp::OnInit() )
+ return false;
- // Exit app when the top level frame is deleted
- SetExitOnFrameDelete(TRUE);
+#if !START_WITH_MFC_WINDOW
+ // as we're not inside wxWidgets main loop, the default logic doesn't work
+ // in our case and we need to do this explicitly
+ SetExitOnFrameDelete(true);
(void) CreateFrame();
#endif
- return TRUE;
+ return true;
+}
+
+void MyApp::ExitMainLoop()
+{
+ // instead of existing wxWidgets main loop, terminate the MFC one
+ ::PostQuitMessage(0);
}
wxFrame *MyApp::CreateFrame()
{
- MyChild *subframe = new MyChild(NULL, "Canvas Frame", wxPoint(10, 10), wxSize(300, 300),
+ MyChild *subframe = new MyChild(NULL, wxT("Canvas Frame"), wxPoint(10, 10), wxSize(300, 300),
wxDEFAULT_FRAME_STYLE);
- subframe->SetTitle("wxWidgets canvas frame");
+ subframe->SetTitle(wxT("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");
+ file_menu->Append(HELLO_NEW, wxT("&New MFC Window"));
+ file_menu->Append(HELLO_QUIT, wxT("&Close"));
wxMenuBar *menu_bar = new wxMenuBar;
- menu_bar->Append(file_menu, "&File");
+ menu_bar->Append(file_menu, wxT("&File"));
// Associate the menu bar with the frame
subframe->SetMenuBar(menu_bar);
MyCanvas *canvas = new MyCanvas(subframe, wxPoint(0, 0), wxSize(width, height));
canvas->SetCursor(wxCursor(wxCURSOR_PENCIL));
subframe->canvas = canvas;
- subframe->Show(TRUE);
+ subframe->Show(true);
// Return the main frame window
return subframe;
dc.DrawEllipse(250, 250, 100, 50);
dc.DrawLine(50, 230, 200, 230);
- dc.DrawText("This is a test string", 50, 230);
+ dc.DrawText(wxT("This is a test string"), 50, 230);
}
// This implements a tiny doodling program! Drag the mouse using
MyChild::~MyChild()
{
+ if ( IsLastBeforeExit() )
+ PostQuitMessage(0);
}
void MyChild::OnQuit(wxCommandEvent& WXUNUSED(event))
{
- Close(TRUE);
+ Close(true);
}
void MyChild::OnNew(wxCommandEvent& WXUNUSED(event))
// Dummy MFC window for specifying a valid main window to MFC, using
// a wxWidgets HWND.
-CDummyWindow::CDummyWindow(HWND hWnd):CWnd()
+CDummyWindow::CDummyWindow(HWND hWnd)
{
Attach(hWnd);
}