X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9dea36ef6d117e0562f0079345a77ff1696d3a49..404b319a85dadd7decf7a5a5331020520031a41c:/src/os2/textctrl.cpp diff --git a/src/os2/textctrl.cpp b/src/os2/textctrl.cpp index 2c23d29d1d..3be381a95f 100644 --- a/src/os2/textctrl.cpp +++ b/src/os2/textctrl.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: textctrl.cpp +// Name: src/os2/textctrl.cpp // Purpose: wxTextCtrl // Author: David Webster // Modified by: @@ -16,16 +16,18 @@ // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" +#include "wx/textctrl.h" + #ifndef WX_PRECOMP - #include "wx/textctrl.h" + #include "wx/scrolwin.h" #include "wx/settings.h" #include "wx/brush.h" #include "wx/utils.h" #include "wx/log.h" + #include "wx/app.h" #endif #if wxUSE_CLIPBOARD - #include "wx/app.h" #include "wx/clipbrd.h" #endif @@ -43,15 +45,17 @@ # include #endif -#if !USE_SHARED_LIBRARY +#if !defined(MLE_INDEX) +#define MLE_INDEX 0 +#define MLE_RGB 1 +#endif + // ---------------------------------------------------------------------------- // event tables and other macros // ---------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl) - -BEGIN_EVENT_TABLE(wxTextCtrl, wxControl) +BEGIN_EVENT_TABLE(wxTextCtrl, wxTextCtrlBase) EVT_CHAR(wxTextCtrl::OnChar) EVT_DROP_FILES(wxTextCtrl::OnDropFiles) @@ -68,7 +72,6 @@ BEGIN_EVENT_TABLE(wxTextCtrl, wxControl) EVT_UPDATE_UI(wxID_REDO, wxTextCtrl::OnUpdateRedo) END_EVENT_TABLE() -#endif // USE_SHARED_LIBRARY // ============================================================================ // implementation @@ -82,144 +85,240 @@ wxTextCtrl::wxTextCtrl() { } -bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, - const wxString& value, - const wxPoint& pos, - const wxSize& size, - long style, -#if wxUSE_VALIDATORS - const wxValidator& validator, -#endif - const wxString& name) +wxTextCtrl::~wxTextCtrl() { - // base initialization - if ( !CreateBase(parent, id, pos, size, style, validator, name) ) - return FALSE; +} - // Validator was set in CreateBase - //SetValidator(validator); - if ( parent ) - parent->AddChild(this); +bool wxTextCtrl::Create( + wxWindow* pParent +, wxWindowID vId +, const wxString& rsValue +, const wxPoint& rPos +, const wxSize& rSize +, long lStyle +, const wxValidator& rValidator +, const wxString& rsName +) +{ + // + // Base initialization + // + if ( !CreateBase( pParent + ,vId + ,rPos + ,rSize + ,lStyle + ,rValidator + ,rsName + )) + return false; + + wxPoint vPos = rPos; // The OS/2 position + SWP vSwp; + + if (pParent ) + { + pParent->AddChild(this); + } - // set colours - SetupColours(); + m_windowStyle = lStyle; + m_bIsMLE = false; + m_bSkipUpdate = false; + + long lSstyle = WS_VISIBLE | WS_TABSTOP; - // translate wxWin style flags to MSW ones, checking for consistency while - // doing it -// TODO: -/* - long msStyle = ES_LEFT | WS_VISIBLE | WS_CHILD | WS_TABSTOP; + // + // Single and multiline edit fields are two different controls in PM + // 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)") ); + lSstyle |= MLS_BORDER | MLS_WORDWRAP; + m_bIsMLE = true; - msStyle |= ES_MULTILINE | ES_WANTRETURN; if ((m_windowStyle & wxTE_NO_VSCROLL) == 0) - msStyle |= WS_VSCROLL; - m_windowStyle |= wxTE_PROCESS_ENTER; + lSstyle |= MLS_VSCROLL; + if (m_windowStyle & wxHSCROLL) + lSstyle |= MLS_HSCROLL; + if (m_windowStyle & wxTE_READONLY) + lSstyle |= MLS_READONLY; } else - msStyle |= ES_AUTOHSCROLL; - - if (m_windowStyle & wxHSCROLL) - msStyle |= (WS_HSCROLL | ES_AUTOHSCROLL); - - if (m_windowStyle & wxTE_READONLY) - msStyle |= ES_READONLY; - - if (m_windowStyle & wxHSCROLL) - msStyle |= (WS_HSCROLL | ES_AUTOHSCROLL); - if (m_windowStyle & wxTE_PASSWORD) // hidden input - msStyle |= ES_PASSWORD; - - // 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; - - // do create the control - either an EDIT or RICHEDIT - const wxChar *windowClass = wxT("EDIT"); - - bool want3D; - WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D); - - // Even with extended styles, need to combine with WS_BORDER for them to - // look right. - if ( want3D || wxStyleHasBorder(m_windowStyle) ) - msStyle |= WS_BORDER; - - // NB: don't use pos and size as CreateWindowEx arguments because they - // might be -1 in which case we should use the default values (and - // SetSize called below takes care of it) - m_hWnd = (WXHWND)::CreateWindowEx(exStyle, - windowClass, - NULL, - msStyle, - 0, 0, 0, 0, - GetHwndOf(parent), - (HMENU)m_windowId, - wxGetInstance(), - NULL); - - wxCHECK_MSG( m_hWnd, FALSE, wxT("Failed to create text ctrl") ); -*/ - SubclassWin(GetHWND()); + { + lSstyle |= ES_LEFT | ES_AUTOSCROLL | ES_MARGIN; + + if (m_windowStyle & wxHSCROLL) + lSstyle |= ES_AUTOSCROLL; + if (m_windowStyle & wxTE_READONLY) + lSstyle |= ES_READONLY; + if (m_windowStyle & wxTE_PASSWORD) // hidden input + lSstyle |= ES_UNREADABLE; + } - // set font, position, size and initial value - wxFont& fontParent = parent->GetFont(); - if ( fontParent.Ok() ) + if (m_bIsMLE) { - SetFont(fontParent); + m_hWnd = (WXHWND)::WinCreateWindow( (HWND)GetHwndOf(pParent) // Parent window handle + ,WC_MLE // Window class + ,rsValue.c_str() // Initial Text + ,(ULONG)lSstyle // Style flags + ,(LONG)0 // X pos of origin + ,(LONG)0 // Y pos of origin + ,(LONG)0 // field width + ,(LONG)0 // field height + ,(HWND)GetHwndOf(pParent) // owner window handle (same as parent + ,HWND_TOP // initial z position + ,(ULONG)vId // Window identifier + ,NULL // no control data + ,NULL // no Presentation parameters + ); } else { - SetFont(wxSystemSettings::GetSystemFont(wxSYS_SYSTEM_FONT)); + m_hWnd = (WXHWND)::WinCreateWindow( (HWND)GetHwndOf(pParent) // Parent window handle + ,WC_ENTRYFIELD // Window class + ,rsValue.c_str() // Initial Text + ,(ULONG)lSstyle // Style flags + ,(LONG)0 // X pos of origin + ,(LONG)0 // Y pos of origin + ,(LONG)0 // field width + ,(LONG)0 // field height + ,(HWND)GetHwndOf(pParent) // owner window handle (same as parent + ,HWND_TOP // initial z position + ,(ULONG)vId // Window identifier + ,NULL // no control data + ,NULL // no Presentation parameters + ); } - SetSize(pos.x, pos.y, size.x, size.y); + if (m_hWnd == 0) + { + return false; + } - return TRUE; -} + SubclassWin(GetHWND()); + // + // Set font, position, size and initial value + // + wxFont* pTextFont = new wxFont( 8 + ,wxMODERN + ,wxNORMAL + ,wxNORMAL + ); + SetFont(*pTextFont); + if (!rsValue.empty()) + { + SetValue(rsValue); + } + SetupColours(); + // + // If X and/or Y are not zero the difference is the compensation value + // for margins for OS/2 controls. + // + ::WinQueryWindowPos(m_hWnd, &vSwp); + SetXComp(vSwp.x); + SetYComp(vSwp.y); + SetSize( vPos.x - GetXComp() + ,vPos.y - GetYComp() + ,rSize.x + ,rSize.y + ); + delete pTextFont; + return true; +} // end of wxTextCtrl::Create + +// // Make sure the window style (etc.) reflects the HWND style (roughly) +// void wxTextCtrl::AdoptAttributesFromHWND() { - wxWindow::AdoptAttributesFromHWND(); - - HWND hWnd = GetHwnd(); - // TODO: - /* - long style = GetWindowLong(hWnd, GWL_STYLE); - - if (style & ES_MULTILINE) - m_windowStyle |= wxTE_MULTILINE; - if (style & ES_PASSWORD) - m_windowStyle |= wxTE_PASSWORD; - if (style & ES_READONLY) - m_windowStyle |= wxTE_READONLY; - if (style & ES_WANTRETURN) - m_windowStyle |= wxTE_PROCESS_ENTER; - */ -} + HWND hWnd = GetHwnd(); + LONG lStyle = ::WinQueryWindowULong(hWnd, QWL_STYLE); + + wxWindow::AdoptAttributesFromHWND(); + + if (m_bIsMLE) + { + m_windowStyle |= wxTE_MULTILINE; + if (lStyle & MLS_READONLY) + m_windowStyle |= wxTE_READONLY; + } + else + { + if (lStyle & ES_UNREADABLE) + m_windowStyle |= wxTE_PASSWORD; + if (lStyle & ES_READONLY) + m_windowStyle |= wxTE_READONLY; + } +} // end of wxTextCtrl::AdoptAttributesFromHWND + +WXDWORD wxTextCtrl::OS2GetStyle( + long lStyle +, WXDWORD* pdwExstyle +) const +{ + // + // Default border for the text controls is the sunken one + // + if ((lStyle & wxBORDER_MASK) == wxBORDER_DEFAULT ) + { + lStyle |= wxBORDER_SUNKEN; + } + + long dwStyle = wxControl::OS2GetStyle( lStyle + ,pdwExstyle + ); + + dwStyle = WS_VISIBLE | WS_TABSTOP; + + // + // Single and multiline edit fields are two different controls in PM + // + if ( m_windowStyle & wxTE_MULTILINE ) + { + dwStyle |= MLS_BORDER | MLS_WORDWRAP; + if ((m_windowStyle & wxTE_NO_VSCROLL) == 0) + dwStyle |= MLS_VSCROLL; + if (m_windowStyle & wxHSCROLL) + dwStyle |= MLS_HSCROLL; + if (m_windowStyle & wxTE_READONLY) + dwStyle |= MLS_READONLY; + } + else + { + dwStyle |= ES_LEFT | ES_AUTOSCROLL | ES_MARGIN; + if (m_windowStyle & wxHSCROLL) + dwStyle |= ES_AUTOSCROLL; + if (m_windowStyle & wxTE_READONLY) + dwStyle |= ES_READONLY; + if (m_windowStyle & wxTE_PASSWORD) // hidden input + dwStyle |= ES_UNREADABLE; + } + return dwStyle; +} // end of wxTextCtrl::OS2GetStyle + +void wxTextCtrl::SetWindowStyleFlag( + long lStyle +) +{ + wxControl::SetWindowStyleFlag(lStyle); +} // end of wxTextCtrl::SetWindowStyleFlag void wxTextCtrl::SetupColours() { - // FIXME why is bg colour not inherited from parent? - SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW)); + wxColour vBkgndColour; + + vBkgndColour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + SetBackgroundColour(vBkgndColour); SetForegroundColour(GetParent()->GetForegroundColour()); -} + if (m_bIsMLE) + { + ::WinSendMsg( GetHwnd() + ,MLM_SETTEXTCOLOR + ,(MPARAM)GetParent()->GetForegroundColour().GetPixel() + ,(MPARAM)MLE_RGB + ); + } +} // end of wxTextCtrl::SetupColours // ---------------------------------------------------------------------------- // set/get the controls text @@ -227,46 +326,75 @@ void wxTextCtrl::SetupColours() wxString wxTextCtrl::GetValue() const { - return wxGetWindowText(GetHWND()); -} - -void wxTextCtrl::SetValue(const wxString& value) -{ -// TODO: -/* - wxString valueDos = wxTextFile::Translate(value, wxTextFileType_Dos); - - SetWindowText(GetHwnd(), valueDos); + wxString sStr = wxGetWindowText(GetHWND()); + wxCharBuffer buf(sStr.char_str()); + char* zStr = buf.data(); - AdjustSpaceLimit(); -*/ -} + for ( ; *zStr; zStr++ ) + { + // + // this will replace \r\n with just \n + // + if (*zStr == '\n') + *zStr = '\0'; + if (*zStr == '\r') + *zStr = '\n'; + } + return zStr; +} // end of wxTextCtrl::GetValue -void wxTextCtrl::WriteText(const wxString& value) +void wxTextCtrl::DoSetValue( + const wxString& rsValue, + int flags +) { -// TODO: -/* - wxString valueDos = wxTextFile::Translate(value, wxTextFileType_Dos); + // + // If the text is long enough, it's faster to just set it instead of first + // comparing it with the old one (chances are that it will be different + // anyhow, this comparison is there to avoid flicker for small single-line + // edit controls mostly) + // + if ((rsValue.length() > 0x400) || (rsValue != GetValue())) + { + if ( flags & SetValue_SendEvent ) + m_bSkipUpdate = true; - SendMessage(GetHwnd(), EM_REPLACESEL, 0, (LPARAM)valueDos.c_str()); + ::WinSetWindowText(GetHwnd(), rsValue.c_str()); + AdjustSpaceLimit(); + } +} // end of wxTextCtrl::SetValue +void wxTextCtrl::WriteText( + const wxString& rsValue +) +{ + if (m_bIsMLE) + ::WinSendMsg(GetHwnd(), MLM_INSERT, MPARAM(rsValue.wx_str()), MPARAM(0)); + else + ::WinSetWindowText(GetHwnd(), rsValue.c_str()); AdjustSpaceLimit(); -*/ -} +} // end of wxTextCtrl::WriteText -void wxTextCtrl::AppendText(const wxString& text) +void wxTextCtrl::AppendText( + const wxString& rsText +) { -// TODO: -/* SetInsertionPointEnd(); - WriteText(text); -*/ -} + WriteText(rsText); +} // end of wxTextCtrl::AppendText void wxTextCtrl::Clear() { -// SetWindowText(GetHwnd(), wxT("")); -} + ::WinSetWindowText(GetHwnd(), ""); +} // end of wxTextCtrl::Clear + +bool wxTextCtrl::EmulateKeyPress( + const wxKeyEvent& rEvent +) +{ + SetFocus(); + return(wxTextCtrlBase::EmulateKeyPress(rEvent)); +} // end of wxTextCtrl::EmulateKeyPress // ---------------------------------------------------------------------------- // Clipboard operations @@ -277,286 +405,431 @@ void wxTextCtrl::Copy() if (CanCopy()) { HWND hWnd = GetHwnd(); -// SendMessage(hWnd, WM_COPY, 0, 0L); + if (m_bIsMLE) + ::WinSendMsg(hWnd, MLM_COPY, 0, 0); + else + ::WinSendMsg(hWnd, EM_COPY, 0, 0); } -} +} // end of wxTextCtrl::Copy void wxTextCtrl::Cut() { if (CanCut()) { HWND hWnd = GetHwnd(); -// SendMessage(hWnd, WM_CUT, 0, 0L); + + if (m_bIsMLE) + ::WinSendMsg(hWnd, MLM_CUT, 0, 0); + else + ::WinSendMsg(hWnd, EM_CUT, 0, 0); } -} +} // end of wxTextCtrl::Cut void wxTextCtrl::Paste() { if (CanPaste()) { - HWND hWnd = GetHwnd(); -// SendMessage(hWnd, WM_PASTE, 0, 0L); + HWND hWnd = GetHwnd(); + + ::WinSendMsg(hWnd, EM_PASTE, 0, 0); } -} +} // end of wxTextCtrl::Paste bool wxTextCtrl::CanCopy() const { + // // Can copy if there's a selection - long from = 0L; - long to = 0L; -// GetSelection(& from, & to); - return (from != to); -} + // + long lFrom = 0L; + long lTo = 0L; + + GetSelection(&lFrom, &lTo); + return (lFrom != lTo); +} // end of wxTextCtrl::CanCopy bool wxTextCtrl::CanCut() const { + // // Can cut if there's a selection - long from = 0L; - long to = 0L; -// GetSelection(& from, & to); - return (from != to); -} + // + long lFrom = 0L; + long lTo = 0L; + + GetSelection(&lFrom, &lTo); + return (lFrom != lTo); +} // end of wxTextCtrl::CanCut bool wxTextCtrl::CanPaste() const { + bool bIsTextAvailable = false; + if (!IsEditable()) - return FALSE; + return false; - // Standard edit control: check for straight text on clipboard - bool isTextAvailable = FALSE; -//TODO: -/* - if ( ::OpenClipboard(GetHwndOf(wxTheApp->GetTopWindow())) ) + // + // Check for straight text on clipboard + // + if (::WinOpenClipbrd(vHabmain)) { - isTextAvailable = (::IsClipboardFormatAvailable(CF_TEXT) != 0); - ::CloseClipboard(); + bIsTextAvailable = (::WinQueryClipbrdData(vHabmain, CF_TEXT) != 0); + ::WinCloseClipbrd(vHabmain); } -*/ - return isTextAvailable; -} + return bIsTextAvailable; +} // end of wxTextCtrl::CanPaste // ---------------------------------------------------------------------------- // Accessors // ---------------------------------------------------------------------------- -void wxTextCtrl::SetEditable(bool editable) +void wxTextCtrl::SetEditable( + bool bEditable +) { - HWND hWnd = GetHwnd(); -// SendMessage(hWnd, EM_SETREADONLY, (WPARAM)!editable, (LPARAM)0L); -} + HWND hWnd = GetHwnd(); + + if (m_bIsMLE) + ::WinSendMsg(hWnd, MLM_SETREADONLY, MPFROMLONG(!bEditable), (MPARAM)0); + else + ::WinSendMsg(hWnd, EM_SETREADONLY, MPFROMLONG(!bEditable), (MPARAM)0); +} // end of wxTextCtrl::SetEditable -void wxTextCtrl::SetInsertionPoint(long pos) +void wxTextCtrl::SetInsertionPoint( + long lPos +) { -// TODO: -/* - HWND hWnd = GetHwnd(); - { - SendMessage(hWnd, EM_SETSEL, pos, pos); - SendMessage(hWnd, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0); - } - static const char *nothing = ""; - SendMessage(hWnd, EM_REPLACESEL, 0, (LPARAM)nothing); -*/ -} + HWND hWnd = GetHwnd(); + + if (m_bIsMLE) + ::WinSendMsg(hWnd, MLM_SETSEL, (MPARAM)lPos, (MPARAM)lPos); + else + ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lPos, (USHORT)lPos), (MPARAM)0); +} // end of wxTextCtrl::SetInsertionPoint void wxTextCtrl::SetInsertionPointEnd() { -// TODO: -/* - long pos = GetLastPosition(); - SetInsertionPoint(pos); -*/ -} + wxTextPos lPos = GetLastPosition(); + + // + // We must not do anything if the caret is already there because calling + // SetInsertionPoint() thaws the controls if Freeze() had been called even + // 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()) + return; + SetInsertionPoint(lPos); +} // end of wxTextCtrl::SetInsertionPointEnd long wxTextCtrl::GetInsertionPoint() const { -// TODO: -/* - DWORD Pos = (DWORD)SendMessage(GetHwnd(), EM_GETSEL, 0, 0L); - return Pos & 0xFFFF; -*/ - return 0; -} - -long wxTextCtrl::GetLastPosition() const -{ - HWND hWnd = GetHwnd(); + WXDWORD dwPos = 0L; -// TODO: -/* - // Will always return a number > 0 (according to docs) - int noLines = (int)SendMessage(hWnd, EM_GETLINECOUNT, (WPARAM)0, (LPARAM)0L); + if (m_bIsMLE) + dwPos = (WXDWORD)::WinSendMsg(GetHwnd(), MLM_QUERYSEL, (MPARAM)MLFQS_MINSEL, 0); + else + { + dwPos = (WXDWORD)::WinSendMsg(GetHwnd(), EM_QUERYSEL, 0, 0); + dwPos = SHORT1FROMMP((MPARAM)dwPos); // the first 16 bit value is the min pos + } + return (dwPos & 0xFFFF); +} // end of wxTextCtrl::GetInsertionPoint - // This gets the char index for the _beginning_ of the last line - int charIndex = (int)SendMessage(hWnd, EM_LINEINDEX, (WPARAM)(noLines-1), (LPARAM)0L); +wxTextPos wxTextCtrl::GetLastPosition() const +{ + HWND hWnd = GetHwnd(); + long lCharIndex; + long lLineLength; - // Get number of characters in the last line. We'll add this to the character - // index for the last line, 1st position. - int lineLength = (int)SendMessage(hWnd, EM_LINELENGTH, (WPARAM)charIndex, (LPARAM)0L); + if (m_bIsMLE) + { + lCharIndex = 0; - return (long)(charIndex + lineLength); -*/ - return 0L; -} + // + // This just gets the total text length. The last will be this value + // + lLineLength = (long)::WinSendMsg(hWnd, MLM_QUERYTEXTLENGTH, 0, 0); + } + else + { + WNDPARAMS vParams; + + lCharIndex = 0; + vParams.fsStatus = WPM_CCHTEXT; + if (::WinSendMsg( GetHwnd() + ,WM_QUERYWINDOWPARAMS + ,&vParams + ,0 + )) + { + lLineLength = (long)vParams.cchText; + } + else + lLineLength = 0; + } + return(lCharIndex + lLineLength); +} // end of wxTextCtrl::GetLastPosition // If the return values from and to are the same, there is no // selection. -void wxTextCtrl::GetSelection(long* from, long* to) const +void wxTextCtrl::GetSelection( + long* plFrom +, long* plTo +) const { - DWORD dwStart, dwEnd; - MPARAM wParam = (MPARAM) (DWORD*) & dwStart; // receives starting position - MPARAM lParam = (MPARAM) (DWORD*) & dwEnd; // receives ending position + WXDWORD dwPos; -// ::SendMessage(GetHwnd(), EM_GETSEL, wParam, lParam); - - *from = dwStart; - *to = dwEnd; -} + if (m_bIsMLE) + dwPos = (WXDWORD)::WinSendMsg(GetHwnd(), MLM_QUERYSEL, (MPARAM)MLFQS_MINSEL, 0); + else + { + dwPos = (WXDWORD)::WinSendMsg(GetHwnd(), EM_QUERYSEL, 0, 0); + } + *plFrom = SHORT1FROMMP((MPARAM)dwPos); // the first 16 bit value is the min pos + *plTo = SHORT2FROMMP((MPARAM)dwPos); // the first 16 bit value is the min pos +} // end of wxTextCtrl::GetSelection bool wxTextCtrl::IsEditable() const { -// TODO: -/* - long style = ::GetWindowLong(GetHwnd(), GWL_STYLE); - - return ((style & ES_READONLY) == 0); -*/ - return FALSE; -} + if (m_bIsMLE) + return((bool)LONGFROMMR(::WinSendMsg(GetHwnd(), MLM_QUERYREADONLY, 0, 0))); + else + return((bool)LONGFROMMR(::WinSendMsg(GetHwnd(), EM_QUERYREADONLY, 0, 0))); +} // end of wxTextCtrl::IsEditable // ---------------------------------------------------------------------------- // Editing // ---------------------------------------------------------------------------- -void wxTextCtrl::Replace(long from, long to, const wxString& value) +void wxTextCtrl::Replace( long lFrom, + long lTo, + const wxString& rsValue ) { #if wxUSE_CLIPBOARD HWND hWnd = GetHwnd(); - long fromChar = from; - long toChar = to; + // // Set selection and remove it -// SendMessage(hWnd, EM_SETSEL, fromChar, toChar); -// SendMessage(hWnd, WM_CUT, (WPARAM)0, (LPARAM)0); + // + if (m_bIsMLE) + { + ::WinSendMsg(hWnd, MLM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0); + ::WinSendMsg(hWnd, MLM_CUT, 0, 0); + } + else + { + ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0); + ::WinSendMsg(hWnd, EM_CUT, 0, 0); + } + // // Now replace with 'value', by pasting. - wxSetClipboardData(wxDF_TEXT, (wxObject *) (const wxChar *)value, 0, 0); + // + wxSetClipboardData(wxDF_TEXT, (wxObject *) (const wxChar *)rsValue, 0, 0); // Paste into edit control -// SendMessage(hWnd, WM_PASTE, (WPARAM)0, (LPARAM)0L); + if (m_bIsMLE) + ::WinSendMsg(hWnd, MLM_PASTE, (MPARAM)0, (MPARAM)0); + else + ::WinSendMsg(hWnd, EM_PASTE, (MPARAM)0, (MPARAM)0); #else + wxUnusedVar(lFrom); + wxUnusedVar(lTo); + wxUnusedVar(rsValue); wxFAIL_MSG("wxTextCtrl::Replace not implemented if wxUSE_CLIPBOARD is 0."); #endif -} +} // end of wxTextCtrl::Replace -void wxTextCtrl::Remove(long from, long to) +void wxTextCtrl::Remove( + long lFrom +, long lTo +) { - HWND hWnd = GetHwnd(); - long fromChar = from; - long toChar = to; + HWND hWnd = GetHwnd(); - // Cut all selected text -// SendMessage(hWnd, EM_SETSEL, fromChar, toChar); -// SendMessage(hWnd, WM_CUT, (WPARAM)0, (LPARAM)0); -} + if (m_bIsMLE) + { + ::WinSendMsg(hWnd, MLM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0); + ::WinSendMsg(hWnd, MLM_CUT, 0, 0); + } + else + { + ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0); + ::WinSendMsg(hWnd, EM_CUT, 0, 0); + } +} // end of wxTextCtrl::Remove -void wxTextCtrl::SetSelection(long from, long to) +void wxTextCtrl::SetSelection( + long lFrom +, long lTo +) { - HWND hWnd = GetHwnd(); - long fromChar = from; - long toChar = to; + HWND hWnd = GetHwnd(); + long lFromChar = lFrom; + long lToChar = lTo; - // if from and to are both -1, it means (in wxWindows) that all text should + // + // If from and to are both -1, it means (in wxWidgets) that all text should // be selected. Translate into Windows convention - if ((from == -1) && (to == -1)) + // + if ((lFrom == -1L) && (lTo == -1L)) { - fromChar = 0; - toChar = -1; + lFromChar = 0L; + lToChar = -1L; } + if (m_bIsMLE) + ::WinSendMsg(hWnd, MLM_SETSEL, (MPARAM)lFromChar, (MPARAM)lToChar); + else + ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFromChar, (USHORT)lToChar), (MPARAM)0); +} // end of wxTextCtrl::SetSelection -// SendMessage(hWnd, EM_SETSEL, (WPARAM)fromChar, (LPARAM)toChar); -// SendMessage(hWnd, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0); -} - -bool wxTextCtrl::LoadFile(const wxString& file) +bool wxTextCtrl::DoLoadFile( + const wxString& rsFile, + int fileType +) { -// TODO: -/* - if ( wxTextCtrlBase::LoadFile(file) ) + if ( wxTextCtrlBase::DoLoadFile(rsFile, fileType) ) { - // update the size limit if needed + // + // Update the size limit if needed + // AdjustSpaceLimit(); - - return TRUE; + return true; } -*/ - return FALSE; -} + return false; +} // end of wxTextCtrl::DoLoadFile bool wxTextCtrl::IsModified() const { -// return (SendMessage(GetHwnd(), EM_GETMODIFY, 0, 0) != 0); - return FALSE; + bool bRc; + + if (m_bIsMLE) + bRc = (bool)LONGFROMMR(::WinSendMsg(GetHwnd(), MLM_QUERYCHANGED, 0, 0)); + else + bRc = (bool)LONGFROMMR(::WinSendMsg(GetHwnd(), EM_QUERYCHANGED, 0, 0)); + return bRc; +} // end of wxTextCtrl::IsModified + +void wxTextCtrl::MarkDirty() +{ + if (m_bIsMLE) + ::WinSendMsg(GetHwnd(), MLM_SETCHANGED, MPFROMLONG(TRUE), 0); + else + // EM controls do not have a SETCHANGED, what can we do?? + wxFAIL_MSG( wxT("not implemented") ); } +// // Makes 'unmodified' +// void wxTextCtrl::DiscardEdits() { -// SendMessage(GetHwnd(), EM_SETMODIFY, FALSE, 0L); -} + if (m_bIsMLE) + ::WinSendMsg(GetHwnd(), MLM_SETCHANGED, MPFROMLONG(FALSE), 0); + else + // + // EM controls do not have a SETCHANGED but issuing a query should reset it + // + ::WinSendMsg(GetHwnd(), EM_QUERYCHANGED, 0, 0); +} // end of wxTextCtrl::DiscardEdits int wxTextCtrl::GetNumberOfLines() const { -// return (int)SendMessage(GetHwnd(), EM_GETLINECOUNT, (WPARAM)0, (LPARAM)0); - return 0; -} + int nNumLines; -long wxTextCtrl::XYToPosition(long x, long y) const + if (m_bIsMLE) + nNumLines = (int)::WinSendMsg(GetHwnd(), MLM_QUERYLINECOUNT, 0, 0); + else + nNumLines = 1; + return nNumLines; +} // end of wxTextCtrl::GetNumberOfLines + +long wxTextCtrl::XYToPosition( + long lX +, long lY +) const { - HWND hWnd = GetHwnd(); - - // This gets the char index for the _beginning_ of this line -// TODO: -/* - int charIndex = (int)SendMessage(hWnd, EM_LINEINDEX, (WPARAM)y, (LPARAM)0); - return (long)(x + charIndex); -*/ - return 0L; -} + long lCharIndex = 0L; + long lLen; -bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const + if (m_bIsMLE) + { + lLen = (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH, 0, 0); + lCharIndex = ((lLen * lY) + lX); + } + else + lCharIndex = lX; + return lCharIndex; +} // end of wxTextCtrl::XYToPosition + +bool wxTextCtrl::PositionToXY( + long lPos +, long* plX +, long* plY +) const { - HWND hWnd = GetHwnd(); + HWND hWnd = GetHwnd(); + long nLineNo = -1; + long lCharIndex = 0; - // This gets the line number containing the character - int lineNo = -1; -// lineNo = (int)SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)pos, 0); + if (m_bIsMLE) + nLineNo = (long)::WinSendMsg(hWnd, MLM_LINEFROMCHAR, (MPARAM)lPos, 0); + else + nLineNo = 0; - if ( lineNo == -1 ) + if (nLineNo == -1) { // no such line - return FALSE; + return false; } + // // This gets the char index for the _beginning_ of this line - int charIndex = 0; // TODO: (int)SendMessage(hWnd, EM_LINEINDEX, (WPARAM)lineNo, (LPARAM)0); - if ( charIndex == -1 ) + // + long lLineWidth; + + if (m_bIsMLE) { - return FALSE; + lLineWidth = (long)::WinSendMsg(hWnd, MLM_QUERYLINELENGTH, (MPARAM)0, (MPARAM)0); + lCharIndex = (nLineNo + 1) * lLineWidth; + } + else + { + WNDPARAMS vParams; + + vParams.fsStatus = WPM_CCHTEXT; + if (::WinSendMsg( hWnd + ,WM_QUERYWINDOWPARAMS + ,&vParams + ,0 + )) + { + lCharIndex = vParams.cchText; + } + else + lCharIndex = 32; } - // The X position must therefore be the different between pos and charIndex - if ( x ) - *x = (long)(pos - charIndex); - if ( y ) - *y = (long)lineNo; + if (lCharIndex == -1) + { + return false; + } - return TRUE; -} + // + // The X position must therefore be the difference between pos and charIndex + // + if (plX) + *plX = lPos - lCharIndex; + if (plY) + *plY = nLineNo; -void wxTextCtrl::ShowPosition(long pos) + return true; +} // end of wxTextCtrl::PositionToXY + +void wxTextCtrl::ShowPosition( long WXUNUSED(lPos) ) { HWND hWnd = GetHwnd(); + long lCurrentLineLineNo = 0L; // To scroll to a position, we pass the number of lines and characters // to scroll *by*. This means that we need to: @@ -565,49 +838,97 @@ void wxTextCtrl::ShowPosition(long pos) // (3) Scroll by (pos - current). // For now, ignore the horizontal scrolling. + // // Is this where scrolling is relative to - the line containing the caret? // Or is the first visible line??? Try first visible line. -// int currentLineLineNo1 = (int)SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)-1, (LPARAM)0L); - -// TODO: -/* - int currentLineLineNo = (int)SendMessage(hWnd, EM_GETFIRSTVISIBLELINE, (WPARAM)0, (LPARAM)0L); - - int specifiedLineLineNo = (int)SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)pos, (LPARAM)0L); - - int linesToScroll = specifiedLineLineNo - currentLineLineNo; - - if (linesToScroll != 0) - (void)SendMessage(hWnd, EM_LINESCROLL, (WPARAM)0, (LPARAM)linesToScroll); -*/ -} + // + if (m_bIsMLE) + { + // + // In PM this is the actual char position + // + lCurrentLineLineNo = (long)::WinSendMsg(hWnd, MLM_QUERYFIRSTCHAR, (MPARAM)0, (MPARAM)0); + + // + // This will cause a scroll to the selected position + // + ::WinSendMsg(hWnd, MLM_SETSEL, (MPARAM)lCurrentLineLineNo, (MPARAM)lCurrentLineLineNo); + } +} // end of wxTextCtrl::ShowPosition -int wxTextCtrl::GetLineLength(long lineNo) const +int wxTextCtrl::GetLineLength( long WXUNUSED(lLineNo) ) const { -// TODO: -/* + long lLen = 0L; - long charIndex = XYToPosition(0, lineNo); - int len = (int)SendMessage(GetHwnd(), EM_LINELENGTH, charIndex, 0); - return len; -*/ - return 0; -} + if (m_bIsMLE) + { + lLen = (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH, 0, 0); + } + else + { + WNDPARAMS vParams; + + vParams.fsStatus = WPM_CCHTEXT; + if (::WinSendMsg( GetHwnd() + ,WM_QUERYWINDOWPARAMS + ,&vParams + ,0 + )) + { + lLen = vParams.cchText; + } + else + lLen = 32; + } + return lLen; +} // end ofwxTextCtrl::GetLineLength -wxString wxTextCtrl::GetLineText(long lineNo) const +wxString wxTextCtrl::GetLineText( + long lLineNo +) const { - size_t len = (size_t)GetLineLength(lineNo) + 1; - char *buf = (char *)malloc(len); - *(WORD *)buf = len; - int noChars = 0; // TODO:(int)SendMessage(GetHwnd(), EM_GETLINE, lineNo, (LPARAM)buf); - buf[noChars] = 0; - - wxString str(buf); - - free(buf); - - return str; -} + long lLen = (long)GetLineLength((long)lLineNo) + 1; + wxString sStr; + wxChar* zBuf; + + // + // There must be at least enough place for the length WORD in the + // buffer + // + lLen += sizeof(WORD); + zBuf = new wxChar[lLen]; + if (m_bIsMLE) + { + long lIndex; + long lBuflen; + long lCopied; + + lLen = (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH, 0, 0); + lIndex = lLen * lLineNo; + + ::WinSendMsg(GetHwnd(), MLM_SETSEL, (MPARAM)lIndex, (MPARAM)lIndex); + ::WinSendMsg(GetHwnd(), MLM_SETIMPORTEXPORT, MPFROMP(zBuf), MPFROMSHORT((USHORT)WXSIZEOF(zBuf))); + lBuflen = (long)::WinSendMsg(GetHwnd(), MLM_QUERYFORMATTEXTLENGTH, MPFROMLONG(lIndex), MPFROMLONG(-1)); + lCopied = (long)::WinSendMsg(GetHwnd(), MLM_EXPORT, MPFROMP(&lIndex), MPFROMP(&lBuflen)); + zBuf[lCopied] = '\0'; + } + else + { + WNDPARAMS vParams; + + vParams.fsStatus = WPM_CCHTEXT; + if (::WinSendMsg( GetHwnd() + ,WM_QUERYWINDOWPARAMS + ,&vParams + ,0 + )) + memcpy((char*)zBuf, vParams.pszText, vParams.cchText); + zBuf[vParams.cchText] = '\0'; + } + sStr = zBuf; + delete [] zBuf; + return sStr; +} // end of wxTextCtrl::GetLineText // ---------------------------------------------------------------------------- // Undo/redo @@ -617,80 +938,116 @@ void wxTextCtrl::Undo() { if (CanUndo()) { -// ::SendMessage(GetHwnd(), EM_UNDO, 0, 0); + if (m_bIsMLE) + ::WinSendMsg(GetHwnd(), MLM_UNDO, 0, 0); + // Simple entryfields cannot be undone } -} +} // end of wxTextCtrl::Undo void wxTextCtrl::Redo() { if (CanRedo()) { - // Same as Undo, since Undo undoes the undo, i.e. a redo. -// ::SendMessage(GetHwnd(), EM_UNDO, 0, 0); + if (m_bIsMLE) + ::WinSendMsg(GetHwnd(), MLM_UNDO, 0, 0); + // Simple entryfields cannot be undone } -} +} // end of wxTextCtrl::Redo bool wxTextCtrl::CanUndo() const { -// return (::SendMessage(GetHwnd(), EM_CANUNDO, 0, 0) != 0); - return FALSE; -} + bool bOk; + + if (m_bIsMLE) + bOk = (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO, 0, 0) != 0); + else + bOk = false; // can't undo regular edit fields in PM + return bOk; +} // end of wxTextCtrl::CanUndo bool wxTextCtrl::CanRedo() const { -// return (::SendMessage(GetHwnd(), EM_CANUNDO, 0, 0) != 0); - return FALSE; -} + bool bOk; + + if (m_bIsMLE) + bOk = (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO, 0, 0) != 0); + else + bOk = false; // can't undo regular edit fields in PM + return bOk; +} // end of wxTextCtrl::CanRedo // ---------------------------------------------------------------------------- // implemenation details // ---------------------------------------------------------------------------- -void wxTextCtrl::Command(wxCommandEvent & event) +void wxTextCtrl::Command( + wxCommandEvent& rEvent +) { - SetValue(event.GetString()); - ProcessCommand (event); -} + SetValue(rEvent.GetString()); + ProcessCommand (rEvent); +} // end of wxTextCtrl::Command -void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event) +void wxTextCtrl::OnDropFiles( + wxDropFilesEvent& rEvent +) { // By default, load the first file into the text window. - if (event.GetNumberOfFiles() > 0) + if (rEvent.GetNumberOfFiles() > 0) { - LoadFile(event.GetFiles()[0]); + LoadFile(rEvent.GetFiles()[0]); } -} - -WXHBRUSH wxTextCtrl::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor, - WXUINT message, WXWPARAM wParam, - WXLPARAM lParam) +} // end of wxTextCtrl::OnDropFiles + +WXHBRUSH wxTextCtrl::OnCtlColor( WXHDC hWxDC, + WXHWND WXUNUSED(hWnd), + WXUINT WXUNUSED(uCtlColor), + WXUINT WXUNUSED(uMessage), + WXWPARAM WXUNUSED(wParam), + WXLPARAM WXUNUSED(lParam) ) { - HDC hdc = (HDC)pDC; -// TODO: -/* - SetBkMode(hdc, GetParent()->GetTransparentBackground() ? TRANSPARENT - : OPAQUE); + HPS hPS = (HPS)hWxDC; + wxColour vColBack = GetBackgroundColour(); + wxColour vColFore = GetForegroundColour(); + wxBrush* pBackgroundBrush = wxTheBrushList->FindOrCreateBrush( vColBack, wxSOLID ); - ::SetBkColor(hdc, RGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue())); - ::SetTextColor(hdc, RGB(GetForegroundColour().Red(), GetForegroundColour().Green(), GetForegroundColour().Blue())); -*/ - wxBrush *backgroundBrush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID); + if (m_bUseCtl3D) + { + HBRUSH hBrush = NULLHANDLE; - return (WXHBRUSH) backgroundBrush->GetResourceHandle(); -} + return hBrush; + } + if (GetParent()->GetTransparentBackground()) + ::GpiSetBackMix(hPS, BM_LEAVEALONE); + else + ::GpiSetBackMix(hPS, BM_OVERPAINT); + if (!IsEnabled() && (GetWindowStyle() & wxTE_MULTILINE) == 0) + vColBack = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); + ::GpiSetBackColor(hPS, vColBack.GetPixel()); + ::GpiSetColor(hPS, vColFore.GetPixel()); + return (WXHBRUSH)pBackgroundBrush->GetResourceHandle(); +} // end of wxTextCtrl::OnCtlColor + +bool wxTextCtrl::OS2ShouldPreProcessMessage( + WXMSG* pMsg +) +{ + return wxControl::OS2ShouldPreProcessMessage(pMsg); +} // end of wxTextCtrl::OS2ShouldPreProcessMessage -void wxTextCtrl::OnChar(wxKeyEvent& event) +void wxTextCtrl::OnChar( + wxKeyEvent& rEvent +) { - switch ( event.KeyCode() ) + switch (rEvent.GetKeyCode()) { -// TODO: -/* case WXK_RETURN: if ( !(m_windowStyle & wxTE_MULTILINE) ) { - wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId); - event.SetEventObject( this ); - if ( GetEventHandler()->ProcessEvent(event) ) + wxCommandEvent vEvent(wxEVT_COMMAND_TEXT_ENTER, m_windowId); + + vEvent.SetEventObject(this); + if ( HandleWindowEvent(vEvent)) return; } //else: multiline controls need Enter for themselves @@ -706,168 +1063,293 @@ void wxTextCtrl::OnChar(wxKeyEvent& event) // NB: Notice that Ctrl-Tab is handled elsewhere and Alt-Tab is // handled by Windows { - wxNavigationKeyEvent eventNav; - eventNav.SetDirection(!event.ShiftDown()); - eventNav.SetWindowChange(FALSE); - eventNav.SetEventObject(this); + wxNavigationKeyEvent vEventNav; - if ( GetEventHandler()->ProcessEvent(eventNav) ) + vEventNav.SetDirection(!rEvent.ShiftDown()); + vEventNav.SetWindowChange(false); + vEventNav.SetEventObject(this); + + if ( HandleWindowEvent(vEventNav) ) return; } break; -*/ - default: - event.Skip(); - return; } + rEvent.Skip(); +} // end of wxTextCtrl::OnChar - // don't just call event.Skip() because this will cause TABs and ENTERs - // be passed upwards and we don't always want this - instead process it - // right here - - // FIXME - event.Skip(); -} - -bool wxTextCtrl::OS2Command(WXUINT param, WXWORD WXUNUSED(id)) +bool wxTextCtrl::OS2Command( + WXUINT uParam +, WXWORD WXUNUSED(vId) +) { - switch (param) + switch (uParam) { -// TODO: -/* case EN_SETFOCUS: case EN_KILLFOCUS: { - wxFocusEvent event(param == EN_KILLFOCUS ? wxEVT_KILL_FOCUS - : wxEVT_SET_FOCUS, - m_windowId); - event.SetEventObject( this ); - GetEventHandler()->ProcessEvent(event); + wxFocusEvent vEvent( uParam == EN_KILLFOCUS ? wxEVT_KILL_FOCUS + : wxEVT_SET_FOCUS + ,m_windowId + ); + + vEvent.SetEventObject(this); + HandleWindowEvent(vEvent); } break; case EN_CHANGE: { - wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId); - wxString val(GetValue()); - if ( !val.IsNull() ) - event.m_commandString = WXSTRINGCAST val; - event.SetEventObject( this ); - ProcessCommand(event); + if (m_bSkipUpdate) + { + m_bSkipUpdate = false; + break; + } + + wxCommandEvent vEvent( wxEVT_COMMAND_TEXT_UPDATED + ,m_windowId + ); + + InitCommandEvent(vEvent); + ProcessCommand(vEvent); } break; - case EN_ERRSPACE: - // the text size limit has been hit - increase it + case EN_OVERFLOW: + // + // The text size limit has been hit - increase it + // AdjustSpaceLimit(); break; - // the other notification messages are not processed - case EN_UPDATE: - case EN_MAXTEXT: - case EN_HSCROLL: - case EN_VSCROLL: -*/ + case EN_SCROLL: + case EN_INSERTMODETOGGLE: + case EN_MEMERROR: + return false; default: - return FALSE; + return false; } - // processed - return TRUE; -} + // + // Processed + // + return true; +} // end of wxTextCtrl::OS2Command void wxTextCtrl::AdjustSpaceLimit() { -// TODO: -/* - unsigned int len = ::GetWindowTextLength(GetHwnd()), - limit = ::SendMessage(GetHwnd(), EM_GETLIMITTEXT, 0, 0); - if ( len > limit ) + unsigned int uLen = 0; + unsigned int uLimit = 0; + + uLen = ::WinQueryWindowTextLength(GetHwnd()); + if (m_bIsMLE) { - limit = len + 0x8000; // 32Kb + uLimit = (unsigned int)::WinSendMsg( GetHwnd() + ,MLM_QUERYTEXTLIMIT + ,0 + ,0 + ); + } + else + { + ENTRYFDATA Efd; + WNDPARAMS vParams; + + vParams.fsStatus = WPM_CBCTLDATA; + vParams.pCtlData = &Efd; + vParams.cbCtlData = sizeof(ENTRYFDATA); + + if (::WinSendMsg( GetHwnd() + ,WM_QUERYWINDOWPARAMS + ,&vParams + ,0 + )) + uLimit = (unsigned int)Efd.cchEditLimit; + else + uLimit = 32; //PM's default + } + if (uLen >= uLimit) + { + if (m_bIsMLE) + { + uLimit = uLen + 0x8000; // 32Kb + if (uLimit > 0xffff) + { + uLimit = 0L; + } + } + else + uLimit = 0x7fff; - if ( limit > 0xffff ) - ::SendMessage(GetHwnd(), EM_LIMITTEXT, 0, limit); + if (m_bIsMLE) + ::WinSendMsg(GetHwnd(), MLM_SETTEXTLIMIT, MPFROMLONG(uLimit), 0); else - ::SendMessage(GetHwnd(), EM_LIMITTEXT, limit, 0); + ::WinSendMsg(GetHwnd(), EM_SETTEXTLIMIT, MPFROMSHORT(uLimit), 0); } -*/ -} +} // end of wxTextCtrl::AdjustSpaceLimit bool wxTextCtrl::AcceptsFocus() const { - // we don't want focus if we can't be edited - return IsEditable() && wxControl::AcceptsFocus(); -} + // + // We don't want focus if we can't be edited unless we're a multiline + // control because then it might be still nice to get focus from keyboard + // to be able to scroll it without mouse + // + return (IsEditable() || IsMultiLine()) && wxControl::AcceptsFocus(); +} // end of wxTextCtrl::Command wxSize wxTextCtrl::DoGetBestSize() const { - int cx, cy; - wxGetCharSize(GetHWND(), &cx, &cy, (wxFont*)&GetFont()); + int nCx; + int nCy; + wxFont vFont = (wxFont)GetFont(); - int wText = DEFAULT_ITEM_WIDTH; + wxGetCharSize(GetHWND(), &nCx, &nCy, &vFont); - int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy); - if ( m_windowStyle & wxTE_MULTILINE ) + int wText = DEFAULT_ITEM_WIDTH; + int hText = (int)(EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * .8); + + if (m_windowStyle & wxTE_MULTILINE) { - hText *= wxMin(GetNumberOfLines(), 5); + hText *= wxMax(GetNumberOfLines(), 5); } //else: for single line control everything is ok - return wxSize(wText, hText); -} +} // end of wxTextCtrl::DoGetBestSize // ---------------------------------------------------------------------------- // standard handlers for standard edit menu events // ---------------------------------------------------------------------------- -void wxTextCtrl::OnCut(wxCommandEvent& event) +void wxTextCtrl::OnCut( wxCommandEvent& WXUNUSED(rEvent) ) { Cut(); -} +} // end of wxTextCtrl::OnCut -void wxTextCtrl::OnCopy(wxCommandEvent& event) +void wxTextCtrl::OnCopy( wxCommandEvent& WXUNUSED(rEvent) ) { Copy(); -} +} // end of wxTextCtrl::OnCopy -void wxTextCtrl::OnPaste(wxCommandEvent& event) +void wxTextCtrl::OnPaste( wxCommandEvent& WXUNUSED(rEvent) ) { Paste(); -} +} // end of wxTextCtrl::OnPaste -void wxTextCtrl::OnUndo(wxCommandEvent& event) +void wxTextCtrl::OnUndo( wxCommandEvent& WXUNUSED(rEvent) ) { Undo(); -} +} // end of wxTextCtrl::OnUndo -void wxTextCtrl::OnRedo(wxCommandEvent& event) +void wxTextCtrl::OnRedo( wxCommandEvent& WXUNUSED(rEvent) ) { Redo(); -} +} // end of wxTextCtrl::OnRedo -void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent& event) +void wxTextCtrl::OnDelete( wxCommandEvent& WXUNUSED(rEvent) ) { - event.Enable( CanCut() ); -} + long lFrom, lTo; + + GetSelection( &lFrom, &lTo ); + + if (lFrom != -1 && lTo != -1) + Remove( lFrom, lTo ); +} // end of wxTextCtrl::OnDelete -void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent& event) +void wxTextCtrl::OnSelectAll( wxCommandEvent& WXUNUSED(rEvent) ) { - event.Enable( CanCopy() ); -} + SetSelection(-1, -1); +} // end of wxTextCtrl::OnSelectAll -void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent& event) +void wxTextCtrl::OnUpdateCut( wxUpdateUIEvent& rEvent ) { - event.Enable( CanPaste() ); -} + rEvent.Enable(CanCut()); +} // end of wxTextCtrl::OnUpdateCut -void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent& event) +void wxTextCtrl::OnUpdateCopy( wxUpdateUIEvent& rEvent ) { - event.Enable( CanUndo() ); -} + rEvent.Enable(CanCopy()); +} // end of wxTextCtrl::OnUpdateCopy -void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event) +void wxTextCtrl::OnUpdatePaste( wxUpdateUIEvent& rEvent ) { - event.Enable( CanRedo() ); -} + rEvent.Enable(CanPaste()); +} // end of wxTextCtrl::OnUpdatePaste + +void wxTextCtrl::OnUpdateUndo( wxUpdateUIEvent& rEvent ) +{ + rEvent.Enable(CanUndo()); +} // end of wxTextCtrl::OnUpdateUndo + +void wxTextCtrl::OnUpdateRedo( wxUpdateUIEvent& rEvent ) +{ + rEvent.Enable(CanRedo()); +} // end of wxTextCtrl::OnUpdateRedo + +void wxTextCtrl::OnUpdateDelete( wxUpdateUIEvent& rEvent ) +{ + long lFrom, lTo; + + GetSelection( &lFrom, &lTo ); + rEvent.Enable( lFrom != -1L && lTo != -1L && lFrom != lTo && IsEditable()) ; +} // end of wxTextCtrl::OnUpdateDelete + +void wxTextCtrl::OnUpdateSelectAll( wxUpdateUIEvent& rEvent ) +{ + rEvent.Enable(GetLastPosition() > 0); +} // end of wxTextCtrl::OnUpdateSelectAll + +bool wxTextCtrl::SetBackgroundColour( const wxColour& rColour ) +{ + if (m_bIsMLE) + ::WinSendMsg(GetHwnd(), MLM_SETBACKCOLOR, (MPARAM)rColour.GetPixel(), MLE_INDEX); + return true; +} // end of wxTextCtrl::SetBackgroundColour + +bool wxTextCtrl::SetForegroundColour( const wxColour& rColour ) +{ + if (m_bIsMLE) + ::WinSendMsg(GetHwnd(), MLM_SETTEXTCOLOR, (MPARAM)rColour.GetPixel(), MLE_INDEX); + return true; +} // end of wxTextCtrl::SetForegroundColour + +bool wxTextCtrl::SetStyle( long lStart, + long lEnd, + const wxTextAttr& WXUNUSED(rStyle) ) +{ + HWND hWnd = GetHwnd(); + + if (lStart > lEnd) + { + long lTmp = lStart; + + lStart = lEnd; + lEnd = lTmp; + } + + // + // We can only change the format of the selection, so select the range we + // want and restore the old selection later + // + long lStartOld, lEndOld; + + GetSelection( &lStartOld, &lEndOld ); + + // + // But do we really have to change the selection? + // + bool bChangeSel = lStart != lStartOld || + lEnd != lEndOld; + + if (bChangeSel) + { + if (m_bIsMLE) + ::WinSendMsg(hWnd, MLM_SETSEL, MPFROM2SHORT((USHORT)lStart, (USHORT)lEnd), 0); + else + ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lStart, (USHORT)lEnd), 0); + } + // + // TODO:: finish this part + // + return true; +} // end of wxTextCtrl::SetStyle