1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ---------------------------------------------------------------------------- 
  14 // ---------------------------------------------------------------------------- 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  20     #include "wx/textctrl.h" 
  21     #include "wx/settings.h" 
  29     #include "wx/clipbrd.h" 
  32 #include "wx/textfile.h" 
  34 #include "wx/os2/private.h" 
  38 #include <sys/types.h> 
  46 #if defined(__EMX__) && !defined(MLE_INDEX) 
  52 // ---------------------------------------------------------------------------- 
  53 // event tables and other macros 
  54 // ---------------------------------------------------------------------------- 
  56 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
) 
  58 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
) 
  59     EVT_CHAR(wxTextCtrl::OnChar
) 
  60     EVT_DROP_FILES(wxTextCtrl::OnDropFiles
) 
  62     EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
) 
  63     EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
) 
  64     EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
) 
  65     EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
) 
  66     EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
) 
  68     EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
) 
  69     EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
) 
  70     EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
) 
  71     EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
) 
  72     EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
) 
  76 // ============================================================================ 
  78 // ============================================================================ 
  80 // ---------------------------------------------------------------------------- 
  82 // ---------------------------------------------------------------------------- 
  84 wxTextCtrl::wxTextCtrl() 
  88 bool wxTextCtrl::Create( 
  91 , const wxString
&                   rsValue
 
  96 , const wxValidator
&                rValidator
 
  98 , const wxString
&                   rsName
 
 104     // Base initialization 
 106     if ( !CreateBase( pParent
 
 118     wxPoint                         vPos 
= rPos
; // The OS/2 position 
 122         pParent
->AddChild(this); 
 123         hParent 
= GetWinHwnd(pParent
); 
 125         // OS2 uses normal coordinates, no bassackwards Windows ones 
 127         if (pParent
->IsKindOf(CLASSINFO(wxGenericScrolledWindow
)) || 
 128             pParent
->IsKindOf(CLASSINFO(wxScrolledWindow
)) 
 131             wxWindow
*               pGrandParent 
= NULL
; 
 133             pGrandParent 
= pParent
->GetParent(); 
 135                 nTempy 
= pGrandParent
->GetSize().y 
- (vPos
.y 
+ rSize
.y
); 
 137                 nTempy 
= pParent
->GetSize().y 
- (vPos
.y 
+ rSize
.y
); 
 140             nTempy 
= pParent
->GetSize().y 
- (vPos
.y 
+ rSize
.y
); 
 147         ::WinQueryWindowRect(HWND_DESKTOP
, &vRect
); 
 148         hParent 
= HWND_DESKTOP
; 
 149         vPos
.y 
= vRect
.yTop 
- (vPos
.y 
+ rSize
.y
); 
 152     m_windowStyle 
= lStyle
; 
 154     long                            lSstyle 
= WS_VISIBLE 
| WS_TABSTOP
; 
 157     // Single and multiline edit fields are two different controls in PM 
 159     if ( m_windowStyle 
& wxTE_MULTILINE 
) 
 162         m_windowStyle 
|= wxTE_PROCESS_ENTER
; 
 164         if ((m_windowStyle 
& wxTE_NO_VSCROLL
) == 0) 
 165             lSstyle 
|= MLS_VSCROLL
; 
 166         if (m_windowStyle 
& wxHSCROLL
) 
 167             lSstyle 
|= MLS_HSCROLL
; 
 168         if (m_windowStyle 
& wxTE_READONLY
) 
 169             lSstyle 
|= MLS_READONLY
; 
 175         if (m_windowStyle 
& wxHSCROLL
) 
 176             lSstyle 
|=  ES_AUTOSCROLL
; 
 177         if (m_windowStyle 
& wxTE_READONLY
) 
 178             lSstyle 
|= ES_READONLY
; 
 179         if (m_windowStyle 
& wxTE_PASSWORD
) // hidden input 
 180             lSstyle 
|= ES_UNREADABLE
; 
 182     if ( pParent
->IsKindOf(CLASSINFO(wxGenericScrolledWindow
)) || 
 183          pParent
->IsKindOf(CLASSINFO(wxScrolledWindow
)) 
 185         lSstyle 
|= WS_CLIPSIBLINGS
; 
 188         m_hWnd 
= (WXHWND
)::WinCreateWindow( (HWND
)GetHwndOf(pParent
) // Parent window handle 
 189                                            ,WC_MLE                   
// Window class 
 190                                            ,(PSZ
)rsValue
.c_str()     // Initial Text 
 191                                            ,(ULONG
)lSstyle           
// Style flags 
 192                                            ,(LONG
)0                  // X pos of origin 
 193                                            ,(LONG
)0                  // Y pos of origin 
 194                                            ,(LONG
)0                  // field width 
 195                                            ,(LONG
)0                  // field height 
 196                                            ,(HWND
)GetHwndOf(pParent
) // owner window handle (same as parent 
 197                                            ,HWND_TOP                 
// initial z position 
 198                                            ,(ULONG
)vId               
// Window identifier 
 199                                            ,NULL                     
// no control data 
 200                                            ,NULL                     
// no Presentation parameters 
 205         m_hWnd 
= (WXHWND
)::WinCreateWindow( (HWND
)GetHwndOf(pParent
) // Parent window handle 
 206                                            ,WC_ENTRYFIELD            
// Window class 
 207                                            ,(PSZ
)rsValue
.c_str()     // Initial Text 
 208                                            ,(ULONG
)lSstyle           
// Style flags 
 209                                            ,(LONG
)0                  // X pos of origin 
 210                                            ,(LONG
)0                  // Y pos of origin 
 211                                            ,(LONG
)0                  // field width 
 212                                            ,(LONG
)0                  // field height 
 213                                            ,(HWND
)GetHwndOf(pParent
) // owner window handle (same as parent 
 214                                            ,HWND_TOP                 
// initial z position 
 215                                            ,(ULONG
)vId               
// Window identifier 
 216                                            ,NULL                     
// no control data 
 217                                            ,NULL                     
// no Presentation parameters 
 226     SubclassWin(GetHWND()); 
 229     // Set font, position, size and initial value 
 231     wxFont
&                         vFontParent 
= pParent
->GetFont(); 
 233     if (vFontParent
.Ok()) 
 235         SetFont(vFontParent
); 
 239         SetFont(wxSystemSettings::GetSystemFont(wxSYS_SYSTEM_FONT
)); 
 241     if (!rsValue
.IsEmpty()) 
 252 } // end of wxTextCtrl::Create 
 255 // Make sure the window style (etc.) reflects the HWND style (roughly) 
 257 void wxTextCtrl::AdoptAttributesFromHWND() 
 259     HWND                            hWnd 
= GetHwnd(); 
 260     LONG                            lStyle 
= ::WinQueryWindowULong(hWnd
, QWL_STYLE
); 
 262     wxWindow::AdoptAttributesFromHWND(); 
 266         m_windowStyle 
|= wxTE_MULTILINE
; 
 267         if (lStyle 
& MLS_READONLY
) 
 268             m_windowStyle 
|= wxTE_READONLY
; 
 272         if (lStyle 
& ES_UNREADABLE
) 
 273             m_windowStyle 
|= wxTE_PASSWORD
; 
 274         if (lStyle 
& ES_READONLY
) 
 275             m_windowStyle 
|= wxTE_READONLY
; 
 277 } // end of wxTextCtrl::AdoptAttributesFromHWND 
 279 void wxTextCtrl::SetupColours() 
 281     wxColour                        vBkgndColour
; 
 283     vBkgndColour 
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW
); 
 284     SetBackgroundColour(vBkgndColour
); 
 285     SetForegroundColour(GetParent()->GetForegroundColour()); 
 286 } // end of wxTextCtrl::SetupColours 
 288 // ---------------------------------------------------------------------------- 
 289 // set/get the controls text 
 290 // ---------------------------------------------------------------------------- 
 292 wxString 
wxTextCtrl::GetValue() const 
 294     wxString                        sStr 
= wxGetWindowText(GetHWND()); 
 295     char*                           zStr 
= (char*)sStr
.c_str(); 
 297     for ( ; *zStr
; zStr
++ ) 
 300         // this will replace \r\n with just \n 
 309 } // end of wxTextCtrl::GetValue 
 311 void wxTextCtrl::SetValue( 
 312   const wxString
&                   rsValue
 
 316     // If the text is long enough, it's faster to just set it instead of first 
 317     // comparing it with the old one (chances are that it will be different 
 318     // anyhow, this comparison is there to avoid flicker for small single-line 
 319     // edit controls mostly) 
 321     if ((rsValue
.length() > 0x400) || (rsValue 
!= GetValue())) 
 323         ::WinSetWindowText(GetHwnd(), rsValue
.c_str()); 
 326 } // end of wxTextCtrl::SetValue 
 328 void wxTextCtrl::WriteText( 
 329   const wxString
&                   rsValue
 
 332     ::WinSetWindowText(GetHwnd(), rsValue
.c_str()); 
 334 } // end of wxTextCtrl::WriteText 
 336 void wxTextCtrl::AppendText( 
 337   const wxString
&                   rsText
 
 340     SetInsertionPointEnd(); 
 342 } // end of wxTextCtrl::AppendText 
 344 void wxTextCtrl::Clear() 
 346     ::WinSetWindowText(GetHwnd(), ""); 
 347 } // end of wxTextCtrl::Clear 
 349 // ---------------------------------------------------------------------------- 
 350 // Clipboard operations 
 351 // ---------------------------------------------------------------------------- 
 353 void wxTextCtrl::Copy() 
 357         HWND hWnd 
= GetHwnd(); 
 359             ::WinSendMsg(hWnd
, MLM_COPY
, 0, 0); 
 361             ::WinSendMsg(hWnd
, EM_COPY
, 0, 0); 
 363 } // end of wxTextCtrl::Copy 
 365 void wxTextCtrl::Cut() 
 369         HWND hWnd 
