X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1c089c47f344926e2f95a8aa342992ed844fe609..8429bec1e8e3fcb7d071bc3ef7c665c484b5fdc1:/src/msw/app.cpp diff --git a/src/msw/app.cpp b/src/msw/app.cpp index 4c9218cb88..2380393bfd 100644 --- a/src/msw/app.cpp +++ b/src/msw/app.cpp @@ -52,6 +52,13 @@ #include #endif +// use debug CRT functions for memory leak detections in VC++ +/* Doesn't work when using the makefiles, for some reason. +#if defined(__WXDEBUG__) && defined(_MSC_VER) + #include +#endif +*/ + extern char *wxBuffer; extern char *wxOsVersion; extern wxList *wxWinHandleList; @@ -59,7 +66,7 @@ extern wxList wxPendingDelete; extern void wxSetKeyboardHook(bool doIt); extern wxCursor *g_globalCursor; -HANDLE wxhInstance = 0; +HINSTANCE wxhInstance = 0; static MSG s_currentMsg; wxApp *wxTheApp = NULL; @@ -94,9 +101,9 @@ long wxApp::sm_lastMessageTime = 0; static HINSTANCE gs_hRichEdit = NULL; #endif -bool wxApp::Initialize(WXHANDLE instance) +bool wxApp::Initialize(WXHINSTANCE instance) { - HANDLE hInstance = (HANDLE)instance; + HINSTANCE hInstance = (HINSTANCE) instance; CommonInit(); @@ -161,7 +168,7 @@ bool wxApp::Initialize(WXHANDLE instance) return TRUE; } -bool wxApp::RegisterWindowClasses(void) +bool wxApp::RegisterWindowClasses() { /////////////////////////////////////////////////////////////////////// // Register the frame window class. @@ -248,7 +255,7 @@ bool wxApp::RegisterWindowClasses(void) wndclass2.hIcon = NULL; wndclass2.hCursor = NULL; // wndclass2.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1) ; - wndclass2.hbrBackground = GetStockObject( LTGRAY_BRUSH ); + wndclass2.hbrBackground = (HBRUSH) GetStockObject( LTGRAY_BRUSH ); wndclass2.lpszMenuName = NULL; wndclass2.lpszClassName = wxPanelClassName; if (!RegisterClass( &wndclass2 )) @@ -263,9 +270,9 @@ bool wxApp::RegisterWindowClasses(void) memset(&wndclass3, 0, sizeof(WNDCLASS)); // start with NULL defaults // Use CS_OWNDC to avoid messing about restoring the context // for every graphic operation. -// wndclass3.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS ; +// wndclass3.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS ; // wxWin 2.0 - wndclass3.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ; + wndclass3.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ; wndclass3.lpfnWndProc = (WNDPROC)wxWndProc; wndclass3.cbClsExtra = 0; wndclass3.cbWndExtra = sizeof( DWORD ); // was 4 @@ -286,7 +293,7 @@ bool wxApp::RegisterWindowClasses(void) } // Cleans up any wxWindows internal structures left lying around -void wxApp::CleanUp(void) +void wxApp::CleanUp() { wxModule::CleanUpModules(); @@ -330,14 +337,15 @@ void wxApp::CleanUp(void) if (wxWinHandleList) delete wxWinHandleList ; - + // do it as the very last thing because everything else can log messages + wxLog::DontCreateOnDemand(); delete wxLog::SetActiveTarget(NULL); } -void wxApp::CommonInit(void) +void wxApp::CommonInit() { -#ifdef __WINDOWS__ +#ifdef __WXMSW__ wxBuffer = new char[1500]; #else wxBuffer = new char[BUFSIZ + 512]; @@ -345,36 +353,14 @@ void wxApp::CommonInit(void) wxClassInfo::InitializeClasses(); -#ifdef __X__ - wxTheFontNameDirectory.Initialize(); -#endif - -#if defined(__X__) && USE_RESOURCES - // Read standard font names from .Xdefaults - - extern char *wxDecorativeFontName; - extern char *wxRomanFontName; - extern char *wxModernFontName; - extern char *wxSwissFontName; - extern char *wxScriptFontName; - extern char *wxTeletypeFontName; - extern char *wxDefaultFontName; - - (void) wxGetResource("wxWindows", "defaultFamily", &wxDefaultFontName); - (void) wxGetResource("wxWindows", "decorativeFamily", &wxDecorativeFontName); - (void) wxGetResource("wxWindows", "romanFamily", &wxRomanFontName); - (void) wxGetResource("wxWindows", "modernFamily", &wxModernFontName); - (void) wxGetResource("wxWindows", "swissFamily", &wxSwissFontName); - (void) wxGetResource("wxWindows", "scriptFamily", &wxScriptFontName); - (void) wxGetResource("wxWindows", "teletypeFamily", &wxTeletypeFontName); -#endif - #if USE_RESOURCES - (void) wxGetResource("wxWindows", "OsVersion", &wxOsVersion); + wxGetResource("wxWindows", "OsVersion", &wxOsVersion); #endif wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING); wxTheColourDatabase->Initialize(); + + wxInitializeStockLists(); wxInitializeStockObjects(); #if USE_WX_RESOURCES @@ -393,13 +379,14 @@ void wxApp::CommonInit(void) g_globalCursor = new wxCursor; } -void wxApp::CommonCleanUp(void) +void wxApp::CommonCleanUp() { #if USE_WX_RESOURCES wxCleanUpResourceSystem(); // wxDefaultResourceTable->ClearTable(); #endif + // Indicate that the cursor can be freed, // so that cursor won't be deleted by deleting // the bitmap list before g_globalCursor goes out @@ -410,17 +397,7 @@ void wxApp::CommonCleanUp(void) wxDeleteStockObjects() ; // Destroy all GDI lists, etc. - delete wxTheBrushList; - wxTheBrushList = NULL; - - delete wxThePenList; - wxThePenList = NULL; - - delete wxTheFontList; - wxTheFontList = NULL; - - delete wxTheBitmapList; - wxTheBitmapList = NULL; + wxDeleteStockLists(); delete wxTheColourDatabase; wxTheColourDatabase = NULL; @@ -446,7 +423,16 @@ int wxEntry(WXHINSTANCE hInstance, WXHINSTANCE WXUNUSED(hPrevInstance), char *m_ { wxhInstance = (HINSTANCE) hInstance; -#if (DEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT +/* Doesn't work when using the makefiles, for some reason. + #if defined(__WXDEBUG__) && defined(_MSC_VER) + // 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) + _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF); + #endif // debug build under MS VC++ +*/ + +#if (WXDEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT #if !defined(_WINDLL) streambuf* sBuf = new wxDebugStreamBuf; @@ -456,7 +442,7 @@ int wxEntry(WXHINSTANCE hInstance, WXHINSTANCE WXUNUSED(hPrevInstance), char *m_ ostream* oStr = new ostream(sBuf) ; wxDebugContext::SetStream(oStr, sBuf); -#endif +#endif // USE_MEMORY_TRACING if (!wxApp::Initialize((WXHINSTANCE) wxhInstance)) return 0; @@ -482,10 +468,10 @@ int wxEntry(WXHINSTANCE hInstance, WXHINSTANCE WXUNUSED(hPrevInstance), char *m_ // Split command line into tokens, as in usual main(argc, argv) char **command = new char*[50]; - + int count = 0; char *buf = new char[strlen(m_lpCmdLine) + 1]; - + // Hangs around until end of app. in case // user carries pointers to the tokens @@ -587,7 +573,7 @@ int wxEntry(WXHINSTANCE hInstance, WXHINSTANCE WXUNUSED(hPrevInstance), char *m_ wxTheApp->SetTopWindow(NULL); } } - + wxTheApp->OnExit(); wxApp::CleanUp(); @@ -598,7 +584,7 @@ int wxEntry(WXHINSTANCE hInstance, WXHINSTANCE WXUNUSED(hPrevInstance), char *m_ delete [] command[0] ; delete [] command ; -#if (DEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT +#if (WXDEBUG && USE_MEMORY_TRACING) || USE_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 @@ -660,7 +646,7 @@ int wxEntry(WXHINSTANCE hInstance) // Static member initialization wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL; -wxApp::wxApp(void) +wxApp::wxApp() { m_topWindow = NULL; wxTheApp = this; @@ -672,18 +658,16 @@ wxApp::wxApp(void) m_appName = ""; argc = 0; argv = NULL; -#ifdef __WINDOWS__ +#ifdef __WXMSW__ m_printMode = wxPRINT_WINDOWS; #else m_printMode = wxPRINT_POSTSCRIPT; #endif -// work_proc = NULL; m_exitOnFrameDelete = TRUE; -// m_showOnInit = TRUE; m_auto3D = TRUE; } -bool wxApp::Initialized(void) +bool wxApp::Initialized() { #ifndef _WINDLL if (GetTopWindow()) @@ -701,13 +685,13 @@ bool wxApp::Initialized(void) * received. * */ -bool wxApp::DoMessage(void) +bool wxApp::DoMessage() { if (!::GetMessage(&s_currentMsg, (HWND) NULL, 0, 0)) { return FALSE; } - + // Process the message if (!ProcessMessage((WXMSG *)&s_currentMsg)) { @@ -732,7 +716,7 @@ bool wxApp::DoMessage(void) * are processed (it'll sit in DoMessage). */ -int wxApp::MainLoop(void) +int wxApp::MainLoop() { m_keepGoing = TRUE; while (m_keepGoing) @@ -747,7 +731,7 @@ int wxApp::MainLoop(void) } // Returns TRUE if more time is needed. -bool wxApp::ProcessIdle(void) +bool wxApp::ProcessIdle() { wxIdleEvent event; event.SetEventObject(this); @@ -756,17 +740,17 @@ bool wxApp::ProcessIdle(void) return event.MoreRequested(); } -void wxApp::ExitMainLoop(void) +void wxApp::ExitMainLoop() { m_keepGoing = FALSE; } -bool wxApp::Pending(void) +bool wxApp::Pending() { return (::PeekMessage(&s_currentMsg, 0, 0, 0, PM_NOREMOVE) != 0) ; } -void wxApp::Dispatch(void) +void wxApp::Dispatch() { if (!DoMessage()) m_keepGoing = FALSE; @@ -783,26 +767,29 @@ bool wxApp::ProcessMessage(WXMSG *Msg) HWND hWnd; - // Anyone for a message? Try youngest descendants first. + // Try translations first; find the youngest window with + // a translation table. for (hWnd = msg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd)) { wxWindow *wnd = wxFindWinFromHandle((WXHWND) hWnd); if (wnd) { - if (wnd->MSWProcessMessage(Msg)) + if (wnd->MSWTranslateMessage(Msg)) return TRUE; - - // STOP if we've reached the top of the hierarchy! -// if (m_topWindow && (wnd == m_topWindow)) -// return FALSE; } } - // TODO: Is this now obsolete, given that m_topWindow may not be defined? - // Does it do anything useful anyway? -// if (m_topWindow && m_topWindow->MSWProcessMessage(Msg)) -// return TRUE; - return FALSE; + // Anyone for a non-translation message? Try youngest descendants first. + for (hWnd = msg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd)) + { + wxWindow *wnd = wxFindWinFromHandle((WXHWND) hWnd); + if (wnd) + { + if (wnd->MSWProcessMessage(Msg)) + return TRUE; + } + } + return FALSE; } void wxApp::OnIdle(wxIdleEvent& event) @@ -834,7 +821,7 @@ void wxApp::OnIdle(wxIdleEvent& event) } // Send idle event to all top-level windows -bool wxApp::SendIdleEvents(void) +bool wxApp::SendIdleEvents() { bool needMore = FALSE; wxNode* node = wxTopLevelWindows.First(); @@ -873,26 +860,13 @@ bool wxApp::SendIdleEvents(wxWindow* win) return needMore ; } -// Windows specific. Intercept keyboard input: by default, -// route it to the active frame or dialog box. -#if WXWIN_COMPATIBILITY == 2 -bool wxApp::OldOnCharHook(wxKeyEvent& event) -{ - wxWindow *win = wxGetActiveWindow(); - if (win) - return win->GetEventHandler()->OldOnCharHook(event); - else - return FALSE; -} -#endif - -void wxApp::DeletePendingObjects(void) +void wxApp::DeletePendingObjects() { wxNode *node = wxPendingDelete.First(); while (node) { wxObject *obj = (wxObject *)node->Data(); - + delete obj; if (wxPendingDelete.Member(obj)) @@ -906,7 +880,7 @@ void wxApp::DeletePendingObjects(void) /* // Free up font objects that are not being used at present. -bool wxApp::DoResourceCleanup(void) +bool wxApp::DoResourceCleanup() { // wxDebugMsg("ResourceCleanup\n"); @@ -958,12 +932,12 @@ bool wxApp::DoResourceCleanup(void) } */ -wxLog* wxApp::CreateLogTarget(void) +wxLog* wxApp::CreateLogTarget() { return new wxLogGui; } -wxWindow* wxApp::GetTopWindow(void) const +wxWindow* wxApp::GetTopWindow() const { if (m_topWindow) return m_topWindow; @@ -973,14 +947,57 @@ wxWindow* wxApp::GetTopWindow(void) const return NULL; } -void wxExit(void) +int wxApp::GetComCtl32Version() const +{ + // have we loaded COMCTL32 yet? + HMODULE theModule = ::GetModuleHandle("COMCTL32"); + int version = 0; + + // if so, then we can check for the version + if (theModule) + { + // InitCommonControlsEx is unique to 4.7 and later + FARPROC theProc = ::GetProcAddress(theModule, "InitCommonControlsEx"); + + if (! theProc) + { // not found, must be 4.00 + version = 400; + } + else + { + // The following symbol are unique to 4.71 + // DllInstall + // FlatSB_EnableScrollBar FlatSB_GetScrollInfo FlatSB_GetScrollPos + // FlatSB_GetScrollProp FlatSB_GetScrollRange FlatSB_SetScrollInfo + // FlatSB_SetScrollPos FlatSB_SetScrollProp FlatSB_SetScrollRange + // FlatSB_ShowScrollBar + // _DrawIndirectImageList _DuplicateImageList + // InitializeFlatSB + // UninitializeFlatSB + // we could check for any of these - I chose DllInstall + FARPROC theProc = ::GetProcAddress(theModule, "DllInstall"); + if (! theProc) + { + // not found, must be 4.70 + version = 470; + } + else + { // found, must be 4.71 + version = 471; + } + } + } + return version; +} + +void wxExit() { wxApp::CleanUp(); FatalAppExit(0, "Fatal error: exiting"); } // Yield to incoming messages -bool wxYield(void) +bool wxYield() { MSG msg; // We want to go back to the main message loop