]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/textctrl.cpp
make the string properly 0 terminated and allow for one char more on the output buffer
[wxWidgets.git] / src / msw / textctrl.cpp
index 0dd0da0b7b9f23f4d39c0bb0badb9fb326d8d742..9630d087b9419c51e38a90f5621387e9285cc570 100644 (file)
@@ -39,6 +39,7 @@
 #endif
 
 #include "wx/module.h"
+#include "wx/sysopt.h"
 
 #if wxUSE_CLIPBOARD
     #include "wx/clipbrd.h"
 
 #if wxUSE_RICHEDIT
 
+#if wxUSE_INKEDIT
+#include "wx/dynlib.h"
+#endif
+
 // old mingw32 has richedit stuff directly in windows.h and doesn't have
 // richedit.h at all
 #if !defined(__GNUWIN32_OLD__) || defined(__CYGWIN10__)
@@ -94,15 +99,30 @@ public:
     // load the richedit DLL for the specified version of rich edit
     static bool Load(Version version);
 
+#if wxUSE_INKEDIT
+    // load the InkEdit library
+    static bool LoadInkEdit();
+#endif
+
 private:
     // the handles to richedit 1.0 and 2.0 (or 3.0) DLLs
     static HINSTANCE ms_hRichEdit[Version_Max];
 
+#if wxUSE_INKEDIT
+    static wxDynamicLibrary ms_inkEditLib;
+    static bool             ms_inkEditLibLoadAttemped;
+#endif
+
     DECLARE_DYNAMIC_CLASS(wxRichEditModule)
 };
 
 HINSTANCE wxRichEditModule::ms_hRichEdit[Version_Max] = { NULL, NULL, NULL };
 
+#if wxUSE_INKEDIT
+wxDynamicLibrary wxRichEditModule::ms_inkEditLib;
+bool             wxRichEditModule::ms_inkEditLibLoadAttemped = false;
+#endif
+
 IMPLEMENT_DYNAMIC_CLASS(wxRichEditModule, wxModule)
 
 #endif // wxUSE_RICHEDIT
@@ -252,6 +272,10 @@ void wxTextCtrl::Init()
     m_verRichEdit = 0;
 #endif // wxUSE_RICHEDIT
 
+#if wxUSE_INKEDIT && wxUSE_RICHEDIT
+    m_isInkEdit = 0;
+#endif
+
     m_privateContextMenu = NULL;
     m_updatesCount = -1;
     m_isNativeCaretShown = true;
@@ -321,49 +345,76 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
         m_verRichEdit = m_windowStyle & wxTE_RICH2 ? 2 : 1;
 #endif // wxUSE_UNICODE/!wxUSE_UNICODE
 
-        if ( m_verRichEdit == 2 )
+#if wxUSE_INKEDIT
+        // First test if we can load an ink edit control. Normally, all edit
+        // controls will be made ink edit controls if a tablet environment is
+        // found (or if msw.inkedit != 0 and the InkEd.dll is present).
+        // However, an application can veto ink edit controls by either specifying
+        // msw.inkedit = 0 or by removing wxTE_RICH[2] from the style.
+        //
+        if ((wxSystemSettings::HasFeature(wxSYS_TABLET_PRESENT) || wxSystemOptions::GetOptionInt(wxT("msw.inkedit")) != 0) &&
+            !(wxSystemOptions::HasOption(wxT("msw.inkedit")) && wxSystemOptions::GetOptionInt(wxT("msw.inkedit")) == 0))
         {
-            if ( wxRichEditModule::Load(wxRichEditModule::Version_41) )
+            if (wxRichEditModule::LoadInkEdit())
             {
-                // yes, class name for version 4.1 really is 5.0
-                windowClass = _T("RICHEDIT50W");
+                windowClass = INKEDIT_CLASS;
+
+#if wxUSE_INKEDIT && wxUSE_RICHEDIT
+                m_isInkEdit = 1;
+#endif
+
+                // Fake rich text version for other calls
+                m_verRichEdit = 2;
             }
-            else if ( wxRichEditModule::Load(wxRichEditModule::Version_2or3) )
-            {
-                windowClass = _T("RichEdit20")
+        }
+#endif
+
+        if (!IsInkEdit())
+        {
+            if ( m_verRichEdit == 2 )
+            {            
+                if ( wxRichEditModule::Load(wxRichEditModule::Version_41) )
+                {
+                    // yes, class name for version 4.1 really is 5.0
+                    windowClass = _T("RICHEDIT50W");
+                }
+                else if ( wxRichEditModule::Load(wxRichEditModule::Version_2or3) )
+                {
+                    windowClass = _T("RichEdit20")
 #if wxUSE_UNICODE
-                              _T("W");
+                                _T("W");
 #else // ANSI
-                              _T("A");
+                                _T("A");
 #endif // Unicode/ANSI
+                }
+                else // failed to load msftedit.dll and riched20.dll
+                {
+                    m_verRichEdit = 1;
+                }
             }
-            else // failed to load msftedit.dll and riched20.dll
-            {
-                m_verRichEdit = 1;
-            }
-        }
 
-        if ( m_verRichEdit == 1 )
-        {
-            if ( wxRichEditModule::Load(wxRichEditModule::Version_1) )
-            {
-                windowClass = _T("RICHEDIT");
-            }
-            else // failed to load any richedit control DLL
+            if ( m_verRichEdit == 1 )
             {
-                // only give the error msg once if the DLL can't be loaded
-                static bool s_errorGiven = false; // MT ok as only used by GUI
-
-                if ( !s_errorGiven )
+                if ( wxRichEditModule::Load(wxRichEditModule::Version_1) )
                 {
-                    wxLogError(_("Impossible to create a rich edit control, using simple text control instead. Please reinstall riched32.dll"));
-
-                    s_errorGiven = true;
+                    windowClass = _T("RICHEDIT");
                 }
+                else // failed to load any richedit control DLL
+                {
+                    // only give the error msg once if the DLL can't be loaded
+                    static bool s_errorGiven = false; // MT ok as only used by GUI
+
+                    if ( !s_errorGiven )
+                    {
+                        wxLogError(_("Impossible to create a rich edit control, using simple text control instead. Please reinstall riched32.dll"));
 
-                m_verRichEdit = 0;
+                        s_errorGiven = true;
+                    }
+
+                    m_verRichEdit = 0;
+                }
             }
-        }
+        } // !useInkEdit 
     }
 #endif // wxUSE_RICHEDIT
 
