diff --git a/samples/mfc/mfctest.cpp b/samples/mfc/mfctest.cpp index d60b17fa4f..b0b14c38de 100644 --- a/samples/mfc/mfctest.cpp +++ b/samples/mfc/mfctest.cpp @@ -70,6 +70,8 @@ #endif #include "wx/evtloop.h" +#include "wx/nativewin.h" +#include "wx/spinctrl.h" #include "resource.h" @@ -121,6 +123,38 @@ public: wxDECLARE_EVENT_TABLE(); }; +class MyPanel : public wxPanel +{ +public: + MyPanel(wxWindow *parent, const wxPoint& pos) + : wxPanel(parent, wxID_ANY, pos) + { + wxSizer* const sizer = new wxFlexGridSizer(2, wxSize(5, 5)); + sizer->Add(new wxStaticText(this, wxID_ANY, "Enter your &name:"), + wxSizerFlags().Center().Right()); + m_textName = new wxTextCtrl(this, wxID_ANY); + m_textName->SetHint("First Last"); + sizer->Add(m_textName, wxSizerFlags().Expand().CenterVertical()); + + sizer->Add(new wxStaticText(this, wxID_ANY, "And your &age:"), + wxSizerFlags().Center().Right()); + m_spinAge = new wxSpinCtrl(this, wxID_ANY); + sizer->Add(m_spinAge, wxSizerFlags().Expand().CenterVertical()); + + wxStaticBoxSizer* const + box = new wxStaticBoxSizer(wxVERTICAL, this, "wxWidgets box"); + box->Add(sizer, wxSizerFlags(1).Expand()); + SetSizer(box); + + // We won't be resized automatically, so set our size ourselves. + SetSize(GetBestSize()); + } + +private: + wxTextCtrl* m_textName; + wxSpinCtrl* m_spinAge; +}; + // ID for the menu quit command #define HELLO_QUIT 1 #define HELLO_NEW 2 @@ -147,6 +181,18 @@ CMainWindow::CMainWindow() LoadAccelTable( wxT("MainAccelTable") ); Create( NULL, wxT("Hello Foundation Application"), WS_OVERLAPPEDWINDOW, rectDefault, NULL, wxT("MainMenu") ); + + // Create a container representing the MFC window in wxWidgets window + // hierarchy. + m_containerWX = new wxNativeContainerWindow(m_hWnd); + + // Now we can create children of this container as usual. + new MyPanel(m_containerWX, wxPoint(5, 5)); + + // An ugly but necessary workaround to prevent the container TLW from + // resizing the panel to fit its entire client area as it would do if it + // were its only child. + new wxWindow(m_containerWX, wxID_ANY, wxPoint(4, 4), wxSize(1, 1)); } void CMainWindow::OnPaint() diff --git a/samples/mfc/mfctest.h b/samples/mfc/mfctest.h index c42f07a41b..2c49911339 100644 --- a/samples/mfc/mfctest.h +++ b/samples/mfc/mfctest.h @@ -26,6 +26,9 @@ public: //}}AFX_MSG DECLARE_MESSAGE_MAP() + +private: + class wxNativeContainerWindow* m_containerWX; }; // A dummy CWnd pointing to a wxWindow's HWND diff --git a/src/msw/nativewin.cpp b/src/msw/nativewin.cpp index 13b8a77efa..b84bb44372 100644 --- a/src/msw/nativewin.cpp +++ b/src/msw/nativewin.cpp @@ -69,11 +69,24 @@ WXLRESULT wxNativeContainerWindow::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { - if ( nMsg == WM_DESTROY ) + switch ( nMsg ) { - OnNativeDestroyed(); + case WM_CLOSE: + // wxWindow itself, unlike wxFrame, doesn't react to WM_CLOSE and + // just ignores it without even passing it to DefWindowProc(), + // which means that the original WM_CLOSE handler wouldn't be + // called if we didn't explicitly do it here. + return MSWDefWindowProc(nMsg, wParam, lParam); - return 0; + case WM_DESTROY: + // Send it to the original handler which may have some cleanup to + // do as well. Notice that we must do it before calling + // OnNativeDestroyed() as we can't use this object after doing it. + MSWDefWindowProc(nMsg, wParam, lParam); + + OnNativeDestroyed(); + + return 0; } return wxTopLevelWindow::MSWWindowProc(nMsg, wParam, lParam);