if ( parent )
parent->AddChild(this);
- // translate wxWin style flags to MSW ones, checking for consistency while
- // doing it
- long msStyle = ES_LEFT | WS_TABSTOP;
-
- if ( m_windowStyle & wxCLIP_SIBLINGS )
- msStyle |= WS_CLIPSIBLINGS;
-
- if ( m_windowStyle & wxTE_MULTILINE )
- {
- wxASSERT_MSG( !(m_windowStyle & wxTE_PROCESS_ENTER),
- wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
-
- msStyle |= ES_MULTILINE | ES_WANTRETURN;
- if ((m_windowStyle & wxTE_NO_VSCROLL) == 0)
- msStyle |= WS_VSCROLL;
- m_windowStyle |= wxTE_PROCESS_ENTER;
- }
- else // !multiline
- {
- // there is really no reason to not have this style for single line
- // text controls
- msStyle |= ES_AUTOHSCROLL;
- }
-
- if ( m_windowStyle & wxHSCROLL )
- msStyle |= WS_HSCROLL | ES_AUTOHSCROLL;
-
- if ( m_windowStyle & wxTE_READONLY )
- msStyle |= ES_READONLY;
-
- if ( m_windowStyle & wxTE_PASSWORD )
- msStyle |= ES_PASSWORD;
-
- if ( m_windowStyle & wxTE_AUTO_SCROLL )
- msStyle |= ES_AUTOHSCROLL;
-
- if ( m_windowStyle & wxTE_NOHIDESEL )
- msStyle |= ES_NOHIDESEL;
-
- // we always want the characters and the arrows
- m_lDlgCode = DLGC_WANTCHARS | DLGC_WANTARROWS;
-
- // we may have several different cases:
- // 1. normal case: both TAB and ENTER are used for dialog 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 pass to
- // the next control
- if ( m_windowStyle & wxTE_PROCESS_ENTER )
- m_lDlgCode |= DLGC_WANTMESSAGE;
- if ( m_windowStyle & wxTE_PROCESS_TAB )
- m_lDlgCode |= DLGC_WANTTAB;
+ // translate wxWin style flags to MSW ones
+ WXDWORD msStyle = MSWGetCreateWindowFlags();
// do create the control - either an EDIT or RICHEDIT
wxString windowClass = wxT("EDIT");
m_windowStyle |= wxTE_PROCESS_ENTER;
}
+WXDWORD wxTextCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
+{
+ // default border for the text controls is the sunken one
+ if ( (style & wxBORDER_MASK) == wxBORDER_DEFAULT )
+ {
+ style |= wxBORDER_SUNKEN;
+ }
+
+ long msStyle = wxControl::MSWGetStyle(style, exstyle);
+
+ // default styles
+ msStyle |= ES_LEFT;
+
+ if ( style & wxTE_MULTILINE )
+ {
+ wxASSERT_MSG( !(style & wxTE_PROCESS_ENTER),
+ wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
+
+ msStyle |= ES_MULTILINE | ES_WANTRETURN;
+ if ( !(style & wxTE_NO_VSCROLL) )
+ msStyle |= WS_VSCROLL;
+
+ style |= wxTE_PROCESS_ENTER;
+ }
+ else // !multiline
+ {
+ // there is really no reason to not have this style for single line
+ // text controls
+ msStyle |= ES_AUTOHSCROLL;
+ }
+
+ if ( style & wxHSCROLL )
+ msStyle |= WS_HSCROLL | ES_AUTOHSCROLL;
+
+ if ( style & wxTE_READONLY )
+ msStyle |= ES_READONLY;
+
+ if ( style & wxTE_PASSWORD )
+ msStyle |= ES_PASSWORD;
+
+ if ( style & wxTE_AUTO_SCROLL )
+ msStyle |= ES_AUTOHSCROLL;
+
+ if ( style & wxTE_NOHIDESEL )
+ msStyle |= ES_NOHIDESEL;
+
+ return msStyle;
+}
+
+void wxTextCtrl::SetWindowStyleFlag(long style)
+{
+#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
+ // using richedit-specific EM_SETOPTIONS
+ if ( IsRich() &&
+ ((style & wxTE_NOHIDESEL) != (GetWindowStyle() & wxTE_NOHIDESEL)) )
+ {
+ bool set = (style & wxTE_NOHIDESEL) != 0;
+
+ ::SendMessage(GetHwnd(), EM_SETOPTIONS, set ? ECOOP_OR : ECOOP_AND,
+ set ? ECO_NOHIDESEL : ~ECO_NOHIDESEL);
+ }
+#endif // wxUSE_RICHEDIT
+
+ wxControl::SetWindowStyleFlag(style);
+}
+
// ----------------------------------------------------------------------------
// set/get the controls text
// ----------------------------------------------------------------------------
// edit controls mostly)
if ( (value.length() > 0x400) || (value != GetValue()) )
{
- // it is simpler to do this but it could be more efficient to reproduce
- // WriteText() logic here
- Clear();
-
- WriteText(value);
+ DoWriteText(value, FALSE /* not selection only */);
// mark the control as being not dirty - we changed its text, not the
// user
return 0;
}
-extern long wxEncodingToCodepage(wxFontEncoding encoding); // from strconv.cpp
+extern long wxEncodingToCodepage(wxFontEncoding encoding); // from utils.cpp
#if wxUSE_UNICODE_MSLU
-bool wxTextCtrl::StreamIn(const wxString& value, wxFontEncoding WXUNUSED(encoding))
+bool wxTextCtrl::StreamIn(const wxString& value,
+ wxFontEncoding WXUNUSED(encoding),
+ bool selectionOnly)
{
const wchar_t *wpc = value.c_str();
-#else
-bool wxTextCtrl::StreamIn(const wxString& value, wxFontEncoding encoding)
+#else // !wxUSE_UNICODE_MSLU
+bool wxTextCtrl::StreamIn(const wxString& value,
+ wxFontEncoding encoding,
+ bool selectionOnly)
{
// we have to use EM_STREAMIN to force richedit control 2.0+ to show any
// text in the non default charset - otherwise it thinks it knows better
// next translate to Unicode using this code page
int len = ::MultiByteToWideChar(codepage, 0, value, -1, NULL, 0);
+
+#if wxUSE_WCHAR_T
wxWCharBuffer wchBuf(len);
+#else
+ wchar_t *wchBuf = (wchar_t *)malloc((len + 1)*sizeof(wchar_t));
+#endif
+
if ( !::MultiByteToWideChar(codepage, 0, value, -1,
- (wchar_t *)wchBuf.data(), len) )
+ (wchar_t *)(const wchar_t *)wchBuf, len) )
{
wxLogLastError(_T("MultiByteToWideChar"));
}
eds.pfnCallback = (EDITSTREAMCALLBACK)wxRichEditStreamIn;
if ( !::SendMessage(GetHwnd(), EM_STREAMIN,
- SF_TEXT | SF_UNICODE | SFF_SELECTION,
+ SF_TEXT |
+ SF_UNICODE |
+ (selectionOnly ? SFF_SELECTION : 0),
(LPARAM)&eds) || eds.dwError )
{
wxLogLastError(_T("EM_STREAMIN"));
-
- return FALSE;
}
+#if !wxUSE_WCHAR_T
+ free(wchBuf);
+#endif // !wxUSE_WCHAR_T
+
return TRUE;
}
#endif // wxUSE_RICHEDIT
void wxTextCtrl::WriteText(const wxString& value)
+{
+ DoWriteText(value);
+}
+
+void wxTextCtrl::DoWriteText(const wxString& value, bool selectionOnly)
{
wxString valueDos;
if ( m_windowStyle & wxTE_MULTILINE )
#if wxUSE_UNICODE_MSLU
// RichEdit doesn't have Unicode version of EM_REPLACESEL on Win9x,
// but EM_STREAMIN works
- if ( wxGetOsVersion() == wxWIN95 && GetRichVersion() > 1 )
+ if ( wxUsingUnicowsDll() && GetRichVersion() > 1 )
{
- done = StreamIn(valueDos, wxFONTENCODING_SYSTEM);
+ done = StreamIn(valueDos, wxFONTENCODING_SYSTEM, selectionOnly);
}
#endif // wxUSE_UNICODE_MSLU
wxFontEncoding encoding = font.GetEncoding();
if ( encoding != wxFONTENCODING_SYSTEM )
{
- done = StreamIn(valueDos, encoding);
+ done = StreamIn(valueDos, encoding, selectionOnly);
}
}
}
if ( !done )
#endif // wxUSE_RICHEDIT
{
+ if ( !selectionOnly )
+ {
+ SetSelection(-1, -1);
+ }
+
::SendMessage(GetHwnd(), EM_REPLACESEL, 0, (LPARAM)valueDos.c_str());
}
::SetWindowText(GetHwnd(), wxT(""));
}
+#ifdef __WIN32__
+
+bool wxTextCtrl::EmulateKeyPress(const wxKeyEvent& event)
+{
+ SetFocus();
+
+ size_t lenOld = GetValue().length();
+
+ wxUint32 code = event.GetRawKeyCode();
+ ::keybd_event(code, 0, 0 /* key press */, 0);
+ ::keybd_event(code, 0, KEYEVENTF_KEYUP, 0);
+
+ // assume that any alphanumeric key changes the total number of characters
+ // in the control - this should work in 99% of cases
+ return GetValue().length() != lenOld;
+}
+
+#endif // __WIN32__
+
// ----------------------------------------------------------------------------
// Clipboard operations
// ----------------------------------------------------------------------------
bool wxTextCtrl::IsEditable() const
{
+ // strangely enough, we may be called before the control is created: our
+ // own Create() calls MSWGetStyle() which calls AcceptsFocus() which calls
+ // us
+ if ( !m_hWnd )
+ return TRUE;
+
long style = ::GetWindowLong(GetHwnd(), GWL_STYLE);
return (style & ES_READONLY) == 0;
// usual preprocessing for them
if ( msg->message == WM_KEYDOWN )
{
- WORD vkey = msg->wParam;
+ WORD vkey = (WORD) msg->wParam;
if ( (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN )
{
if ( vkey == VK_BACK )
event.Skip();
}
+long wxTextCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+{
+ long lRc = wxTextCtrlBase::MSWWindowProc(nMsg, wParam, lParam);
+
+ if ( nMsg == WM_GETDLGCODE )
+ {
+ // we always want the chars and the arrows
+ long lDlgCode = DLGC_WANTCHARS | DLGC_WANTARROWS;
+
+ // we may have several different cases:
+ // 1. normal case: both TAB and ENTER are used for dialog 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 pass
+ // to the next control
+
+ // the multiline edit control should always get <Return> for itself
+ if ( HasFlag(wxTE_PROCESS_ENTER) || HasFlag(wxTE_MULTILINE) )
+ lDlgCode |= DLGC_WANTMESSAGE;
+
+ if ( HasFlag(wxTE_PROCESS_TAB) )
+ lDlgCode |= DLGC_WANTTAB;
+
+ lRc |= lDlgCode;
+ }
+
+ return lRc;
+}
+
+// ----------------------------------------------------------------------------
+// text control event processing
+// ----------------------------------------------------------------------------
+
bool wxTextCtrl::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
{
switch (param)
// EN_LINK processing
// ----------------------------------------------------------------------------
-bool wxTextCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
+bool wxTextCtrl::MSWOnNotify(int WXUNUSED(idCtrl), WXLPARAM lParam, WXLPARAM *result)
{
NMHDR *hdr = (NMHDR* )lParam;
if ( hdr->code == EN_LINK )
::SetCursor(GetHcursorOf(wxCursor(wxCURSOR_HAND)));
*result = TRUE;
break;
-
case WM_MOUSEMOVE:
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
void wxRichEditModule::OnExit()
{
- for ( int i = 0; i < WXSIZEOF(ms_hRichEdit); i++ )
+ for ( size_t i = 0; i < WXSIZEOF(ms_hRichEdit); i++ )
{
if ( ms_hRichEdit[i] )
{
// make it the index in the array
version--;
- if ( ms_hRichEdit[version] )
- {
- // we've already got this one
- return TRUE;
- }
-
if ( ms_hRichEdit[version] == (HINSTANCE)-1 )
{
// we had already tried to load it and failed
return FALSE;
}
+ if ( ms_hRichEdit[version] )
+ {
+ // we've already got this one
+ return TRUE;
+ }
+
wxString dllname = version ? _T("riched20") : _T("riched32");
dllname += _T(".dll");