// 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/cmdline.h"
+#include "wx/apptrait.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
-#ifndef __WXMICROWIN__
-#include "wx/msw/msvcrt.h"
-#endif
-
// ----------------------------------------------------------------------------
// conditional compilation
// ----------------------------------------------------------------------------
// global variables
// ---------------------------------------------------------------------------
-extern wxChar *wxBuffer;
extern wxList WXDLLEXPORT wxPendingDelete;
#ifndef __WXMICROWIN__
extern void wxSetKeyboardHook(bool doIt);
#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
const wxChar *wxMDIChildFrameClassName = wxT("wxMDIChildFrameClass");
const wxChar *wxMDIChildFrameClassNameNoRedraw = wxT("wxMDIChildFrameClassNR");
-HICON wxSTD_FRAME_ICON = (HICON) NULL;
-HICON wxSTD_MDICHILDFRAME_ICON = (HICON) NULL;
-HICON wxSTD_MDIPARENTFRAME_ICON = (HICON) NULL;
-
-HICON wxDEFAULT_FRAME_ICON = (HICON) NULL;
-HICON wxDEFAULT_MDICHILDFRAME_ICON = (HICON) NULL;
-HICON wxDEFAULT_MDIPARENTFRAME_ICON = (HICON) NULL;
-
HBRUSH wxDisableButtonBrush = (HBRUSH) 0;
+// ----------------------------------------------------------------------------
+// private functions
+// ----------------------------------------------------------------------------
+
LRESULT WXDLLEXPORT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
-// FIXME wxUSE_ON_FATAL_EXCEPTION is only supported for VC++ now because it
-// needs compiler support for Win32 SEH. Others (especially Borland)
-// probably have it too, but I'm not sure about how it works
-// JACS: get 'Cannot use __try in functions that require unwinding
-// in Unicode mode, so disabling.
-#if !defined(__VISUALC__) || defined(__WIN16__) || defined(UNICODE)
- #undef wxUSE_ON_FATAL_EXCEPTION
- #define wxUSE_ON_FATAL_EXCEPTION 0
-#endif // VC++
-
-#if wxUSE_ON_FATAL_EXCEPTION
- static bool gs_handleExceptions = FALSE;
-#endif
+// ===========================================================================
+// 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();
+}
// ===========================================================================
-// implementation
+// wxApp implementation
// ===========================================================================
+int wxApp::m_nCmdShow = SW_SHOWNORMAL;
+
// ---------------------------------------------------------------------------
-// wxApp
+// wxWin macros
// ---------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession)
END_EVENT_TABLE()
+// class to ensure that wxAppBase::CleanUp() is called if our Initialize()
+// fails
+class wxCallBaseCleanup
+{
+public:
+ wxCallBaseCleanup(wxApp *app) : m_app(app) { }
+ ~wxCallBaseCleanup() { if ( m_app ) m_app->wxAppBase::CleanUp(); }
+
+ void Dismiss() { m_app = NULL; }
+
+private:
+ wxApp *m_app;
+};
+
//// Initialize
-bool wxApp::Initialize()
+bool wxApp::Initialize(int& argc, wxChar **argv)
{
+ if ( !wxAppBase::Initialize(argc, argv) )
+ return false;
+
+ // ensure that base cleanup is done if we return too early
+ wxCallBaseCleanup callBaseCleanup(this);
+
// 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 )
}
#endif // wxUSE_UNICODE && !wxUSE_UNICODE_MSLU
- wxBuffer = new wxChar[1500]; // FIXME
-
- wxClassInfo::InitializeClasses();
-
-#if wxUSE_THREADS
- wxPendingEventsLocker = new wxCriticalSection;
-#endif
-
- wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
- wxTheColourDatabase->Initialize();
-
- wxInitializeStockLists();
- wxInitializeStockObjects();
-
-#if wxUSE_WX_RESOURCES
- wxInitializeResourceSystem();
-#endif
-
- wxBitmap::InitStandardHandlers();
-
#if defined(__WIN95__) && !defined(__WXMICROWIN__)
InitCommonControls();
#endif // __WIN95__
Ctl3dAutoSubclass(wxhInstance);
#endif // wxUSE_CTL3D
- // VZ: these icons are not in wx.rc anyhow (but should they?)!
-#if 0
- wxSTD_FRAME_ICON = LoadIcon(wxhInstance, wxT("wxSTD_FRAME"));
- wxSTD_MDIPARENTFRAME_ICON = LoadIcon(wxhInstance, wxT("wxSTD_MDIPARENTFRAME"));
- wxSTD_MDICHILDFRAME_ICON = LoadIcon(wxhInstance, wxT("wxSTD_MDICHILDFRAME"));
-
- wxDEFAULT_FRAME_ICON = LoadIcon(wxhInstance, wxT("wxDEFAULT_FRAME"));
- wxDEFAULT_MDIPARENTFRAME_ICON = LoadIcon(wxhInstance, wxT("wxDEFAULT_MDIPARENTFRAME"));
- wxDEFAULT_MDICHILDFRAME_ICON = LoadIcon(wxhInstance, wxT("wxDEFAULT_MDICHILDFRAME"));
-#endif // 0
-
RegisterWindowClasses();
#ifndef __WXMICROWIN__
wxSetKeyboardHook(TRUE);
#endif
- wxModule::RegisterModules();
- if (!wxModule::InitializeModules())
- return FALSE;
- return TRUE;
+ callBaseCleanup.Dismiss();
+
+ return true;
}
// ---------------------------------------------------------------------------
return retval;
}
-// ---------------------------------------------------------------------------
-// Convert Windows to argc, argv style
-// ---------------------------------------------------------------------------
-
-void wxApp::ConvertToStandardCommandArgs(const char* lpCmdLine)
-{
- // break the command line in words
- wxArrayString args =
- wxCmdLineParser::ConvertStringToArgs(wxConvertMB2WX(lpCmdLine));
-
- // +1 here for the program name
- argc = args.GetCount() + 1;
-
- // and +1 here for the terminating NULL
- argv = new wxChar *[argc + 1];
-
- argv[0] = new wxChar[260]; // 260 is MAX_PATH value from windef.h
- ::GetModuleFileName(wxhInstance, argv[0], 260);
-
- // also set the app name from argv[0]
- wxString name;
- wxFileName::SplitPath(argv[0], NULL, &name, NULL);
-
- // but don't override the name already set by the user code, if any
- if ( GetAppName().empty() )
- SetAppName(name);
-
- // copy all the other arguments to wxApp::argv[]
- for ( int i = 1; i < argc; i++ )
- {
- argv[i] = copystring(args[i - 1]);
- }
-
- // argv[] must be NULL-terminated
- argv[argc] = NULL;
-}
-
-//// Cleans up any wxWindows internal structures left lying around
-
void wxApp::CleanUp()
{
- //// COMMON CLEANUP
-
-#if wxUSE_LOG
- // flush the logged messages if any and install a 'safer' log target: the
- // default one (wxLogGui) can't be used after the resources are freed just
- // below and the user suppliedo ne might be even more unsafe (using any
- // wxWindows GUI function is unsafe starting from now)
- wxLog::DontCreateOnDemand();
-
- // this will flush the old messages if any
- delete wxLog::SetActiveTarget(new wxLogStderr);
-#endif // wxUSE_LOG
-
- // One last chance for pending objects to be cleaned up
- wxTheApp->DeletePendingObjects();
-
- wxModule::CleanUpModules();
-
-#if wxUSE_WX_RESOURCES
- wxCleanUpResourceSystem();
-
- // wxDefaultResourceTable->ClearTable();
-#endif
-
- wxDeleteStockObjects();
-
- // Destroy all GDI lists, etc.
- wxDeleteStockLists();
-
- delete wxTheColourDatabase;
- wxTheColourDatabase = NULL;
-
- wxBitmap::CleanUpHandlers();
-
- delete[] wxBuffer;
- wxBuffer = NULL;
-
- //// WINDOWS-SPECIFIC CLEANUP
-
#ifndef __WXMICROWIN__
wxSetKeyboardHook(FALSE);
#endif
wxCleanUpPenWin();
#endif
- if (wxSTD_FRAME_ICON)
- DestroyIcon(wxSTD_FRAME_ICON);
- if (wxSTD_MDICHILDFRAME_ICON)
- DestroyIcon(wxSTD_MDICHILDFRAME_ICON);
- if (wxSTD_MDIPARENTFRAME_ICON)
- DestroyIcon(wxSTD_MDIPARENTFRAME_ICON);
-
- if (wxDEFAULT_FRAME_ICON)
- DestroyIcon(wxDEFAULT_FRAME_ICON);
- if (wxDEFAULT_MDICHILDFRAME_ICON)
- DestroyIcon(wxDEFAULT_MDICHILDFRAME_ICON);
- if (wxDEFAULT_MDIPARENTFRAME_ICON)
- DestroyIcon(wxDEFAULT_MDIPARENTFRAME_ICON);
-
if ( wxDisableButtonBrush )
::DeleteObject( wxDisableButtonBrush );
::OleUninitialize();
#endif
-#ifdef WXMAKINGDLL
// for an EXE the classes are unregistered when it terminates but DLL may
// be loaded several times (load/unload/load) into the same process in
// which case the registration will fail after the first time if we don't
// unregister the classes now
UnregisterWindowClasses();
-#endif // WXMAKINGDLL
#if wxUSE_CTL3D
Ctl3dUnregister(wxhInstance);
#endif
delete wxWinHandleHash;
+ wxWinHandleHash = NULL;
- // 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;
-
-#if wxUSE_THREADS
- delete wxPendingEventsLocker;
- // If we don't do the following, we get an apparent memory leak
-#if wxUSE_VALIDATORS
- ((wxEvtHandler&) wxDefaultValidator).ClearEventLocker();
-#endif // wxUSE_VALIDATORS
-#endif // wxUSE_THREADS
-
- wxClassInfo::CleanUpClasses();
-
- delete wxTheApp;
- wxTheApp = NULL;
-
-#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
- // At this point we want to check if there are any memory
- // blocks that aren't part of the wxDebugContext itself,
- // as a special case. Then when dumping we need to ignore
- // wxDebugContext, too.
- if (wxDebugContext::CountObjectsLeft(TRUE) > 0)
- {
- wxLogMessage(wxT("There were memory leaks."));
- wxDebugContext::Dump();
- wxDebugContext::PrintStatistics();
- }
- // wxDebugContext::SetStream(NULL, NULL);
-#endif
-
-#if wxUSE_LOG
- // do it as the very last thing because everything else can log messages
- delete wxLog::SetActiveTarget(NULL);
-#endif // wxUSE_LOG
-}
-
-//----------------------------------------------------------------------
-// Entry point helpers, used by wxPython
-//----------------------------------------------------------------------
-
-int WXDLLEXPORT wxEntryStart( int WXUNUSED(argc), char** WXUNUSED(argv) )
-{
- return wxApp::Initialize();
-}
-
-int WXDLLEXPORT wxEntryInitGui()
-{
- return wxTheApp->OnInitGui();
-}
-
-void WXDLLEXPORT wxEntryCleanup()
-{
- wxApp::CleanUp();
-}
-
-
-#if !defined(_WINDLL) || (defined(_WINDLL) && defined(WXMAKINGDLL))
-
-// temporarily disable this warning which would be generated in release builds
-// because of __try
-#ifdef __VISUALC__
- #pragma warning(disable: 4715) // not all control paths return a value
-#endif // Visual C++
-
-//----------------------------------------------------------------------
-// Main wxWindows entry point
-//----------------------------------------------------------------------
-int wxEntry(WXHINSTANCE hInstance,
- WXHINSTANCE WXUNUSED(hPrevInstance),
- char *lpCmdLine,
- int nCmdShow,
- bool enterLoop)
-{
- // do check for memory leaks on program exit
- // (another useful flag is _CRTDBG_DELAY_FREE_MEM_DF which doesn't free
- // deallocated memory which may be used to simulate low-memory condition)
-#ifndef __WXMICROWIN__
- wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
-#endif
-
-#ifdef __MWERKS__
-#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
- // This seems to be necessary since there are 'rogue'
- // objects present at this point (perhaps global objects?)
- // Setting a checkpoint will ignore them as far as the
- // memory checking facility is concerned.
- // Of course you may argue that memory allocated in globals should be
- // checked, but this is a reasonable compromise.
- wxDebugContext::SetCheckpoint();
-#endif
-#endif
-
- // take everything into a try-except block to be able to call
- // OnFatalException() if necessary
-#if wxUSE_ON_FATAL_EXCEPTION
- __try {
-#endif
- wxhInstance = (HINSTANCE) hInstance;
-
- if (!wxEntryStart(0,0))
- return 0;
-
- // create the application object or ensure that one already exists
- if (!wxTheApp)
- {
- // The app may have declared a global application object, but we recommend
- // the IMPLEMENT_APP macro is used instead, which sets an initializer
- // function for delayed, dynamic app object construction.
- wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
- wxT("No initializer - use IMPLEMENT_APP macro.") );
-
- wxTheApp = (wxApp*) (*wxApp::GetInitializerFunction()) ();
- }
-
- wxCHECK_MSG( wxTheApp, 0, wxT("You have to define an instance of wxApp!") );
-
- // save the WinMain() parameters
- if (lpCmdLine) // MicroWindows passes NULL
- wxTheApp->ConvertToStandardCommandArgs(lpCmdLine);
- wxTheApp->m_nCmdShow = nCmdShow;
-
- // We really don't want timestamps by default, because it means
- // we can't simply double-click on the error message and get to that
- // line in the source. So VC++ at least, let's have a sensible default.
-#ifdef __VISUALC__
-#if wxUSE_LOG
- wxLog::SetTimestamp(NULL);
-#endif // wxUSE_LOG
-#endif // __VISUALC__
-
- // init the app
- int retValue = wxEntryInitGui() && wxTheApp->OnInit() ? 0 : -1;
-
- if ( retValue == 0 )
- {
- if ( enterLoop )
- {
- // run the main loop
- wxTheApp->OnRun();
- }
- else
- {
- // we want to initialize, but not run or exit immediately.
- return 1;
- }
- }
- //else: app initialization failed, so we skipped OnRun()
-
- wxWindow *topWindow = wxTheApp->GetTopWindow();
- if ( topWindow )
- {
- // Forcibly delete the window.
- if ( topWindow->IsKindOf(CLASSINFO(wxFrame)) ||
- topWindow->IsKindOf(CLASSINFO(wxDialog)) )
- {
- topWindow->Close(TRUE);
- wxTheApp->DeletePendingObjects();
- }
- else
- {
- delete topWindow;
- wxTheApp->SetTopWindow(NULL);
- }
- }
-
- retValue = wxTheApp->OnExit();
-
- wxEntryCleanup();
-
- return retValue;
-
-#if wxUSE_ON_FATAL_EXCEPTION
- }
- __except ( gs_handleExceptions ? EXCEPTION_EXECUTE_HANDLER
- : EXCEPTION_CONTINUE_SEARCH ) {
- if ( wxTheApp )
- {
- // give the user a chance to do something special about this
- wxTheApp->OnFatalException();
- }
-
- ::ExitProcess(3); // the same exit code as abort()
-
- // NOTREACHED
- }
-#endif // wxUSE_ON_FATAL_EXCEPTION
-}
-
-// restore warning state
-#ifdef __VISUALC__
- #pragma warning(default: 4715) // not all control paths return a value
-#endif // Visual C++
-
-#else /* _WINDLL */
-
-//----------------------------------------------------------------------
-// Entry point for wxWindows + the App in a DLL
-//----------------------------------------------------------------------
-
-int wxEntry(WXHINSTANCE hInstance)
-{
- wxhInstance = (HINSTANCE) hInstance;
- wxEntryStart(0, 0);
-
- // The app may have declared a global application object, but we recommend
- // the IMPLEMENT_APP macro is used instead, which sets an initializer function
- // for delayed, dynamic app object construction.
- if (!wxTheApp)
- {
- wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
- "No initializer - use IMPLEMENT_APP macro." );
-
- wxTheApp = (* wxApp::GetInitializerFunction()) ();
- }
-
- wxCHECK_MSG( wxTheApp, 0, "You have to define an instance of wxApp!" );
-
- wxTheApp->argc = 0;
- wxTheApp->argv = NULL;
-
- wxEntryInitGui();
-
- wxTheApp->OnInit();
-
- wxWindow *topWindow = wxTheApp->GetTopWindow();
- if ( topWindow && topWindow->GetHWND())
- {
- topWindow->Show(TRUE);
- }
-
- return 1;
+ wxAppBase::CleanUp();
}
-#endif // _WINDLL
-
-//// Static member initialization
-wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
+// ----------------------------------------------------------------------------
+// wxApp ctor/dtor
+// ----------------------------------------------------------------------------
wxApp::wxApp()
{
- argc = 0;
- argv = NULL;
m_printMode = wxPRINT_WINDOWS;
- m_auto3D = TRUE;
}
wxApp::~wxApp()
{
- // Delete command-line args
- int i;
- for (i = 0; i < argc; i++)
+ // our cmd line arguments are allocated inside wxEntry(HINSTANCE), they
+ // don't come from main(), so we have to free them
+
+ while ( argc )
{
- delete[] argv[i];
+ // m_argv elements were allocated by wxStrdup()
+ free(argv[--argc]);
}
- delete[] argv;
+
+ // but m_argv itself -- using new[]
+ delete [] argv;
}
bool wxApp::Initialized()
event.SetEventObject(this);
ProcessEvent(event);
+ wxUpdateUIEvent::ResetUpdateTime();
+
return event.MoreRequested();
}
// 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();
- wxWindowList::Node* node = win->GetChildren().GetFirst();
- while (node)
+ wxWindowList::Node *node = win->GetChildren().GetFirst();
+ while ( node )
{
- wxWindow* win = node->GetData();
+ wxWindow *win = node->GetData();
if (SendIdleEvents(win))
needMore = TRUE;
node = node->GetNext();
}
+
return needMore;
}
-void wxApp::DeletePendingObjects()
+void wxApp::WakeUpIdle()
{
- wxNode *node = wxPendingDelete.GetFirst();
- while (node)
+ // 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 )
{
- wxObject *obj = node->GetData();
-
- delete obj;
-
- if (wxPendingDelete.Member(obj))
- delete node;
-
- // Deleting one object may have deleted other pending
- // objects, so start from beginning of list again.
- node = wxPendingDelete.GetFirst();
+ if ( !::PostMessage(GetHwndOf(topWindow), WM_NULL, 0, 0) )
+ {
+ // should never happen
+ wxLogLastError(wxT("PostMessage(WM_NULL)"));
+ }
}
}
}
}
+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)
return TRUE;
}
-bool wxHandleFatalExceptions(bool doit)
-{
-#if wxUSE_ON_FATAL_EXCEPTION
- // assume this can only be called from the main thread
- gs_handleExceptions = doit;
-
- return TRUE;
-#else
- wxFAIL_MSG(_T("set wxUSE_ON_FATAL_EXCEPTION to 1 to use this function"));
-
- (void)doit;
- return FALSE;
-#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))
-#include "main.cpp"
-#endif