]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/textctrl.cpp
wxNavigationKeyEvent doesn't derive from wxCommandEvent (but from wxEvent)
[wxWidgets.git] / src / msw / textctrl.cpp
index 05df7e86d299124d2adcc028d3ae79b4ee27a0c9..f70aa21b7cc4fe296a4af1c64489e5ad8a68cf6f 100644 (file)
@@ -13,7 +13,7 @@
 // declarations
 // ============================================================================
 
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
     #pragma implementation "textctrl.h"
 #endif
 
@@ -52,6 +52,7 @@
 #include <windowsx.h>
 
 #include "wx/msw/private.h"
+#include "wx/msw/winundef.h"
 
 #include <string.h>
 #include <stdlib.h>
@@ -115,7 +116,75 @@ IMPLEMENT_DYNAMIC_CLASS(wxRichEditModule, wxModule)
 // event tables and other macros
 // ----------------------------------------------------------------------------
 
+#if wxUSE_EXTENDED_RTTI
+WX_DEFINE_FLAGS( wxTextCtrlStyle )
+
+wxBEGIN_FLAGS( wxTextCtrlStyle )
+    // new style border flags, we put them first to
+    // use them for streaming out
+    wxFLAGS_MEMBER(wxBORDER_SIMPLE)
+    wxFLAGS_MEMBER(wxBORDER_SUNKEN)
+    wxFLAGS_MEMBER(wxBORDER_DOUBLE)
+    wxFLAGS_MEMBER(wxBORDER_RAISED)
+    wxFLAGS_MEMBER(wxBORDER_STATIC)
+    wxFLAGS_MEMBER(wxBORDER_NONE)
+    
+    // old style border flags
+    wxFLAGS_MEMBER(wxSIMPLE_BORDER)
+    wxFLAGS_MEMBER(wxSUNKEN_BORDER)
+    wxFLAGS_MEMBER(wxDOUBLE_BORDER)
+    wxFLAGS_MEMBER(wxRAISED_BORDER)
+    wxFLAGS_MEMBER(wxSTATIC_BORDER)
+    wxFLAGS_MEMBER(wxNO_BORDER)
+
+    // standard window styles
+    wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
+    wxFLAGS_MEMBER(wxCLIP_CHILDREN)
+    wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
+    wxFLAGS_MEMBER(wxWANTS_CHARS)
+    wxFLAGS_MEMBER(wxNO_FULL_REPAINT_ON_RESIZE)
+    wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
+    wxFLAGS_MEMBER(wxVSCROLL)
+    wxFLAGS_MEMBER(wxHSCROLL)
+
+    wxFLAGS_MEMBER(wxTE_PROCESS_ENTER)
+    wxFLAGS_MEMBER(wxTE_PROCESS_TAB)
+    wxFLAGS_MEMBER(wxTE_MULTILINE)
+    wxFLAGS_MEMBER(wxTE_PASSWORD)
+    wxFLAGS_MEMBER(wxTE_READONLY)
+    wxFLAGS_MEMBER(wxHSCROLL)
+    wxFLAGS_MEMBER(wxTE_RICH)
+    wxFLAGS_MEMBER(wxTE_RICH2)
+    wxFLAGS_MEMBER(wxTE_AUTO_URL)
+    wxFLAGS_MEMBER(wxTE_NOHIDESEL)
+    wxFLAGS_MEMBER(wxTE_LEFT)
+    wxFLAGS_MEMBER(wxTE_CENTRE)
+    wxFLAGS_MEMBER(wxTE_RIGHT)
+    wxFLAGS_MEMBER(wxTE_DONTWRAP)
+    wxFLAGS_MEMBER(wxTE_LINEWRAP)
+    wxFLAGS_MEMBER(wxTE_WORDWRAP)
+
+wxEND_FLAGS( wxTextCtrlStyle )
+
+IMPLEMENT_DYNAMIC_CLASS_XTI(wxTextCtrl, wxControl,"wx/textctrl.h")
+
+wxBEGIN_PROPERTIES_TABLE(wxTextCtrl)
+    wxEVENT_PROPERTY( TextUpdated , wxEVT_COMMAND_TEXT_UPDATED , wxCommandEvent ) 
+    wxEVENT_PROPERTY( TextEnter , wxEVT_COMMAND_TEXT_ENTER , wxCommandEvent )
+
+    wxPROPERTY( Font , wxFont , SetFont , GetFont  ,, 0 /*flags*/ , wxT("Helpstring") , wxT("group") )
+       wxPROPERTY( Value , wxString , SetValue, GetValue, wxString() , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
+    wxPROPERTY_FLAGS( WindowStyle , wxTextCtrlStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
+wxEND_PROPERTIES_TABLE()
+
+wxBEGIN_HANDLERS_TABLE(wxTextCtrl)
+wxEND_HANDLERS_TABLE()
+
+wxCONSTRUCTOR_6( wxTextCtrl , wxWindow* , Parent , wxWindowID , Id , wxString , Value , wxPoint , Position , wxSize , Size , long , WindowStyle)
+#else
 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
+#endif
+
 
 BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
     EVT_CHAR(wxTextCtrl::OnChar)
@@ -143,6 +212,8 @@ BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
 #ifdef __WIN16__
     EVT_ERASE_BACKGROUND(wxTextCtrl::OnEraseBackground)
 #endif
+
+    EVT_SET_FOCUS(wxTextCtrl::OnSetFocus)
 END_EVENT_TABLE()
 
 // ============================================================================
@@ -161,6 +232,7 @@ void wxTextCtrl::Init()
 
     m_privateContextMenu = NULL;
     m_suppressNextUpdate = FALSE;
+    m_isNativeCaretShown = true;
 }
 
 wxTextCtrl::~wxTextCtrl()
@@ -392,11 +464,12 @@ WXDWORD wxTextCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
         msStyle |= ES_AUTOHSCROLL;
     }
 
