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/scrolwin.h"
22 #include "wx/settings.h"
30 #include "wx/clipbrd.h"
33 #include "wx/textfile.h"
35 #include "wx/os2/private.h"
39 #include <sys/types.h>
47 #if !defined(MLE_INDEX)
53 // ----------------------------------------------------------------------------
54 // event tables and other macros
55 // ----------------------------------------------------------------------------
57 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
59 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
60 EVT_CHAR(wxTextCtrl::OnChar
)
61 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
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
)
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
)
77 // ============================================================================
79 // ============================================================================
81 // ----------------------------------------------------------------------------
83 // ----------------------------------------------------------------------------
85 wxTextCtrl::wxTextCtrl()
89 wxTextCtrl::~wxTextCtrl()
93 bool wxTextCtrl::Create(
96 , const wxString
& rsValue
100 , const wxValidator
& rValidator
101 , const wxString
& rsName
108 // Base initialization
110 if ( !CreateBase( pParent
120 wxPoint vPos
= rPos
; // The OS/2 position
125 pParent
->AddChild(this);
128 m_windowStyle
= lStyle
;
131 long lSstyle
= WS_VISIBLE
| WS_TABSTOP
;
134 // Single and multiline edit fields are two different controls in PM
136 if ( m_windowStyle
& wxTE_MULTILINE
)
138 lSstyle
|= MLS_BORDER
| MLS_WORDWRAP
;
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
;
150 lSstyle
|= ES_LEFT
| ES_AUTOSCROLL
| ES_MARGIN
;
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
;
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
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
200 SubclassWin(GetHWND());
203 // Set font, position, size and initial value
205 wxFont
* pTextFont
= new wxFont( 8
211 if (!rsValue
.IsEmpty())
217 // If X and/or Y are not zero the difference is the compensation value
218 // for margins for OS/2 controls.
220 ::WinQueryWindowPos(m_hWnd
, &vSwp
);
223 SetSize( vPos
.x
- GetXComp()
230 } // end of wxTextCtrl::Create
233 // Make sure the window style (etc.) reflects the HWND style (roughly)
235 void wxTextCtrl::AdoptAttributesFromHWND()
237 HWND hWnd
= GetHwnd();
238 LONG lStyle
= ::WinQueryWindowULong(hWnd
, QWL_STYLE
);
240 wxWindow::AdoptAttributesFromHWND();
244 m_windowStyle
|= wxTE_MULTILINE
;
245 if (lStyle
& MLS_READONLY
)
246 m_windowStyle
|= wxTE_READONLY
;
250 if (lStyle
& ES_UNREADABLE
)
251 m_windowStyle
|= wxTE_PASSWORD
;
252 if (lStyle
& ES_READONLY
)
253 m_windowStyle
|= wxTE_READONLY
;
255 } // end of wxTextCtrl::AdoptAttributesFromHWND
257 WXDWORD
wxTextCtrl::OS2GetStyle(
259 , WXDWORD
* pdwExstyle
263 // Default border for the text controls is the sunken one
265 if ((lStyle
& wxBORDER_MASK
) == wxBORDER_DEFAULT
)
267 lStyle
|= wxBORDER_SUNKEN
;
270 long dwStyle
= wxControl::OS2GetStyle( lStyle
274 dwStyle
= WS_VISIBLE
| WS_TABSTOP
;
277 // Single and multiline edit fields are two different controls in PM
279 if ( m_windowStyle
& wxTE_MULTILINE
)
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
;
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
;
300 } // end of wxTextCtrl::OS2GetStyle
302 void wxTextCtrl::SetWindowStyleFlag(
306 wxControl::SetWindowStyleFlag(lStyle
);
307 } // end of wxTextCtrl::SetWindowStyleFlag
309 void wxTextCtrl::SetupColours()
311 wxColour vBkgndColour
;
313 vBkgndColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
);
314 SetBackgroundColour(vBkgndColour
);
315 SetForegroundColour(GetParent()->GetForegroundColour());
318 ::WinSendMsg( GetHwnd()
320 ,(MPARAM
)GetParent()->GetForegroundColour().GetPixel()
324 } // end of wxTextCtrl::SetupColours
326 // ----------------------------------------------------------------------------
327 // set/get the controls text
328 // ----------------------------------------------------------------------------
330 wxString
wxTextCtrl::GetValue() const
332 wxString sStr
= wxGetWindowText(GetHWND());
333 char* zStr
= (char*)sStr
.c_str();
335 for ( ; *zStr
; zStr
++ )
338 // this will replace \r\n with just \n
346 } // end of wxTextCtrl::GetValue
348 void wxTextCtrl::SetValue(
349 const wxString
& rsValue
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)
358 if ((rsValue
.length() > 0x400) || (rsValue
!= GetValue()))
360 ::WinSetWindowText(GetHwnd(), rsValue
.c_str());
363 } // end of wxTextCtrl::SetValue
365 void wxTextCtrl::WriteText(
366 const wxString
& rsValue
370 ::WinSendMsg(GetHwnd(), MLM_INSERT
, MPARAM((PCHAR
)rsValue
.c_str()), MPARAM(0));
372 ::WinSetWindowText(GetHwnd(), rsValue
.c_str());
374 } // end of wxTextCtrl::WriteText
376 void wxTextCtrl::AppendText(
377 const wxString
& rsText
380 SetInsertionPointEnd();
382 } // end of wxTextCtrl::AppendText
384 void wxTextCtrl::Clear()
386 ::WinSetWindowText(GetHwnd(), "");
387 } // end of wxTextCtrl::Clear
389 bool wxTextCtrl::EmulateKeyPress(
390 const wxKeyEvent
& rEvent
394 return(wxTextCtrlBase::EmulateKeyPress(rEvent
));
395 } // end of wxTextCtrl::EmulateKeyPress
397 // ----------------------------------------------------------------------------
398 // Clipboard operations
399 // ----------------------------------------------------------------------------
401 void wxTextCtrl::Copy()
405 HWND hWnd
= GetHwnd();
407 ::WinSendMsg(hWnd
, MLM_COPY
, 0, 0);
409 ::WinSendMsg(hWnd
, EM_COPY
, 0, 0);
411 } // end of wxTextCtrl::Copy
413 void wxTextCtrl::Cut()
417 HWND hWnd
= GetHwnd();
420 ::WinSendMsg(hWnd
, MLM_CUT
, 0, 0);
422 ::WinSendMsg(hWnd
, EM_CUT
, 0, 0);
424 } // end of wxTextCtrl::Cut
426 void wxTextCtrl::Paste()
430 HWND hWnd
= GetHwnd();
432 ::WinSendMsg(hWnd
, EM_PASTE
, 0, 0);
434 } // end of wxTextCtrl::Paste
436 bool wxTextCtrl::CanCopy() const
439 // Can copy if there's a selection
444 GetSelection(&lFrom
, &lTo
);
445 return (lFrom
!= lTo
);
446 } // end of wxTextCtrl::CanCopy
448 bool wxTextCtrl::CanCut() const
451 // Can cut if there's a selection
456 GetSelection(&lFrom
, &lTo
);
457 return (lFrom
!= lTo
);
458 } // end of wxTextCtrl::CanCut
460 bool wxTextCtrl::CanPaste() const
462 bool bIsTextAvailable
= FALSE
;
468 // Check for straight text on clipboard
470 if (::WinOpenClipbrd(vHabmain
))
472 bIsTextAvailable
= (::WinQueryClipbrdData(vHabmain
, CF_TEXT
) != 0);
473 ::WinCloseClipbrd(vHabmain
);
475 return bIsTextAvailable
;
476 } // end of wxTextCtrl::CanPaste
478 // ----------------------------------------------------------------------------
480 // ----------------------------------------------------------------------------
482 void wxTextCtrl::SetEditable(
486 HWND hWnd
= GetHwnd();
489 ::WinSendMsg(hWnd
, MLM_SETREADONLY
, MPFROMLONG(!bEditable
), (MPARAM
)0);
491 ::WinSendMsg(hWnd
, EM_SETREADONLY
, MPFROMLONG(!bEditable
), (MPARAM
)0);
492 } // end of wxTextCtrl::SetEditable
494 void wxTextCtrl::SetInsertionPoint(
498 HWND hWnd
= GetHwnd();
501 ::WinSendMsg(hWnd
, MLM_SETSEL
, (MPARAM
)lPos
, (MPARAM
)lPos
);
503 ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lPos
, (USHORT
)lPos
), (MPARAM
)0);
504 } // end of wxTextCtrl::SetInsertionPoint
506 void wxTextCtrl::SetInsertionPointEnd()
508 long lPos
= GetLastPosition();
511 // We must not do anything if the caret is already there because calling
512 // SetInsertionPoint() thaws the controls if Freeze() had been called even
513 // if it doesn't actually move the caret anywhere and so the simple fact of
514 // doing it results in horrible flicker when appending big amounts of text
515 // to the control in a few chunks (see DoAddText() test in the text sample)
517 if (GetInsertionPoint() == GetLastPosition())
519 SetInsertionPoint(lPos
);
520 } // end of wxTextCtrl::SetInsertionPointEnd
522 long wxTextCtrl::GetInsertionPoint() const
527 dwPos
= (WXDWORD
)::WinSendMsg(GetHwnd(), MLM_QUERYSEL
, (MPARAM
)MLFQS_MINSEL
, 0);
530 dwPos
= (WXDWORD
)::WinSendMsg(GetHwnd(), EM_QUERYSEL
, 0, 0);
531 dwPos
= SHORT1FROMMP((MPARAM
)dwPos
); // the first 16 bit value is the min pos
533 return (dwPos
& 0xFFFF);
534 } // end of wxTextCtrl::GetInsertionPoint
536 long wxTextCtrl::GetLastPosition() const
538 HWND hWnd
= GetHwnd();
547 // This just gets the total text length. The last will be this value
549 lLineLength
= (long)::WinSendMsg(hWnd
, MLM_QUERYTEXTLENGTH
, 0, 0);
556 vParams
.fsStatus
= WPM_CCHTEXT
;
557 if (::WinSendMsg( GetHwnd()
558 ,WM_QUERYWINDOWPARAMS
563 lLineLength
= (long)vParams
.cchText
;
568 return(lCharIndex
+ lLineLength
);
569 } // end of wxTextCtrl::GetLastPosition
571 // If the return values from and to are the same, there is no
573 void wxTextCtrl::GetSelection(
581 dwPos
= (WXDWORD
)::WinSendMsg(GetHwnd(), MLM_QUERYSEL
, (MPARAM
)MLFQS_MINSEL
, 0);
584 dwPos
= (WXDWORD
)::WinSendMsg(GetHwnd(), EM_QUERYSEL
, 0, 0);
586 *plFrom
= SHORT1FROMMP((MPARAM
)dwPos
); // the first 16 bit value is the min pos
587 *plTo
= SHORT2FROMMP((MPARAM
)dwPos
); // the first 16 bit value is the min pos
588 } // end of wxTextCtrl::GetSelection
590 bool wxTextCtrl::IsEditable() const
593 return((bool)LONGFROMMR(::WinSendMsg(GetHwnd(), MLM_QUERYREADONLY
, 0, 0)));
595 return((bool)LONGFROMMR(::WinSendMsg(GetHwnd(), EM_QUERYREADONLY
, 0, 0)));
596 } // end of wxTextCtrl::IsEditable
598 // ----------------------------------------------------------------------------
600 // ----------------------------------------------------------------------------
602 void wxTextCtrl::Replace(
605 , const wxString
& rsValue
609 HWND hWnd
= GetHwnd();
610 long lFromChar
= lFrom
;
614 // Set selection and remove it
618 ::WinSendMsg(hWnd
, MLM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0);
619 ::WinSendMsg(hWnd
, MLM_CUT
, 0, 0);
623 ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0);
624 ::WinSendMsg(hWnd
, EM_CUT
, 0, 0);
628 // Now replace with 'value', by pasting.
630 wxSetClipboardData(wxDF_TEXT
, (wxObject
*) (const wxChar
*)rsValue
, 0, 0);
632 // Paste into edit control
634 ::WinSendMsg(hWnd
, MLM_PASTE
, (MPARAM
)0, (MPARAM
)0);
636 ::WinSendMsg(hWnd
, EM_PASTE
, (MPARAM
)0, (MPARAM
)0);
638 wxFAIL_MSG("wxTextCtrl::Replace not implemented if wxUSE_CLIPBOARD is 0.");
640 } // end of wxTextCtrl::Replace
642 void wxTextCtrl::Remove(
647 HWND hWnd
= GetHwnd();
648 long lFromChar
= lFrom
;
653 ::WinSendMsg(hWnd
, MLM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0);
654 ::WinSendMsg(hWnd
, MLM_CUT
, 0, 0);
658 ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0);
659 ::WinSendMsg(hWnd
, EM_CUT
, 0, 0);
661 } // end of wxTextCtrl::Remove
663 void wxTextCtrl::SetSelection(
668 HWND hWnd
= GetHwnd();
669 long lFromChar
= lFrom
;
673 // If from and to are both -1, it means (in wxWindows) that all text should
674 // be selected. Translate into Windows convention
676 if ((lFrom
== -1L) && (lTo
== -1L))
682 ::WinSendMsg(hWnd
, MLM_SETSEL
, (MPARAM
)lFromChar
, (MPARAM
)lToChar
);
684 ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lFromChar
, (USHORT
)lToChar
), (MPARAM
)0);
685 } // end of wxTextCtrl::SetSelection
687 bool wxTextCtrl::LoadFile(
688 const wxString
& rsFile
691 if ( wxTextCtrlBase::LoadFile(rsFile
) )
694 // Update the size limit if needed
700 } // end of wxTextCtrl::LoadFile
702 bool wxTextCtrl::IsModified() const
707 bRc
= (bool)LONGFROMMR(::WinSendMsg(GetHwnd(), MLM_QUERYCHANGED
, 0, 0));
709 bRc
= (bool)LONGFROMMR(::WinSendMsg(GetHwnd(), EM_QUERYCHANGED
, 0, 0));
711 } // end of wxTextCtrl::IsModified
713 void wxTextCtrl::MarkDirty()
716 ::WinSendMsg(GetHwnd(), MLM_SETCHANGED
, MPFROMLONG(TRUE
), 0);
718 // EM controls do not have a SETCHANGED, what can we do??
719 wxFAIL_MSG( _T("not implemented") );
723 // Makes 'unmodified'
725 void wxTextCtrl::DiscardEdits()
728 ::WinSendMsg(GetHwnd(), MLM_SETCHANGED
, MPFROMLONG(FALSE
), 0);
731 // EM controls do not have a SETCHANGED but issuing a query should reset it
733 ::WinSendMsg(GetHwnd(), EM_QUERYCHANGED
, 0, 0);
734 } // end of wxTextCtrl::DiscardEdits
736 int wxTextCtrl::GetNumberOfLines() const
741 nNumLines
= (int)::WinSendMsg(GetHwnd(), MLM_QUERYLINECOUNT
, 0, 0);
745 } // end of wxTextCtrl::GetNumberOfLines
747 long wxTextCtrl::XYToPosition(
752 HWND hWnd
= GetHwnd();
753 long lCharIndex
= 0L;
758 lLen
= (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH
, 0, 0);
759 lCharIndex
= ((lLen
* lY
) + lX
);
764 } // end of wxTextCtrl::XYToPosition
766 bool wxTextCtrl::PositionToXY(
772 HWND hWnd
= GetHwnd();
777 nLineNo
= (long)::WinSendMsg(hWnd
, MLM_LINEFROMCHAR
, (MPARAM
)lPos
, 0);
788 // This gets the char index for the _beginning_ of this line
794 lLineWidth
= (long)::WinSendMsg(hWnd
, MLM_QUERYLINELENGTH
, (MPARAM
)0, (MPARAM
)0);
795 lCharIndex
= (nLineNo
+ 1) * lLineWidth
;
801 vParams
.fsStatus
= WPM_CCHTEXT
;
802 if (::WinSendMsg( hWnd
803 ,WM_QUERYWINDOWPARAMS
808 lCharIndex
= vParams
.cchText
;
814 if (lCharIndex
== -1)
820 // The X position must therefore be the difference between pos and charIndex
823 *plX
= lPos
- lCharIndex
;
828 } // end of wxTextCtrl::PositionToXY
830 void wxTextCtrl::ShowPosition(
834 HWND hWnd
= GetHwnd();
835 long lCurrentLineLineNo
= 0L;
837 // To scroll to a position, we pass the number of lines and characters
838 // to scroll *by*. This means that we need to:
839 // (1) Find the line position of the current line.
840 // (2) Find the line position of pos.
841 // (3) Scroll by (pos - current).
842 // For now, ignore the horizontal scrolling.
845 // Is this where scrolling is relative to - the line containing the caret?
846 // Or is the first visible line??? Try first visible line.
851 // In PM this is the actual char position
853 lCurrentLineLineNo
= (long)::WinSendMsg(hWnd
, MLM_QUERYFIRSTCHAR
, (MPARAM
)0, (MPARAM
)0);
856 // This will cause a scroll to the selected position
858 ::WinSendMsg(hWnd
, MLM_SETSEL
, (MPARAM
)lCurrentLineLineNo
, (MPARAM
)lCurrentLineLineNo
);
860 } // end of wxTextCtrl::ShowPosition
862 int wxTextCtrl::GetLineLength(
869 lLen
= (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH
, 0, 0);
874 vParams
.fsStatus
= WPM_CCHTEXT
;
875 if (::WinSendMsg( GetHwnd()
876 ,WM_QUERYWINDOWPARAMS
881 lLen
= vParams
.cchText
;
887 } // end ofwxTextCtrl::GetLineLength
889 wxString
wxTextCtrl::GetLineText(
893 long lLen
= (long)GetLineLength((long)lLineNo
) + 1;
898 // There must be at least enough place for the length WORD in the
901 lLen
+= sizeof(WORD
);
902 zBuf
= new char[lLen
];
909 lLen
= (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH
, 0, 0);
910 lIndex
= lLen
* lLineNo
;
912 ::WinSendMsg(GetHwnd(), MLM_SETSEL
, (MPARAM
)lIndex
, (MPARAM
)lIndex
);
913 ::WinSendMsg(GetHwnd(), MLM_SETIMPORTEXPORT
, MPFROMP(zBuf
), MPFROMSHORT((USHORT
)sizeof(zBuf
)));
914 lBuflen
= (long)::WinSendMsg(GetHwnd(), MLM_QUERYFORMATTEXTLENGTH
, MPFROMLONG(lIndex
), MPFROMLONG(-1));
915 lCopied
= (long)::WinSendMsg(GetHwnd(), MLM_EXPORT
, MPFROMP(&lIndex
), MPFROMP(&lBuflen
));
916 zBuf
[lCopied
] = '\0';
922 vParams
.fsStatus
= WPM_CCHTEXT
;
923 if (::WinSendMsg( GetHwnd()
924 ,WM_QUERYWINDOWPARAMS
928 memcpy(zBuf
, vParams
.pszText
, vParams
.cchText
);
929 zBuf
[vParams
.cchText
] = '\0';
934 } // end of wxTextCtrl::GetLineText
936 // ----------------------------------------------------------------------------
938 // ----------------------------------------------------------------------------
940 void wxTextCtrl::Undo()
945 ::WinSendMsg(GetHwnd(), MLM_UNDO
, 0, 0);
946 // Simple entryfields cannot be undone
948 } // end of wxTextCtrl::Undo
950 void wxTextCtrl::Redo()
955 ::WinSendMsg(GetHwnd(), MLM_UNDO
, 0, 0);
956 // Simple entryfields cannot be undone
958 } // end of wxTextCtrl::Redo
960 bool wxTextCtrl::CanUndo() const
965 bOk
= (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO
, 0, 0) != 0);
967 bOk
= FALSE
; // can't undo regular edit fields in PM
969 } // end of wxTextCtrl::CanUndo
971 bool wxTextCtrl::CanRedo() const
976 bOk
= (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO
, 0, 0) != 0);
978 bOk
= FALSE
; // can't undo regular edit fields in PM
980 } // end of wxTextCtrl::CanRedo
982 // ----------------------------------------------------------------------------
983 // implemenation details
984 // ----------------------------------------------------------------------------
986 void wxTextCtrl::Command(
987 wxCommandEvent
& rEvent
990 SetValue(rEvent
.GetString());
991 ProcessCommand (rEvent
);
992 } // end of wxTextCtrl::Command
994 void wxTextCtrl::OnDropFiles(
995 wxDropFilesEvent
& rEvent
998 // By default, load the first file into the text window.
999 if (rEvent
.GetNumberOfFiles() > 0)
1001 LoadFile(rEvent
.GetFiles()[0]);
1003 } // end of wxTextCtrl::OnDropFiles
1005 WXHBRUSH
wxTextCtrl::OnCtlColor(
1014 HPS hPS
= (HPS
)hWxDC
;
1015 wxBrush
* pBrush
= NULL
;
1016 wxColour vColBack
= GetBackgroundColour();
1017 wxColour vColFore
= GetForegroundColour();
1018 wxBrush
* pBackgroundBrush
= wxTheBrushList
->FindOrCreateBrush( GetBackgroundColour()
1024 HBRUSH hBrush
= NULLHANDLE
;
1028 if (GetParent()->GetTransparentBackground())
1029 ::GpiSetBackMix(hPS
, BM_LEAVEALONE
);
1031 ::GpiSetBackMix(hPS
, BM_OVERPAINT
);
1032 if (!IsEnabled() && (GetWindowStyle() & wxTE_MULTILINE
) == 0)
1033 vColBack
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
1034 ::GpiSetBackColor(hPS
, vColBack
.GetPixel());
1035 ::GpiSetColor(hPS
, vColFore
.GetPixel());
1036 return (WXHBRUSH
)pBackgroundBrush
->GetResourceHandle();
1037 } // end of wxTextCtrl::OnCtlColor
1039 bool wxTextCtrl::OS2ShouldPreProcessMessage(
1043 return wxControl::OS2ShouldPreProcessMessage(pMsg
);
1044 } // end of wxTextCtrl::OS2ShouldPreProcessMessage
1046 void wxTextCtrl::OnChar(
1050 switch (rEvent
.KeyCode())
1053 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1055 wxCommandEvent
vEvent(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1057 vEvent
.SetEventObject(this);
1058 if ( GetEventHandler()->ProcessEvent(vEvent
))
1061 //else: multiline controls need Enter for themselves
1066 // always produce navigation event - even if we process TAB
1067 // ourselves the fact that we got here means that the user code
1068 // decided to skip processing of this TAB - probably to let it
1069 // do its default job.
1071 // NB: Notice that Ctrl-Tab is handled elsewhere and Alt-Tab is
1072 // handled by Windows
1074 wxNavigationKeyEvent vEventNav
;
1076 vEventNav
.SetDirection(!rEvent
.ShiftDown());
1077 vEventNav
.SetWindowChange(FALSE
);
1078 vEventNav
.SetEventObject(this);
1080 if ( GetEventHandler()->ProcessEvent(vEventNav
) )
1086 } // end of wxTextCtrl::OnChar
1088 bool wxTextCtrl::OS2Command(
1090 , WXWORD
WXUNUSED(vId
)
1098 wxFocusEvent
vEvent( uParam
== EN_KILLFOCUS
? wxEVT_KILL_FOCUS
1103 vEvent
.SetEventObject(this);
1104 GetEventHandler()->ProcessEvent(vEvent
);
1110 wxCommandEvent
vEvent( wxEVT_COMMAND_TEXT_UPDATED
1114 InitCommandEvent(vEvent
);
1115 vEvent
.SetString((char*)GetValue().c_str());
1116 ProcessCommand(vEvent
);
1122 // The text size limit has been hit - increase it
1128 case EN_INSERTMODETOGGLE
:
1139 } // end of wxTextCtrl::OS2Command
1141 void wxTextCtrl::AdjustSpaceLimit()
1143 unsigned int uLen
= 0;
1144 unsigned int uLimit
= 0;
1146 uLen
= ::WinQueryWindowTextLength(GetHwnd());
1149 uLimit
= (unsigned int)::WinSendMsg( GetHwnd()
1160 vParams
.fsStatus
= WPM_CBCTLDATA
;
1161 vParams
.pCtlData
= &Efd
;
1162 vParams
.cbCtlData
= sizeof(ENTRYFDATA
);
1164 if (::WinSendMsg( GetHwnd()
1165 ,WM_QUERYWINDOWPARAMS
1169 uLimit
= (unsigned int)Efd
.cchEditLimit
;
1171 uLimit
= 32; //PM's default
1175 uLimit
= uLen
+ 0x8000; // 32Kb
1176 if (uLimit
> 0xffff)
1181 ::WinSendMsg(GetHwnd(), MLM_SETTEXTLIMIT
, MPFROMLONG(uLimit
), 0);
1183 ::WinSendMsg(GetHwnd(), EM_SETTEXTLIMIT
, MPFROMSHORT(uLimit
), 0);
1185 } // end of wxTextCtrl::AdjustSpaceLimit
1187 bool wxTextCtrl::AcceptsFocus() const
1190 // We don't want focus if we can't be edited unless we're a multiline
1191 // control because then it might be still nice to get focus from keyboard
1192 // to be able to scroll it without mouse
1194 return (IsEditable() || IsMultiLine()) && wxControl::AcceptsFocus();
1195 } // end of wxTextCtrl::Command
1197 wxSize
wxTextCtrl::DoGetBestSize() const
1202 wxGetCharSize(GetHWND(), &nCx
, &nCy
, (wxFont
*)&GetFont());
1204 int wText
= DEFAULT_ITEM_WIDTH
;
1205 int hText
= (EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy
) * .8);
1207 if (m_windowStyle
& wxTE_MULTILINE
)
1209 hText
*= wxMax(GetNumberOfLines(), 5);
1211 //else: for single line control everything is ok
1212 return wxSize(wText
, hText
);
1213 } // end of wxTextCtrl::DoGetBestSize
1215 // ----------------------------------------------------------------------------
1216 // standard handlers for standard edit menu events
1217 // ----------------------------------------------------------------------------
1219 void wxTextCtrl::OnCut(
1220 wxCommandEvent
& rEvent
1224 } // end of wxTextCtrl::OnCut
1226 void wxTextCtrl::OnCopy(
1227 wxCommandEvent
& rEvent
1231 } // end of wxTextCtrl::OnCopy
1233 void wxTextCtrl::OnPaste(
1234 wxCommandEvent
& rEvent
1238 } // end of wxTextCtrl::OnPaste
1240 void wxTextCtrl::OnUndo(
1241 wxCommandEvent
& rEvent
1245 } // end of wxTextCtrl::OnUndo
1247 void wxTextCtrl::OnRedo(
1248 wxCommandEvent
& rEvent
1252 } // end of wxTextCtrl::OnRedo
1254 void wxTextCtrl::OnDelete(
1255 wxCommandEvent
& rEvent
1261 GetSelection( &lFrom
1264 if (lFrom
!= -1 && lTo
!= -1)
1268 } // end of wxTextCtrl::OnDelete
1270 void wxTextCtrl::OnSelectAll(
1271 wxCommandEvent
& rEvent
1274 SetSelection(-1, -1);
1275 } // end of wxTextCtrl::OnSelectAll
1277 void wxTextCtrl::OnUpdateCut(
1278 wxUpdateUIEvent
& rEvent
1281 rEvent
.Enable(CanCut());
1282 } // end of wxTextCtrl::OnUpdateCut
1284 void wxTextCtrl::OnUpdateCopy(
1285 wxUpdateUIEvent
& rEvent
1288 rEvent
.Enable(CanCopy());
1289 } // end of wxTextCtrl::OnUpdateCopy
1291 void wxTextCtrl::OnUpdatePaste(
1292 wxUpdateUIEvent
& rEvent
1295 rEvent
.Enable(CanPaste());
1296 } // end of wxTextCtrl::OnUpdatePaste
1298 void wxTextCtrl::OnUpdateUndo(
1299 wxUpdateUIEvent
& rEvent
1302 rEvent
.Enable(CanUndo());
1303 } // end of wxTextCtrl::OnUpdateUndo
1305 void wxTextCtrl::OnUpdateRedo(
1306 wxUpdateUIEvent
& rEvent
1309 rEvent
.Enable(CanRedo());
1310 } // end of wxTextCtrl::OnUpdateRedo
1312 void wxTextCtrl::OnUpdateDelete(
1313 wxUpdateUIEvent
& rEvent
1319 GetSelection( &lFrom
1322 rEvent
.Enable( lFrom
!= -1L && lTo
!= -1L && lFrom
!= lTo
&& IsEditable()) ;
1323 } // end of wxTextCtrl::OnUpdateDelete
1325 void wxTextCtrl::OnUpdateSelectAll(
1326 wxUpdateUIEvent
& rEvent
1329 rEvent
.Enable(GetLastPosition() > 0);
1330 } // end of wxTextCtrl::OnUpdateSelectAll
1332 bool wxTextCtrl::SetBackgroundColour(
1333 const wxColour
& rColour
1337 ::WinSendMsg(GetHwnd(), MLM_SETBACKCOLOR
, (MPARAM
)rColour
.GetPixel(), MLE_INDEX
);
1339 } // end of wxTextCtrl::SetBackgroundColour
1341 bool wxTextCtrl::SetForegroundColour(
1342 const wxColour
& rColour
1346 ::WinSendMsg(GetHwnd(), MLM_SETTEXTCOLOR
, (MPARAM
)rColour
.GetPixel(), MLE_INDEX
);
1348 } // end of wxTextCtrl::SetForegroundColour
1350 bool wxTextCtrl::SetStyle(
1353 , const wxTextAttr
& rStyle
1356 HWND hWnd
= GetHwnd();
1367 // We can only change the format of the selection, so select the range we
1368 // want and restore the old selection later
1373 GetSelection( &lStartOld
1378 // But do we really have to change the selection?
1380 bool bChangeSel
= lStart
!= lStartOld
||
1386 ::WinSendMsg(hWnd
, MLM_SETSEL
, MPFROM2SHORT((USHORT
)lStart
, (USHORT
)lEnd
), 0);
1388 ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lStart
, (USHORT
)lEnd
), 0);
1392 // TODO:: finish this part
1395 } // end of wxTextCtrl::SetStyle