]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/textctrl.cpp
Another RTL fix.
[wxWidgets.git] / src / msw / textctrl.cpp
index c2c88e5525b35a58f706ff190468715254d52871..f4193cf875a4b74848e0011e4aa8714a30b642cf 100644 (file)
@@ -27,6 +27,7 @@
 #if wxUSE_TEXTCTRL && !(defined(__SMARTPHONE__) && defined(__WXWINCE__))
 
 #ifndef WX_PRECOMP
+    #include "wx/msw/missing.h"
     #include "wx/textctrl.h"
     #include "wx/settings.h"
     #include "wx/brush.h"
@@ -36,9 +37,9 @@
     #include "wx/app.h"
     #include "wx/menu.h"
     #include "wx/math.h"
+    #include "wx/module.h"
 #endif
 
-#include "wx/module.h"
 #include "wx/sysopt.h"
 
 #if wxUSE_CLIPBOARD
@@ -71,8 +72,6 @@
     #include <richedit.h>
 #endif
 
-#include "wx/msw/missing.h"
-
 #endif // wxUSE_RICHEDIT
 
 // ----------------------------------------------------------------------------
@@ -227,11 +226,11 @@ wxEND_HANDLERS_TABLE()
 
 wxCONSTRUCTOR_6( wxTextCtrl , wxWindow* , Parent , wxWindowID , Id , wxString , Value , wxPoint , Position , wxSize , Size , long , WindowStyle)
 #else
-IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
+IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxTextCtrlBase)
 #endif
 
 
-BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
+BEGIN_EVENT_TABLE(wxTextCtrl, wxTextCtrlBase)
     EVT_CHAR(wxTextCtrl::OnChar)
     EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
 
@@ -258,10 +257,50 @@ BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
     EVT_SET_FOCUS(wxTextCtrl::OnSetFocus)
 END_EVENT_TABLE()
 
+// ----------------------------------------------------------------------------
+// function prototypes
+// ----------------------------------------------------------------------------
+
+LRESULT APIENTRY _EXPORT wxTextCtrlWndProc(HWND hWnd,
+                                           UINT message,
+                                           WPARAM wParam,
+                                           LPARAM lParam);
+
+// ---------------------------------------------------------------------------
+// global vars
+// ---------------------------------------------------------------------------
+
+// the pointer to standard text control wnd proc
+static WNDPROC gs_wndprocEdit = (WNDPROC)NULL;
+
 // ============================================================================
 // implementation
 // ============================================================================
 
+// ----------------------------------------------------------------------------
+// wnd proc for subclassed edit control
+// ----------------------------------------------------------------------------
+
+LRESULT APIENTRY _EXPORT wxTextCtrlWndProc(HWND hWnd,
+                                           UINT message,
+                                           WPARAM wParam,
+                                           LPARAM lParam)
+{
+    switch ( message )
+    {
+        case WM_CUT:
+        case WM_COPY:
+        case WM_PASTE:
+            {
+                wxWindow *win = wxFindWinFromHandle((WXHWND)hWnd);
+                if( win->HandleClipboardEvent( message ) )
+                    return 0;
+                break;
+            }
+    }
+    return ::CallWindowProc(CASTWNDPROC gs_wndprocEdit, hWnd, message, wParam, lParam);
+}
+
 // ----------------------------------------------------------------------------
 // creation
 // ----------------------------------------------------------------------------
@@ -479,6 +518,9 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
     }
 #endif // wxUSE_RICHEDIT
 
+    gs_wndprocEdit = wxSetWindowProc((HWND)GetHwnd(),
+                                     wxTextCtrlWndProc);
+
     return true;
 }
 
