diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 4c471dde28..6b72cd1e4f 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -1334,7 +1334,12 @@ wxTextPos wxTextCtrl::GetLastPosition() const { if ( IsMultiLine() ) { - return ::GetWindowTextLength(GetHwnd()); + int numLines = GetNumberOfLines(); + long posStartLastLine = XYToPosition(0, numLines - 1); + + long lenLastLine = GetLengthOfLineContainingPos(posStartLastLine); + + return posStartLastLine + lenLastLine; } return wxTextEntry::GetLastPosition(); @@ -1486,13 +1491,12 @@ long wxTextCtrl::XYToPosition(long x, long y) const // Line is identified by a character position! long lineLength = ::SendMessage(GetHwnd(), EM_LINELENGTH, charIndex, 0); - // For all lines but last one we need to adjust the length - // to include new line character (only one because both CR and LF - // are virtually "displayed" at the same position). - if ( y < GetNumberOfLines() - 1 ) - lineLength += 1; - if ( x >= lineLength ) + // Notice that x == lineLength is still valid because it corresponds either + // to the position of the LF at the end of any line except the last one or + // to the last position, which is the position after the last character, + // for the last line. + if ( x > lineLength ) return -1; return charIndex + x; diff --git a/tests/controls/textctrltest.cpp b/tests/controls/textctrltest.cpp index 15e2c0d3e2..6d3579077c 100644 --- a/tests/controls/textctrltest.cpp +++ b/tests/controls/textctrltest.cpp @@ -71,6 +71,7 @@ private: // don't pass neither but this could be a bug. CPPUNIT_TEST( SetValue ); CPPUNIT_TEST( Selection ); + CPPUNIT_TEST( InsertionPoint ); CPPUNIT_TEST( Replace ); WXUISIM_TEST( Editable ); CPPUNIT_TEST( CopyPaste ); @@ -831,7 +832,7 @@ void TextCtrlTestCase::XYToPositionMultiLine() const long numLines_0 = 1; CPPUNIT_ASSERT_EQUAL( m_text->GetNumberOfLines(), numLines_0 ); long pos_0[numLines_0+1][maxLineLength_0+1] = - { { -1 } }; + { { 0 } }; for ( long y = 0; y < numLines_0; y++ ) for( long x = 0; x < maxLineLength_0+1; x++ ) { @@ -846,7 +847,7 @@ void TextCtrlTestCase::XYToPositionMultiLine() const long numLines_1 = 1; CPPUNIT_ASSERT_EQUAL( m_text->GetNumberOfLines(), numLines_1 ); long pos_1[numLines_1+1][maxLineLength_1+1] = - { { 0, 1, 2, 3, -1 }, + { { 0, 1, 2, 3, 4 }, { -1, -1, -1, -1, -1 } }; for ( long y = 0; y < numLines_1; y++ ) for( long x = 0; x < maxLineLength_1+1; x++ ) @@ -866,7 +867,7 @@ void TextCtrlTestCase::XYToPositionMultiLine() long pos_2[numLines_2 + 1][maxLineLength_2 + 1] = { { 0, 1, 2, 3, -1 }, // New line occupies positions 3, 4 { 5, 6, 7, -1, -1 }, // New line occupies positions 7, 8 - { 9, -1, -1, -1, -1 } }; + { 9, 10, -1, -1, -1 } }; #else long pos_2[numLines_2+1][maxLineLength_2+1] = { { 0, 1, 2, 3, -1 }, @@ -893,7 +894,7 @@ void TextCtrlTestCase::XYToPositionMultiLine() { { 0, -1 }, // New line occupies positions 0, 1 { 2, -1 }, // New line occupies positions 2, 3 { 4, -1 }, // New line occupies positions 4, 5 - { -1, -1 }, + { 6, -1 }, { -1, -1 } }; #else long pos_3[numLines_3+1][maxLineLength_3+1] = @@ -925,7 +926,7 @@ void TextCtrlTestCase::XYToPositionMultiLine() { 8, -1, -1, -1, -1 }, // New line occupies positions 8, 9 { 10, 11, -1, -1, -1 }, // New line occupies positions 11, 12 { 13, -1, -1, -1, -1 }, // New line occupies positions 13, 14 - { -1, -1, -1, -1, -1 }, + { 15, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1 } }; #else long pos_4[numLines_4+1][maxLineLength_4+1] = @@ -1013,7 +1014,7 @@ void TextCtrlTestCase::XYToPositionSingleLine() for( long x = 0; x < m_text->GetLastPosition()+2; x++ ) { long p0 = m_text->XYToPosition(x, 0); - if ( x < m_text->GetLastPosition() ) + if ( x <= m_text->GetLastPosition() ) CPPUNIT_ASSERT_EQUAL( p0, x ); else CPPUNIT_ASSERT_EQUAL( p0, -1 ); @@ -1029,7 +1030,7 @@ void TextCtrlTestCase::XYToPositionSingleLine() for( long x = 0; x < m_text->GetLastPosition()+2; x++ ) { long p1 = m_text->XYToPosition(x, 0); - if ( x < m_text->GetLastPosition() ) + if ( x <= m_text->GetLastPosition() ) CPPUNIT_ASSERT_EQUAL( p1, x ); else CPPUNIT_ASSERT_EQUAL( p1, -1 ); @@ -1045,7 +1046,7 @@ void TextCtrlTestCase::XYToPositionSingleLine() for( long x = 0; x < m_text->GetLastPosition()+2; x++ ) { long p2 = m_text->XYToPosition(x, 0); - if ( x < m_text->GetLastPosition() ) + if ( x <= m_text->GetLastPosition() ) CPPUNIT_ASSERT_EQUAL( p2, x ); else CPPUNIT_ASSERT_EQUAL( p2, -1 );