]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/app.cpp
Disable wxUSE_ENH_METAFILE for wxGTK builds.
[wxWidgets.git] / src / msw / app.cpp
index c24475e00e61c60d63ebe6307efdf04af630d19c..633722e0167055e31feb9507d8f48ee6b6afdabb 100644 (file)
@@ -50,6 +50,8 @@
 #include "wx/dynlib.h"
 #include "wx/evtloop.h"
 #include "wx/thread.h"
 #include "wx/dynlib.h"
 #include "wx/evtloop.h"
 #include "wx/thread.h"
+#include "wx/scopeguard.h"
+#include "wx/vector.h"
 
 #include "wx/msw/private.h"
 #include "wx/msw/dc.h"
 
 #include "wx/msw/private.h"
 #include "wx/msw/dc.h"
 extern void wxSetKeyboardHook(bool doIt);
 #endif
 
 extern void wxSetKeyboardHook(bool doIt);
 #endif
 
-// NB: all "NoRedraw" classes must have the same names as the "normal" classes
-//     with NR suffix - wxWindow::MSWCreate() supposes this
-#ifdef __WXWINCE__
-WXDLLIMPEXP_CORE       wxChar *wxCanvasClassName;
-WXDLLIMPEXP_CORE       wxChar *wxCanvasClassNameNR;
-#else
-WXDLLIMPEXP_CORE const wxChar *wxCanvasClassName = NULL;
-WXDLLIMPEXP_CORE const wxChar *wxCanvasClassNameNR = NULL;
-#endif
-WXDLLIMPEXP_CORE const wxChar *wxMDIFrameClassName = NULL;
-WXDLLIMPEXP_CORE const wxChar *wxMDIFrameClassNameNoRedraw = NULL;
-WXDLLIMPEXP_CORE const wxChar *wxMDIChildFrameClassName = NULL;
-WXDLLIMPEXP_CORE const wxChar *wxMDIChildFrameClassNameNoRedraw = NULL;
+// because of mingw32 4.3 bug this struct can't be inside the namespace below:
+// see http://article.gmane.org/gmane.comp.lib.wxwidgets.devel/110282
+struct ClassRegInfo
+{
+    ClassRegInfo(const wxChar *name)
+        : regname(name),
+          regnameNR(regname + wxApp::GetNoRedrawClassSuffix())
+    {
+    }
+
+    // the name of the registered class with and without CS_[HV]REDRAW styles
+    wxString regname;
+    wxString regnameNR;
+};
+
+namespace
+{
+
+wxVector<ClassRegInfo> gs_regClassesInfo;
+
+} // anonymous namespace
 
 // ----------------------------------------------------------------------------
 // private functions
 
 // ----------------------------------------------------------------------------
 // private functions
@@ -162,12 +172,12 @@ void *wxGUIAppTraits::BeforeChildWaitLoop()
        focus/activation entirely when the child process terminates which would
        happen if we simply disabled everything using wxWindowDisabler. Indeed,
        remember that Windows will never activate a disabled window and when the
        focus/activation entirely when the child process terminates which would
        happen if we simply disabled everything using wxWindowDisabler. Indeed,
        remember that Windows will never activate a disabled window and when the
-       last childs window is closed and Windows looks for a window to activate
+       last child's window is closed and Windows looks for a window to activate
        all our windows are still disabled. There is no way to enable them in
        all our windows are still disabled. There is no way to enable them in
-       time because we don't know when the childs windows are going to be
-       closed, so the solution we use here is to keep one special tiny frame
+       time because we don't know when the child's windows are going to be
+       closed, so the solution we use here is to keep one special tiny dialog
        enabled all the time. Then when the child terminates it will get
        enabled all the time. Then when the child terminates it will get
-       activated and when we close it below -- after reenabling all the other
+       activated and when we close it below -- after re-enabling all the other
        windows! -- the previously active window becomes activated again and
        everything is ok.
      */
        windows! -- the previously active window becomes activated again and
        everything is ok.
      */
@@ -176,27 +186,22 @@ void *wxGUIAppTraits::BeforeChildWaitLoop()
     // first disable all existing windows
     wxWindowDisabler *wd = new wxWindowDisabler;
 
     // first disable all existing windows
     wxWindowDisabler *wd = new wxWindowDisabler;
 
