]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/app.cpp
missing commit
[wxWidgets.git] / src / msw / app.cpp
index 0e79d4627f32896f9f4b52139eb8d21b15c85f3d..633722e0167055e31feb9507d8f48ee6b6afdabb 100644 (file)
@@ -121,13 +121,15 @@ extern void wxSetKeyboardHook(bool doIt);
 // see http://article.gmane.org/gmane.comp.lib.wxwidgets.devel/110282
 struct ClassRegInfo
 {
-    // the base name of the class: this is used to construct the unique name in
-    // wxApp::GetRegisteredClassName()
-    wxString basename;
+    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,
-             regnameNR;
+    wxString regname;
+    wxString regnameNR;
 };
 
 namespace
@@ -170,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
-       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
-       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
-       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.
      */
@@ -184,16 +186,16 @@ void *wxGUIAppTraits::BeforeChildWaitLoop()
     // 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),
-                        wxSize(1, 1),
-                        wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR
+                        wxSize(1, 1)
                     );
     winActive->Show();
 
@@ -208,15 +210,16 @@ void wxGUIAppTraits::AfterChildWaitLoop(void *dataOrig)
 
     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;
 }
 
+#if wxUSE_THREADS
 bool wxGUIAppTraits::DoMessageFromThreadWait()
 {
     // we should return false only if the app should exit, i.e. only if
@@ -231,14 +234,20 @@ bool wxGUIAppTraits::DoMessageFromThreadWait()
     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 ::MsgWaitForMultipleObjects
              (
@@ -250,6 +259,7 @@ DWORD wxGUIAppTraits::WaitForThread(WXHANDLE hThread)
                QS_ALLPOSTMESSAGE
              );
 }
+#endif // wxUSE_THREADS
 
 wxPortId wxGUIAppTraits::GetToolkitVersion(int *majVer, int *minVer) const
 {
@@ -294,6 +304,8 @@ wxEventLoopBase* wxGUIAppTraits::CreateEventLoop()
 
 #ifndef __WXWINCE__
 
+#if wxUSE_DYNLIB_CLASS
+
 #include <wx/dynlib.h>
 
 namespace
@@ -545,7 +557,7 @@ bool wxConsoleStderr::Write(const wxString& text)
         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(wxT("WriteConsole"));
         return false;
@@ -570,6 +582,20 @@ bool wxGUIAppTraits::WriteToStderr(const wxString& 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__
 
 // ===========================================================================
@@ -650,7 +676,7 @@ const wxChar *wxApp::GetRegisteredClassName(const wxChar *name,
     const size_t count = gs_regClassesInfo.size();
     for ( size_t n = 0; n < count; n++ )
     {
-        if ( gs_regClassesInfo[n].basename == name )
+        if ( gs_regClassesInfo[n].regname == name )
             return gs_regClassesInfo[n].regname.c_str();
     }
 
@@ -659,23 +685,14 @@ const wxChar *wxApp::GetRegisteredClassName(const wxChar *name,
     wxZeroMemory(wndclass);
 
     wndclass.lpfnWndProc   = (WNDPROC)wxWndProc;
-    wndclass.hInstance     = wxhInstance;
+    wndclass.hInstance     = wxGetInstance();
     wndclass.hCursor       = ::LoadCursor(NULL, IDC_ARROW);
     wndclass.hbrBackground = (HBRUSH)wxUIntToPtr(bgBrushCol + 1);
     wndclass.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | extraStyles;
 
 
-    ClassRegInfo regClass;
-    regClass.basename = name;
-
-    // constuct a unique suffix to allow registering the class with the same
-    // base name in a main application using wxWidgets and a DLL using
-    // wxWidgets loaded into its address space: as gs_regClassesInfo variable
-    // is different in them, we're going to obtain a unique prefix by using its
-    // address here
-    regClass.regname = regClass.basename +
-                            wxString::Format(wxT("@%p"), &gs_regClassesInfo);
-    wndclass.lpszClassName = regClass.regname.wx_str();
+    ClassRegInfo regClass(name);
+    wndclass.lpszClassName = regClass.regname.t_str();
     if ( !::RegisterClass(&wndclass) )
     {
         wxLogLastError(wxString::Format(wxT("RegisterClass(%s)"),
@@ -683,17 +700,13 @@ const wxChar *wxApp::GetRegisteredClassName(const wxChar *name,
         return NULL;
     }
 
-    // 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
-    regClass.regnameNR = regClass.regname + GetNoRedrawClassSuffix();
     wndclass.style &= ~(CS_HREDRAW | CS_VREDRAW);
-    wndclass.lpszClassName = regClass.regnameNR.wx_str();
+    wndclass.lpszClassName = regClass.regnameNR.t_str();
     if ( !::RegisterClass(&wndclass) )
     {
         wxLogLastError(wxString::Format(wxT("RegisterClass(%s)"),
                        regClass.regname));
-        ::UnregisterClass(regClass.regname.c_str(), wxhInstance);
+        ::UnregisterClass(regClass.regname.c_str(), wxGetInstance());
         return NULL;
     }
 
@@ -703,7 +716,7 @@ const wxChar *wxApp::GetRegisteredClassName(const wxChar *name,
     // 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.wx_str();
+    return gs_regClassesInfo.back().regname.t_str();
 }
 
 bool wxApp::IsRegisteredClassName(const wxString& name)
@@ -725,13 +738,13 @@ void wxApp::UnregisterWindowClasses()
     for ( size_t n = 0; n < count; n++ )
     {
         const ClassRegInfo& regClass = gs_regClassesInfo[n];
-        if ( !::UnregisterClass(regClass.regname.c_str(), wxhInstance) )
+        if ( !::UnregisterClass(regClass.regname.c_str(), wxGetInstance()) )
         {
             wxLogLastError(wxString::Format(wxT("UnregisterClass(%s)"),
                            regClass.regname));
         }
 
-        if ( !::UnregisterClass(regClass.regnameNR.c_str(), wxhInstance) )
+        if ( !::UnregisterClass(regClass.regnameNR.c_str(), wxGetInstance()) )
         {
             wxLogLastError(wxString::Format(wxT("UnregisterClass(%s)"),
                            regClass.regnameNR));