= GetHwnd(); 
 372             ::WinSendMsg(hWnd
, MLM_CUT
, 0, 0); 
 374             ::WinSendMsg(hWnd
, EM_CUT
, 0, 0); 
 376 } // end of wxTextCtrl::Cut 
 378 void wxTextCtrl::Paste() 
 382         HWND                        hWnd 
= GetHwnd(); 
 384         ::WinSendMsg(hWnd
, EM_PASTE
, 0, 0); 
 386 } // end of wxTextCtrl::Paste 
 388 bool wxTextCtrl::CanCopy() const 
 391     // Can copy if there's a selection 
 396     GetSelection(&lFrom
, &lTo
); 
 397     return (lFrom 
!= lTo
); 
 398 } // end of wxTextCtrl::CanCopy 
 400 bool wxTextCtrl::CanCut() const 
 403     // Can cut if there's a selection 
 408     GetSelection(&lFrom
, &lTo
); 
 409     return (lFrom 
!= lTo
); 
 410 } // end of wxTextCtrl::CanCut 
 412 bool wxTextCtrl::CanPaste() const 
 414     bool                            bIsTextAvailable 
= FALSE
; 
 420     // Check for straight text on clipboard 
 422     if (::WinOpenClipbrd(vHabmain
)) 
 424         bIsTextAvailable 