-    // then create an "invisible" frame: it has minimal size, is positioned
-    // (hopefully) outside the screen and doesn't appear on the taskbar
-    wxWindow *winActive = new wxFrame
+    // then create an "invisible" dialog: it has minimal size, is positioned
+    // (hopefully) outside the screen and doesn't appear in the Alt-TAB list
+    // (unlike the frames, which is why we use a dialog here)
+    wxWindow *winActive = new wxDialog
                     (
                         wxTheApp->GetTopWindow(),
                         wxID_ANY,
                         wxEmptyString,
                         wxPoint(32600, 32600),
                     (
                         wxTheApp->GetTopWindow(),
                         wxID_ANY,
                         wxEmptyString,
                         wxPoint(32600, 32600),
-                        wxSize(1, 1),
-                        wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR
+                        wxSize(1, 1)
                     );
     winActive->Show();
 
     return new ChildWaitLoopData(wd, winActive);
 }
 
                     );
     winActive->Show();
 
     return new ChildWaitLoopData(wd, winActive);
 }
 
-void wxGUIAppTraits::AlwaysYield()
-{
-    wxYield();
-}
-
 void wxGUIAppTraits::AfterChildWaitLoop(void *dataOrig)
 {
     wxEndBusyCursor();
 void wxGUIAppTraits::AfterChildWaitLoop(void *dataOrig)
 {
     wxEndBusyCursor();
@@ -205,15 +210,16 @@ void wxGUIAppTraits::AfterChildWaitLoop(void *dataOrig)
 
     delete data->wd;
 
 
     delete data->wd;
 
-    // finally delete the dummy frame and, as wd has been already destroyed and
-    // the other windows reenabled, the activation is going to return to the
-    // window which had had it before
+    // finally delete the dummy dialog and, as wd has been already destroyed
+    // and the other windows reenabled, the activation is going to return to
+    // the window which had had it before
     data->winActive->Destroy();
 
     // also delete the temporary data object itself
     delete data;
 }
 
     data->winActive->Destroy();
 
     // also delete the temporary data object itself
     delete data;
 }
 
+#if wxUSE_THREADS
 bool wxGUIAppTraits::DoMessageFromThreadWait()
 {
     // we should return false only if the app should exit, i.e. only if
 bool wxGUIAppTraits::DoMessageFromThreadWait()
 {
     // we should return false only if the app should exit, i.e. only if
@@ -228,14 +234,20 @@ bool wxGUIAppTraits::DoMessageFromThreadWait()
     return evtLoop->Dispatch();
 }
 
     return evtLoop->Dispatch();
 }
 
-DWORD wxGUIAppTraits::WaitForThread(WXHANDLE hThread)
+DWORD wxGUIAppTraits::WaitForThread(WXHANDLE hThread, int flags)
 {
 {
-    // if we don't have a running event loop, we shouldn't wait for the
-    // messages as we never remove them from the message queue and so we enter
-    // an infinite loop as MsgWaitForMultipleObjects() keeps returning
-    // WAIT_OBJECT_0 + 1
-    if ( !wxEventLoop::GetActive() )
+    // We only ever dispatch messages from the main thread and, additionally,
+    // even from the main thread we shouldn't wait for the message if we don't
+    // have a running event loop as we would never remove them from the message
+    // queue then and so we would enter an infinite loop as
+    // MsgWaitForMultipleObjects() keeps returning WAIT_OBJECT_0 + 1.
+    if ( flags == wxTHREAD_WAIT_BLOCK ||
+            !wxIsMainThread() ||
+                !wxEventLoop::GetActive() )
+    {
+        // Simple blocking wait.
         return DoSimpleWaitForThread(hThread);
         return DoSimpleWaitForThread(hThread);
+    }
 
     return ::MsgWaitForMultipleObjects
              (
 
     return ::MsgWaitForMultipleObjects
              (
@@ -247,6 +259,7 @@ DWORD wxGUIAppTraits::WaitForThread(WXHANDLE hThread)
                QS_ALLPOSTMESSAGE
              );
 }
                QS_ALLPOSTMESSAGE
              );
 }
+#endif // wxUSE_THREADS
 
 wxPortId wxGUIAppTraits::GetToolkitVersion(int *majVer, int *minVer) const
 {
 
 wxPortId wxGUIAppTraits::GetToolkitVersion(int *majVer, int *minVer) const
 {
@@ -291,6 +304,8 @@ wxEventLoopBase* wxGUIAppTraits::CreateEventLoop()
 
 #ifndef __WXWINCE__
 
 
 #ifndef __WXWINCE__
 
+#if wxUSE_DYNLIB_CLASS
+
 #include <wx/dynlib.h>
 
 namespace
 #include <wx/dynlib.h>
 
 namespace
@@ -329,7 +344,7 @@ public:
         {
             if ( !::FreeConsole() )
             {
         {
             if ( !::FreeConsole() )
             {
-                wxLogLastError(_T("FreeConsole"));
+                wxLogLastError(wxT("FreeConsole"));
             }
         }
     }
             }
         }
     }
