home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / os2 / textctrl.cpp < prev    next >
C/C++ Source or Header  |  2002-12-27  |  41KB  |  1,381 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        textctrl.cpp
  3. // Purpose:     wxTextCtrl
  4. // Author:      David Webster
  5. // Modified by:
  6. // Created:     10/17/99
  7. // RCS-ID:      $Id: TEXTCTRL.CPP,v 1.32.2.3 2002/12/27 14:49:36 JS Exp $
  8. // Copyright:   (c) David Webster
  9. // Licence:     wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ----------------------------------------------------------------------------
  13. // headers
  14. // ----------------------------------------------------------------------------
  15.  
  16. // For compilers that support precompilation, includes "wx.h".
  17. #include "wx/wxprec.h"
  18.  
  19. #ifndef WX_PRECOMP
  20.     #include "wx/textctrl.h"
  21.     #include "wx/scrolwin.h"
  22.     #include "wx/settings.h"
  23.     #include "wx/brush.h"
  24.     #include "wx/utils.h"
  25.     #include "wx/log.h"
  26. #endif
  27.  
  28. #if wxUSE_CLIPBOARD
  29.     #include "wx/app.h"
  30.     #include "wx/clipbrd.h"
  31. #endif
  32.  
  33. #include "wx/textfile.h"
  34.  
  35. #include "wx/os2/private.h"
  36.  
  37. #include <string.h>
  38. #include <stdlib.h>
  39. #include <sys/types.h>
  40.  
  41. #if wxUSE_IOSTREAMH
  42. #   include <fstream.h>
  43. #else
  44. #   include <fstream>
  45. #endif
  46.  
  47. #if !defined(MLE_INDEX)
  48. #define MLE_INDEX  0
  49. #define MLE_RGB    1
  50. #endif
  51.  
  52.  
  53. // ----------------------------------------------------------------------------
  54. // event tables and other macros
  55. // ----------------------------------------------------------------------------
  56.  
  57. IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
  58.  
  59. BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
  60.     EVT_CHAR(wxTextCtrl::OnChar)
  61.     EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
  62.  
  63.     EVT_MENU(wxID_CUT, wxTextCtrl::OnCut)
  64.     EVT_MENU(wxID_COPY, wxTextCtrl::OnCopy)
  65.     EVT_MENU(wxID_PASTE, wxTextCtrl::OnPaste)
  66.     EVT_MENU(wxID_UNDO, wxTextCtrl::OnUndo)
  67.     EVT_MENU(wxID_REDO, wxTextCtrl::OnRedo)
  68.  
  69.     EVT_UPDATE_UI(wxID_CUT, wxTextCtrl::OnUpdateCut)
  70.     EVT_UPDATE_UI(wxID_COPY, wxTextCtrl::OnUpdateCopy)
  71.     EVT_UPDATE_UI(wxID_PASTE, wxTextCtrl::OnUpdatePaste)
  72.     EVT_UPDATE_UI(wxID_UNDO, wxTextCtrl::OnUpdateUndo)
  73.     EVT_UPDATE_UI(wxID_REDO, wxTextCtrl::OnUpdateRedo)
  74. END_EVENT_TABLE()
  75.  
  76.  
  77. // ============================================================================
  78. // implementation
  79. // ============================================================================
  80.  
  81. // ----------------------------------------------------------------------------
  82. // creation
  83. // ----------------------------------------------------------------------------
  84.  
  85. wxTextCtrl::wxTextCtrl()
  86. {
  87. }
  88.  
  89. wxTextCtrl::~wxTextCtrl()
  90. {
  91. }
  92.  
  93. bool wxTextCtrl::Create(
  94.   wxWindow*                         pParent
  95. , wxWindowID                        vId
  96. , const wxString&                   rsValue
  97. , const wxPoint&                    rPos
  98. , const wxSize&                     rSize
  99. , long                              lStyle
  100. , const wxValidator&                rValidator
  101. , const wxString&                   rsName
  102. )
  103. {
  104.     HWND                            hParent;
  105.     int                             nTempy;
  106.  
  107.     //
  108.     // Base initialization
  109.     //
  110.     if ( !CreateBase( pParent
  111.                      ,vId
  112.                      ,rPos
  113.                      ,rSize
  114.                      ,lStyle
  115.                      ,rValidator
  116.                      ,rsName
  117.                     ))
  118.         return FALSE;
  119.  
  120.     wxPoint                         vPos = rPos; // The OS/2 position
  121.     SWP                             vSwp;
  122.  
  123.     if (pParent )
  124.     {
  125.         pParent->AddChild(this);
  126.     }
  127.  
  128.     m_windowStyle = lStyle;
  129.     m_bIsMLE = FALSE;
  130.  
  131.     long                            lSstyle = WS_VISIBLE | WS_TABSTOP;
  132.  
  133.     //
  134.     // Single and multiline edit fields are two different controls in PM
  135.     //
  136.     if ( m_windowStyle & wxTE_MULTILINE )
  137.     {
  138.         lSstyle |= MLS_BORDER | MLS_WORDWRAP;
  139.         m_bIsMLE = TRUE;
  140.  
  141.         if ((m_windowStyle & wxTE_NO_VSCROLL) == 0)
  142.             lSstyle |= MLS_VSCROLL;
  143.         if (m_windowStyle & wxHSCROLL)
  144.             lSstyle |= MLS_HSCROLL;
  145.         if (m_windowStyle & wxTE_READONLY)
  146.             lSstyle |= MLS_READONLY;
  147.     }
  148.     else
  149.     {
  150.         lSstyle |= ES_LEFT | ES_AUTOSCROLL | ES_MARGIN;
  151.  
  152.         if (m_windowStyle & wxHSCROLL)
  153.             lSstyle |=  ES_AUTOSCROLL;
  154.         if (m_windowStyle & wxTE_READONLY)
  155.             lSstyle |= ES_READONLY;
  156.         if (m_windowStyle & wxTE_PASSWORD) // hidden input
  157.             lSstyle |= ES_UNREADABLE;
  158.     }
  159.  
  160.     if (m_bIsMLE)
  161.     {
  162.         m_hWnd = (WXHWND)::WinCreateWindow( (HWND)GetHwndOf(pParent) // Parent window handle
  163.                                            ,WC_MLE                   // Window class
  164.                                            ,(PSZ)rsValue.c_str()     // Initial Text
  165.                                            ,(ULONG)lSstyle           // Style flags
  166.                                            ,(LONG)0                  // X pos of origin
  167.                                            ,(LONG)0                  // Y pos of origin
  168.                                            ,(LONG)0                  // field width
  169.                                            ,(LONG)0                  // field height
  170.                                            ,(HWND)GetHwndOf(pParent) // owner window handle (same as parent
  171.                                            ,HWND_TOP                 // initial z position
  172.                                            ,(ULONG)vId               // Window identifier
  173.                                            ,NULL                     // no control data
  174.                                            ,NULL                     // no Presentation parameters
  175.                                           );
  176.     }
  177.     else
  178.     {
  179.         m_hWnd = (WXHWND)::WinCreateWindow( (HWND)GetHwndOf(pParent) // Parent window handle
  180.                                            ,WC_ENTRYFIELD            // Window class
  181.                                            ,(PSZ)rsValue.c_str()     // Initial Text
  182.                                            ,(ULONG)lSstyle           // Style flags
  183.                                            ,(LONG)0                  // X pos of origin
  184.                                            ,(LONG)0                  // Y pos of origin
  185.                                            ,(LONG)0                  // field width
  186.                                            ,(LONG)0                  // field height
  187.                                            ,(HWND)GetHwndOf(pParent) // owner window handle (same as parent
  188.                                            ,HWND_TOP                 // initial z position
  189.                                            ,(ULONG)vId               // Window identifier
  190.                                            ,NULL                     // no control data
  191.                                            ,NULL                     // no Presentation parameters
  192.                                           );
  193.     }
  194.  
  195.     if (m_hWnd == 0)
  196.     {
  197.         return FALSE;
  198.     }
  199.  
  200.     SubclassWin(GetHWND());
  201.  
  202.     //
  203.     // Set font, position, size and initial value
  204.     //
  205.     wxFont*                          pTextFont = new wxFont( 8
  206.                                                             ,wxMODERN
  207.                                                             ,wxNORMAL
  208.                                                             ,wxNORMAL
  209.                                                            );
  210.     SetFont(*pTextFont);
  211.     if (!rsValue.IsEmpty())
  212.     {
  213.         SetValue(rsValue);
  214.     }
  215.     SetupColours();
  216.     //
  217.     // If X and/or Y are not zero the difference is the compensation value
  218.     // for margins for OS/2 controls.
  219.     //
  220.     ::WinQueryWindowPos(m_hWnd, &vSwp);
  221.     SetXComp(vSwp.x);
  222.     SetYComp(vSwp.y);
  223.     SetSize( vPos.x - GetXComp()
  224.             ,vPos.y - GetYComp()
  225.             ,rSize.x
  226.             ,rSize.y
  227.            );
  228.     delete pTextFont;
  229.     return TRUE;
  230. } // end of wxTextCtrl::Create
  231.  
  232. //
  233. // Make sure the window style (etc.) reflects the HWND style (roughly)
  234. //
  235. void wxTextCtrl::AdoptAttributesFromHWND()
  236. {
  237.     HWND                            hWnd = GetHwnd();
  238.     LONG                            lStyle = ::WinQueryWindowULong(hWnd, QWL_STYLE);
  239.  
  240.     wxWindow::AdoptAttributesFromHWND();
  241.  
  242.     if (m_bIsMLE)
  243.     {
  244.         m_windowStyle |= wxTE_MULTILINE;
  245.         if (lStyle & MLS_READONLY)
  246.             m_windowStyle |= wxTE_READONLY;
  247.     }
  248.     else
  249.     {
  250.         if (lStyle & ES_UNREADABLE)
  251.             m_windowStyle |= wxTE_PASSWORD;
  252.         if (lStyle & ES_READONLY)
  253.             m_windowStyle |= wxTE_READONLY;
  254.     }
  255. } // end of wxTextCtrl::AdoptAttributesFromHWND
  256.  
  257. WXDWORD wxTextCtrl::OS2GetStyle(
  258.   long                              lStyle
  259. , WXDWORD*                          pdwExstyle
  260. ) const
  261. {
  262.     //
  263.     // Default border for the text controls is the sunken one
  264.     //
  265.     if ((lStyle & wxBORDER_MASK) == wxBORDER_DEFAULT )
  266.     {
  267.         lStyle |= wxBORDER_SUNKEN;
  268.     }
  269.  
  270.     long                            dwStyle = wxControl::OS2GetStyle( lStyle
  271.                                                                      ,pdwExstyle
  272.                                                                     );
  273.  
  274.     dwStyle = WS_VISIBLE | WS_TABSTOP;
  275.  
  276.     //
  277.     // Single and multiline edit fields are two different controls in PM
  278.     //
  279.     if ( m_windowStyle & wxTE_MULTILINE )
  280.     {
  281.         dwStyle |= MLS_BORDER | MLS_WORDWRAP;
  282.         if ((m_windowStyle & wxTE_NO_VSCROLL) == 0)
  283.             dwStyle |= MLS_VSCROLL;
  284.         if (m_windowStyle & wxHSCROLL)
  285.             dwStyle |= MLS_HSCROLL;
  286.         if (m_windowStyle & wxTE_READONLY)
  287.             dwStyle |= MLS_READONLY;
  288.     }
  289.     else
  290.     {
  291.         dwStyle |= ES_LEFT | ES_AUTOSCROLL | ES_MARGIN;
  292.         if (m_windowStyle & wxHSCROLL)
  293.             dwStyle |=  ES_AUTOSCROLL;
  294.         if (m_windowStyle & wxTE_READONLY)
  295.             dwStyle |= ES_READONLY;
  296.         if (m_windowStyle & wxTE_PASSWORD) // hidden input
  297.             dwStyle |= ES_UNREADABLE;
  298.     }
  299.     return dwStyle;
  300. } // end of wxTextCtrl::OS2GetStyle
  301.  
  302. void wxTextCtrl::SetWindowStyleFlag(
  303.   long                              lStyle
  304. )
  305. {
  306.     wxControl::SetWindowStyleFlag(lStyle);
  307. } // end of wxTextCtrl::SetWindowStyleFlag
  308.  
  309. void wxTextCtrl::SetupColours()
  310. {
  311.     wxColour                        vBkgndColour;
  312.  
  313.     vBkgndColour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
  314.     SetBackgroundColour(vBkgndColour);
  315.     SetForegroundColour(GetParent()->GetForegroundColour());
  316.     if (m_bIsMLE)
  317.     {
  318.         ::WinSendMsg( GetHwnd()
  319.                      ,MLM_SETTEXTCOLOR
  320.                      ,(MPARAM)GetParent()->GetForegroundColour().GetPixel()
  321.                      ,(MPARAM)MLE_RGB
  322.                     );
  323.     }
  324. } // end of wxTextCtrl::SetupColours
  325.  
  326. // ----------------------------------------------------------------------------
  327. // set/get the controls text
  328. // ----------------------------------------------------------------------------
  329.  
  330. wxString wxTextCtrl::GetValue() const
  331. {
  332.     wxString                        sStr = wxGetWindowText(GetHWND());
  333.     char*                           zStr = (char*)sStr.c_str();
  334.  
  335.     for ( ; *zStr; zStr++ )
  336.     {
  337.         //
  338.         // this will replace \r\n with just \n
  339.         //
  340.         if (*zStr == '\n')
  341.             *zStr = '\0';
  342.         if (*zStr == '\r')
  343.             *zStr = '\n';
  344.     }
  345.     return sStr;
  346. } // end of wxTextCtrl::GetValue
  347.  
  348. void wxTextCtrl::SetValue(
  349.   const wxString&                   rsValue
  350. )
  351. {
  352.     //
  353.     // If the text is long enough, it's faster to just set it instead of first
  354.     // comparing it with the old one (chances are that it will be different
  355.     // anyhow, this comparison is there to avoid flicker for small single-line
  356.     // edit controls mostly)
  357.     //
  358.     if ((rsValue.length() > 0x400) || (rsValue != GetValue()))
  359.     {
  360.         ::WinSetWindowText(GetHwnd(), rsValue.c_str());
  361.         AdjustSpaceLimit();
  362.     }
  363. } // end of wxTextCtrl::SetValue
  364.  
  365. void wxTextCtrl::WriteText(
  366.   const wxString&                   rsValue
  367. )
  368. {
  369.     if (m_bIsMLE)
  370.         ::WinSendMsg(GetHwnd(), MLM_INSERT, MPARAM((PCHAR)rsValue.c_str()), MPARAM(0));
  371.     else
  372.         ::WinSetWindowText(GetHwnd(), rsValue.c_str());
  373.     AdjustSpaceLimit();
  374. } // end of wxTextCtrl::WriteText
  375.  
  376. void wxTextCtrl::AppendText(
  377.   const wxString&                   rsText
  378. )
  379. {
  380.     SetInsertionPointEnd();
  381.     WriteText(rsText);
  382. } // end of wxTextCtrl::AppendText
  383.  
  384. void wxTextCtrl::Clear()
  385. {
  386.     ::WinSetWindowText(GetHwnd(), "");
  387. } // end of wxTextCtrl::Clear
  388.  
  389. bool wxTextCtrl::EmulateKeyPress(
  390.   const wxKeyEvent&                 rEvent
  391. )
  392. {
  393.     SetFocus();
  394.     return(wxTextCtrlBase::EmulateKeyPress(rEvent));
  395. } // end of wxTextCtrl::EmulateKeyPress
  396.  
  397. // ----------------------------------------------------------------------------
  398. // Clipboard operations
  399. // ----------------------------------------------------------------------------
  400.  
  401. void wxTextCtrl::Copy()
  402. {
  403.     if (CanCopy())
  404.     {
  405.         HWND hWnd = GetHwnd();
  406.         if (m_bIsMLE)
  407.             ::WinSendMsg(hWnd, MLM_COPY, 0, 0);
  408.         else
  409.             ::WinSendMsg(hWnd, EM_COPY, 0, 0);
  410.     }
  411. } // end of wxTextCtrl::Copy
  412.  
  413. void wxTextCtrl::Cut()
  414. {
  415.     if (CanCut())
  416.     {
  417.         HWND hWnd = GetHwnd();
  418.  
  419.         if (m_bIsMLE)
  420.             ::WinSendMsg(hWnd, MLM_CUT, 0, 0);
  421.         else
  422.             ::WinSendMsg(hWnd, EM_CUT, 0, 0);
  423.     }
  424. } // end of wxTextCtrl::Cut
  425.  
  426. void wxTextCtrl::Paste()
  427. {
  428.     if (CanPaste())
  429.     {
  430.         HWND                        hWnd = GetHwnd();
  431.  
  432.         ::WinSendMsg(hWnd, EM_PASTE, 0, 0);
  433.     }
  434. } // end of wxTextCtrl::Paste
  435.  
  436. bool wxTextCtrl::CanCopy() const
  437. {
  438.     //
  439.     // Can copy if there's a selection
  440.     //
  441.     long                            lFrom = 0L;
  442.     long                            lTo = 0L;
  443.  
  444.     GetSelection(&lFrom, &lTo);
  445.     return (lFrom != lTo);
  446. } // end of wxTextCtrl::CanCopy
  447.  
  448. bool wxTextCtrl::CanCut() const
  449. {
  450.     //
  451.     // Can cut if there's a selection
  452.     //
  453.     long                            lFrom = 0L;
  454.     long                            lTo = 0L;
  455.  
  456.     GetSelection(&lFrom, &lTo);
  457.     return (lFrom != lTo);
  458. } // end of wxTextCtrl::CanCut
  459.  
  460. bool wxTextCtrl::CanPaste() const
  461. {
  462.     bool                            bIsTextAvailable = FALSE;
  463.  
  464.     if (!IsEditable())
  465.         return FALSE;
  466.  
  467.     //
  468.     // Check for straight text on clipboard
  469.     //
  470.     if (::WinOpenClipbrd(vHabmain))
  471.     {
  472.         bIsTextAvailable = (::WinQueryClipbrdData(vHabmain, CF_TEXT) != 0);
  473.         ::WinCloseClipbrd(vHabmain);
  474.     }
  475.     return bIsTextAvailable;
  476. } // end of wxTextCtrl::CanPaste
  477.  
  478. // ----------------------------------------------------------------------------
  479. // Accessors
  480. // ----------------------------------------------------------------------------
  481.  
  482. void wxTextCtrl::SetEditable(
  483.   bool                              bEditable
  484. )
  485. {
  486.     HWND                            hWnd = GetHwnd();
  487.  
  488.     if (m_bIsMLE)
  489.         ::WinSendMsg(hWnd, MLM_SETREADONLY, MPFROMLONG(!bEditable), (MPARAM)0);
  490.     else
  491.         ::WinSendMsg(hWnd, EM_SETREADONLY, MPFROMLONG(!bEditable), (MPARAM)0);
  492. } // end of wxTextCtrl::SetEditable
  493.  
  494. void wxTextCtrl::SetInsertionPoint(
  495.   long                              lPos
  496. )
  497. {
  498.     HWND                            hWnd = GetHwnd();
  499.  
  500.     if (m_bIsMLE)
  501.         ::WinSendMsg(hWnd, MLM_SETSEL, (MPARAM)lPos, (MPARAM)lPos);
  502.     else
  503.         ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lPos, (USHORT)lPos), (MPARAM)0);
  504. } // end of wxTextCtrl::SetInsertionPoint
  505.  
  506. void wxTextCtrl::SetInsertionPointEnd()
  507. {
  508.     long                            lPos = GetLastPosition();
  509.  
  510.     SetInsertionPoint(lPos);
  511. } // end of wxTextCtrl::SetInsertionPointEnd
  512.  
  513. long wxTextCtrl::GetInsertionPoint() const
  514. {
  515.     WXDWORD                         dwPos = 0L;
  516.  
  517.     if (m_bIsMLE)
  518.         dwPos = (WXDWORD)::WinSendMsg(GetHwnd(), MLM_QUERYSEL, (MPARAM)MLFQS_MINSEL, 0);
  519.     else
  520.     {
  521.         dwPos = (WXDWORD)::WinSendMsg(GetHwnd(), EM_QUERYSEL, 0, 0);
  522.         dwPos = SHORT1FROMMP((MPARAM)dwPos);  // the first 16 bit value is the min pos
  523.     }
  524.     return (dwPos & 0xFFFF);
  525. } // end of wxTextCtrl::GetInsertionPoint
  526.  
  527. long wxTextCtrl::GetLastPosition() const
  528. {
  529.     HWND                            hWnd = GetHwnd();
  530.     long                            lCharIndex;
  531.     long                            lLineLength;
  532.  
  533.     if (m_bIsMLE)
  534.     {
  535.         lCharIndex = 0;
  536.  
  537.         //
  538.         // This just gets the total text length.  The last will be this value
  539.         //
  540.         lLineLength = (long)::WinSendMsg(hWnd, MLM_QUERYTEXTLENGTH, 0, 0);
  541.     }
  542.     else
  543.     {
  544.         WNDPARAMS                   vParams;
  545.  
  546.         lCharIndex = 0;
  547.         vParams.fsStatus = WPM_CCHTEXT;
  548.         if (::WinSendMsg( GetHwnd()
  549.                          ,WM_QUERYWINDOWPARAMS
  550.                          ,&vParams
  551.                          ,0
  552.                         ))
  553.         {
  554.             lLineLength = (long)vParams.cchText;
  555.         }
  556.         else
  557.             lLineLength = 0;
  558.     }
  559.     return(lCharIndex + lLineLength);
  560. } // end of wxTextCtrl::GetLastPosition
  561.  
  562. // If the return values from and to are the same, there is no
  563. // selection.
  564. void wxTextCtrl::GetSelection(
  565.   long*                             plFrom
  566. , long*                             plTo
  567. ) const
  568. {
  569.     WXDWORD                         dwPos;
  570.  
  571.     if (m_bIsMLE)
  572.         dwPos = (WXDWORD)::WinSendMsg(GetHwnd(), MLM_QUERYSEL, (MPARAM)MLFQS_MINSEL, 0);
  573.     else
  574.     {
  575.         dwPos = (WXDWORD)::WinSendMsg(GetHwnd(), EM_QUERYSEL, 0, 0);
  576.     }
  577.     *plFrom = SHORT1FROMMP((MPARAM)dwPos);  // the first 16 bit value is the min pos
  578.     *plTo = SHORT2FROMMP((MPARAM)dwPos);  // the first 16 bit value is the min pos
  579. } // end of wxTextCtrl::GetSelection
  580.  
  581. bool wxTextCtrl::IsEditable() const
  582. {
  583.     if (m_bIsMLE)
  584.         return((bool)LONGFROMMR(::WinSendMsg(GetHwnd(), MLM_QUERYREADONLY, 0, 0)));
  585.     else
  586.         return((bool)LONGFROMMR(::WinSendMsg(GetHwnd(), EM_QUERYREADONLY, 0, 0)));
  587. } // end of wxTextCtrl::IsEditable
  588.  
  589. // ----------------------------------------------------------------------------
  590. // Editing
  591. // ----------------------------------------------------------------------------
  592.  
  593. void wxTextCtrl::Replace(
  594.   long                              lFrom
  595. , long                              lTo
  596. , const wxString&                   rsValue
  597. )
  598. {
  599. #if wxUSE_CLIPBOARD
  600.     HWND                            hWnd      = GetHwnd();
  601.     long                            lFromChar = lFrom;
  602.     long                            lToChar   = lTo;
  603.  
  604.     //
  605.     // Set selection and remove it
  606.     //
  607.     if (m_bIsMLE)
  608.     {
  609.         ::WinSendMsg(hWnd, MLM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
  610.         ::WinSendMsg(hWnd, MLM_CUT, 0, 0);
  611.     }
  612.     else
  613.     {
  614.         ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
  615.         ::WinSendMsg(hWnd, EM_CUT, 0, 0);
  616.     }
  617.  
  618.     //
  619.     // Now replace with 'value', by pasting.
  620.     //
  621.     wxSetClipboardData(wxDF_TEXT, (wxObject *) (const wxChar *)rsValue, 0, 0);
  622.  
  623.     // Paste into edit control
  624.     if (m_bIsMLE)
  625.         ::WinSendMsg(hWnd, MLM_PASTE, (MPARAM)0, (MPARAM)0);
  626.     else
  627.         ::WinSendMsg(hWnd, EM_PASTE, (MPARAM)0, (MPARAM)0);
  628. #else
  629.     wxFAIL_MSG("wxTextCtrl::Replace not implemented if wxUSE_CLIPBOARD is 0.");
  630. #endif
  631. }  // end of wxTextCtrl::Replace
  632.  
  633. void wxTextCtrl::Remove(
  634.   long                              lFrom
  635. , long                              lTo
  636. )
  637. {
  638.     HWND                            hWnd      = GetHwnd();
  639.     long                            lFromChar = lFrom;
  640.     long                            lToChar   = lTo;
  641.  
  642.     if (m_bIsMLE)
  643.     {
  644.         ::WinSendMsg(hWnd, MLM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
  645.         ::WinSendMsg(hWnd, MLM_CUT, 0, 0);
  646.     }
  647.     else
  648.     {
  649.         ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
  650.         ::WinSendMsg(hWnd, EM_CUT, 0, 0);
  651.     }
  652. } // end of wxTextCtrl::Remove
  653.  
  654. void wxTextCtrl::SetSelection(
  655.   long                              lFrom
  656. , long                              lTo
  657. )
  658. {
  659.     HWND                            hWnd = GetHwnd();
  660.     long                            lFromChar = lFrom;
  661.     long                            lToChar = lTo;
  662.  
  663.     //
  664.     // If from and to are both -1, it means (in wxWindows) that all text should
  665.     // be selected. Translate into Windows convention
  666.     //
  667.     if ((lFrom == -1L) && (lTo == -1L))
  668.     {
  669.         lFromChar = 0L;
  670.         lToChar   = -1L;
  671.     }
  672.     if (m_bIsMLE)
  673.         ::WinSendMsg(hWnd, MLM_SETSEL, (MPARAM)lFromChar, (MPARAM)lToChar);
  674.     else
  675.         ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFromChar, (USHORT)lToChar), (MPARAM)0);
  676. } // end of wxTextCtrl::SetSelection
  677.  
  678. bool wxTextCtrl::LoadFile(
  679.   const wxString&                   rsFile
  680. )
  681. {
  682.     if ( wxTextCtrlBase::LoadFile(rsFile) )
  683.     {
  684.         //
  685.         // Update the size limit if needed
  686.         //
  687.         AdjustSpaceLimit();
  688.         return TRUE;
  689.     }
  690.     return FALSE;
  691. } // end of wxTextCtrl::LoadFile
  692.  
  693. bool wxTextCtrl::IsModified() const
  694. {
  695.     bool                            bRc;
  696.  
  697.     if (m_bIsMLE)
  698.         bRc = (bool)LONGFROMMR(::WinSendMsg(GetHwnd(), MLM_QUERYCHANGED, 0, 0));
  699.     else
  700.         bRc = (bool)LONGFROMMR(::WinSendMsg(GetHwnd(), EM_QUERYCHANGED, 0, 0));
  701.     return bRc;
  702. } // end of wxTextCtrl::IsModified
  703.  
  704. //
  705. // Makes 'unmodified'
  706. //
  707. void wxTextCtrl::DiscardEdits()
  708. {
  709.     if (m_bIsMLE)
  710.         ::WinSendMsg(GetHwnd(), MLM_SETCHANGED, MPFROMLONG(FALSE), 0);
  711.     else
  712.         //
  713.         // EM controls do not have a SETCHANGED but issuing a query should reset it
  714.         //
  715.         ::WinSendMsg(GetHwnd(), EM_QUERYCHANGED, 0, 0);
  716. } // end of wxTextCtrl::DiscardEdits
  717.  
  718. int wxTextCtrl::GetNumberOfLines() const
  719. {
  720.     int                             nNumLines;
  721.  
  722.     if (m_bIsMLE)
  723.         nNumLines = (int)::WinSendMsg(GetHwnd(), MLM_QUERYLINECOUNT, 0, 0);
  724.     else
  725.         nNumLines = 1;
  726.     return nNumLines;
  727. } // end of wxTextCtrl::GetNumberOfLines
  728.  
  729. long wxTextCtrl::XYToPosition(
  730.   long                              lX
  731. , long                              lY
  732. ) const
  733. {
  734.     HWND                            hWnd = GetHwnd();
  735.     long                            lCharIndex = 0L;
  736.     long                            lLen;
  737.  
  738.     if (m_bIsMLE)
  739.     {
  740.         lLen = (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH, 0, 0);
  741.         lCharIndex = ((lLen * lY) + lX);
  742.     }
  743.     else
  744.         lCharIndex = lX;
  745.     return lCharIndex;
  746. } // end of wxTextCtrl::XYToPosition
  747.  
  748. bool wxTextCtrl::PositionToXY(
  749.   long                              lPos
  750. , long*                             plX
  751. , long*                             plY
  752. ) const
  753. {
  754.     HWND                            hWnd = GetHwnd();
  755.     long                            nLineNo = -1;
  756.     long                            lCharIndex = 0;
  757.  
  758.     if (m_bIsMLE)
  759.         nLineNo = (long)::WinSendMsg(hWnd, MLM_LINEFROMCHAR, (MPARAM)lPos, 0);
  760.     else
  761.         nLineNo = 0;
  762.  
  763.     if (nLineNo == -1)
  764.     {
  765.         // no such line
  766.         return FALSE;
  767.     }
  768.  
  769.     //
  770.     // This gets the char index for the _beginning_ of this line
  771.     //
  772.     long                            lLineWidth;
  773.  
  774.     if (m_bIsMLE)
  775.     {
  776.         lLineWidth = (long)::WinSendMsg(hWnd, MLM_QUERYLINELENGTH, (MPARAM)0, (MPARAM)0);
  777.         lCharIndex = (nLineNo + 1) * lLineWidth;
  778.     }
  779.     else
  780.     {
  781.         WNDPARAMS                   vParams;
  782.  
  783.         vParams.fsStatus = WPM_CCHTEXT;
  784.         if (::WinSendMsg( hWnd
  785.                          ,WM_QUERYWINDOWPARAMS
  786.                          ,&vParams
  787.                          ,0
  788.                         ))
  789.         {
  790.             lCharIndex = vParams.cchText;
  791.         }
  792.         else
  793.             lCharIndex = 32;
  794.     }
  795.  
  796.     if (lCharIndex == -1)
  797.     {
  798.         return FALSE;
  799.     }
  800.  
  801.     //
  802.     // The X position must therefore be the difference between pos and charIndex
  803.     //
  804.     if (plX)
  805.         *plX = lPos - lCharIndex;
  806.     if (plY)
  807.         *plY = nLineNo;
  808.  
  809.     return TRUE;
  810. } // end of wxTextCtrl::PositionToXY
  811.  
  812. void wxTextCtrl::ShowPosition(
  813.   long                              lPos
  814. )
  815. {
  816.     HWND                            hWnd = GetHwnd();
  817.     long                            lCurrentLineLineNo = 0L;
  818.  
  819.     // To scroll to a position, we pass the number of lines and characters
  820.     // to scroll *by*. This means that we need to:
  821.     // (1) Find the line position of the current line.
  822.     // (2) Find the line position of pos.
  823.     // (3) Scroll by (pos - current).
  824.     // For now, ignore the horizontal scrolling.
  825.  
  826.     //
  827.     // Is this where scrolling is relative to - the line containing the caret?
  828.     // Or is the first visible line??? Try first visible line.
  829.     //
  830.     if (m_bIsMLE)
  831.     {
  832.         //
  833.         // In PM this is the actual char position
  834.         //
  835.         lCurrentLineLineNo = (long)::WinSendMsg(hWnd, MLM_QUERYFIRSTCHAR, (MPARAM)0, (MPARAM)0);
  836.  
  837.         //
  838.         // This will cause a scroll to the selected position
  839.         //
  840.         ::WinSendMsg(hWnd, MLM_SETSEL, (MPARAM)lCurrentLineLineNo, (MPARAM)lCurrentLineLineNo);
  841.     }
  842. } // end of wxTextCtrl::ShowPosition
  843.  
  844. int wxTextCtrl::GetLineLength(
  845.   long                              lLineNo
  846. ) const
  847. {
  848.     long                            lLen = 0L;
  849.  
  850.     if (m_bIsMLE)
  851.         lLen = (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH, 0, 0);
  852.     else
  853.     {
  854.         WNDPARAMS                   vParams;
  855.  
  856.         vParams.fsStatus = WPM_CCHTEXT;
  857.         if (::WinSendMsg( GetHwnd()
  858.                          ,WM_QUERYWINDOWPARAMS
  859.                          ,&vParams
  860.                          ,0
  861.                         ))
  862.         {
  863.             lLen = vParams.cchText;
  864.         }
  865.         else
  866.             lLen = 32;
  867.     }
  868.     return lLen;
  869. } // end ofwxTextCtrl::GetLineLength
  870.  
  871. wxString wxTextCtrl::GetLineText(
  872.   long                              lLineNo
  873. ) const
  874. {
  875.     long                            lLen = (long)GetLineLength((long)lLineNo) + 1;
  876.     wxString                        sStr;
  877.     char*                           zBuf;
  878.  
  879.     //
  880.     // There must be at least enough place for the length WORD in the
  881.     // buffer
  882.     //
  883.     lLen += sizeof(WORD);
  884.     zBuf = new char[lLen];
  885.     if (m_bIsMLE)
  886.     {
  887.         long                        lIndex;
  888.         long                        lBuflen;
  889.         long                        lCopied;
  890.  
  891.         lLen = (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH, 0, 0);
  892.         lIndex = lLen * lLineNo;
  893.  
  894.         ::WinSendMsg(GetHwnd(), MLM_SETSEL, (MPARAM)lIndex, (MPARAM)lIndex);
  895.         ::WinSendMsg(GetHwnd(), MLM_SETIMPORTEXPORT, MPFROMP(zBuf), MPFROMSHORT((USHORT)sizeof(zBuf)));
  896.         lBuflen = (long)::WinSendMsg(GetHwnd(), MLM_QUERYFORMATTEXTLENGTH, MPFROMLONG(lIndex), MPFROMLONG(-1));
  897.         lCopied = (long)::WinSendMsg(GetHwnd(), MLM_EXPORT, MPFROMP(&lIndex), MPFROMP(&lBuflen));
  898.         zBuf[lCopied] = '\0';
  899.     }
  900.     else
  901.     {
  902.         WNDPARAMS                   vParams;
  903.  
  904.         vParams.fsStatus = WPM_CCHTEXT;
  905.         if (::WinSendMsg( GetHwnd()
  906.                          ,WM_QUERYWINDOWPARAMS
  907.                          ,&vParams
  908.                          ,0
  909.                         ))
  910.          memcpy(zBuf, vParams.pszText, vParams.cchText);
  911.          zBuf[vParams.cchText] = '\0';
  912.      }
  913.      sStr = zBuf;
  914.      delete [] zBuf;
  915.      return sStr;
  916. } // end of wxTextCtrl::GetLineText
  917.  
  918. // ----------------------------------------------------------------------------
  919. // Undo/redo
  920. // ----------------------------------------------------------------------------
  921.  
  922. void wxTextCtrl::Undo()
  923. {
  924.     if (CanUndo())
  925.     {
  926.         if (m_bIsMLE)
  927.             ::WinSendMsg(GetHwnd(), MLM_UNDO, 0, 0);
  928.         // Simple entryfields cannot be undone
  929.     }
  930. } // end of wxTextCtrl::Undo
  931.  
  932. void wxTextCtrl::Redo()
  933. {
  934.     if (CanRedo())
  935.     {
  936.         if (m_bIsMLE)
  937.             ::WinSendMsg(GetHwnd(), MLM_UNDO, 0, 0);
  938.         // Simple entryfields cannot be undone
  939.     }
  940. } // end of wxTextCtrl::Redo
  941.  
  942. bool wxTextCtrl::CanUndo() const
  943. {
  944.     bool                            bOk;
  945.  
  946.     if (m_bIsMLE)
  947.         bOk = (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO, 0, 0) != 0);
  948.     else
  949.         bOk = FALSE; // can't undo regular edit fields in PM
  950.     return bOk;
  951. } // end of wxTextCtrl::CanUndo
  952.  
  953. bool wxTextCtrl::CanRedo() const
  954. {
  955.     bool                            bOk;
  956.  
  957.     if (m_bIsMLE)
  958.         bOk = (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO, 0, 0) != 0);
  959.     else
  960.         bOk = FALSE; // can't undo regular edit fields in PM
  961.     return bOk;
  962. } // end of wxTextCtrl::CanRedo
  963.  
  964. // ----------------------------------------------------------------------------
  965. // implemenation details
  966. // ----------------------------------------------------------------------------
  967.  
  968. void wxTextCtrl::Command(
  969.   wxCommandEvent&                   rEvent
  970. )
  971. {
  972.     SetValue(rEvent.GetString());
  973.     ProcessCommand (rEvent);
  974. } // end of wxTextCtrl::Command
  975.  
  976. void wxTextCtrl::OnDropFiles(
  977.   wxDropFilesEvent&                 rEvent
  978. )
  979. {
  980.     // By default, load the first file into the text window.
  981.     if (rEvent.GetNumberOfFiles() > 0)
  982.     {
  983.         LoadFile(rEvent.GetFiles()[0]);
  984.     }
  985. } // end of wxTextCtrl::OnDropFiles
  986.  
  987. WXHBRUSH wxTextCtrl::OnCtlColor(
  988.   WXHDC                             hWxDC
  989. , WXHWND                            hWnd
  990. , WXUINT                            uCtlColor
  991. , WXUINT                            uMessage
  992. , WXWPARAM                          wParam
  993. , WXLPARAM                          lParam
  994. )
  995. {
  996.     HPS                             hPS = (HPS)hWxDC;
  997.     wxBrush*                        pBrush = NULL;
  998.     wxColour                        vColBack = GetBackgroundColour();
  999.     wxColour                        vColFore = GetForegroundColour();
  1000.     wxBrush*                        pBackgroundBrush = wxTheBrushList->FindOrCreateBrush( GetBackgroundColour()
  1001.                                                                                          ,wxSOLID
  1002.                                                                                         );
  1003.  
  1004.     if (m_bUseCtl3D)
  1005.     {
  1006.         HBRUSH                      hBrush = NULLHANDLE;
  1007.  
  1008.         return hBrush;
  1009.     }
  1010.     if (GetParent()->GetTransparentBackground())
  1011.         ::GpiSetBackMix(hPS, BM_LEAVEALONE);
  1012.     else
  1013.         ::GpiSetBackMix(hPS, BM_OVERPAINT);
  1014.     if (!IsEnabled() && (GetWindowStyle() & wxTE_MULTILINE) == 0)
  1015.         vColBack = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
  1016.     ::GpiSetBackColor(hPS, vColBack.GetPixel());
  1017.     ::GpiSetColor(hPS, vColFore.GetPixel());
  1018.     return (WXHBRUSH)pBackgroundBrush->GetResourceHandle();
  1019. } // end of wxTextCtrl::OnCtlColor
  1020.  
  1021. bool wxTextCtrl::OS2ShouldPreProcessMessage(
  1022.   WXMSG*                            pMsg
  1023. )
  1024. {
  1025.     return wxControl::OS2ShouldPreProcessMessage(pMsg);
  1026. } // end of wxTextCtrl::OS2ShouldPreProcessMessage
  1027.  
  1028. void wxTextCtrl::OnChar(
  1029.   wxKeyEvent&                       rEvent
  1030. )
  1031. {
  1032.     switch (rEvent.KeyCode())
  1033.     {
  1034.         case WXK_RETURN:
  1035.             if ( !(m_windowStyle & wxTE_MULTILINE) )
  1036.             {
  1037.                 wxCommandEvent      vEvent(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
  1038.  
  1039.                 vEvent.SetEventObject(this);
  1040.                 if ( GetEventHandler()->ProcessEvent(vEvent))
  1041.                     return;
  1042.             }
  1043.             //else: multiline controls need Enter for themselves
  1044.  
  1045.             break;
  1046.  
  1047.         case WXK_TAB:
  1048.             // always produce navigation event - even if we process TAB
  1049.             // ourselves the fact that we got here means that the user code
  1050.             // decided to skip processing of this TAB - probably to let it
  1051.             // do its default job.
  1052.             //
  1053.             // NB: Notice that Ctrl-Tab is handled elsewhere and Alt-Tab is
  1054.             //     handled by Windows
  1055.             {
  1056.                 wxNavigationKeyEvent    vEventNav;
  1057.  
  1058.                 vEventNav.SetDirection(!rEvent.ShiftDown());
  1059.                 vEventNav.SetWindowChange(FALSE);
  1060.                 vEventNav.SetEventObject(this);
  1061.  
  1062.                 if ( GetEventHandler()->ProcessEvent(vEventNav) )
  1063.                     return;
  1064.             }
  1065.             break;
  1066.     }
  1067.     rEvent.Skip();
  1068. } // end of wxTextCtrl::OnChar
  1069.  
  1070. bool wxTextCtrl::OS2Command(
  1071.   WXUINT                            uParam
  1072. , WXWORD                            WXUNUSED(vId)
  1073. )
  1074. {
  1075.     switch (uParam)
  1076.     {
  1077.         case EN_SETFOCUS:
  1078.         case EN_KILLFOCUS:
  1079.             {
  1080.                 wxFocusEvent        vEvent( uParam == EN_KILLFOCUS ? wxEVT_KILL_FOCUS
  1081.                                                                    : wxEVT_SET_FOCUS
  1082.                                            ,m_windowId
  1083.                                           );
  1084.  
  1085.                 vEvent.SetEventObject(this);
  1086.                 GetEventHandler()->ProcessEvent(vEvent);
  1087.             }
  1088.             break;
  1089.  
  1090.         case EN_CHANGE:
  1091.             {
  1092.                 wxCommandEvent      vEvent( wxEVT_COMMAND_TEXT_UPDATED
  1093.                                            ,m_windowId
  1094.                                           );
  1095.  
  1096.                 InitCommandEvent(vEvent);
  1097.                 vEvent.SetString((char*)GetValue().c_str());
  1098.                 ProcessCommand(vEvent);
  1099.             }
  1100.             break;
  1101.  
  1102.         case EN_OVERFLOW:
  1103.             //
  1104.             // The text size limit has been hit - increase it
  1105.             //
  1106.             AdjustSpaceLimit();
  1107.             break;
  1108.  
  1109.         case EN_SCROLL:
  1110.         case EN_INSERTMODETOGGLE:
  1111.         case EN_MEMERROR:
  1112.             return FALSE;
  1113.         default:
  1114.             return FALSE;
  1115.     }
  1116.  
  1117.     //
  1118.     // Processed
  1119.     //
  1120.     return TRUE;
  1121. } // end of wxTextCtrl::OS2Command
  1122.  
  1123. void wxTextCtrl::AdjustSpaceLimit()
  1124. {
  1125.     unsigned int                    uLen = 0;
  1126.     unsigned int                    uLimit = 0;
  1127.  
  1128.     uLen   = ::WinQueryWindowTextLength(GetHwnd());
  1129.     if (m_bIsMLE)
  1130.     {
  1131.         uLimit = (unsigned int)::WinSendMsg( GetHwnd()
  1132.                                             ,MLM_QUERYTEXTLIMIT
  1133.                                             ,0
  1134.                                             ,0
  1135.                                            );
  1136.     }
  1137.     else
  1138.     {
  1139.         ENTRYFDATA*                 pEfd;
  1140.         WNDPARAMS                   vParams;
  1141.  
  1142.         vParams.fsStatus = WPM_CBCTLDATA;
  1143.         vParams.cbCtlData = sizeof(ENTRYFDATA);
  1144.  
  1145.         if (::WinSendMsg( GetHwnd()
  1146.                          ,WM_QUERYWINDOWPARAMS
  1147.                          ,&vParams
  1148.                          ,0
  1149.                         ))
  1150.         {
  1151.             pEfd = (ENTRYFDATA*)vParams.pCtlData;
  1152.             uLimit = (unsigned int)pEfd->cchEditLimit;
  1153.         }
  1154.         else
  1155.             uLimit = 32; //PM's default
  1156.     }
  1157.     if (uLen >= uLimit)
  1158.     {
  1159.         uLimit = uLen + 0x8000;    // 32Kb
  1160.         if (uLimit > 0xffff)
  1161.         {
  1162.             uLimit = 0L;
  1163.         }
  1164.         if (m_bIsMLE)
  1165.             ::WinSendMsg(GetHwnd(), MLM_SETTEXTLIMIT, MPFROMLONG(uLimit), 0);
  1166.         else
  1167.             ::WinSendMsg(GetHwnd(), EM_SETTEXTLIMIT, MPFROMLONG(uLimit), 0);
  1168.     }
  1169. } // end of wxTextCtrl::AdjustSpaceLimit
  1170.  
  1171. bool wxTextCtrl::AcceptsFocus() const
  1172. {
  1173.     //
  1174.     // We don't want focus if we can't be edited unless we're a multiline
  1175.     // control because then it might be still nice to get focus from keyboard
  1176.     // to be able to scroll it without mouse
  1177.     //
  1178.     return (IsEditable() || IsMultiLine()) && wxControl::AcceptsFocus();
  1179. } // end of wxTextCtrl::Command
  1180.  
  1181. wxSize wxTextCtrl::DoGetBestSize() const
  1182. {
  1183.     int                             nCx;
  1184.     int                             nCy;
  1185.  
  1186.     wxGetCharSize(GetHWND(), &nCx, &nCy, (wxFont*)&GetFont());
  1187.  
  1188.     int                             wText = DEFAULT_ITEM_WIDTH;
  1189.     int                             hText = (EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * .8);
  1190.  
  1191.     if (m_windowStyle & wxTE_MULTILINE)
  1192.     {
  1193.         hText *= wxMax(GetNumberOfLines(), 5);
  1194.     }
  1195.     //else: for single line control everything is ok
  1196.     return wxSize(wText, hText);
  1197. } // end of wxTextCtrl::DoGetBestSize
  1198.  
  1199. // ----------------------------------------------------------------------------
  1200. // standard handlers for standard edit menu events
  1201. // ----------------------------------------------------------------------------
  1202.  
  1203. void wxTextCtrl::OnCut(
  1204.   wxCommandEvent&                   rEvent
  1205. )
  1206. {
  1207.     Cut();
  1208. } // end of wxTextCtrl::OnCut
  1209.  
  1210. void wxTextCtrl::OnCopy(
  1211.   wxCommandEvent&                   rEvent
  1212. )
  1213. {
  1214.     Copy();
  1215. } // end of wxTextCtrl::OnCopy
  1216.  
  1217. void wxTextCtrl::OnPaste(
  1218.   wxCommandEvent&                   rEvent
  1219. )
  1220. {
  1221.     Paste();
  1222. } // end of wxTextCtrl::OnPaste
  1223.  
  1224. void wxTextCtrl::OnUndo(
  1225.   wxCommandEvent&                   rEvent
  1226. )
  1227. {
  1228.     Undo();
  1229. } // end of wxTextCtrl::OnUndo
  1230.  
  1231. void wxTextCtrl::OnRedo(
  1232.   wxCommandEvent&                   rEvent
  1233. )
  1234. {
  1235.     Redo();
  1236. } // end of wxTextCtrl::OnRedo
  1237.  
  1238. void wxTextCtrl::OnDelete(
  1239.   wxCommandEvent&                   rEvent
  1240. )
  1241. {
  1242.     long                            lFrom;
  1243.     long                            lTo;
  1244.  
  1245.     GetSelection( &lFrom
  1246.                  ,&lTo
  1247.                 );
  1248.     if (lFrom != -1 && lTo != -1)
  1249.         Remove( lFrom
  1250.                ,lTo
  1251.               );
  1252. } // end of wxTextCtrl::OnDelete
  1253.  
  1254. void wxTextCtrl::OnSelectAll(
  1255.   wxCommandEvent&                   rEvent
  1256. )
  1257. {
  1258.     SetSelection(-1, -1);
  1259. } // end of wxTextCtrl::OnSelectAll
  1260.  
  1261. void wxTextCtrl::OnUpdateCut(
  1262.   wxUpdateUIEvent&                  rEvent
  1263. )
  1264. {
  1265.     rEvent.Enable(CanCut());
  1266. } // end of wxTextCtrl::OnUpdateCut
  1267.  
  1268. void wxTextCtrl::OnUpdateCopy(
  1269.   wxUpdateUIEvent&                  rEvent
  1270. )
  1271. {
  1272.     rEvent.Enable(CanCopy());
  1273. } // end of wxTextCtrl::OnUpdateCopy
  1274.  
  1275. void wxTextCtrl::OnUpdatePaste(
  1276.   wxUpdateUIEvent&                  rEvent
  1277. )
  1278. {
  1279.     rEvent.Enable(CanPaste());
  1280. } // end of wxTextCtrl::OnUpdatePaste
  1281.  
  1282. void wxTextCtrl::OnUpdateUndo(
  1283.   wxUpdateUIEvent&                  rEvent
  1284. )
  1285. {
  1286.     rEvent.Enable(CanUndo());
  1287. } // end of wxTextCtrl::OnUpdateUndo
  1288.  
  1289. void wxTextCtrl::OnUpdateRedo(
  1290.   wxUpdateUIEvent&                  rEvent
  1291. )
  1292. {
  1293.     rEvent.Enable(CanRedo());
  1294. } // end of wxTextCtrl::OnUpdateRedo
  1295.  
  1296. void wxTextCtrl::OnUpdateDelete(
  1297.   wxUpdateUIEvent&                  rEvent
  1298. )
  1299. {
  1300.     long                            lFrom;
  1301.     long                            lTo;
  1302.  
  1303.     GetSelection( &lFrom
  1304.                  ,&lTo
  1305.                 );
  1306.     rEvent.Enable( lFrom != -1L && lTo != -1L && lFrom != lTo && IsEditable()) ;
  1307. } // end of wxTextCtrl::OnUpdateDelete
  1308.  
  1309. void wxTextCtrl::OnUpdateSelectAll(
  1310.   wxUpdateUIEvent&                  rEvent
  1311. )
  1312. {
  1313.     rEvent.Enable(GetLastPosition() > 0);
  1314. } // end of wxTextCtrl::OnUpdateSelectAll
  1315.  
  1316. bool wxTextCtrl::SetBackgroundColour(
  1317.   const wxColour&                   rColour
  1318. )
  1319. {
  1320.     if (m_bIsMLE)
  1321.         ::WinSendMsg(GetHwnd(), MLM_SETBACKCOLOR, (MPARAM)rColour.GetPixel(), MLE_INDEX);
  1322.     return TRUE;
  1323. } // end of wxTextCtrl::SetBackgroundColour
  1324.  
  1325. bool wxTextCtrl::SetForegroundColour(
  1326.   const wxColour&                   rColour
  1327. )
  1328. {
  1329.     if (m_bIsMLE)
  1330.         ::WinSendMsg(GetHwnd(), MLM_SETTEXTCOLOR, (MPARAM)rColour.GetPixel(), MLE_INDEX);
  1331.     return TRUE;
  1332. } // end of wxTextCtrl::SetForegroundColour
  1333.  
  1334. bool wxTextCtrl::SetStyle(
  1335.   long                              lStart
  1336. , long                              lEnd
  1337. , const wxTextAttr&                 rStyle
  1338. )
  1339. {
  1340.     HWND                            hWnd = GetHwnd();
  1341.  
  1342.     if (lStart > lEnd)
  1343.     {
  1344.         long                        lTmp = lStart;
  1345.  
  1346.         lStart = lEnd;
  1347.         lEnd   = lTmp;
  1348.     }
  1349.  
  1350.     //
  1351.     // We can only change the format of the selection, so select the range we
  1352.     // want and restore the old selection later
  1353.     //
  1354.     long                            lStartOld;
  1355.     long                            lEndOld;
  1356.  
  1357.     GetSelection( &lStartOld
  1358.                  ,&lEndOld
  1359.                 );
  1360.  
  1361.     //
  1362.     // But do we really have to change the selection?
  1363.     //
  1364.     bool                            bChangeSel = lStart != lStartOld ||
  1365.                                                  lEnd != lEndOld;
  1366.  
  1367.     if (bChangeSel)
  1368.     {
  1369.         if (m_bIsMLE)
  1370.             ::WinSendMsg(hWnd, MLM_SETSEL, MPFROM2SHORT((USHORT)lStart, (USHORT)lEnd), 0);
  1371.         else
  1372.             ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lStart, (USHORT)lEnd), 0);
  1373.     }
  1374.  
  1375.     //
  1376.     // TODO:: finish this part
  1377.     //
  1378.     return TRUE;
  1379. } // end of wxTextCtrl::SetStyle
  1380.  
  1381.