]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/textctrl.cpp
better learn the operators...
[wxWidgets.git] / src / msw / textctrl.cpp
index caa8d82fe0bf23e8640ba183ba27e9e333966397..0de8b105d56145bad059dcec0a3239e9679bf602 100644 (file)
     #define CFM_BACKCOLOR 0x04000000
 #endif
 
+// cygwin does not have these defined for richedit
+#ifndef ENM_LINK
+    #define ENM_LINK 0x04000000
+#endif
+
+#ifndef EM_AUTOURLDETECT
+    #define EM_AUTOURLDETECT (WM_USER + 91)
+#endif
+
+#ifndef EN_LINK
+    #define EN_LINK 0x070b
+
+    typedef struct _enlink
+    {
+        NMHDR nmhdr;
+        UINT msg;
+        WPARAM wParam;
+        LPARAM lParam;
+        CHARRANGE chrg;
+    } ENLINK;
+#endif // ENLINK
+
 // ----------------------------------------------------------------------------
 // private classes
 // ----------------------------------------------------------------------------
@@ -237,6 +259,11 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
         else
         {
             msStyle |= ES_AUTOVSCROLL;
+            // Experimental: this seems to help with the scroll problem. See messages from Jekabs Andrushaitis <j.andrusaitis@konts.lv>
+            // wx-dev list, entitled "[wx-dev] wxMSW-EVT_KEY_DOWN and wxMSW-wxTextCtrl" and "[wx-dev] TextCtrl (RichEdit)"
+            // Unfortunately, showing the selection in blue when the control doesn't have
+            // the focus is non-standard behaviour, and we need to find another workaround.
+            //msStyle |= ES_NOHIDESEL ;
             m_isRich = TRUE;
 
             int ver = wxRichEditModule::GetLoadedVersion();
@@ -592,8 +619,13 @@ void wxTextCtrl::SetInsertionPoint(long pos)
     SendMessage(hWnd, EM_SETSEL, 0, MAKELPARAM(pos, pos));
 #endif // Win32/16
 
-    static const wxChar *nothing = _T("");
-    SendMessage(hWnd, EM_REPLACESEL, 0, (LPARAM)nothing);
+#if wxUSE_RICHEDIT
+    if ( !m_isRich)
+#endif
+    {
+        static const wxChar *nothing = _T("");
+        SendMessage(hWnd, EM_REPLACESEL, 0, (LPARAM)nothing);
+    }
 }
 
 void wxTextCtrl::SetInsertionPointEnd()
@@ -676,7 +708,6 @@ bool wxTextCtrl::IsEditable() const
 
 void wxTextCtrl::Replace(long from, long to, const wxString& value)
 {
-#if wxUSE_CLIPBOARD
     HWND hWnd = GetHwnd();
     long fromChar = from;
     long toChar = to;
@@ -684,18 +715,10 @@ void wxTextCtrl::Replace(long from, long to, const wxString& value)
     // Set selection and remove it
 #ifdef __WIN32__
     SendMessage(hWnd, EM_SETSEL, fromChar, toChar);
+    SendMessage(hWnd, EM_REPLACESEL, (WPARAM)TRUE, (LPARAM)value.c_str());
 #else
     SendMessage(hWnd, EM_SETSEL, (WPARAM)0, (LPARAM)MAKELONG(fromChar, toChar));
-#endif
-    SendMessage(hWnd, WM_CUT, (WPARAM)0, (LPARAM)0);
-
-    // Now replace with 'value', by pasting.
-    wxSetClipboardData(wxDF_TEXT, (wxObject *) (const wxChar *)value, 0, 0);
-
-    // Paste into edit control
-    SendMessage(hWnd, WM_PASTE, (WPARAM)0, (LPARAM)0L);
-#else
-    wxFAIL_MSG("wxTextCtrl::Replace not implemented if wxUSE_CLIPBOARD is 0.");
+    SendMessage(hWnd, EM_REPLACESEL, (WPARAM)0, (LPARAM)value.c_str());
 #endif
 }
 
@@ -708,10 +731,11 @@ void wxTextCtrl::Remove(long from, long to)
     // Cut all selected text
 #ifdef __WIN32__
     SendMessage(hWnd, EM_SETSEL, fromChar, toChar);
+    SendMessage(hWnd, EM_REPLACESEL, (WPARAM)TRUE, (LPARAM)"");
 #else
     SendMessage(hWnd, EM_SETSEL, (WPARAM)0, (LPARAM)MAKELONG(fromChar, toChar));
+    SendMessage(hWnd, EM_REPLACESEL, (WPARAM)0, (LPARAM)"");
 #endif