@@ -340,7 +355,7 @@ public:
     {
         if ( m_ok == -1 )
         {
     {
         if ( m_ok == -1 )
         {
-            wxConsoleStderr * const self = wx_const_cast(wxConsoleStderr *, this);
+            wxConsoleStderr * const self = const_cast<wxConsoleStderr *>(this);
             self->m_ok = self->DoInit();
 
             // no need to call IsHistoryUnchanged() as we just initialized
             self->m_ok = self->DoInit();
 
             // no need to call IsHistoryUnchanged() as we just initialized
@@ -388,7 +403,7 @@ private:
     GetConsoleCommandHistory_t m_pfnGetConsoleCommandHistory;
     GetConsoleCommandHistoryLength_t m_pfnGetConsoleCommandHistoryLength;
 
     GetConsoleCommandHistory_t m_pfnGetConsoleCommandHistory;
     GetConsoleCommandHistoryLength_t m_pfnGetConsoleCommandHistoryLength;
 
-    DECLARE_NO_COPY_CLASS(wxConsoleStderr)
+    wxDECLARE_NO_COPY_CLASS(wxConsoleStderr);
 };
 
 bool wxConsoleStderr::DoInit()
 };
 
 bool wxConsoleStderr::DoInit()
@@ -398,7 +413,7 @@ bool wxConsoleStderr::DoInit()
     if ( hStderr == INVALID_HANDLE_VALUE || !hStderr )
         return false;
 
     if ( hStderr == INVALID_HANDLE_VALUE || !hStderr )
         return false;
 
-    if ( !m_dllKernel32.Load(_T("kernel32.dll")) )
+    if ( !m_dllKernel32.Load(wxT("kernel32.dll")) )
         return false;
 
     typedef BOOL (WINAPI *AttachConsole_t)(DWORD dwProcessId);
         return false;
 
     typedef BOOL (WINAPI *AttachConsole_t)(DWORD dwProcessId);
@@ -431,7 +446,7 @@ bool wxConsoleStderr::DoInit()
 
     if ( !::GetConsoleScreenBufferInfo(m_hStderr, &csbi) )
     {
 
     if ( !::GetConsoleScreenBufferInfo(m_hStderr, &csbi) )
     {
-        wxLogLastError(_T("GetConsoleScreenBufferInfo"));
+        wxLogLastError(wxT("GetConsoleScreenBufferInfo"));
         return false;
     }
 
         return false;
     }
 
@@ -448,7 +463,7 @@ bool wxConsoleStderr::DoInit()
         if ( !::ReadConsoleOutputCharacterA(m_hStderr, buf, WXSIZEOF(buf),
                                             pos, &ret) )
         {
         if ( !::ReadConsoleOutputCharacterA(m_hStderr, buf, WXSIZEOF(buf),
                                             pos, &ret) )
         {
-            wxLogLastError(_T("ReadConsoleOutputCharacterA"));
+            wxLogLastError(wxT("ReadConsoleOutputCharacterA"));
             return false;
         }
     } while ( wxStrncmp("    ", buf, WXSIZEOF(buf)) != 0 );
             return false;
         }
     } while ( wxStrncmp("    ", buf, WXSIZEOF(buf)) != 0 );
@@ -463,7 +478,7 @@ bool wxConsoleStderr::DoInit()
         if ( !::ReadConsoleOutputCharacterA(m_hStderr, m_data.data(), m_dataLen,
                                             pos, &ret) )
         {
         if ( !::ReadConsoleOutputCharacterA(m_hStderr, m_data.data(), m_dataLen,
                                             pos, &ret) )
         {
-            wxLogLastError(_T("ReadConsoleOutputCharacterA"));
+            wxLogLastError(wxT("ReadConsoleOutputCharacterA"));
             return false;
         }
     }
             return false;
         }
     }