= (::WinQueryClipbrdData(vHabmain
, CF_TEXT
) != 0); 
 425         ::WinCloseClipbrd(vHabmain
); 
 427     return bIsTextAvailable
; 
 428 } // end of wxTextCtrl::CanPaste 
 430 // ---------------------------------------------------------------------------- 
 432 // ---------------------------------------------------------------------------- 
 434 void wxTextCtrl::SetEditable( 
 438     HWND                            hWnd 
= GetHwnd(); 
 441         ::WinSendMsg(hWnd
, MLM_SETREADONLY
, MPFROMLONG(!bEditable
), (MPARAM
)0); 
 443         ::WinSendMsg(hWnd
, EM_SETREADONLY
, MPFROMLONG(!bEditable
), (MPARAM
)0); 
 444 } // end of wxTextCtrl::SetEditable 
 446 void wxTextCtrl::SetInsertionPoint( 
 450     HWND                            hWnd 
= GetHwnd(); 
 453         ::WinSendMsg(hWnd
, MLM_SETSEL
, (MPARAM
)lPos
, (MPARAM
)lPos
); 
 455         ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lPos
, (USHORT
)lPos
), (MPARAM
)0); 
 456 } // end of wxTextCtrl::SetInsertionPoint 
 458 void wxTextCtrl::SetInsertionPointEnd() 
 460     long                            lPos 
= GetLastPosition(); 
 462     SetInsertionPoint(lPos
); 
 463 } // end of wxTextCtrl::SetInsertionPointEnd 
 465 long wxTextCtrl::GetInsertionPoint() const 
 470         dwPos 
= (WXDWORD
)::WinSendMsg(GetHwnd(), MLM_QUERYSEL
, (MPARAM
)MLFQS_MINSEL
, 0); 
 473         dwPos 
