// Modified by:
// Created: 04/01/98
// RCS-ID: $Id$
-// Copyright: (c) Julian Smart and Markus Holzem
-// Licence: wxWindows license
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ===========================================================================
#include "wx/log.h"
#endif
+#include "wx/apptrait.h"
#include "wx/cmdline.h"
#include "wx/filename.h"
#include "wx/module.h"
WX_DEFINE_OBJARRAY(wxMsgArray);
#endif // wxUSE_THREADS
-#if wxUSE_WX_RESOURCES
- #include "wx/resource.h"
-#endif
-
#if wxUSE_TOOLTIPS
#include "wx/tooltip.h"
#endif // wxUSE_TOOLTIPS
// OLE is used for drag-and-drop, clipboard, OLE Automation..., but some
// compilers don't support it (missing headers, libs, ...)
-#if defined(__GNUWIN32_OLD__) || defined(__SC__) || defined(__SALFORDC__)
+#if defined(__GNUWIN32_OLD__) || defined(__SYMANTEC__) || defined(__SALFORDC__)
#undef wxUSE_OLE
#define wxUSE_OLE 0
#include <string.h>
#include <ctype.h>
-#if defined(__WIN95__) && !((defined(__GNUWIN32_OLD__) || defined(__TWIN32__) || defined(__WXMICROWIN__)) && !defined(__CYGWIN10__))
+#if defined(__WIN95__) && !((defined(__GNUWIN32_OLD__) || defined(__WXMICROWIN__)) && !defined(__CYGWIN10__))
#include <commctrl.h>
#endif
#endif
MSG s_currentMsg;
-wxApp *wxTheApp = NULL;
// NB: all "NoRedraw" classes must have the same names as the "normal" classes
// with NR suffix - wxWindow::MSWCreate() supposes this
#endif
// ===========================================================================
-// implementation
+// wxGUIAppTraits implementation
+// ===========================================================================
+
+// private class which we use to pass parameters from BeforeChildWaitLoop() to
+// AfterChildWaitLoop()
+struct ChildWaitLoopData
+{
+ ChildWaitLoopData(wxWindowDisabler *wd_, wxWindow *winActive_)
+ {
+ wd = wd_;
+ winActive = winActive_;
+ }
+
+ wxWindowDisabler *wd;
+ wxWindow *winActive;
+};
+
+void *wxGUIAppTraits::BeforeChildWaitLoop()
+{
+ /*
+ We use a dirty hack here to disable all application windows (which we
+ must do because otherwise the calls to wxYield() could lead to some very
+ unexpected reentrancies in the users code) but to avoid losing
+ 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
+ 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
+ enabled all the time. Then when the child terminates it will get
+ activated and when we close it below -- after reenabling all the other
+ windows! -- the previously active window becomes activated again and
+ everything is ok.
+ */
+ wxBeginBusyCursor();
+
+ // 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
+ (
+ wxTheApp->GetTopWindow(),
+ -1,
+ _T(""),
+ wxPoint(32600, 32600),
+ wxSize(1, 1),
+ wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR
+ );
+ winActive->Show();
+
+ return new ChildWaitLoopData(wd, winActive);
+}
+
+void wxGUIAppTraits::AlwaysYield()
+{
+ wxYield();
+}
+
+void wxGUIAppTraits::AfterChildWaitLoop(void *dataOrig)
+{
+ wxEndBusyCursor();
+
+ const ChildWaitLoopData * const data = (ChildWaitLoopData *)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
+ data->winActive->Destroy();
+}
+
+bool wxGUIAppTraits::DoMessageFromThreadWait()
+{
+ return !wxTheApp || wxTheApp->DoMessage();
+}
+
+// ===========================================================================
+// wxApp implementation
// ===========================================================================
// ---------------------------------------------------------------------------
-// wxApp
+// wxWin macros
// ---------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
bool wxApp::Initialize()
{
// the first thing to do is to check if we're trying to run an Unicode
- // program under Win9x w/o MSLU emulation layer - if so, abort right now
+ // program under Win9x w/o MSLU emulation layer - if so, abort right now
// as it has no chance to work
#if wxUSE_UNICODE && !wxUSE_UNICODE_MSLU
if ( wxGetOsVersion() != wxWINDOWS_NT )
wxInitializeStockLists();
wxInitializeStockObjects();
-#if wxUSE_WX_RESOURCES
- wxInitializeResourceSystem();
-#endif
-
wxBitmap::InitStandardHandlers();
#if defined(__WIN95__) && !defined(__WXMICROWIN__)
wxModule::CleanUpModules();
-#if wxUSE_WX_RESOURCES
- wxCleanUpResourceSystem();
-
- // wxDefaultResourceTable->ClearTable();
-#endif
-
wxDeleteStockObjects();
// Destroy all GDI lists, etc.
#endif
delete wxWinHandleHash;
+ wxWinHandleHash = NULL; // Set to null in case anything later tries to ref it.
- // GL: I'm annoyed ... I don't know where to put this and I don't want to
- // create a module for that as it's part of the core.
delete wxPendingEvents;
+ wxPendingEvents = NULL; // Set to null because wxAppBase::wxEvtHandler is destroyed later.
#if wxUSE_THREADS
delete wxPendingEventsLocker;
+ wxPendingEventsLocker = NULL; // Set to null because wxAppBase::wxEvtHandler is destroyed later.
// If we don't do the following, we get an apparent memory leak
#if wxUSE_VALIDATORS
((wxEvtHandler&) wxDefaultValidator).ClearEventLocker();
//// Static member initialization
-wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
-
wxApp::wxApp()
{
argc = 0;
// Send idle event to window and all subwindows
bool wxApp::SendIdleEvents(wxWindow* win)
{
- bool needMore = FALSE;
-
wxIdleEvent event;
event.SetEventObject(win);
win->GetEventHandler()->ProcessEvent(event);
- if (event.MoreRequested())
- needMore = TRUE;
+ bool needMore = event.MoreRequested();
- wxNode* node = win->GetChildren().First();
- while (node)
+ wxWindowList::Node *node = win->GetChildren().GetFirst();
+ while ( node )
{
- wxWindow* win = (wxWindow*) node->Data();
+ wxWindow *win = node->GetData();
if (SendIdleEvents(win))
needMore = TRUE;
- node = node->Next();
+ node = node->GetNext();
}
+
return needMore;
}
+void wxApp::WakeUpIdle()
+{
+ // Send the top window a dummy message so idle handler processing will
+ // start up again. Doing it this way ensures that the idle handler
+ // wakes up in the right thread (see also wxWakeUpMainThread() which does
+ // the same for the main app thread only)
+ wxWindow *topWindow = wxTheApp->GetTopWindow();
+ if ( topWindow )
+ {
+ if ( !::PostMessage(GetHwndOf(topWindow), WM_NULL, 0, 0) )
+ {
+ // should never happen
+ wxLogLastError(wxT("PostMessage(WM_NULL)"));
+ }
+ }
+}
+
void wxApp::DeletePendingObjects()
{
- wxNode *node = wxPendingDelete.First();
+ wxNode *node = wxPendingDelete.GetFirst();
while (node)
{
- wxObject *obj = (wxObject *)node->Data();
+ wxObject *obj = node->GetData();
delete obj;
// Deleting one object may have deleted other pending
// objects, so start from beginning of list again.
- node = wxPendingDelete.First();
+ node = wxPendingDelete.GetFirst();
}
}
}
}
+typedef struct _WXADllVersionInfo
+{
+ DWORD cbSize;
+ DWORD dwMajorVersion; // Major version
+ DWORD dwMinorVersion; // Minor version
+ DWORD dwBuildNumber; // Build number
+ DWORD dwPlatformID; // DLLVER_PLATFORM_*
+} WXADLLVERSIONINFO;
+
+typedef HRESULT (CALLBACK* WXADLLGETVERSIONPROC)(WXADLLVERSIONINFO *);
+
/* static */
int wxApp::GetComCtl32Version()
{
// do we have it?
HMODULE hModuleComCtl32 = ::GetModuleHandle(wxT("COMCTL32"));
+ BOOL bFreeComCtl32 = FALSE ;
+ if(!hModuleComCtl32)
+ {
+ hModuleComCtl32 = ::LoadLibrary(wxT("COMCTL32.DLL")) ;
+ if(hModuleComCtl32)
+ {
+ bFreeComCtl32 = TRUE ;
+ }
+ }
// if so, then we can check for the version
if ( hModuleComCtl32 )
{
// try to use DllGetVersion() if available in _headers_
- #ifdef DLLVER_PLATFORM_WINDOWS // defined in shlwapi.h
- DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)
+ WXADLLGETVERSIONPROC pfnDllGetVersion = (WXADLLGETVERSIONPROC)
::GetProcAddress(hModuleComCtl32, "DllGetVersion");
if ( pfnDllGetVersion )
{
- DLLVERSIONINFO dvi;
+ WXADLLVERSIONINFO dvi;
dvi.cbSize = sizeof(dvi);
HRESULT hr = (*pfnDllGetVersion)(&dvi);
dvi.dwMinorVersion;
}
}
- #endif
// DllGetVersion() unavailable either during compile or
// run-time, try to guess the version otherwise
if ( !s_verComCtl32 )
}
}
}
+
+ if(bFreeComCtl32)
+ {
+ ::FreeLibrary(hModuleComCtl32) ;
+ }
}
return s_verComCtl32;
#endif
}
-void wxExit()
-{
- wxLogError(_("Fatal error: exiting"));
-
- wxApp::CleanUp();
- exit(0);
-}
-
// Yield to incoming messages
bool wxApp::Yield(bool onlyIfNeeded)
#endif
}
-//-----------------------------------------------------------------------------
-// wxWakeUpIdle
-//-----------------------------------------------------------------------------
-
-void wxWakeUpIdle()
-{
- // Send the top window a dummy message so idle handler processing will
- // start up again. Doing it this way ensures that the idle handler
- // wakes up in the right thread (see also wxWakeUpMainThread() which does
- // the same for the main app thread only)
- wxWindow *topWindow = wxTheApp->GetTopWindow();
- if ( topWindow )
- {
- if ( !::PostMessage(GetHwndOf(topWindow), WM_NULL, 0, 0) )
- {
- // should never happen
- wxLogLastError(wxT("PostMessage(WM_NULL)"));
- }
- }
-}
-
//-----------------------------------------------------------------------------
// For some reason, with MSVC++ 1.5, WinMain isn't linked in properly
// if in a separate file. So include it here to ensure it's linked.
-#if (defined(__VISUALC__) && !defined(__WIN32__)) || (defined(__GNUWIN32__) && !defined(__WINE__) && !defined(__TWIN32__) && !defined(WXMAKINGDLL))
+#if (defined(__VISUALC__) && !defined(__WIN32__)) || (defined(__GNUWIN32__) && !defined(__WINE__) && !defined(WXMAKINGDLL))
#include "main.cpp"
#endif