X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/11d6793f15854403a536dc5bd08dba75b4697a3a..a738f87caeafd5e51fc029a6228c540e942505b7:/src/msw/textctrl.cpp diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 32c83c9b9b..974fa7a30d 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -37,6 +37,7 @@ #include "wx/menu.h" #include "wx/math.h" #include "wx/module.h" + #include "wx/wxcrtvararg.h" #endif #include "wx/sysopt.h" @@ -263,50 +264,10 @@ BEGIN_EVENT_TABLE(wxTextCtrl, wxTextCtrlBase) 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 // ---------------------------------------------------------------------------- @@ -331,7 +292,8 @@ wxTextCtrl::~wxTextCtrl() delete m_privateContextMenu; } -bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, +bool wxTextCtrl::Create(wxWindow *parent, + wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, @@ -339,15 +301,31 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, const wxValidator& validator, const wxString& name) { -#ifdef __WXWINCE__ - if ((style & wxBORDER_MASK) == 0) - style |= wxBORDER_SIMPLE; -#endif - // base initialization if ( !CreateControl(parent, id, pos, size, style, validator, name) ) return false; + if ( !MSWCreateText(value, pos, size) ) + return false; + + return true; +} + +// returns true if the platform should explicitly apply a theme border +bool wxTextCtrl::CanApplyThemeBorder() const +{ +#ifdef __WXWINCE__ + return false; +#else + // Standard text control already handles theming + return ((GetWindowStyle() & (wxTE_RICH|wxTE_RICH2)) != 0); +#endif +} + +bool wxTextCtrl::MSWCreateText(const wxString& value, + const wxPoint& pos, + const wxSize& size) +{ // translate wxWin style flags to MSW ones WXDWORD msStyle = MSWGetCreateWindowFlags(); @@ -356,7 +334,7 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, #if defined(__POCKETPC__) || defined(__SMARTPHONE__) // A control that capitalizes the first letter - if (style & wxTE_CAPITALIZE) + if ( HasFlag(wxTE_CAPITALIZE) ) windowClass = wxT("CAPEDIT"); #endif @@ -474,7 +452,7 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, valueWin = value; } - if ( !MSWCreateControl(windowClass, msStyle, pos, size, valueWin) ) + if ( !MSWCreateControl(windowClass.wx_str(), msStyle, pos, size, valueWin) ) return false; #if wxUSE_RICHEDIT @@ -511,7 +489,7 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, // Windows XP, so if we're sure it works correctly under other // systems we could do this only for XP SetSize(-1, 1); // 1 is small enough to force vert scrollbar - SetSize(size); + SetInitialSize(size); } else if ( m_windowStyle & wxTE_AUTO_URL ) { @@ -524,9 +502,6 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, } #endif // wxUSE_RICHEDIT - gs_wndprocEdit = wxSetWindowProc((HWND)GetHwnd(), - wxTextCtrlWndProc); - return true; } @@ -640,6 +615,62 @@ WXDWORD wxTextCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const void wxTextCtrl::SetWindowStyleFlag(long style) { + // changing the alignment of the control dynamically works under Win2003 + // (but not older Windows version: it seems to work under some versions of + // XP but not other ones, and we have no way to determine it so be + // conservative here) and only for plain EDIT controls (not RICH ones) and + // we have to recreate the control to make it always work + if ( IsRich() || wxGetWinVersion() < wxWinVersion_2003 ) + { + const long alignMask = wxTE_LEFT | wxTE_CENTRE | wxTE_RIGHT; + if ( (style & alignMask) != (GetWindowStyle() & alignMask) ) + { + const wxString value = GetValue(); + const wxPoint pos = GetPosition(); + const wxSize size = GetSize(); + + // delete the old window + HWND hwnd = GetHwnd(); + DissociateHandle(); + ::DestroyWindow(hwnd); + + // create the new one with the updated flags + m_windowStyle = style; + MSWCreateText(value, pos, size); + + // and make sure it has the same attributes as before + if ( m_hasFont ) + { + // calling SetFont(m_font) would do nothing as the code would + // notice that the font didn't change, so force it to believe + // that it did + wxFont font = m_font; + m_font = wxNullFont; + SetFont(font); + } + + if ( m_hasFgCol ) + { + wxColour colFg = m_foregroundColour; + m_foregroundColour = wxNullColour; + SetForegroundColour(colFg); + } + + if ( m_hasBgCol ) + { + wxColour colBg = m_backgroundColour; + m_backgroundColour = wxNullColour; + SetBackgroundColour(colBg); + } + + // note that text styles are lost but this is probably not a big + // problem: if you use styles, you probably don't use nor change + // alignment flags anyhow + + return; + } + } + #if wxUSE_RICHEDIT // we have to deal with some styles separately because they can't be // changed by simply calling SetWindowLong(GWL_STYLE) but can be changed @@ -902,7 +933,7 @@ wxTextCtrl::StreamIn(const wxString& value, #else // !wxUSE_UNICODE_MSLU wxCSConv conv(encoding); - const size_t len = conv.MB2WC(NULL, value, value.length()); + const size_t len = conv.MB2WC(NULL, value.mb_str(), value.length()); #if wxUSE_WCHAR_T wxWCharBuffer wchBuf(len); @@ -912,7 +943,7 @@ wxTextCtrl::StreamIn(const wxString& value, wchar_t *wpc = wchBuf; #endif - conv.MB2WC(wpc, value, value.length()); + conv.MB2WC(wpc, value.mb_str(), value.length()); #endif // wxUSE_UNICODE_MSLU // finally, stream it in the control @@ -1091,7 +1122,7 @@ void wxTextCtrl::DoWriteText(const wxString& value, int flags) ::SendMessage(GetHwnd(), selectionOnly ? EM_REPLACESEL : WM_SETTEXT, // EM_REPLACESEL takes 1 to indicate the operation should be redoable - selectionOnly ? 1 : 0, (LPARAM)valueDos.c_str()); + selectionOnly ? 1 : 0, (LPARAM)valueDos.wx_str()); if ( !ucf.GotUpdate() && (flags & SetValue_SendEvent) ) { @@ -1923,41 +1954,53 @@ WXLRESULT wxTextCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPara { WXLRESULT lRc = wxTextCtrlBase::MSWWindowProc(nMsg, wParam, lParam); - if ( nMsg == WM_GETDLGCODE ) + switch ( nMsg ) { - // we always want the chars and the arrows: the arrows for navigation - // and the chars because we want Ctrl-C to work even in a read only - // control - long lDlgCode = DLGC_WANTCHARS | DLGC_WANTARROWS; + case WM_GETDLGCODE: + { + // we always want the chars and the arrows: the arrows for + // navigation and the chars because we want Ctrl-C to work even + // in a read only control + long lDlgCode = DLGC_WANTCHARS | DLGC_WANTARROWS; - if ( IsEditable() ) - { - // we may have several different cases: - // 1. normal case: both TAB and ENTER are used for dlg navigation - // 2. ctrl which wants TAB for itself: ENTER is used to pass to the - // next control in the dialog - // 3. ctrl which wants ENTER for itself: TAB is used for dialog - // navigation - // 4. ctrl which wants both TAB and ENTER: Ctrl-ENTER is used to go - // to the next control - - // the multiline edit control should always get for itself - if ( HasFlag(wxTE_PROCESS_ENTER) || HasFlag(wxTE_MULTILINE) ) - lDlgCode |= DLGC_WANTMESSAGE; - - if ( HasFlag(wxTE_PROCESS_TAB) ) - lDlgCode |= DLGC_WANTTAB; - - lRc |= lDlgCode; - } - else // !editable - { - // NB: use "=", not "|=" as the base class version returns the - // same flags is this state as usual (i.e. including - // DLGC_WANTMESSAGE). This is strange (how does it work in the - // native Win32 apps?) but for now live with it. - lRc = lDlgCode; - } + if ( IsEditable() ) + { + // we may have several different cases: + // 1. normal: both TAB and ENTER are used for navigation + // 2. ctrl wants TAB for itself: ENTER is used to pass to + // the next control in the dialog + // 3. ctrl wants ENTER for itself: TAB is used for dialog + // navigation + // 4. ctrl wants both TAB and ENTER: Ctrl-ENTER is used to + // go to the next control (we need some way to do it) + + // multiline controls should always get ENTER for themselves + if ( HasFlag(wxTE_PROCESS_ENTER) || HasFlag(wxTE_MULTILINE) ) + lDlgCode |= DLGC_WANTMESSAGE; + + if ( HasFlag(wxTE_PROCESS_TAB) ) + lDlgCode |= DLGC_WANTTAB; + + lRc |= lDlgCode; + } + else // !editable + { + // NB: use "=", not "|=" as the base class version returns + // the same flags is this state as usual (i.e. + // including DLGC_WANTMESSAGE). This is strange (how + // does it work in the native Win32 apps?) but for now + // live with it. + lRc = lDlgCode; + } + } + break; + + case WM_CUT: + case WM_COPY: + case WM_PASTE: + if ( HandleClipboardEvent(nMsg) ) + lRc = 0; + break; } return lRc;