@@ -382,13 +433,25 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
         return false;
 
 #if wxUSE_RICHEDIT
-    if ( IsRich() )
+    if (IsRich())
     {
+#if wxUSE_INKEDIT
+        if (IsInkEdit())
+        {
+            // Pass IEM_InsertText (0) as wParam, in order to have the ink always
+            // converted to text.
+            ::SendMessage(GetHwnd(), EM_SETINKINSERTMODE, 0, 0);
+            
+            // Make sure the mouse can be used for input
+            ::SendMessage(GetHwnd(), EM_SETUSEMOUSEFORINPUT, 1, 0);
+        }
+#endif
+        
         // enable the events we're interested in: we want to get EN_CHANGE as
         // for the normal controls
         LPARAM mask = ENM_CHANGE;
 
-        if ( GetRichVersion() == 1 )
+        if (GetRichVersion() == 1 && !IsInkEdit())
         {
             // we also need EN_MSGFILTER for richedit 1.0 for the reasons
             // explained in its handler
@@ -1737,16 +1800,15 @@ void wxTextCtrl::OnChar(wxKeyEvent& event)
     switch ( event.GetKeyCode() )
     {
         case WXK_RETURN:
-            if ( !HasFlag(wxTE_MULTILINE) )
             {
                 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
                 InitCommandEvent(event);
                 event.SetString(GetValue());
                 if ( GetEventHandler()->ProcessEvent(event) )
+                if ( !HasFlag(wxTE_MULTILINE) )
                     return;
+                //else: multiline controls need Enter for themselves
             }
-            //else: multiline controls need Enter for themselves
-
             break;
 
         case WXK_TAB:
@@ -2660,6 +2722,10 @@ void wxRichEditModule::OnExit()
             ms_hRichEdit[i] = NULL;
         }
     }
+#if wxUSE_INKEDIT
+    if (ms_inkEditLib.IsLoaded())
+        ms_inkEditLib.Unload();
+#endif
 }
 
 /* static */
@@ -2699,6 +2765,23 @@ bool wxRichEditModule::Load(Version version)
     return true;
 }
 
+#if wxUSE_INKEDIT
+// load the InkEdit library
+bool wxRichEditModule::LoadInkEdit()
+{
+    static wxDynamicLibrary ms_inkEditLib;
+    static bool             ms_inkEditLibLoadAttemped;
+    if (ms_inkEditLibLoadAttemped)
+        ms_inkEditLib.IsLoaded();
+    
+    ms_inkEditLibLoadAttemped = true;
+    
+    wxLogNull logNull;
+    return ms_inkEditLib.Load(wxT("inked"));
+}
+#endif
+
+
 #endif // wxUSE_RICHEDIT
 
 #endif // wxUSE_TEXTCTRL && !(__SMARTPHONE__ && __WXWINCE__)