]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/app.cpp
more backwards compatible kbd handling in wxScrolledWindow
[wxWidgets.git] / src / msw / app.cpp
index 0b947a540974716b12f63b748328cf06709b090f..1be88f6a6eb0f08a7a33f50c0e58a02d78d00cf2 100644 (file)
     #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...
 #ifndef wxUSE_NORLANDER_HEADERS
 #if defined(__GNUWIN32__) || defined(__SC__) || defined(__SALFORDC__)
 
 #include "wx/msw/msvcrt.h"
 
+// ----------------------------------------------------------------------------
+// conditional compilation
+// ----------------------------------------------------------------------------
+
+// The macro _WIN32_IE is defined by commctrl.h (unless it had already been
+// defined before) and shows us what common control features are available
+// during the compile time (it doesn't mean that they will be available during
+// the run-time, use GetComCtl32Version() to test for them!). The possible
+// values are:
+//
+// 0x0200     for comctl32.dll 4.00 shipped with Win95/NT 4.0
+// 0x0300                      4.70              IE 3.x
+// 0x0400                      4.71              IE 4.0
+// 0x0401                      4.72              IE 4.01 and Win98
+// 0x0500                      5.00              IE 5.x and NT 5.0 (Win2000)
+
+#ifndef _WIN32_IE
+    // minimal set of features by default
+    #define _WIN32_IE 0x0200
+#endif
+
+#if _WIN32_IE >= 0x0300
+    #include <shlwapi.h>
+#endif
+
 // ---------------------------------------------------------------------------
 // global variables
 // ---------------------------------------------------------------------------
@@ -103,18 +132,16 @@ extern wxCursor *g_globalCursor;
 MSG s_currentMsg;
 wxApp *wxTheApp = NULL;
 
-// FIXME why not const? and not static?
-
 // NB: all "NoRedraw" classes must have the same names as the "normal" classes
 //     with NR suffix - wxWindow::MSWCreate() supposes this
-wxChar wxFrameClassName[]         = wxT("wxFrameClass");
-wxChar wxFrameClassNameNoRedraw[] = wxT("wxFrameClassNR");
-wxChar wxMDIFrameClassName[]      = wxT("wxMDIFrameClass");
-wxChar wxMDIFrameClassNameNoRedraw[] = wxT("wxMDIFrameClassNR");
-wxChar wxMDIChildFrameClassName[] = wxT("wxMDIChildFrameClass");
-wxChar wxMDIChildFrameClassNameNoRedraw[] = wxT("wxMDIChildFrameClassNR");
-wxChar wxPanelClassName[]         = wxT("wxPanelClass");
-wxChar wxCanvasClassName[]        = wxT("wxCanvasClass");
+const wxChar *wxFrameClassName         = wxT("wxFrameClass");
+const wxChar *wxFrameClassNameNoRedraw = wxT("wxFrameClassNR");
+const wxChar *wxMDIFrameClassName      = wxT("wxMDIFrameClass");
+const wxChar *wxMDIFrameClassNameNoRedraw = wxT("wxMDIFrameClassNR");
+const wxChar *wxMDIChildFrameClassName = wxT("wxMDIChildFrameClass");
+const wxChar *wxMDIChildFrameClassNameNoRedraw = wxT("wxMDIChildFrameClassNR");
+const wxChar *wxPanelClassName         = wxT("wxPanelClass");
+const wxChar *wxCanvasClassName        = wxT("wxCanvasClass");
 
 HICON wxSTD_FRAME_ICON = (HICON) NULL;
 HICON wxSTD_MDICHILDFRAME_ICON = (HICON) NULL;
@@ -128,12 +155,6 @@ HBRUSH wxDisableButtonBrush = (HBRUSH) 0;
 
 LRESULT WXDLLEXPORT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
 
-#if wxUSE_RICHEDIT
-    // the handle to richedit DLL and the version of the DLL loaded
-    static HINSTANCE gs_hRichEdit = (HINSTANCE)NULL;
-    static int gs_verRichEdit = -1;
-#endif
-
 // ===========================================================================
 // implementation
 // ===========================================================================