@@ -474,7 +489,7 @@ bool wxConsoleStderr::DoInit()
 int wxConsoleStderr::GetCommandHistory(wxWxCharBuffer& buf) const
 {
     // these functions are internal and may only be called by cmd.exe
 int wxConsoleStderr::GetCommandHistory(wxWxCharBuffer& buf) const
 {
     // these functions are internal and may only be called by cmd.exe
-    static const wxChar *CMD_EXE = _T("cmd.exe");
+    static const wxChar *CMD_EXE = wxT("cmd.exe");
 
     const int len = m_pfnGetConsoleCommandHistoryLength(CMD_EXE);
     if ( len )
 
     const int len = m_pfnGetConsoleCommandHistoryLength(CMD_EXE);
     if ( len )
@@ -491,7 +506,7 @@ int wxConsoleStderr::GetCommandHistory(wxWxCharBuffer& buf) const
 
         if ( len2 != len )
         {
 
         if ( len2 != len )
         {
-            wxFAIL_MSG( _T("failed getting history?") );
+            wxFAIL_MSG( wxT("failed getting history?") );
         }
     }
 
         }
     }
 
@@ -500,7 +515,7 @@ int wxConsoleStderr::GetCommandHistory(wxWxCharBuffer& buf) const
 
 bool wxConsoleStderr::IsHistoryUnchanged() const
 {
 
 bool wxConsoleStderr::IsHistoryUnchanged() const
 {
-    wxASSERT_MSG( m_ok == 1, _T("shouldn't be called if not initialized") );
+    wxASSERT_MSG( m_ok == 1, wxT("shouldn't be called if not initialized") );
 
     // get (possibly changed) command history
     wxWxCharBuffer history;
 
     // get (possibly changed) command history
     wxWxCharBuffer history;
@@ -514,13 +529,13 @@ bool wxConsoleStderr::IsHistoryUnchanged() const
 bool wxConsoleStderr::Write(const wxString& text)
 {
     wxASSERT_MSG( m_hStderr != INVALID_HANDLE_VALUE,
 bool wxConsoleStderr::Write(const wxString& text)
 {
     wxASSERT_MSG( m_hStderr != INVALID_HANDLE_VALUE,
-                    _T("should only be called if Init() returned true") );
+                    wxT("should only be called if Init() returned true") );
 
     // get current position
     CONSOLE_SCREEN_BUFFER_INFO csbi;
     if ( !::GetConsoleScreenBufferInfo(m_hStderr, &csbi) )
     {
 
     // get current position
     CONSOLE_SCREEN_BUFFER_INFO csbi;
     if ( !::GetConsoleScreenBufferInfo(m_hStderr, &csbi) )
     {
-        wxLogLastError(_T("GetConsoleScreenBufferInfo"));
+        wxLogLastError(wxT("GetConsoleScreenBufferInfo"));
         return false;
     }
 
         return false;
     }
 
@@ -530,21 +545,21 @@ bool wxConsoleStderr::Write(const wxString& text)
 
     if ( !::SetConsoleCursorPosition(m_hStderr, csbi.dwCursorPosition) )
     {
 
     if ( !::SetConsoleCursorPosition(m_hStderr, csbi.dwCursorPosition) )
     {
-        wxLogLastError(_T("SetConsoleCursorPosition"));
+        wxLogLastError(wxT("SetConsoleCursorPosition"));
         return false;
     }
 
     DWORD ret;
         return false;
     }
 
     DWORD ret;
-    if ( !::FillConsoleOutputCharacter(m_hStderr, _T(' '), m_dataLen,
+    if ( !::FillConsoleOutputCharacter(m_hStderr, wxT(' '), m_dataLen,
                                        csbi.dwCursorPosition, &ret) )
     {
                                        csbi.dwCursorPosition, &ret) )
     {
-        wxLogLastError(_T("FillConsoleOutputCharacter"));
+        wxLogLastError(wxT("FillConsoleOutputCharacter"));
         return false;
     }
 
         return false;
     }
 
-    if ( !::WriteConsole(m_hStderr, text.wx_str(), text.length(), &ret, NULL) )
+    if ( !::WriteConsole(m_hStderr, text.t_str(), text.length(), &ret, NULL) )
     {
     {
-        wxLogLastError(_T("WriteConsole"));
+        wxLogLastError(wxT("WriteConsole"));
         return false;
     }
 
         return false;
     }
 
@@ -567,6 +582,20 @@ bool wxGUIAppTraits::WriteToStderr(const wxString& text)
     return s_consoleStderr.IsOkToUse() && s_consoleStderr.Write(text);
 }
 
     return s_consoleStderr.IsOkToUse() && s_consoleStderr.Write(text);
 }
 
+#else // !wxUSE_DYNLIB_CLASS
+
+bool wxGUIAppTraits::CanUseStderr()
+{
+    return false;
+}
+
+bool wxGUIAppTraits::WriteToStderr(const wxString& WXUNUSED(text))
+{
+    return false;
+}
+
+#endif // wxUSE_DYNLIB_CLASS/!wxUSE_DYNLIB_CLASS
+
 #endif // !__WXWINCE__
 
 // ===========================================================================
 #endif // !__WXWINCE__
 
 // ===========================================================================
@@ -610,20 +639,6 @@ bool wxApp::Initialize(int& argc, wxChar **argv)
     // ensure that base cleanup is done if we return too early
     wxCallBaseCleanup callBaseCleanup(this);
 
     // ensure that base cleanup is done if we return too early
     wxCallBaseCleanup callBaseCleanup(this);
 
-#ifdef __WXWINCE__
-    wxString tmp = GetAppName();
-    tmp += wxT("ClassName");
-    wxCanvasClassName = wxStrdup( tmp.wc_str() );
-    tmp += wxT("NR");
-    wxCanvasClassNameNR = wxStrdup( tmp.wc_str() );
-    HWND hWnd = FindWindow( wxCanvasClassNameNR, NULL );
-    if (hWnd)
-    {
-        SetForegroundWindow( (HWND)(((DWORD)hWnd)|0x01) );
-        return false;
-    }
-#endif
-
 #if !defined(__WXMICROWIN__)
     InitCommonControls();
 #endif // !defined(__WXMICROWIN__)
 #if !defined(__WXMICROWIN__)
     InitCommonControls();
 #endif // !defined(__WXMICROWIN__)
@@ -640,8 +655,6 @@ bool wxApp::Initialize(int& argc, wxChar **argv)
 
     wxOleInitialize();
 
 
     wxOleInitialize();
 
-    RegisterWindowClasses();
-
 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
     wxSetKeyboardHook(true);
 #endif
 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
     wxSetKeyboardHook(true);
 #endif
@@ -652,143 +665,93 @@ bool wxApp::Initialize(int& argc, wxChar **argv)
 }
 
 // ---------------------------------------------------------------------------
 }
 
 // ---------------------------------------------------------------------------