@@ -749,20 +791,24 @@ void wxTextCtrl::SetValue(const wxString& value)
     {
         DoWriteText(value, false /* not selection only */);
 
+        // mark the control as being not dirty - we changed its text, not the
+        // user
+        DiscardEdits();
+
         // for compatibility, don't move the cursor when doing SetValue()
         SetInsertionPoint(0);
     }
     else // same text
     {
+        // still reset the modified flag even if the value didn't really change
+        // because now it comes from the program and not the user (and do it
+        // before generating the event so that the event handler could get the
+        // expected value from IsModified())
+        DiscardEdits();
+
         // still send an event for consistency
         SendUpdateEvent();
     }
-
-    // we should reset the modified flag even if the value didn't really change
-
-    // mark the control as being not dirty - we changed its text, not the
-    // user
-    DiscardEdits();
 }
 
 #if wxUSE_RICHEDIT && (!wxUSE_UNICODE || wxUSE_UNICODE_MSLU)
@@ -1184,7 +1230,8 @@ void wxTextCtrl::SetInsertionPointEnd()
     // if it doesn't actually move the caret anywhere and so the simple fact of
     // doing it results in horrible flicker when appending big amounts of text
     // to the control in a few chunks (see DoAddText() test in the text sample)
-    if ( GetInsertionPoint() == GetLastPosition() )
+    const wxTextPos lastPosition = GetLastPosition();
+    if ( GetInsertionPoint() == lastPosition )
     {
         return;
     }
@@ -1200,7 +1247,7 @@ void wxTextCtrl::SetInsertionPointEnd()
     else // !RichEdit 1.0
 #endif // wxUSE_RICHEDIT
     {
-        pos = GetLastPosition();
+        pos = lastPosition;
     }
 
     SetInsertionPoint(pos);
@@ -1735,18 +1782,17 @@ void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event)
 // kbd input processing
 // ----------------------------------------------------------------------------
 
-bool wxTextCtrl::MSWShouldPreProcessMessage(WXMSG* pMsg)
+bool wxTextCtrl::MSWShouldPreProcessMessage(WXMSG* msg)
 {
-    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 = (WORD) msg->wParam;
-        if ( (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN )
+        const WPARAM vkey = msg->wParam;
+        if ( HIWORD(msg->lParam) & KF_ALTDOWN )
         {
+            // Alt-Backspace is accelerator for "Undo"
             if ( vkey == VK_BACK )
                 return false;
         }
@@ -1764,6 +1810,9 @@ bool wxTextCtrl::MSWShouldPreProcessMessage(WXMSG* pMsg)
                     // fall through
 
                 case 0:
+                    if ( IsMultiLine() && vkey == VK_RETURN )
+                        return false;
+                    // fall through
                 case 2:
                     break;
 
@@ -1792,7 +1841,7 @@ bool wxTextCtrl::MSWShouldPreProcessMessage(WXMSG* pMsg)
         }
     }
 
-    return wxControl::MSWShouldPreProcessMessage(pMsg);
+    return wxControl::MSWShouldPreProcessMessage(msg);
 }
 
 void wxTextCtrl::OnChar(wxKeyEvent& event)
@@ -2515,11 +2564,23 @@ bool wxTextCtrl::SetStyle(long start, long end, const wxTextAttr& style)
         }
     }
 
-    if (pf.dwMask != 0)
+#if wxUSE_RICHEDIT2
+    if ( m_verRichEdit > 1 )
+    {
+        if ( wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft )
+        {
+            // Use RTL paragraphs in RTL mode to get proper layout
+            pf.dwMask |= PFM_RTLPARA;
+            pf.wEffects |= PFE_RTLPARA;
+        }
+    }
+#endif // wxUSE_RICHEDIT2
+
+    if ( pf.dwMask )
     {
         // do format the selection
         bool ok = ::SendMessage(GetHwnd(), EM_SETPARAFORMAT,
-            0, (LPARAM) &pf) != 0;
+                                0, (LPARAM) &pf) != 0;
         if ( !ok )
         {
             wxLogDebug(_T("SendMessage(EM_SETPARAFORMAT, 0) failed"));