@@ -142,7 +163,6 @@ LRESULT WXDLLEXPORT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
 // wxApp
 // ---------------------------------------------------------------------------
 
-#if !USE_SHARED_LIBRARY
     IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
 
     BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
@@ -150,7 +170,6 @@ LRESULT WXDLLEXPORT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
         EVT_END_SESSION(wxApp::OnEndSession)
         EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession)
     END_EVENT_TABLE()
-#endif
 
 //// Initialize
 bool wxApp::Initialize()
@@ -503,11 +522,6 @@ void wxApp::CleanUp()
 
     wxSetKeyboardHook(FALSE);
 
-#if wxUSE_RICHEDIT
-    if (gs_hRichEdit != (HINSTANCE) NULL)
-        FreeLibrary(gs_hRichEdit);
-#endif
-
 #if wxUSE_PENWINDOWS
     wxCleanUpPenWin();
 #endif
@@ -593,7 +607,17 @@ int wxEntry(WXHINSTANCE hInstance,
     // (another useful flag is _CRTDBG_DELAY_FREE_MEM_DF which doesn't free
     //  deallocated memory which may be used to simulate low-memory condition)
     wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
-
+#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 in release build
     // FIXME other compilers must support Win32 SEH (structured exception
     //       handling) too, just find the appropriate keyword in their docs!
@@ -939,19 +963,24 @@ bool wxApp::ProcessMessage(WXMSG *wxmsg)
 {
     MSG *msg = (MSG *)wxmsg;
     HWND hWnd = msg->hwnd;
-    wxWindow *wndThis = wxFindWinFromHandle((WXHWND)hWnd), *wnd;
+    wxWindow *wndThis = wxGetWindowFromHWND((WXHWND)hWnd);
 
-    // for some composite controls (like a combobox), wndThis might be NULL
-    // because the subcontrol is not a wxWindow, but only the control itself
-    // is - try to catch this case
-    while ( hWnd && !wndThis )
+#if wxUSE_TOOLTIPS
+    // we must relay WM_MOUSEMOVE events to the tooltip ctrl if we want it to
+    // popup the tooltip bubbles
+    if ( wndThis && (msg->message == WM_MOUSEMOVE) )
     {
-        hWnd = ::GetParent(hWnd);
-        wndThis = wxFindWinFromHandle((WXHWND)hWnd);
+        wxToolTip *tt = wndThis->GetToolTip();
+        if ( tt )
+        {
+            tt->RelayEvent(wxmsg);
+        }
     }
+#endif // wxUSE_TOOLTIPS
 
     // Try translations first; find the youngest window with
     // a translation table.
+    wxWindow *wnd;
     for ( wnd = wndThis; wnd; wnd = wnd->GetParent() )
     {
         if ( wnd->MSWTranslateMessage(wxmsg) )
@@ -1080,101 +1109,95 @@ void wxApp::OnQueryEndSession(wxCloseEvent& event)
     }
 }
 
-#if wxUSE_RICHEDIT
-
-/* static */
-bool wxApp::InitRichEdit(int version)
-{
-    wxCHECK_MSG( version >= 1 && version <= 3, FALSE,
-                 _T("incorrect richedit control version requested") );
-
-    if ( version <= gs_verRichEdit )
-    {
-        // we've already got this or better
-        return TRUE;
-    }
-
-    if ( gs_hRichEdit )
-    {
-        ::FreeLibrary(gs_hRichEdit);
-    }
-
-    // always try load riched20.dll first - like this we won't have to reload
-    // it later if we're first asked for RE 1 and then for RE 2 or 3
-    wxString dllname = _T("riched20.dll");
-    gs_hRichEdit = ::LoadLibrary(dllname);
-    if ( !gs_hRichEdit && (version == 1) )
-    {
-        // fall back to RE 1
-        dllname = _T("riched32.dll");
-        gs_hRichEdit = ::LoadLibrary(dllname);
-    }
-
-    if ( !gs_hRichEdit )
-    {
-        wxLogSysError(_("Could not load Rich Edit DLL '%s'"), dllname.c_str());
-
-        gs_verRichEdit = -1;
-
-        return FALSE;
-    }
-
-    gs_verRichEdit = version;
-
-    return TRUE;
-}
-
-#endif // wxUSE_RICHEDIT
-
 /* static */
 int wxApp::GetComCtl32Version()
 {
-    // TODO should use DllGetVersion() instead of this hack
-
     // cache the result
-    static int s_verComCtl32 = -1;      // MT-FIXME
+    static int s_verComCtl32 = -1;
+
+    wxCRIT_SECT_DECLARE(csComCtl32);
+    wxCRIT_SECT_LOCKER(lock, csComCtl32);
 
     if ( s_verComCtl32 == -1 )
     {
+        // initally assume no comctl32.dll at all
         s_verComCtl32 = 0;
 
-        // have we loaded COMCTL32 yet?
-        HMODULE theModule = ::GetModuleHandle(wxT("COMCTL32"));
+        // do we have it?
+        HMODULE hModuleComCtl32 = ::GetModuleHandle(wxT("COMCTL32"));
 
         // if so, then we can check for the version
-        if (theModule)
+        if ( hModuleComCtl32 )
         {
-            // InitCommonControlsEx is unique to 4.7 and later
-            FARPROC theProc = ::GetProcAddress(theModule,
-                                               _T("InitCommonControlsEx"));
-
-            if ( !theProc )
-            {                    // not found, must be 4.00
-                s_verComCtl32 = 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, _T("DllInstall"));
-                if ( !theProc )
+            // try to use DllGetVersion() if available in _headers_
+            #ifdef DLLVER_PLATFORM_WINDOWS // defined in shlwapi.h
+                DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)
+                    ::GetProcAddress(hModuleComCtl32, _T("DllGetVersion"));
+                if ( pfnDllGetVersion )
                 {
-                    // not found, must be 4.70
-                    s_verComCtl32 = 470;
+                    DLLVERSIONINFO dvi;
+                    dvi.cbSize = sizeof(dvi);
+
+                    HRESULT hr = (*pfnDllGetVersion)(&dvi);
+                    if ( FAILED(hr) )
+                    {
+                        wxLogApiError(_T("DllGetVersion"), hr);
+                    }
+                    else
+                    {
+                        // this is incompatible with _WIN32_IE values, but
+                        // compatible with the other values returned by
+                        // GetComCtl32Version()
+                        s_verComCtl32 = 100*dvi.dwMajorVersion +
+                                            dvi.dwMinorVersion;
+                    }
                 }
-                else
-                {                         // found, must be 4.71
-                    s_verComCtl32 = 471;
+            #endif
+                // DllGetVersion() unavailable either during compile or
+                // run-time, try to guess the version otherwise
+                if ( !s_verComCtl32 )
+                {
+                    // InitCommonControlsEx is unique to 4.70 and later
+                    FARPROC theProc = ::GetProcAddress
+                                        (
+                                         hModuleComCtl32,
+#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x520)
+                                         "InitCommonControlsEx"
+#else
+                                         _T("InitCommonControlsEx")
+#endif
+                                        );
+
+                    if ( !theProc )
+                    {
+                        // not found, must be 4.00
+                        s_verComCtl32 = 400;
+                    }
+                    else
+                    {
+                        // many symbols appeared in comctl32 4.71, could use
+                        // any of them except may be DllInstall
+                        theProc = ::GetProcAddress
+                                    (
+                                     hModuleComCtl32,
+#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x520)
+                                     "InitializeFlatSB"
+#else
+                                     _T("InitializeFlatSB")
+#endif
+                                    );
+                        if ( !theProc )
+                        {
+                            // not found, must be 4.70
+                            s_verComCtl32 = 470;
+                        }
+                        else
+                        {
+                            // found, must be 4.71
+                            s_verComCtl32 = 471;
+                        }
+                    }
                 }
-            }
         }
     }
 
@@ -1256,6 +1279,6 @@ wxApp::GetStdIcon(int which) const
 
 // 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(__TWIN32__))
+#if (defined(__VISUALC__) && !defined(__WIN32__)) || (defined(__GNUWIN32__) && !defined(__TWIN32__) && !defined(WXMAKINGDLL))
 #include "main.cpp"
 #endif