-// RegisterWindowClasses
+// Win32 window class registration
 // ---------------------------------------------------------------------------
 
 // ---------------------------------------------------------------------------
 
-// This function registers the given class name and stores a pointer to a
-// heap-allocated copy of it at the specified location, it must be deleted
-// later.
-static void RegisterAndStoreClassName(const wxString& uniqueClassName,
-                                      const wxChar **className,
-                                      WNDCLASS *lpWndClass)
+/* static */
+const wxChar *wxApp::GetRegisteredClassName(const wxChar *name,
+                                            int bgBrushCol,
+                                            int extraStyles)
 {
 {
-    const size_t length = uniqueClassName.length() + 1; // for trailing NUL
-    wxChar *newChars = new wxChar[length];
-    wxStrncpy(newChars, uniqueClassName, length);
-    *className = newChars;
-    lpWndClass->lpszClassName = *className;
-
-    if ( !::RegisterClass(lpWndClass) )
+    const size_t count = gs_regClassesInfo.size();
+    for ( size_t n = 0; n < count; n++ )
     {
     {
-        wxLogLastError(wxString::Format(wxT("RegisterClass(%s)"), newChars));
+        if ( gs_regClassesInfo[n].regname == name )
+            return gs_regClassesInfo[n].regname.c_str();
     }
     }
-}
-
-// This function registers the class defined by the provided WNDCLASS struct
-// contents using a unique name constructed from the specified base name and
-// and a suffix unique to this library instance. It also stores the generated
-// unique names for normal and "no redraw" versions of the class in the
-// provided variables, caller must delete their contents later.
-static void RegisterClassWithUniqueNames(const wxString& baseName,
-                                         const wxChar **className,
-                                         const wxChar **classNameNR,
-                                         WNDCLASS *lpWndClass)
-{
-    // for each class we register one with CS_(V|H)REDRAW style and one
-    // without for windows created with wxNO_FULL_REDRAW_ON_REPAINT flag
-    static const long styleNormal = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
-    static const long styleNoRedraw = CS_DBLCLKS;
-
-    const wxString uniqueSuffix(wxString::Format(wxT("@%p"), className));
-
-    wxString uniqueClassName(baseName + uniqueSuffix);
-    lpWndClass->style = styleNormal;
-    RegisterAndStoreClassName(uniqueClassName, className, lpWndClass);
-
-    // NB: remember that code elsewhere supposes that no redraw class names
-    //     use the same names as normal classes with "NR" suffix so we must put
-    //     "NR" at the end instead of using more natural baseName+"NR"+suffix
-    wxString uniqueClassNameNR(uniqueClassName + wxT("NR"));
-    lpWndClass->style = styleNoRedraw;
-    RegisterAndStoreClassName(uniqueClassNameNR, classNameNR, lpWndClass);
-}
 
 
-// TODO we should only register classes really used by the app. For this it
-//      would be enough to just delay the class registration until an attempt
-//      to create a window of this class is made.
-bool wxApp::RegisterWindowClasses()
-{
+    // we need to register this class
     WNDCLASS wndclass;
     wxZeroMemory(wndclass);
 
     WNDCLASS wndclass;
     wxZeroMemory(wndclass);
 
-    // the fields which are common to all classes
     wndclass.lpfnWndProc   = (WNDPROC)wxWndProc;
     wndclass.lpfnWndProc   = (WNDPROC)wxWndProc;
-    wndclass.hInstance     = wxhInstance;
-    wndclass.hCursor       = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW);
-
-    // register the class for all normal windows and "no redraw" frames
-    wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
-    RegisterClassWithUniqueNames(wxT("wxWindowClass"),
-                                 &wxCanvasClassName,
-                                 &wxCanvasClassNameNR,
-                                 &wndclass);
-
-    // Register the MDI frame window class and "no redraw" MDI frame
-    wndclass.hbrBackground = (HBRUSH)NULL; // paint MDI frame ourselves
-    RegisterClassWithUniqueNames(wxT("wxMDIFrameClass"),
-                                 &wxMDIFrameClassName,
-                                 &wxMDIFrameClassNameNoRedraw,
-                                 &wndclass);
-
-    // Register the MDI child frame window class and "no redraw" MDI child frame
-    wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
-    RegisterClassWithUniqueNames(wxT("wxMDIChildFrameClass"),
-                                 &wxMDIChildFrameClassName,
-                                 &wxMDIChildFrameClassNameNoRedraw,
-                                 &wndclass);
+    wndclass.hInstance     = wxGetInstance();
+    wndclass.hCursor       = ::LoadCursor(NULL, IDC_ARROW);
+    wndclass.hbrBackground = (HBRUSH)wxUIntToPtr(bgBrushCol + 1);
+    wndclass.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | extraStyles;
 
 
-    return true;
-}
 
 
-// ---------------------------------------------------------------------------
-// UnregisterWindowClasses
-// ---------------------------------------------------------------------------
-
-// This function unregisters the class with the given name and frees memory
-// allocated for it by RegisterAndStoreClassName().
-static bool UnregisterAndFreeClassName(const wxChar **ppClassName)
-{
-    bool retval = true;
-
-    if ( !::UnregisterClass(*ppClassName, wxhInstance) )
+    ClassRegInfo regClass(name);
+    wndclass.lpszClassName = regClass.regname.t_str();
+    if ( !::RegisterClass(&wndclass) )
     {
     {
-        wxLogLastError(
-                wxString::Format(wxT("UnregisterClass(%s)"), *ppClassName));
+        wxLogLastError(wxString::Format(wxT("RegisterClass(%s)"),
+                       regClass.regname));
+        return NULL;
+    }
 
 
-        retval = false;
+    wndclass.style &= ~(CS_HREDRAW | CS_VREDRAW);
+    wndclass.lpszClassName = regClass.regnameNR.t_str();
+    if ( !::RegisterClass(&wndclass) )
+    {
+        wxLogLastError(wxString::Format(wxT("RegisterClass(%s)"),
+                       regClass.regname));
+        ::UnregisterClass(regClass.regname.c_str(), wxGetInstance());
+        return NULL;
     }
 
     }
 
-    delete [] (wxChar*) *ppClassName;
-    *ppClassName = NULL;
+    gs_regClassesInfo.push_back(regClass);
 
 
-    return retval;
+    // take care to return the pointer which will remain valid after the
+    // function returns (it could be invalidated later if new elements are
+    // added to the vector and it's reallocated but this shouldn't matter as
+    // this pointer should be used right now, not stored)
+    return gs_regClassesInfo.back().regname.t_str();
 }
 
 }
 