-    // styles which we add depending on the specified wxWindows styles
-    if ( style & wxHSCROLL )
+    // note that wxTE_DONTWRAP is the same as wxHSCROLL so if we have a horz
+    // scrollbar, there is no wrapping -- which makes sense
+    if ( style & wxTE_DONTWRAP )
     {
         // automatically scroll the control horizontally as necessary
-        msStyle |= WS_HSCROLL;// | ES_AUTOHSCROLL;
+        msStyle |= WS_HSCROLL;
     }
 
     if ( style & wxTE_READONLY )
@@ -414,7 +487,7 @@ WXDWORD wxTextCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
     else if ( style & wxTE_RIGHT )
         msStyle |= ES_RIGHT;
     else
-        msStyle |= ES_LEFT; // ES_LEFT if 0 as well but for consistency...
+        msStyle |= ES_LEFT; // ES_LEFT is 0 as well but for consistency...
 
     return msStyle;
 }
@@ -464,30 +537,32 @@ wxString wxTextCtrl::GetRange(long from, long to) const
         int len = GetWindowTextLength(GetHwnd());
         if ( len > from )
         {
-            // alloc one extra WORD as needed by the control
-            wxChar *p = str.GetWriteBuf(++len);
+            {
+                // alloc one extra WORD as needed by the control
+                wxStringBuffer tmp(str, ++len);
+                wxChar *p = tmp;
 
-            TEXTRANGE textRange;
-            textRange.chrg.cpMin = from;
-            textRange.chrg.cpMax = to == -1 ? len : to;
-            textRange.lpstrText = p;
+                TEXTRANGE textRange;
+                textRange.chrg.cpMin = from;
+                textRange.chrg.cpMax = to == -1 ? len : to;
+                textRange.lpstrText = p;
 
-            (void)SendMessage(GetHwnd(), EM_GETTEXTRANGE, 0, (LPARAM)&textRange);
+                (void)SendMessage(GetHwnd(), EM_GETTEXTRANGE,
+                                  0, (LPARAM)&textRange);
 
-            if ( m_verRichEdit > 1 )
-            {
-                // RichEdit 2.0 uses just CR ('\r') for the newlines which is
-                // neither Unix nor Windows style - convert it to something
-                // reasonable
-                for ( ; *p; p++ )
+                if ( m_verRichEdit > 1 )
                 {
-                    if ( *p == _T('\r') )
-                        *p = _T('\n');
+                    // RichEdit 2.0 uses just CR ('\r') for the
+                    // newlines which is neither Unix nor Windows
+                    // style - convert it to something reasonable
+                    for ( ; *p; p++ )
+                    {
+                        if ( *p == _T('\r') )
+                            *p = _T('\n');
+                    }
                 }
             }
 
-            str.UngetWriteBuf();
-
             if ( m_verRichEdit == 1 )
             {
                 // convert to the canonical form - see comment below
@@ -527,6 +602,11 @@ void wxTextCtrl::SetValue(const wxString& value)
     {
         DoWriteText(value, FALSE /* not selection only */);
     }
+    else // same text
+    {
+        // still send an event for consistency
+        SendUpdateEvent();
+    }
 
     // we should reset the modified flag even if the value didn't really change
 
@@ -1192,13 +1272,36 @@ wxString wxTextCtrl::GetLineText(long lineNo) const
     len += sizeof(WORD);
 
     wxString str;
-    wxChar *buf = str.GetWriteBuf(len);
+    {
+        wxStringBufferLength tmp(str, len);
+        wxChar *buf = tmp;
+
+        *(WORD *)buf = (WORD)len;
+        len = (size_t)::SendMessage(GetHwnd(), EM_GETLINE, lineNo, (LPARAM)buf);
+
+#if wxUSE_RICHEDIT
+        if ( IsRich() )
+        {
+            // remove the '\r' returned by the rich edit control, the user code
+            // should never see it
+            if ( buf[len - 2] == _T('\r') && buf[len - 1] == _T('\n') )
+            {
+                buf[len - 2] = _T('\n');
+                len--;
+            }
+        }
+#endif // wxUSE_RICHEDIT
 
-    *(WORD *)buf = (WORD)len;
-    len = (size_t)::SendMessage(GetHwnd(), EM_GETLINE, lineNo, (LPARAM)buf);
-    buf[len] = 0;
+        // remove the '\n' at the end, if any (this is how this function is
+        // supposed to work according to the docs)
+        if ( buf[len - 1] == _T('\n') )
+        {
+            len--;
+        }
 
-    str.UngetWriteBuf(len);
+        buf[len] = 0;
+        tmp.SetLength(len);
+    }
 
     return str;
 }
@@ -1239,6 +1342,27 @@ bool wxTextCtrl::CanRedo() const
     return ::SendMessage(GetHwnd(), EM_CANUNDO, 0, 0) != 0;
 }
 
+// ----------------------------------------------------------------------------
+// caret handling (Windows only)
+// ----------------------------------------------------------------------------
+
+bool wxTextCtrl::ShowNativeCaret(bool show)
+{
+    if ( show != m_isNativeCaretShown )
+    {
+        if ( !(show ? ::ShowCaret(GetHwnd()) : ::HideCaret(GetHwnd())) )
+        {
+            // not an error, may simply indicate that it's not shown/hidden
+            // yet (i.e. it had been hidden/showh 2 times before)
+            return false;
+        }
+
+        m_isNativeCaretShown = show;
+    }
+
+    return true;
+}
+
 // ----------------------------------------------------------------------------
 // implemenation details
 // ----------------------------------------------------------------------------
@@ -1634,7 +1758,7 @@ void wxTextCtrl::OnRedo(wxCommandEvent& WXUNUSED(event))
     Redo();
 }
 