-    SendMessage(hWnd, WM_CUT, (WPARAM)0, (LPARAM)0);
 }
 
 void wxTextCtrl::SetSelection(long from, long to)
@@ -864,6 +888,11 @@ wxString wxTextCtrl::GetLineText(long lineNo) const
     return str;
 }
 
+void wxTextCtrl::SetMaxLength(unsigned long len)
+{
+    ::SendMessage(GetHwnd(), EM_LIMITTEXT, len, 0);
+}
+
 // ----------------------------------------------------------------------------
 // Undo/redo
 // ----------------------------------------------------------------------------
@@ -914,6 +943,52 @@ void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event)
     }
 }
 
+// ----------------------------------------------------------------------------
+// kbd input processing
+// ----------------------------------------------------------------------------
+
+bool wxTextCtrl::MSWShouldPreProcessMessage(WXMSG* pMsg)
+{
+    MSG *msg = (MSG *)pMsg;
+
+    // check for our special keys here: if we don't do it and the parent frame
+    // uses them as accelerators, they wouldn't work at all, so we disable
+    // usual preprocessing for them
+    if ( msg->message == WM_KEYDOWN )
+    {
+        WORD vkey = msg->wParam;
+        if ( (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN )
+        {
+            if ( vkey == VK_BACK )
+                return FALSE;
+        }
+        else // no Alt
+        {
+            if ( wxIsCtrlDown() )
+            {
+                switch ( vkey )
+                {
+                    case 'C':
+                    case 'V':
+                    case 'X':
+                    case VK_INSERT:
+                    case VK_DELETE:
+                    case VK_HOME:
+                    case VK_END:
+                        return FALSE;
+                }
+            }
+            else if ( wxIsShiftDown() )
+            {
+                if ( vkey == VK_INSERT || vkey == VK_DELETE )
+                    return FALSE;
+            }
+        }
+    }
+
+    return wxControl::MSWShouldPreProcessMessage(pMsg);
+}
+
 void wxTextCtrl::OnChar(wxKeyEvent& event)
 {
     switch ( event.KeyCode() )
@@ -960,8 +1035,8 @@ bool wxTextCtrl::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
         case EN_KILLFOCUS:
             {
                 wxFocusEvent event(param == EN_KILLFOCUS ? wxEVT_KILL_FOCUS
-                        : wxEVT_SET_FOCUS,
-                        m_windowId);
+                                                         : wxEVT_SET_FOCUS,
+                                   m_windowId);
                 event.SetEventObject( this );
                 GetEventHandler()->ProcessEvent(event);
             }
@@ -978,7 +1053,13 @@ bool wxTextCtrl::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
 
         case EN_MAXTEXT:
             // the text size limit has been hit - increase it
-            AdjustSpaceLimit();
+            if ( !AdjustSpaceLimit() )
+            {
+                wxCommandEvent event(wxEVT_COMMAND_TEXT_MAXLEN, m_windowId);
+                InitCommandEvent(event);
+                event.SetString(GetValue());
+                ProcessCommand(event);
+            }
             break;
 
             // the other notification messages are not processed
@@ -1067,11 +1148,27 @@ void wxTextCtrl::OnEraseBackground(wxEraseEvent& event)
 }
 #endif
 
-void wxTextCtrl::AdjustSpaceLimit()
+bool wxTextCtrl::AdjustSpaceLimit()
 {
 #ifndef __WIN16__
-    unsigned int len = ::GetWindowTextLength(GetHwnd()),
-    limit = ::SendMessage(GetHwnd(), EM_GETLIMITTEXT, 0, 0);
+    unsigned int limit = ::SendMessage(GetHwnd(), EM_GETLIMITTEXT, 0, 0);
+
+    // HACK: we try to automatically extend the limit for the amount of text
+    //       to allow (interactively) entering more than 64Kb of text under
+    //       Win9x but we shouldn't reset the text limit which was previously
+    //       set explicitly with SetMaxLength()
+    //
+    //       we could solve this by storing the limit we set in wxTextCtrl but
+    //       to save space we prefer to simply test here the actual limit
+    //       value: we consider that SetMaxLength() can only be called for
+    //       values < 32Kb
+    if ( limit < 0x8000 )
+    {
+        // we've got more text than limit set by SetMaxLength()
+        return FALSE;
+    }
+
+    unsigned int len = ::GetWindowTextLength(GetHwnd());
     if ( len >= limit )
     {
         limit = len + 0x8000;    // 32Kb
@@ -1096,6 +1193,9 @@ void wxTextCtrl::AdjustSpaceLimit()
         }
     }
 #endif // !Win16
+
+    // we changed the limit
+    return TRUE;
 }
 
 bool wxTextCtrl::AcceptsFocus() const