-bool wxApp::UnregisterWindowClasses()
+bool wxApp::IsRegisteredClassName(const wxString& name)
 {
 {
-    bool retval = true;
-
-#ifndef __WXMICROWIN__
-    if ( !UnregisterAndFreeClassName(&wxMDIFrameClassName) )
-        retval = false;
-
-    if ( !UnregisterAndFreeClassName(&wxMDIFrameClassNameNoRedraw) )
-        retval = false;
-
-    if ( !UnregisterAndFreeClassName(&wxMDIChildFrameClassName) )
-        retval = false;
+    const size_t count = gs_regClassesInfo.size();
+    for ( size_t n = 0; n < count; n++ )
+    {
+        if ( gs_regClassesInfo[n].regname == name ||
+                gs_regClassesInfo[n].regnameNR == name )
+            return true;
+    }
 
 
-    if ( !UnregisterAndFreeClassName(&wxMDIChildFrameClassNameNoRedraw) )
-        retval = false;
+    return false;
+}
 
 
-    if ( !UnregisterAndFreeClassName(&wxCanvasClassName) )
-        retval = false;
+void wxApp::UnregisterWindowClasses()
+{
+    const size_t count = gs_regClassesInfo.size();
+    for ( size_t n = 0; n < count; n++ )
+    {
+        const ClassRegInfo& regClass = gs_regClassesInfo[n];
+        if ( !::UnregisterClass(regClass.regname.c_str(), wxGetInstance()) )
+        {
+            wxLogLastError(wxString::Format(wxT("UnregisterClass(%s)"),
+                           regClass.regname));
+        }
 
 
-    if ( !UnregisterAndFreeClassName(&wxCanvasClassNameNR) )
-        retval = false;
-#endif // __WXMICROWIN__
+        if ( !::UnregisterClass(regClass.regnameNR.c_str(), wxGetInstance()) )
+        {
+            wxLogLastError(wxString::Format(wxT("UnregisterClass(%s)"),
+                           regClass.regnameNR));
+        }
+    }
 
 
-    return retval;
+    gs_regClassesInfo.clear();
 }
 
 void wxApp::CleanUp()
 }
 
 void wxApp::CleanUp()