= (WXDWORD
)::WinSendMsg(GetHwnd(), EM_QUERYSEL
, 0, 0); 
 474         dwPos 
= SHORT1FROMMP((MPARAM
)dwPos
);  // the first 16 bit value is the min pos 
 476     return (dwPos 
& 0xFFFF); 
 477 } // end of wxTextCtrl::GetInsertionPoint 
 479 long wxTextCtrl::GetLastPosition() const 
 481     HWND                            hWnd 
= GetHwnd(); 
 490         // This just gets the total text length.  The last will be this value 
 492         lLineLength 
= (long)::WinSendMsg(hWnd
, MLM_QUERYTEXTLENGTH
, 0, 0); 
 499         vParams
.fsStatus 
= WPM_CCHTEXT
; 
 500         if (::WinSendMsg( GetHwnd() 
 501                          ,WM_QUERYWINDOWPARAMS
 
 506             lLineLength 
= (long)vParams
.cchText
; 
 511     return(lCharIndex 
+ lLineLength
); 
 512 } // end of wxTextCtrl::GetLastPosition 
 514 // If the return values from and to are the same, there is no 
 516 void wxTextCtrl::GetSelection( 
 524         dwPos 
= (WXDWORD
)::WinSendMsg(GetHwnd(), MLM_QUERYSEL
, (MPARAM
)MLFQS_MINSEL
, 0); 
 527         dwPos 
= (WXDWORD
)::WinSendMsg(GetHwnd(), EM_QUERYSEL
, 0, 0); 
 529     *plFrom 
= SHORT1FROMMP((MPARAM
)dwPos
);  // the first 16 bit value is the min pos 
 530     *plTo 
= SHORT2FROMMP((MPARAM
)dwPos
);  // the first 16 bit value is the min pos 
 531 } // end of wxTextCtrl::GetSelection 
 533 bool wxTextCtrl::IsEditable() const 
 536         return((bool)LONGFROMMR(::WinSendMsg(GetHwnd(), MLM_QUERYREADONLY
, 0, 0))); 
 538         return((bool)LONGFROMMR(::WinSendMsg(GetHwnd(), EM_QUERYREADONLY
, 0, 0))); 
 539 } // end of wxTextCtrl::IsEditable 
 541 // ---------------------------------------------------------------------------- 
 543 // ---------------------------------------------------------------------------- 
 545 void wxTextCtrl::Replace( 
 548 , const wxString
&                   rsValue
 
 552     HWND                            hWnd      
= GetHwnd(); 
 553     long                            lFromChar 
= lFrom
; 
 557     // Set selection and remove it 
 561         ::WinSendMsg(hWnd
, MLM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0); 
 562         ::WinSendMsg(hWnd
, MLM_CUT
, 0, 0); 
 566         ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0); 
 567         ::WinSendMsg(hWnd
, EM_CUT
, 0, 0); 
 571     // Now replace with 'value', by pasting. 
 573     wxSetClipboardData(wxDF_TEXT
, (wxObject 
*) (const wxChar 
*)rsValue
, 0, 0); 
 575     // Paste into edit control 
 577         ::WinSendMsg(hWnd
, MLM_PASTE
, (MPARAM
)0, (MPARAM
)0); 
 579         ::WinSendMsg(hWnd
, EM_PASTE
, (MPARAM
)0, (MPARAM
)0); 
 581     wxFAIL_MSG("wxTextCtrl::Replace not implemented if wxUSE_CLIPBOARD is 0."); 
 583 }  // end of wxTextCtrl::Replace 
 585 void wxTextCtrl::Remove( 
 590     HWND                            hWnd      
= GetHwnd(); 
 591     long                            lFromChar 
= lFrom
; 
 596         ::WinSendMsg(hWnd
, MLM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0); 
 597         ::WinSendMsg(hWnd
, MLM_CUT
, 0, 0); 
 601         ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0); 
 602         ::WinSendMsg(hWnd
, EM_CUT
, 0, 0); 
 604 } // end of wxTextCtrl::Remove 
 606 void wxTextCtrl::SetSelection( 
 611     HWND                            hWnd 
= GetHwnd(); 
 612     long                            lFromChar 
= lFrom
; 
 616     // If from and to are both -1, it means (in wxWindows) that all text should 
 617     // be selected. Translate into Windows convention 
 619     if ((lFrom 
== -1L) && (lTo 
== -1L)) 
 625         ::WinSendMsg(hWnd
, MLM_SETSEL
, (MPARAM
)lFromChar
, (MPARAM
)lToChar
); 
 627         ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lFromChar
, (USHORT
)lToChar
), (MPARAM
)0); 
 628 } // end of wxTextCtrl::SetSelection 
 630 bool wxTextCtrl::LoadFile( 
 631   const wxString
&                   rsFile
 
 634     if ( wxTextCtrlBase::LoadFile(rsFile
) ) 
 637         // Update the size limit if needed 
 643 } // end of wxTextCtrl::LoadFile 
 645 bool wxTextCtrl::IsModified() const 
 650         bRc 
