| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 |
- /////////////////////////////////////////////////////////////////////////////
- // Name: mfctest.cpp
- // Purpose: Sample to demonstrate mixing MFC and wxWidgets code
- // Author: Julian Smart
- // Copyright: (c) Julian Smart
- // Licence: wxWindows licence
- /////////////////////////////////////////////////////////////////////////////
- // This sample pops up an initial wxWidgets frame, with a menu item
- // that allows a new MFC window to be created. Note that CDummyWindow
- // is a class that allows a wxWidgets window to be seen as a CWnd
- // for the purposes of specifying a valid main window to the
- // MFC initialisation.
- //
- // You can easily modify this code so that an MFC window pops up
- // initially as the main frame, and allows wxWidgets frames to be
- // created subsequently.
- //
- // (1) Make MyApp::OnInit not create a main window.
- // (2) Make MFC's InitInstance create a main window, and remove
- // creation of CDummyWindow.
- //
- // This can be accomplished by setting START_WITH_MFC_WINDOW to 1 below.
- #define START_WITH_MFC_WINDOW 0
- //
- // IMPORTANT NOTES:
- //
- // (1) You may need to set wxUSE_MFC to 1 in include/wx/msw/setup.h but
- // 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: 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
- // 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 0x0600
- #endif
- #include "stdafx.h"
- // For compilers that support precompilation, includes "wx/wx.h".
- #include "wx/wxprec.h"
- #ifdef __BORLANDC__
- #pragma hdrstop
- #endif
- #ifndef WX_PRECOMP
- #include "wx/wx.h"
- #endif
- #include "wx/evtloop.h"
- #include "resource.h"
- #include "mfctest.h"
- /////////////////////////////////////////////////////////////////////////////
- // theApp:
- // Just creating this application object runs the whole application.
- //
- CTheApp theApp;
- // wxWidgets elements
- // Define a new application type
- class MyApp: public wxApp
- {
- 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();
- };
- class MyCanvas: public wxScrolledWindow
- {
- public:
- MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size);
- void OnPaint(wxPaintEvent& event);
- void OnMouseEvent(wxMouseEvent& event);
- wxDECLARE_EVENT_TABLE();
- };
- class MyChild: public wxFrame
- {
- public:
- MyChild(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size, const long style);
- virtual ~MyChild();
- void OnQuit(wxCommandEvent& event);
- void OnNew(wxCommandEvent& event);
- void OnActivate(wxActivateEvent& event);
- MyCanvas *canvas;
- wxDECLARE_EVENT_TABLE();
- };
- // ID for the menu quit command
- #define HELLO_QUIT 1
- #define HELLO_NEW 2
- DECLARE_APP(MyApp)
- // 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( wxT("MainAccelTable") );
- Create( NULL, wxT("Hello Foundation Application"),
- WS_OVERLAPPEDWINDOW, rectDefault, NULL, wxT("MainMenu") );
- }
- void CMainWindow::OnPaint()
- {
- CString s = wxT("Hello, Windows!");
- CPaintDC dc( this );
- CRect rect;
- GetClientRect( rect );
- dc.SetTextAlign( TA_BASELINE | TA_CENTER );
- dc.SetTextColor( ::GetSysColor( COLOR_WINDOWTEXT ) );
- dc.SetBkMode(TRANSPARENT);
- dc.TextOut( ( rect.right / 2 ), ( rect.bottom / 2 ),
- s, s.GetLength() );
- }
- void CMainWindow::OnAbout()
- {
- CDialog about( wxT("AboutBox"), this );
- about.DoModal();
- }
- void CMainWindow::OnTest()
- {
- wxMessageBox(wxT("This is a wxWidgets message box.\nWe're about to create a new wxWidgets frame."), wxT("wxWidgets"), wxOK);
- wxGetApp().CreateFrame();
- }
- // CMainWindow message map:
- // Associate messages with member functions.
- //
- // It is implied that the ON_WM_PAINT macro expects a member function
- // "void OnPaint()".
- //
- // It is implied that members connected with the ON_COMMAND macro
- // receive no arguments and are void of return type, e.g., "void OnAbout()".
- //
- BEGIN_MESSAGE_MAP( CMainWindow, CFrameWnd )
- //{{AFX_MSG_MAP( CMainWindow )
- ON_WM_PAINT()
- ON_COMMAND( IDM_ABOUT, OnAbout )
- ON_COMMAND( IDM_TEST, OnTest )
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- BOOL CTheApp::InitInstance()
- {
- if ( !CWinApp::InitInstance() )
- return FALSE;
- // TODO: cmd line parsing
- WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
- wxSetInstance(m_hInstance);
- wxApp::m_nCmdShow = m_nCmdShow;
- int argc = 0;
- wxChar **argv = NULL;
- wxEntryStart(argc, argv);
- if ( !wxTheApp || !wxTheApp->CallOnInit() )
- return FALSE;
- #if START_WITH_MFC_WINDOW
- // Demonstrate creation of an initial MFC main window.
- m_pMainWnd = new CMainWindow();
- m_pMainWnd->ShowWindow( m_nCmdShow );
- m_pMainWnd->UpdateWindow();
- #else
- // Demonstrate creation of an initial wxWidgets main window.
- // Wrap wxWidgets window in a dummy MFC window and
- // make the main window.
- if (wxTheApp && wxTheApp->GetTopWindow())
- {
- m_pMainWnd = new CDummyWindow((HWND) wxTheApp->GetTopWindow()->GetHWND());
- }
- #endif
- return TRUE;
- }
- int CTheApp::ExitInstance()
- {
- #if !START_WITH_MFC_WINDOW
- delete m_pMainWnd;
- #endif
- if ( wxTheApp )
- wxTheApp->OnExit();
- wxEntryCleanup();
- return CWinApp::ExitInstance();
- }
- // Override this to provide wxWidgets message loop compatibility
- BOOL CTheApp::PreTranslateMessage(MSG *msg)
- {
- wxEventLoop * const
- evtLoop = static_cast<wxEventLoop *>(wxEventLoop::GetActive());
- if ( evtLoop && evtLoop->PreProcessMessage(msg) )
- return TRUE;
- return CWinApp::PreTranslateMessage(msg);
- }
- BOOL CTheApp::OnIdle(LONG WXUNUSED(lCount))
- {
- return wxTheApp && wxTheApp->ProcessIdle();
- }
- /*********************************************************************
- * wxWidgets elements
- ********************************************************************/
- bool MyApp::OnInit()
- {
- if ( !wxApp::OnInit() )
- return false;
- #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;
- }
- void MyApp::ExitMainLoop()
- {
- // instead of existing wxWidgets main loop, terminate the MFC one
- ::PostQuitMessage(0);
- }
- wxFrame *MyApp::CreateFrame()
- {
- MyChild *subframe = new MyChild(NULL, wxT("Canvas Frame"), wxPoint(10, 10), wxSize(300, 300),
- wxDEFAULT_FRAME_STYLE);
- 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, wxT("&New MFC Window"));
- file_menu->Append(HELLO_QUIT, wxT("&Close"));
- wxMenuBar *menu_bar = new wxMenuBar;
- menu_bar->Append(file_menu, wxT("&File"));
- // Associate the menu bar with the frame
- subframe->SetMenuBar(menu_bar);
- int width, height;
- subframe->GetClientSize(&width, &height);
- MyCanvas *canvas = new MyCanvas(subframe, wxPoint(0, 0), wxSize(width, height));
- canvas->SetCursor(wxCursor(wxCURSOR_PENCIL));
- subframe->canvas = canvas;
- subframe->Show(true);
- // Return the main frame window
- return subframe;
- }
- wxBEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
- EVT_PAINT(MyCanvas::OnPaint)
- EVT_MOUSE_EVENTS(MyCanvas::OnMouseEvent)
- wxEND_EVENT_TABLE()
- // Define a constructor for my canvas
- MyCanvas::MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size)
- : wxScrolledWindow(parent, -1, pos, size)
- {
- }
- // Define the repainting behaviour
- void MyCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
- {
- wxPaintDC dc(this);
- dc.SetFont(* wxSWISS_FONT);
- dc.SetPen(* wxGREEN_PEN);
- dc.DrawLine(0, 0, 200, 200);
- dc.DrawLine(200, 0, 0, 200);
- dc.SetBrush(* wxCYAN_BRUSH);
- dc.SetPen(* wxRED_PEN);
- dc.DrawRectangle(100, 100, 100, 50);
- dc.DrawRoundedRectangle(150, 150, 100, 50, 20);
- dc.DrawEllipse(250, 250, 100, 50);
- dc.DrawLine(50, 230, 200, 230);
- dc.DrawText(wxT("This is a test string"), 50, 230);
- }
- // This implements a tiny doodling program! Drag the mouse using
- // the left button.
- void MyCanvas::OnMouseEvent(wxMouseEvent& event)
- {
- static long s_xpos = -1;
- static long s_ypos = -1;
- wxClientDC dc(this);
- dc.SetPen(* wxBLACK_PEN);
- wxPoint pos = event.GetPosition();
- if (s_xpos > -1 && s_ypos > -1 && event.Dragging())
- {
- dc.DrawLine(s_xpos, s_ypos, pos.x, pos.y);
- }
- s_xpos = pos.x;
- s_ypos = pos.y;
- }
- wxBEGIN_EVENT_TABLE(MyChild, wxFrame)
- EVT_MENU(HELLO_QUIT, MyChild::OnQuit)
- EVT_MENU(HELLO_NEW, MyChild::OnNew)
- EVT_ACTIVATE(MyChild::OnActivate)
- wxEND_EVENT_TABLE()
- MyChild::MyChild(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size, const long style)
- : wxFrame(frame, -1, title, pos, size, style)
- {
- canvas = NULL;
- }
- MyChild::~MyChild()
- {
- if ( IsLastBeforeExit() )
- PostQuitMessage(0);
- }
- void MyChild::OnQuit(wxCommandEvent& WXUNUSED(event))
- {
- Close(true);
- }
- void MyChild::OnNew(wxCommandEvent& WXUNUSED(event))
- {
- CMainWindow *mainWin = new CMainWindow();
- mainWin->ShowWindow( TRUE );
- mainWin->UpdateWindow();
- }
- void MyChild::OnActivate(wxActivateEvent& event)
- {
- if (event.GetActive() && canvas)
- canvas->SetFocus();
- }
- // Dummy MFC window for specifying a valid main window to MFC, using
- // a wxWidgets HWND.
- CDummyWindow::CDummyWindow(HWND hWnd)
- {
- Attach(hWnd);
- }
- // Don't let the CWnd destructor delete the HWND
- CDummyWindow::~CDummyWindow()
- {
- Detach();
- }
|