@@ -810,11 +773,6 @@ void wxApp::CleanUp()
     // which case the registration will fail after the first time if we don't
     // unregister the classes now
     UnregisterWindowClasses();
     // which case the registration will fail after the first time if we don't
     // unregister the classes now
     UnregisterWindowClasses();
-
-#ifdef __WXWINCE__
-    free( wxCanvasClassName );
-    free( wxCanvasClassNameNR );
-#endif
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -875,6 +833,10 @@ void wxApp::WakeUpIdle()
             }
         }
     }
             }
         }
     }
+#if wxUSE_THREADS
+    else
+        wxWakeUpMainThread();
+#endif // wxUSE_THREADS
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -941,7 +903,7 @@ int CallDllGetVersion(wxDynamicLibrary& dll)
     HRESULT hr = (*pfnDllGetVersion)(&dvi);
     if ( FAILED(hr) )
     {
     HRESULT hr = (*pfnDllGetVersion)(&dvi);
     if ( FAILED(hr) )
     {
-        wxLogApiError(_T("DllGetVersion"), hr);
+        wxLogApiError(wxT("DllGetVersion"), hr);
 
         return 0;
     }
 
         return 0;
     }
@@ -965,8 +927,11 @@ int wxApp::GetComCtl32Version()
         // we're prepared to handle the errors
         wxLogNull noLog;
 
         // we're prepared to handle the errors
         wxLogNull noLog;
 