-void wxTextCtrl::OnDelete(wxCommandEvent& event)
+void wxTextCtrl::OnDelete(wxCommandEvent& WXUNUSED(event))
 {
     long from, to;
     GetSelection(& from, & to);
@@ -1642,7 +1766,7 @@ void wxTextCtrl::OnDelete(wxCommandEvent& event)
         Remove(from, to);
 }
 
-void wxTextCtrl::OnSelectAll(wxCommandEvent& event)
+void wxTextCtrl::OnSelectAll(wxCommandEvent& WXUNUSED(event))
 {
     SetSelection(-1, -1);
 }
@@ -1710,6 +1834,15 @@ void wxTextCtrl::OnRightClick(wxMouseEvent& event)
     event.Skip();
 }
 
+void wxTextCtrl::OnSetFocus(wxFocusEvent& WXUNUSED(event))
+{
+    // be sure the caret remains invisible if the user had hidden it
+    if ( !m_isNativeCaretShown )
+    {
+        ::HideCaret(GetHwnd());
+    }
+}
+
 // the rest of the file only deals with the rich edit controls
 #if wxUSE_RICHEDIT
 
@@ -1805,7 +1938,7 @@ bool wxTextCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
             }
             return TRUE;
     }
-    
+
     // not processed, leave it to the base class
     return wxTextCtrlBase::MSWOnNotify(idCtrl, lParam, result);
 }
@@ -2233,6 +2366,7 @@ void wxRichEditModule::OnExit()
         if ( ms_hRichEdit[i] )
         {
             ::FreeLibrary(ms_hRichEdit[i]);
+            ms_hRichEdit[i] = NULL;
         }
     }
 }