= (bool)LONGFROMMR(::WinSendMsg(GetHwnd(), MLM_QUERYCHANGED
, 0, 0)); 
 652         bRc 
= (bool)LONGFROMMR(::WinSendMsg(GetHwnd(), EM_QUERYCHANGED
, 0, 0)); 
 654 } // end of wxTextCtrl::IsModified 
 657 // Makes 'unmodified' 
 659 void wxTextCtrl::DiscardEdits() 
 662         ::WinSendMsg(GetHwnd(), MLM_SETCHANGED
, MPFROMLONG(FALSE
), 0); 
 665         // EM controls do not have a SETCHANGED but issuing a query should reset it 
 667         ::WinSendMsg(GetHwnd(), EM_QUERYCHANGED
, 0, 0); 
 668 } // end of wxTextCtrl::DiscardEdits 
 670 int wxTextCtrl::GetNumberOfLines() const 
 675         nNumLines 
= (int)::WinSendMsg(GetHwnd(), MLM_QUERYLINECOUNT
, 0, 0); 
 679 } // end of wxTextCtrl::GetNumberOfLines 
 681 long wxTextCtrl::XYToPosition( 
 686     HWND                            hWnd 
= GetHwnd(); 
 687     long                            lCharIndex 
= 0L; 
 692         lLen 
= (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH
, 0, 0); 
 693         lCharIndex 
= ((lLen 
* lY
) + lX
); 
 698 } // end of wxTextCtrl::XYToPosition 
 700 bool wxTextCtrl::PositionToXY( 
 706     HWND                            hWnd 
= GetHwnd(); 
 711         nLineNo 
= (long)::WinSendMsg(hWnd
, MLM_LINEFROMCHAR
, (MPARAM
)lPos
, 0); 
 722     // This gets the char index for the _beginning_ of this line 
 728         lLineWidth 
= (long)::WinSendMsg(hWnd
, MLM_QUERYLINELENGTH
, (MPARAM
)0, (MPARAM
)0); 
 729         lCharIndex 
= (nLineNo 
+ 1) * lLineWidth
; 
 735         vParams
.fsStatus 
= WPM_CCHTEXT
; 
 736         if (::WinSendMsg( hWnd
 
 737                          ,WM_QUERYWINDOWPARAMS
 
 742             lCharIndex 
= vParams
.cchText
; 
 748     if (lCharIndex 
== -1) 
 754     // The X position must therefore be the difference between pos and charIndex 
 757         *plX 
= lPos 
- lCharIndex
; 
 762 } // end of wxTextCtrl::PositionToXY 
 764 void wxTextCtrl::ShowPosition( 
 768     HWND                            hWnd 
= GetHwnd(); 
 769     long                            lCurrentLineLineNo 
= 0L; 
 771     // To scroll to a position, we pass the number of lines and characters 
 772     // to scroll *by*. This means that we need to: 
 773     // (1) Find the line position of the current line. 
 774     // (2) Find the line position of pos. 
 775     // (3) Scroll by (pos - current). 
 776     // For now, ignore the horizontal scrolling. 
 779     // Is this where scrolling is relative to - the line containing the caret? 
 780     // Or is the first visible line??? Try first visible line. 
 785         // In PM this is the actual char position 
 787         lCurrentLineLineNo 
= (long)::WinSendMsg(hWnd
, MLM_QUERYFIRSTCHAR
, (MPARAM
)0, (MPARAM
)0); 
 790         // This will cause a scroll to the selected position 
 792         ::WinSendMsg(hWnd
, MLM_SETSEL
, (MPARAM
)lCurrentLineLineNo
, (MPARAM
)lCurrentLineLineNo
); 
 794 } // end of wxTextCtrl::ShowPosition 
 796 int wxTextCtrl::GetLineLength( 
 803         lLen 
= (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH
, 0, 0); 
 808         vParams
.fsStatus 
= WPM_CCHTEXT
; 
 809         if (::WinSendMsg( GetHwnd() 
 810                          ,WM_QUERYWINDOWPARAMS
 
 815             lLen 
= vParams
.cchText
; 
 821 } // end ofwxTextCtrl::GetLineLength 
 823 wxString 
wxTextCtrl::GetLineText( 
 827     long                            lLen 
= (long)GetLineLength((long)lLineNo
) + 1; 
 832     // There must be at least enough place for the length WORD in the 
 835     lLen 
+= sizeof(WORD
); 
 836     zBuf 
= new char[lLen
]; 
 843         lLen 
= (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH
, 0, 0); 
 844         lIndex 
= lLen 
* lLineNo
; 
 846         ::WinSendMsg(GetHwnd(), MLM_SETSEL
, (MPARAM
)lIndex
, (MPARAM
)lIndex
); 
 847         ::WinSendMsg(GetHwnd(), MLM_SETIMPORTEXPORT
, MPFROMP(zBuf
), MPFROMSHORT((USHORT
)sizeof(zBuf
))); 
 848         lBuflen 
= (long)::WinSendMsg(GetHwnd(), MLM_QUERYFORMATTEXTLENGTH
, MPFROMLONG(lIndex
), MPFROMLONG(-1)); 
 849         lCopied 
= (long)::WinSendMsg(GetHwnd(), MLM_EXPORT
, MPFROMP(&lIndex
), MPFROMP(&lBuflen
)); 
 850         zBuf
[lCopied
] = '\0'; 
 856         vParams
.fsStatus 
= WPM_CCHTEXT
; 
 857         if (::WinSendMsg( GetHwnd() 
 858                          ,WM_QUERYWINDOWPARAMS
 
 862          memcpy(zBuf
, vParams
.pszText
, vParams
.cchText
); 
 863          zBuf
[vParams
.cchText
] = '\0'; 
 868 } // end of wxTextCtrl::GetLineText 
 870 // ---------------------------------------------------------------------------- 
 872 // ---------------------------------------------------------------------------- 
 874 void wxTextCtrl::Undo() 
 879             ::WinSendMsg(GetHwnd(), MLM_UNDO
, 0, 0); 
 880         // Simple entryfields cannot be undone 
 882 } // end of wxTextCtrl::Undo 
 884 void wxTextCtrl::Redo() 
 889             ::WinSendMsg(GetHwnd(), MLM_UNDO
, 0, 0); 
 890         // Simple entryfields cannot be undone 
 892 } // end of wxTextCtrl::Redo 
 894 bool wxTextCtrl::CanUndo() const 
 899         bOk 
= (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO
, 0, 0) != 0); 
 901         bOk 
= FALSE
; // can't undo regular edit fields in PM 
 903 } // end of wxTextCtrl::CanUndo 
 905 bool wxTextCtrl::CanRedo() const 
 910         bOk 
= (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO
, 0, 0) != 0); 
 912         bOk 
= FALSE
; // can't undo regular edit fields in PM 
 914 } // end of wxTextCtrl::CanRedo 
 916 // ---------------------------------------------------------------------------- 
 917 // implemenation details 
 918 // ---------------------------------------------------------------------------- 
 920 void wxTextCtrl::Command( 
 921   wxCommandEvent
&                   rEvent
 
 924     SetValue(rEvent
.GetString()); 
 925     ProcessCommand (rEvent
); 
 926 } // end of wxTextCtrl::Command 
 928 void wxTextCtrl::OnDropFiles( 
 929   wxDropFilesEvent
&                 rEvent
 
 932     // By default, load the first file into the text window. 
 933     if (rEvent
.GetNumberOfFiles() > 0) 
 935         LoadFile(rEvent
.GetFiles()[0]); 
 937 } // end of wxTextCtrl::OnDropFiles 
 939 WXHBRUSH 
wxTextCtrl::OnCtlColor( 
 948     HPS                             hPS 
= (HPS
)hWxDC
; 
 949     wxBrush
*                        pBrush 
= NULL
; 
 950     wxColour                        vColBack 
= GetBackgroundColour(); 
 951     wxColour                        vColFore 
= GetForegroundColour(); 
 952     wxBrush
*                        pBackgroundBrush 
= wxTheBrushList
->FindOrCreateBrush( GetBackgroundColour() 
 958         HBRUSH                      hBrush 
= NULLHANDLE
; 
 962     if (GetParent()->GetTransparentBackground()) 
 963         ::GpiSetBackMix(hPS
, BM_LEAVEALONE
); 
 965         ::GpiSetBackMix(hPS
, BM_OVERPAINT
); 
 966     if (!IsEnabled() && (GetWindowStyle() & wxTE_MULTILINE
) == 0) 
 967         vColBack 
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
); 
 968     ::GpiSetBackColor(hPS
, vColBack
.GetPixel()); 
 969     ::GpiSetColor(hPS
, vColFore
.GetPixel()); 
 970     return (WXHBRUSH
)pBackgroundBrush
->GetResourceHandle(); 
 971 } // end of wxTextCtrl::OnCtlColor 
 973 void wxTextCtrl::OnChar( 
 977     switch (rEvent
.KeyCode()) 
 980             if ( !(m_windowStyle 
& wxTE_MULTILINE
) ) 
 982                 wxCommandEvent      
vEvent(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
); 
 984                 vEvent
.SetEventObject(this); 
 985                 if ( GetEventHandler()->ProcessEvent(vEvent
)) 
 988             //else: multiline controls need Enter for themselves 
 993             // always produce navigation event - even if we process TAB 
 994             // ourselves the fact that we got here means that the user code 
 995             // decided to skip processing of this TAB - probably to let it 
 996             // do its default job. 
 998             // NB: Notice that Ctrl-Tab is handled elsewhere and Alt-Tab is 
 999             //     handled by Windows 
1001                 wxNavigationKeyEvent    vEventNav
; 
1003                 vEventNav
.SetDirection(!rEvent
.ShiftDown()); 
1004                 vEventNav
.SetWindowChange(FALSE
); 
1005                 vEventNav
.SetEventObject(this); 
1007                 if ( GetEventHandler()->ProcessEvent(vEventNav
) ) 
1013 } // end of wxTextCtrl::OnChar 
1015 bool wxTextCtrl::OS2Command( 
1017 , WXWORD                            
WXUNUSED(vId
) 
1025                 wxFocusEvent        
vEvent( uParam 
== EN_KILLFOCUS 
? wxEVT_KILL_FOCUS
 
1030                 vEvent
.SetEventObject(this); 
1031                 GetEventHandler()->ProcessEvent(vEvent
); 
1037                 wxCommandEvent      
vEvent( wxEVT_COMMAND_TEXT_UPDATED
 
1041                 InitCommandEvent(vEvent
); 
1042                 vEvent
.SetString((char*)GetValue().c_str()); 
1043                 ProcessCommand(vEvent
); 
1049             // The text size limit has been hit - increase it 
1055         case EN_INSERTMODETOGGLE
: 
1066 } // end of wxTextCtrl::OS2Command 
1068 void wxTextCtrl::AdjustSpaceLimit() 
1070     unsigned int                    uLen 
= 0; 
1071     unsigned int                    uLimit 
= 0; 
1073     uLen   
= ::WinQueryWindowTextLength(GetHwnd()); 
1076         uLimit 
= (unsigned int)::WinSendMsg( GetHwnd() 
1087         vParams
.fsStatus 
= WPM_CBCTLDATA
; 
1088         vParams
.cbCtlData 
= sizeof(ENTRYFDATA
); 
1090         if (::WinSendMsg( GetHwnd() 
1091                          ,WM_QUERYWINDOWPARAMS
 
1096             pEfd 
= (ENTRYFDATA
*)vParams
.pCtlData
; 
1097             uLimit 
= (unsigned int)pEfd
->cchEditLimit
; 
1100             uLimit 
= 32; //PM's default 
1104         uLimit 
= uLen 
+ 0x8000;    // 32Kb 
1105         if (uLimit 
> 0xffff) 
1110             ::WinSendMsg(GetHwnd(), MLM_SETTEXTLIMIT
, MPFROMLONG(uLimit
), 0); 
1112             ::WinSendMsg(GetHwnd(), EM_SETTEXTLIMIT
, MPFROMLONG(uLimit
), 0); 
1114 } // end of wxTextCtrl::AdjustSpaceLimit 
1116 bool wxTextCtrl::AcceptsFocus() const 
1119     // We don't want focus if we can't be edited 
1121     return IsEditable() && wxControl::AcceptsFocus(); 
1122 } // end of wxTextCtrl::Command 
1124 wxSize 
wxTextCtrl::DoGetBestSize() const 
1129     wxGetCharSize(GetHWND(), &nCx
, &nCy
, (wxFont
*)&GetFont()); 
1131     int                             wText 
= DEFAULT_ITEM_WIDTH
; 
1132     int                             hText 
= EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy
); 
1134     if (m_windowStyle 
& wxTE_MULTILINE
) 
1136         hText 
*= wxMin(GetNumberOfLines(), 5); 
1138     //else: for single line control everything is ok 
1139     return wxSize(wText
, hText
); 
1140 } // end of wxTextCtrl::DoGetBestSize 
1142 // ---------------------------------------------------------------------------- 
1143 // standard handlers for standard edit menu events 
1144 // ---------------------------------------------------------------------------- 
1146 void wxTextCtrl::OnCut( 
1147   wxCommandEvent
&                   rEvent
 
1151 } // end of wxTextCtrl::OnCut 
1153 void wxTextCtrl::OnCopy( 
1154   wxCommandEvent
&                   rEvent
 
1158 } // end of wxTextCtrl::OnCopy 
1160 void wxTextCtrl::OnPaste( 
1161   wxCommandEvent
&                   rEvent
 
1165 } // end of wxTextCtrl::OnPaste 
1167 void wxTextCtrl::OnUndo( 
1168   wxCommandEvent
&                   rEvent
 
1172 } // end of wxTextCtrl::OnUndo 
1174 void wxTextCtrl::OnRedo( 
1175   wxCommandEvent
&                   rEvent
 
1179 } // end of wxTextCtrl::OnRedo 
1181 void wxTextCtrl::OnUpdateCut( 
1182   wxUpdateUIEvent
&                  rEvent
 
1185     rEvent
.Enable(CanCut()); 
1186 } // end of wxTextCtrl::OnUpdateCut 
1188 void wxTextCtrl::OnUpdateCopy( 
1189   wxUpdateUIEvent
&                  rEvent
 
1192     rEvent
.Enable(CanCopy()); 
1193 } // end of wxTextCtrl::OnUpdateCopy 
1195 void wxTextCtrl::OnUpdatePaste( 
1196   wxUpdateUIEvent
&                  rEvent
 
1199     rEvent
.Enable(CanPaste()); 
1200 } // end of wxTextCtrl::OnUpdatePaste 
1202 void wxTextCtrl::OnUpdateUndo( 
1203   wxUpdateUIEvent
&                  rEvent
 
1206     rEvent
.Enable(CanUndo()); 
1207 } // end of wxTextCtrl::OnUpdateUndo 
1209 void wxTextCtrl::OnUpdateRedo( 
1210   wxUpdateUIEvent
&                  rEvent
 
1213     rEvent
.Enable(CanRedo()); 
1214 } // end of wxTextCtrl::OnUpdateRedo 
1216 bool wxTextCtrl::SetBackgroundColour( 
1217   const wxColour
&                   rColour
 
1221         ::WinSendMsg(GetHwnd(), MLM_SETBACKCOLOR
, (MPARAM
)rColour
.GetPixel(), MLE_INDEX
); 
1223 } // end of wxTextCtrl::SetBackgroundColour 
1225 bool wxTextCtrl::SetForegroundColour( 
1226   const wxColour
&                   rColour
 
1230         ::WinSendMsg(GetHwnd(), MLM_SETTEXTCOLOR
, (MPARAM
)rColour
.GetPixel(), MLE_INDEX
); 
1232 } // end of wxTextCtrl::SetForegroundColour 
1234 bool wxTextCtrl::SetStyle( 
1237 , const wxTextAttr
&                 rStyle
 
1240     HWND                            hWnd 
= GetHwnd(); 
1251     // We can only change the format of the selection, so select the range we 
1252     // want and restore the old selection later 
1257     GetSelection( &lStartOld
 
1262     // But do we really have to change the selection? 
1264     bool                            bChangeSel 
= lStart 
!= lStartOld 
|| 
1270             ::WinSendMsg(hWnd
, MLM_SETSEL
, MPFROM2SHORT((USHORT
)lStart
, (USHORT
)lEnd
), 0); 
1272             ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lStart
, (USHORT
)lEnd
), 0); 
1276     // TODO:: finish this part 
1279 } // end of wxTextCtrl::SetStyle