-        // the DLL should really be available
-        wxDynamicLibrary dllComCtl32(_T("comctl32.dll"), wxDL_VERBATIM);
+        // we don't want to load comctl32.dll, it should be already loaded but,
+        // depending on the OS version and the presence of the manifest, it can
+        // be either v5 or v6 and instead of trying to guess it just get the
+        // handle of the already loaded version
+        wxLoadedDLL dllComCtl32(wxT("comctl32.dll"));
         if ( !dllComCtl32.IsLoaded() )
         {
             s_verComCtl32 = 0;
         if ( !dllComCtl32.IsLoaded() )
         {
             s_verComCtl32 = 0;
@@ -981,7 +946,7 @@ int wxApp::GetComCtl32Version()
         if ( !s_verComCtl32 )
         {
             // InitCommonControlsEx is unique to 4.70 and later
         if ( !s_verComCtl32 )
         {
             // InitCommonControlsEx is unique to 4.70 and later
-            void *pfn = dllComCtl32.GetSymbol(_T("InitCommonControlsEx"));
+            void *pfn = dllComCtl32.GetSymbol(wxT("InitCommonControlsEx"));
             if ( !pfn )
             {
                 // not found, must be 4.00
             if ( !pfn )
             {
                 // not found, must be 4.00
@@ -991,7 +956,7 @@ int wxApp::GetComCtl32Version()
             {
                 // many symbols appeared in comctl32 4.71, could use any of
                 // them except may be DllInstall()
             {
                 // many symbols appeared in comctl32 4.71, could use any of
                 // them except may be DllInstall()
-                pfn = dllComCtl32.GetSymbol(_T("InitializeFlatSB"));
+                pfn = dllComCtl32.GetSymbol(wxT("InitializeFlatSB"));
                 if ( !pfn )
                 {
                     // not found, must be 4.70
                 if ( !pfn )
                 {
                     // not found, must be 4.70
@@ -1018,7 +983,7 @@ int wxApp::GetShell32Version()
         // we're prepared to handle the errors
         wxLogNull noLog;
 
         // we're prepared to handle the errors
         wxLogNull noLog;
 
-        wxDynamicLibrary dllShell32(_T("shell32.dll"), wxDL_VERBATIM);
+        wxDynamicLibrary dllShell32(wxT("shell32.dll"), wxDL_VERBATIM);
         if ( dllShell32.IsLoaded() )
         {
             s_verShell32 = CallDllGetVersion(dllShell32);
         if ( dllShell32.IsLoaded() )
         {
             s_verShell32 = CallDllGetVersion(dllShell32);
@@ -1058,61 +1023,6 @@ int wxApp::GetShell32Version()
 
 #endif // !__WXWINCE__
 
 
 #endif // !__WXWINCE__
 
-// ----------------------------------------------------------------------------
-// Yield to incoming messages
-// ----------------------------------------------------------------------------
-
-bool wxApp::Yield(bool onlyIfNeeded)
-{
-    // MT-FIXME
-    static bool s_inYield = false;
-
-#if wxUSE_LOG
-    // disable log flushing from here because a call to wxYield() shouldn't
-    // normally result in message boxes popping up &c
-    wxLog::Suspend();
-#endif // wxUSE_LOG
-
-    if ( s_inYield )
-    {
-        if ( !onlyIfNeeded )
-        {
-            wxFAIL_MSG( wxT("wxYield called recursively" ) );
-        }
-
-        return false;
-    }
-
-    s_inYield = true;
-
-    // we don't want to process WM_QUIT from here - it should be processed in
-    // the main event loop in order to stop it
-    wxEventLoopGuarantor dummyLoopIfNeeded;
-    MSG msg;
-    while ( PeekMessage(&msg, (HWND)0, 0, 0, PM_NOREMOVE) &&
-            msg.message != WM_QUIT )
-    {
-#if wxUSE_THREADS
-        wxMutexGuiLeaveOrEnter();
-#endif // wxUSE_THREADS
-
-        if ( !wxTheApp->Dispatch() )
-            break;
-    }
-
-    // if there are pending events, we must process them.
-    ProcessPendingEvents();
-
-#if wxUSE_LOG
-    // let the logs be flashed again
-    wxLog::Resume();
-#endif // wxUSE_LOG
-
-    s_inYield = false;
-
-    return true;
-}
-
 #if wxUSE_EXCEPTIONS
 
 // ----------------------------------------------------------------------------
 #if wxUSE_EXCEPTIONS
 
 // ----------------------------------------------------------------------------
@@ -1127,10 +1037,10 @@ bool wxApp::OnExceptionInMainLoop()
             ::MessageBox
               (
                 NULL,
             ::MessageBox
               (
                 NULL,
-                _T("An unhandled exception occurred. Press \"Abort\" to \
+                wxT("An unhandled exception occurred. Press \"Abort\" to \
 terminate the program,\r\n\
 \"Retry\" to exit the program normally and \"Ignore\" to try to continue."),
 terminate the program,\r\n\
 \"Retry\" to exit the program normally and \"Ignore\" to try to continue."),
-                _T("Unhandled exception"),
+                wxT("Unhandled exception"),
                 MB_ABORTRETRYIGNORE |
                 MB_ICONERROR|
                 MB_TASKMODAL
                 MB_ABORTRETRYIGNORE |
                 MB_ICONERROR|
                 MB_TASKMODAL
@@ -1141,7 +1051,7 @@ terminate the program,\r\n\
             throw;
 
         default:
             throw;
 
         default:
-            wxFAIL_MSG( _T("unexpected MessageBox() return code") );
+            wxFAIL_MSG( wxT("unexpected MessageBox() return code") );
             // fall through
 
         case IDRETRY:
             // fall through
 
         case IDRETRY: