X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3bd418ca9f373bb90457b816858ba83039768bd3..7d09b97f5321d0accd758eb420c008853ad9ec26:/src/os2/textctrl.cpp diff --git a/src/os2/textctrl.cpp b/src/os2/textctrl.cpp index acbe4bca0a..c9bc9d2411 100644 --- a/src/os2/textctrl.cpp +++ b/src/os2/textctrl.cpp @@ -18,14 +18,16 @@ #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" #endif +#include "wx/app.h" + #if wxUSE_CLIPBOARD - #include "wx/app.h" #include "wx/clipbrd.h" #endif @@ -43,6 +45,11 @@ # include #endif +#if !defined(MLE_INDEX) +#define MLE_INDEX 0 +#define MLE_RGB 1 +#endif + // ---------------------------------------------------------------------------- // event tables and other macros @@ -80,6 +87,10 @@ wxTextCtrl::wxTextCtrl() { } +wxTextCtrl::~wxTextCtrl() +{ +} + bool wxTextCtrl::Create( wxWindow* pParent , wxWindowID vId @@ -87,9 +98,7 @@ bool wxTextCtrl::Create( , const wxPoint& rPos , const wxSize& rSize , long lStyle -#if wxUSE_VALIDATORS , const wxValidator& rValidator -#endif , const wxString& rsName ) { @@ -101,17 +110,21 @@ bool wxTextCtrl::Create( ,rPos ,rSize ,lStyle -#if wxUSE_VALIDATORS ,rValidator -#endif ,rsName )) - return FALSE; + return false; + + wxPoint vPos = rPos; // The OS/2 position + SWP vSwp; if (pParent ) + { pParent->AddChild(this); + } m_windowStyle = lStyle; + m_bIsMLE = false; long lSstyle = WS_VISIBLE | WS_TABSTOP; @@ -120,8 +133,8 @@ bool wxTextCtrl::Create( // if ( m_windowStyle & wxTE_MULTILINE ) { - m_bIsMLE = TRUE; - m_windowStyle |= wxTE_PROCESS_ENTER; + lSstyle |= MLS_BORDER | MLS_WORDWRAP; + m_bIsMLE = true; if ((m_windowStyle & wxTE_NO_VSCROLL) == 0) lSstyle |= MLS_VSCROLL; @@ -132,7 +145,7 @@ bool wxTextCtrl::Create( } else { - lSstyle |= ES_LEFT; + lSstyle |= ES_LEFT | ES_AUTOSCROLL | ES_MARGIN; if (m_windowStyle & wxHSCROLL) lSstyle |= ES_AUTOSCROLL; @@ -141,16 +154,17 @@ bool wxTextCtrl::Create( if (m_windowStyle & wxTE_PASSWORD) // hidden input lSstyle |= ES_UNREADABLE; } + if (m_bIsMLE) { m_hWnd = (WXHWND)::WinCreateWindow( (HWND)GetHwndOf(pParent) // Parent window handle ,WC_MLE // Window class ,(PSZ)rsValue.c_str() // Initial Text ,(ULONG)lSstyle // Style flags - ,(LONG)rPos.x // X pos of origin - ,(LONG)rPos.y // Y pos of origin - ,(LONG)rSize.x // field width - ,(LONG)rSize.y // field height + ,(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 @@ -164,10 +178,10 @@ bool wxTextCtrl::Create( ,WC_ENTRYFIELD // Window class ,(PSZ)rsValue.c_str() // Initial Text ,(ULONG)lSstyle // Style flags - ,(LONG)rPos.x // X pos of origin - ,(LONG)rPos.y // Y pos of origin - ,(LONG)rSize.x // field width - ,(LONG)rSize.y // field height + ,(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 @@ -178,7 +192,7 @@ bool wxTextCtrl::Create( if (m_hWnd == 0) { - return FALSE; + return false; } SubclassWin(GetHWND()); @@ -186,27 +200,31 @@ bool wxTextCtrl::Create( // // Set font, position, size and initial value // - wxFont& vFontParent = pParent->GetFont(); - - if (vFontParent.Ok()) - { - SetFont(vFontParent); - } - else - { - SetFont(wxSystemSettings::GetSystemFont(wxSYS_SYSTEM_FONT)); - } - if (!rsValue.IsEmpty()) + wxFont* pTextFont = new wxFont( 8 + ,wxMODERN + ,wxNORMAL + ,wxNORMAL + ); + SetFont(*pTextFont); + if (!rsValue.empty()) { SetValue(rsValue); } SetupColours(); - SetSize( rPos.x - ,rPos.y + // + // 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 ); - return TRUE; + delete pTextFont; + return true; } // end of wxTextCtrl::Create // @@ -232,14 +250,76 @@ void wxTextCtrl::AdoptAttributesFromHWND() 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 @@ -247,46 +327,70 @@ void wxTextCtrl::SetupColours() wxString wxTextCtrl::GetValue() const { - return wxGetWindowText(GetHWND()); -} - -void wxTextCtrl::SetValue(const wxString& value) -{ -// TODO: -/* - wxString valueDos = wxTextFile::Translate(value, wxTextFileType_Dos); + wxString sStr = wxGetWindowText(GetHWND()); + char* zStr = (char*)sStr.c_str(); - SetWindowText(GetHwnd(), valueDos); - - AdjustSpaceLimit(); -*/ -} + for ( ; *zStr; zStr++ ) + { + // + // this will replace \r\n with just \n + // + if (*zStr == '\n') + *zStr = '\0'; + if (*zStr == '\r') + *zStr = '\n'; + } + return sStr; +} // end of wxTextCtrl::GetValue -void wxTextCtrl::WriteText(const wxString& value) +void wxTextCtrl::SetValue( + const wxString& rsValue +) { -// TODO: -/* - wxString valueDos = wxTextFile::Translate(value, wxTextFileType_Dos); - - SendMessage(GetHwnd(), EM_REPLACESEL, 0, (LPARAM)valueDos.c_str()); + // + // 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())) + { + ::WinSetWindowText(GetHwnd(), (PSZ)rsValue.c_str()); + AdjustSpaceLimit(); + } +} // end of wxTextCtrl::SetValue +void wxTextCtrl::WriteText( + const wxString& rsValue +) +{ + if (m_bIsMLE) + ::WinSendMsg(GetHwnd(), MLM_INSERT, MPARAM((PCHAR)rsValue.c_str()), MPARAM(0)); + else + ::WinSetWindowText(GetHwnd(), (PSZ)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 @@ -315,41 +419,48 @@ void wxTextCtrl::Cut() 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; + bool bIsTextAvailable = false; if (!IsEditable()) - return FALSE; + return false; // // Check for straight text on clipboard @@ -366,29 +477,45 @@ bool wxTextCtrl::CanPaste() const // 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() { -} + 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 { @@ -404,7 +531,7 @@ long wxTextCtrl::GetInsertionPoint() const return (dwPos & 0xFFFF); } // end of wxTextCtrl::GetInsertionPoint -long wxTextCtrl::GetLastPosition() const +wxTextPos wxTextCtrl::GetLastPosition() const { HWND hWnd = GetHwnd(); long lCharIndex; @@ -441,102 +568,150 @@ long wxTextCtrl::GetLastPosition() const // 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::LoadFile( + const wxString& rsFile +) { -// TODO: -/* - if ( wxTextCtrlBase::LoadFile(file) ) + if ( wxTextCtrlBase::LoadFile(rsFile) ) { - // update the size limit if needed + // + // Update the size limit if needed + // AdjustSpaceLimit(); - - return TRUE; + return true; } -*/ - return FALSE; -} + return false; +} // end of wxTextCtrl::LoadFile 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( _T("not implemented") ); } // @@ -555,56 +730,101 @@ void 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 -{ - HWND hWnd = GetHwnd(); + if (m_bIsMLE) + nNumLines = (int)::WinSendMsg(GetHwnd(), MLM_QUERYLINECOUNT, 0, 0); + else + nNumLines = 1; + return nNumLines; +} // end of wxTextCtrl::GetNumberOfLines - // 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 wxTextCtrl::XYToPosition( + long lX +, long lY +) const +{ + 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; - // The X position must therefore be the different between pos and charIndex - if ( x ) - *x = (long)(pos - charIndex); - if ( y ) - *y = (long)lineNo; + vParams.fsStatus = WPM_CCHTEXT; + if (::WinSendMsg( hWnd + ,WM_QUERYWINDOWPARAMS + ,&vParams + ,0 + )) + { + lCharIndex = vParams.cchText; + } + else + lCharIndex = 32; + } - return TRUE; -} + if (lCharIndex == -1) + { + return false; + } + + // + // The X position must therefore be the difference between pos and charIndex + // + if (plX) + *plX = lPos - lCharIndex; + if (plY) + *plY = nLineNo; + + return true; +} // end of wxTextCtrl::PositionToXY -void wxTextCtrl::ShowPosition(long pos) +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: @@ -613,34 +833,35 @@ 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 (m_bIsMLE) + { + // + // In PM this is the actual char position + // + lCurrentLineLineNo = (long)::WinSendMsg(hWnd, MLM_QUERYFIRSTCHAR, (MPARAM)0, (MPARAM)0); - if (linesToScroll != 0) - (void)SendMessage(hWnd, EM_LINESCROLL, (WPARAM)0, (LPARAM)linesToScroll); -*/ -} + // + // 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 lLineNo -) const +int wxTextCtrl::GetLineLength( long WXUNUSED(lLineNo) ) const { - long lLen = 0L; + long lLen = 0L; if (m_bIsMLE) + { lLen = (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH, 0, 0); + } else { - WNDPARAMS vParams; + WNDPARAMS vParams; vParams.fsStatus = WPM_CCHTEXT; if (::WinSendMsg( GetHwnd() @@ -655,22 +876,54 @@ int wxTextCtrl::GetLineLength( lLen = 32; } return lLen; -} // end of +} // 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; + 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; - wxString str(buf); + lLen = (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH, 0, 0); + lIndex = lLen * lLineNo; - free(buf); + ::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; - return str; -} + 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 @@ -680,18 +933,21 @@ 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 { @@ -700,7 +956,7 @@ bool wxTextCtrl::CanUndo() const if (m_bIsMLE) bOk = (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO, 0, 0) != 0); else - bOk = FALSE; // can't undo regular edit fields in PM + bOk = false; // can't undo regular edit fields in PM return bOk; } // end of wxTextCtrl::CanUndo @@ -711,7 +967,7 @@ bool wxTextCtrl::CanRedo() const if (m_bIsMLE) bOk = (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO, 0, 0) != 0); else - bOk = FALSE; // can't undo regular edit fields in PM + bOk = false; // can't undo regular edit fields in PM return bOk; } // end of wxTextCtrl::CanRedo @@ -719,51 +975,74 @@ bool wxTextCtrl::CanRedo() const // 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 ( GetEventHandler()->ProcessEvent(vEvent)) return; } //else: multiline controls need Enter for themselves @@ -779,75 +1058,71 @@ 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; + + vEventNav.SetDirection(!rEvent.ShiftDown()); + vEventNav.SetWindowChange(false); + vEventNav.SetEventObject(this); - if ( GetEventHandler()->ProcessEvent(eventNav) ) + if ( GetEventHandler()->ProcessEvent(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); + GetEventHandler()->ProcessEvent(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); + 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() { @@ -865,10 +1140,11 @@ void wxTextCtrl::AdjustSpaceLimit() } else { - ENTRYFDATA* pEfd; + ENTRYFDATA Efd; WNDPARAMS vParams; vParams.fsStatus = WPM_CBCTLDATA; + vParams.pCtlData = &Efd; vParams.cbCtlData = sizeof(ENTRYFDATA); if (::WinSendMsg( GetHwnd() @@ -876,10 +1152,7 @@ void wxTextCtrl::AdjustSpaceLimit() ,&vParams ,0 )) - { - pEfd = (ENTRYFDATA*)vParams.pCtlData; - uLimit = (unsigned int)pEfd->cchEditLimit; - } + uLimit = (unsigned int)Efd.cchEditLimit; else uLimit = 32; //PM's default } @@ -893,84 +1166,173 @@ void wxTextCtrl::AdjustSpaceLimit() if (m_bIsMLE) ::WinSendMsg(GetHwnd(), MLM_SETTEXTLIMIT, MPFROMLONG(uLimit), 0); else - ::WinSendMsg(GetHwnd(), EM_SETTEXTLIMIT, MPFROMLONG(uLimit), 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; -void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent& event) + GetSelection( &lFrom, &lTo ); + + if (lFrom != -1 && lTo != -1) + Remove( lFrom, lTo ); +} // end of wxTextCtrl::OnDelete + +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