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
105 // Base initialization
107 if ( !CreateBase( pParent
117 wxPoint vPos
= rPos
; // The OS/2 position
122 pParent
->AddChild(this);
125 m_windowStyle
= lStyle
;
128 long lSstyle
= WS_VISIBLE
| WS_TABSTOP
;
131 // Single and multiline edit fields are two different controls in PM
133 if ( m_windowStyle
& wxTE_MULTILINE
)
135 lSstyle
|= MLS_BORDER
| MLS_WORDWRAP
;
138 if ((m_windowStyle
& wxTE_NO_VSCROLL
) == 0)
139 lSstyle
|= MLS_VSCROLL
;
140 if (m_windowStyle
& wxHSCROLL
)
141 lSstyle
|= MLS_HSCROLL
;
142 if (m_windowStyle
& wxTE_READONLY
)
143 lSstyle
|= MLS_READONLY
;
147 lSstyle
|= ES_LEFT
| ES_AUTOSCROLL
| ES_MARGIN
;
149 if (m_windowStyle
& wxHSCROLL
)
150 lSstyle
|= ES_AUTOSCROLL
;
151 if (m_windowStyle
& wxTE_READONLY
)
152 lSstyle
|= ES_READONLY
;
153 if (m_windowStyle
& wxTE_PASSWORD
) // hidden input
154 lSstyle
|= ES_UNREADABLE
;
159 m_hWnd
= (WXHWND
)::WinCreateWindow( (HWND
)GetHwndOf(pParent
) // Parent window handle
160 ,WC_MLE
// Window class
161 ,(PSZ
)rsValue
.c_str() // Initial Text
162 ,(ULONG
)lSstyle
// Style flags
163 ,(LONG
)0 // X pos of origin
164 ,(LONG
)0 // Y pos of origin
165 ,(LONG
)0 // field width
166 ,(LONG
)0 // field height
167 ,(HWND
)GetHwndOf(pParent
) // owner window handle (same as parent
168 ,HWND_TOP
// initial z position
169 ,(ULONG
)vId
// Window identifier
170 ,NULL
// no control data
171 ,NULL
// no Presentation parameters
176 m_hWnd
= (WXHWND
)::WinCreateWindow( (HWND
)GetHwndOf(pParent
) // Parent window handle
177 ,WC_ENTRYFIELD
// Window class
178 ,(PSZ
)rsValue
.c_str() // Initial Text
179 ,(ULONG
)lSstyle
// Style flags
180 ,(LONG
)0 // X pos of origin
181 ,(LONG
)0 // Y pos of origin
182 ,(LONG
)0 // field width
183 ,(LONG
)0 // field height
184 ,(HWND
)GetHwndOf(pParent
) // owner window handle (same as parent
185 ,HWND_TOP
// initial z position
186 ,(ULONG
)vId
// Window identifier
187 ,NULL
// no control data
188 ,NULL
// no Presentation parameters
197 SubclassWin(GetHWND());
200 // Set font, position, size and initial value
202 wxFont
* pTextFont
= new wxFont( 8
208 if (!rsValue
.IsEmpty())
214 // If X and/or Y are not zero the difference is the compensation value
215 // for margins for OS/2 controls.
217 ::WinQueryWindowPos(m_hWnd
, &vSwp
);
220 SetSize( vPos
.x
- GetXComp()
227 } // end of wxTextCtrl::Create
230 // Make sure the window style (etc.) reflects the HWND style (roughly)
232 void wxTextCtrl::AdoptAttributesFromHWND()
234 HWND hWnd
= GetHwnd();
235 LONG lStyle
= ::WinQueryWindowULong(hWnd
, QWL_STYLE
);
237 wxWindow::AdoptAttributesFromHWND();
241 m_windowStyle
|= wxTE_MULTILINE
;
242 if (lStyle
& MLS_READONLY
)
243 m_windowStyle
|= wxTE_READONLY
;
247 if (lStyle
& ES_UNREADABLE
)
248 m_windowStyle
|= wxTE_PASSWORD
;
249 if (lStyle
& ES_READONLY
)
250 m_windowStyle
|= wxTE_READONLY
;
252 } // end of wxTextCtrl::AdoptAttributesFromHWND
254 WXDWORD
wxTextCtrl::OS2GetStyle(
256 , WXDWORD
* pdwExstyle
260 // Default border for the text controls is the sunken one
262 if ((lStyle
& wxBORDER_MASK
) == wxBORDER_DEFAULT
)
264 lStyle
|= wxBORDER_SUNKEN
;
267 long dwStyle
= wxControl::OS2GetStyle( lStyle
271 dwStyle
= WS_VISIBLE
| WS_TABSTOP
;
274 // Single and multiline edit fields are two different controls in PM
276 if ( m_windowStyle
& wxTE_MULTILINE
)
278 dwStyle
|= MLS_BORDER
| MLS_WORDWRAP
;
279 if ((m_windowStyle
& wxTE_NO_VSCROLL
) == 0)
280 dwStyle
|= MLS_VSCROLL
;
281 if (m_windowStyle
& wxHSCROLL
)
282 dwStyle
|= MLS_HSCROLL
;
283 if (m_windowStyle
& wxTE_READONLY
)
284 dwStyle
|= MLS_READONLY
;
288 dwStyle
|= ES_LEFT
| ES_AUTOSCROLL
| ES_MARGIN
;
289 if (m_windowStyle
& wxHSCROLL
)
290 dwStyle
|= ES_AUTOSCROLL
;
291 if (m_windowStyle
& wxTE_READONLY
)
292 dwStyle
|= ES_READONLY
;
293 if (m_windowStyle
& wxTE_PASSWORD
) // hidden input
294 dwStyle
|= ES_UNREADABLE
;
297 } // end of wxTextCtrl::OS2GetStyle
299 void wxTextCtrl::SetWindowStyleFlag(
303 wxControl::SetWindowStyleFlag(lStyle
);
304 } // end of wxTextCtrl::SetWindowStyleFlag
306 void wxTextCtrl::SetupColours()
308 wxColour vBkgndColour
;
310 vBkgndColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
);
311 SetBackgroundColour(vBkgndColour
);
312 SetForegroundColour(GetParent()->GetForegroundColour());
315 ::WinSendMsg( GetHwnd()
317 ,(MPARAM
)GetParent()->GetForegroundColour().GetPixel()
321 } // end of wxTextCtrl::SetupColours
323 // ----------------------------------------------------------------------------
324 // set/get the controls text
325 // ----------------------------------------------------------------------------
327 wxString
wxTextCtrl::GetValue() const
329 wxString sStr
= wxGetWindowText(GetHWND());
330 char* zStr
= (char*)sStr
.c_str();
332 for ( ; *zStr
; zStr
++ )
335 // this will replace \r\n with just \n
343 } // end of wxTextCtrl::GetValue
345 void wxTextCtrl::SetValue(
346 const wxString
& rsValue
350 // If the text is long enough, it's faster to just set it instead of first
351 // comparing it with the old one (chances are that it will be different
352 // anyhow, this comparison is there to avoid flicker for small single-line
353 // edit controls mostly)
355 if ((rsValue
.length() > 0x400) || (rsValue
!= GetValue()))
357 ::WinSetWindowText(GetHwnd(), rsValue
.c_str());
360 } // end of wxTextCtrl::SetValue
362 void wxTextCtrl::WriteText(
363 const wxString
& rsValue
367 ::WinSendMsg(GetHwnd(), MLM_INSERT
, MPARAM((PCHAR
)rsValue
.c_str()), MPARAM(0));
369 ::WinSetWindowText(GetHwnd(), rsValue
.c_str());
371 } // end of wxTextCtrl::WriteText
373 void wxTextCtrl::AppendText(
374 const wxString
& rsText
377 SetInsertionPointEnd();
379 } // end of wxTextCtrl::AppendText
381 void wxTextCtrl::Clear()
383 ::WinSetWindowText(GetHwnd(), "");
384 } // end of wxTextCtrl::Clear
386 bool wxTextCtrl::EmulateKeyPress(
387 const wxKeyEvent
& rEvent
391 return(wxTextCtrlBase::EmulateKeyPress(rEvent
));
392 } // end of wxTextCtrl::EmulateKeyPress
394 // ----------------------------------------------------------------------------
395 // Clipboard operations
396 // ----------------------------------------------------------------------------
398 void wxTextCtrl::Copy()
402 HWND hWnd
= GetHwnd();
404 ::WinSendMsg(hWnd
, MLM_COPY
, 0, 0);
406 ::WinSendMsg(hWnd
, EM_COPY
, 0, 0);
408 } // end of wxTextCtrl::Copy
410 void wxTextCtrl::Cut()
414 HWND hWnd
= GetHwnd();
417 ::WinSendMsg(hWnd
, MLM_CUT
, 0, 0);
419 ::WinSendMsg(hWnd
, EM_CUT
, 0, 0);
421 } // end of wxTextCtrl::Cut
423 void wxTextCtrl::Paste()
427 HWND hWnd
= GetHwnd();
429 ::WinSendMsg(hWnd
, EM_PASTE
, 0, 0);
431 } // end of wxTextCtrl::Paste
433 bool wxTextCtrl::CanCopy() const
436 // Can copy if there's a selection
441 GetSelection(&lFrom
, &lTo
);
442 return (lFrom
!= lTo
);
443 } // end of wxTextCtrl::CanCopy
445 bool wxTextCtrl::CanCut() const
448 // Can cut if there's a selection
453 GetSelection(&lFrom
, &lTo
);
454 return (lFrom
!= lTo
);
455 } // end of wxTextCtrl::CanCut
457 bool wxTextCtrl::CanPaste() const
459 bool bIsTextAvailable
= FALSE
;
465 // Check for straight text on clipboard
467 if (::WinOpenClipbrd(vHabmain
))
469 bIsTextAvailable
= (::WinQueryClipbrdData(vHabmain
, CF_TEXT
) != 0);
470 ::WinCloseClipbrd(vHabmain
);
472 return bIsTextAvailable
;
473 } // end of wxTextCtrl::CanPaste
475 // ----------------------------------------------------------------------------
477 // ----------------------------------------------------------------------------
479 void wxTextCtrl::SetEditable(
483 HWND hWnd
= GetHwnd();
486 ::WinSendMsg(hWnd
, MLM_SETREADONLY
, MPFROMLONG(!bEditable
), (MPARAM
)0);
488 ::WinSendMsg(hWnd
, EM_SETREADONLY
, MPFROMLONG(!bEditable
), (MPARAM
)0);
489 } // end of wxTextCtrl::SetEditable
491 void wxTextCtrl::SetInsertionPoint(
495 HWND hWnd
= GetHwnd();
498 ::WinSendMsg(hWnd
, MLM_SETSEL
, (MPARAM
)lPos
, (MPARAM
)lPos
);
500 ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lPos
, (USHORT
)lPos
), (MPARAM
)0);
501 } // end of wxTextCtrl::SetInsertionPoint
503 void wxTextCtrl::SetInsertionPointEnd()
505 long lPos
= GetLastPosition();
508 // We must not do anything if the caret is already there because calling
509 // SetInsertionPoint() thaws the controls if Freeze() had been called even
510 // if it doesn't actually move the caret anywhere and so the simple fact of
511 // doing it results in horrible flicker when appending big amounts of text
512 // to the control in a few chunks (see DoAddText() test in the text sample)
514 if (GetInsertionPoint() == GetLastPosition())
516 SetInsertionPoint(lPos
);
517 } // end of wxTextCtrl::SetInsertionPointEnd
519 long wxTextCtrl::GetInsertionPoint() const
524 dwPos
= (WXDWORD
)::WinSendMsg(GetHwnd(), MLM_QUERYSEL
, (MPARAM
)MLFQS_MINSEL
, 0);
527 dwPos
= (WXDWORD
)::WinSendMsg(GetHwnd(), EM_QUERYSEL
, 0, 0);
528 dwPos
= SHORT1FROMMP((MPARAM
)dwPos
); // the first 16 bit value is the min pos
530 return (dwPos
& 0xFFFF);
531 } // end of wxTextCtrl::GetInsertionPoint
533 long wxTextCtrl::GetLastPosition() const
535 HWND hWnd
= GetHwnd();
544 // This just gets the total text length. The last will be this value
546 lLineLength
= (long)::WinSendMsg(hWnd
, MLM_QUERYTEXTLENGTH
, 0, 0);
553 vParams
.fsStatus
= WPM_CCHTEXT
;
554 if (::WinSendMsg( GetHwnd()
555 ,WM_QUERYWINDOWPARAMS
560 lLineLength
= (long)vParams
.cchText
;
565 return(lCharIndex
+ lLineLength
);
566 } // end of wxTextCtrl::GetLastPosition
568 // If the return values from and to are the same, there is no
570 void wxTextCtrl::GetSelection(
578 dwPos
= (WXDWORD
)::WinSendMsg(GetHwnd(), MLM_QUERYSEL
, (MPARAM
)MLFQS_MINSEL
, 0);
581 dwPos
= (WXDWORD
)::WinSendMsg(GetHwnd(), EM_QUERYSEL
, 0, 0);
583 *plFrom
= SHORT1FROMMP((MPARAM
)dwPos
); // the first 16 bit value is the min pos
584 *plTo
= SHORT2FROMMP((MPARAM
)dwPos
); // the first 16 bit value is the min pos
585 } // end of wxTextCtrl::GetSelection
587 bool wxTextCtrl::IsEditable() const
590 return((bool)LONGFROMMR(::WinSendMsg(GetHwnd(), MLM_QUERYREADONLY
, 0, 0)));
592 return((bool)LONGFROMMR(::WinSendMsg(GetHwnd(), EM_QUERYREADONLY
, 0, 0)));
593 } // end of wxTextCtrl::IsEditable
595 // ----------------------------------------------------------------------------
597 // ----------------------------------------------------------------------------
599 void wxTextCtrl::Replace(
602 , const wxString
& rsValue
606 HWND hWnd
= GetHwnd();
609 // Set selection and remove it
613 ::WinSendMsg(hWnd
, MLM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0);
614 ::WinSendMsg(hWnd
, MLM_CUT
, 0, 0);
618 ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0);
619 ::WinSendMsg(hWnd
, EM_CUT
, 0, 0);
623 // Now replace with 'value', by pasting.
625 wxSetClipboardData(wxDF_TEXT
, (wxObject
*) (const wxChar
*)rsValue
, 0, 0);
627 // Paste into edit control
629 ::WinSendMsg(hWnd
, MLM_PASTE
, (MPARAM
)0, (MPARAM
)0);
631 ::WinSendMsg(hWnd
, EM_PASTE
, (MPARAM
)0, (MPARAM
)0);
633 wxFAIL_MSG("wxTextCtrl::Replace not implemented if wxUSE_CLIPBOARD is 0.");
635 } // end of wxTextCtrl::Replace
637 void wxTextCtrl::Remove(
642 HWND hWnd
= GetHwnd();
646 ::WinSendMsg(hWnd
, MLM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0);
647 ::WinSendMsg(hWnd
, MLM_CUT
, 0, 0);
651 ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0);
652 ::WinSendMsg(hWnd
, EM_CUT
, 0, 0);
654 } // end of wxTextCtrl::Remove
656 void wxTextCtrl::SetSelection(
661 HWND hWnd
= GetHwnd();
662 long lFromChar
= lFrom
;
666 // If from and to are both -1, it means (in wxWindows) that all text should
667 // be selected. Translate into Windows convention
669 if ((lFrom
== -1L) && (lTo
== -1L))
675 ::WinSendMsg(hWnd
, MLM_SETSEL
, (MPARAM
)lFromChar
, (MPARAM
)lToChar
);
677 ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lFromChar
, (USHORT
)lToChar
), (MPARAM
)0);
678 } // end of wxTextCtrl::SetSelection
680 bool wxTextCtrl::LoadFile(
681 const wxString
& rsFile
684 if ( wxTextCtrlBase::LoadFile(rsFile
) )
687 // Update the size limit if needed
693 } // end of wxTextCtrl::LoadFile
695 bool wxTextCtrl::IsModified() const
700 bRc
= (bool)LONGFROMMR(::WinSendMsg(GetHwnd(), MLM_QUERYCHANGED
, 0, 0));
702 bRc
= (bool)LONGFROMMR(::WinSendMsg(GetHwnd(), EM_QUERYCHANGED
, 0, 0));
704 } // end of wxTextCtrl::IsModified
706 void wxTextCtrl::MarkDirty()
709 ::WinSendMsg(GetHwnd(), MLM_SETCHANGED
, MPFROMLONG(TRUE
), 0);
711 // EM controls do not have a SETCHANGED, what can we do??
712 wxFAIL_MSG( _T("not implemented") );
716 // Makes 'unmodified'
718 void wxTextCtrl::DiscardEdits()
721 ::WinSendMsg(GetHwnd(), MLM_SETCHANGED
, MPFROMLONG(FALSE
), 0);
724 // EM controls do not have a SETCHANGED but issuing a query should reset it
726 ::WinSendMsg(GetHwnd(), EM_QUERYCHANGED
, 0, 0);
727 } // end of wxTextCtrl::DiscardEdits
729 int wxTextCtrl::GetNumberOfLines() const
734 nNumLines
= (int)::WinSendMsg(GetHwnd(), MLM_QUERYLINECOUNT
, 0, 0);
738 } // end of wxTextCtrl::GetNumberOfLines
740 long wxTextCtrl::XYToPosition(
745 long lCharIndex
= 0L;
750 lLen
= (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH
, 0, 0);
751 lCharIndex
= ((lLen
* lY
) + lX
);
756 } // end of wxTextCtrl::XYToPosition
758 bool wxTextCtrl::PositionToXY(
764 HWND hWnd
= GetHwnd();
769 nLineNo
= (long)::WinSendMsg(hWnd
, MLM_LINEFROMCHAR
, (MPARAM
)lPos
, 0);
780 // This gets the char index for the _beginning_ of this line
786 lLineWidth
= (long)::WinSendMsg(hWnd
, MLM_QUERYLINELENGTH
, (MPARAM
)0, (MPARAM
)0);
787 lCharIndex
= (nLineNo
+ 1) * lLineWidth
;
793 vParams
.fsStatus
= WPM_CCHTEXT
;
794 if (::WinSendMsg( hWnd
795 ,WM_QUERYWINDOWPARAMS
800 lCharIndex
= vParams
.cchText
;
806 if (lCharIndex
== -1)
812 // The X position must therefore be the difference between pos and charIndex
815 *plX
= lPos
- lCharIndex
;
820 } // end of wxTextCtrl::PositionToXY
822 void wxTextCtrl::ShowPosition(
826 HWND hWnd
= GetHwnd();
827 long lCurrentLineLineNo
= 0L;
829 // To scroll to a position, we pass the number of lines and characters
830 // to scroll *by*. This means that we need to:
831 // (1) Find the line position of the current line.
832 // (2) Find the line position of pos.
833 // (3) Scroll by (pos - current).
834 // For now, ignore the horizontal scrolling.
837 // Is this where scrolling is relative to - the line containing the caret?
838 // Or is the first visible line??? Try first visible line.
843 // In PM this is the actual char position
845 lCurrentLineLineNo
= (long)::WinSendMsg(hWnd
, MLM_QUERYFIRSTCHAR
, (MPARAM
)0, (MPARAM
)0);
848 // This will cause a scroll to the selected position
850 ::WinSendMsg(hWnd
, MLM_SETSEL
, (MPARAM
)lCurrentLineLineNo
, (MPARAM
)lCurrentLineLineNo
);
852 } // end of wxTextCtrl::ShowPosition
854 int wxTextCtrl::GetLineLength(
861 lLen
= (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH
, 0, 0);
866 vParams
.fsStatus
= WPM_CCHTEXT
;
867 if (::WinSendMsg( GetHwnd()
868 ,WM_QUERYWINDOWPARAMS
873 lLen
= vParams
.cchText
;
879 } // end ofwxTextCtrl::GetLineLength
881 wxString
wxTextCtrl::GetLineText(
885 long lLen
= (long)GetLineLength((long)lLineNo
) + 1;
890 // There must be at least enough place for the length WORD in the
893 lLen
+= sizeof(WORD
);
894 zBuf
= new char[lLen
];
901 lLen
= (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH
, 0, 0);
902 lIndex
= lLen
* lLineNo
;
904 ::WinSendMsg(GetHwnd(), MLM_SETSEL
, (MPARAM
)lIndex
, (MPARAM
)lIndex
);
905 ::WinSendMsg(GetHwnd(), MLM_SETIMPORTEXPORT
, MPFROMP(zBuf
), MPFROMSHORT((USHORT
)sizeof(zBuf
)));
906 lBuflen
= (long)::WinSendMsg(GetHwnd(), MLM_QUERYFORMATTEXTLENGTH
, MPFROMLONG(lIndex
), MPFROMLONG(-1));
907 lCopied
= (long)::WinSendMsg(GetHwnd(), MLM_EXPORT
, MPFROMP(&lIndex
), MPFROMP(&lBuflen
));
908 zBuf
[lCopied
] = '\0';
914 vParams
.fsStatus
= WPM_CCHTEXT
;
915 if (::WinSendMsg( GetHwnd()
916 ,WM_QUERYWINDOWPARAMS
920 memcpy(zBuf
, vParams
.pszText
, vParams
.cchText
);
921 zBuf
[vParams
.cchText
] = '\0';
926 } // end of wxTextCtrl::GetLineText
928 // ----------------------------------------------------------------------------
930 // ----------------------------------------------------------------------------
932 void wxTextCtrl::Undo()
937 ::WinSendMsg(GetHwnd(), MLM_UNDO
, 0, 0);
938 // Simple entryfields cannot be undone
940 } // end of wxTextCtrl::Undo
942 void wxTextCtrl::Redo()
947 ::WinSendMsg(GetHwnd(), MLM_UNDO
, 0, 0);
948 // Simple entryfields cannot be undone
950 } // end of wxTextCtrl::Redo
952 bool wxTextCtrl::CanUndo() const
957 bOk
= (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO
, 0, 0) != 0);
959 bOk
= FALSE
; // can't undo regular edit fields in PM
961 } // end of wxTextCtrl::CanUndo
963 bool wxTextCtrl::CanRedo() const
968 bOk
= (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO
, 0, 0) != 0);
970 bOk
= FALSE
; // can't undo regular edit fields in PM
972 } // end of wxTextCtrl::CanRedo
974 // ----------------------------------------------------------------------------
975 // implemenation details
976 // ----------------------------------------------------------------------------
978 void wxTextCtrl::Command(
979 wxCommandEvent
& rEvent
982 SetValue(rEvent
.GetString());
983 ProcessCommand (rEvent
);
984 } // end of wxTextCtrl::Command
986 void wxTextCtrl::OnDropFiles(
987 wxDropFilesEvent
& rEvent
990 // By default, load the first file into the text window.
991 if (rEvent
.GetNumberOfFiles() > 0)
993 LoadFile(rEvent
.GetFiles()[0]);
995 } // end of wxTextCtrl::OnDropFiles
997 WXHBRUSH
wxTextCtrl::OnCtlColor(
1006 HPS hPS
= (HPS
)hWxDC
;
1007 wxColour vColBack
= GetBackgroundColour();
1008 wxColour vColFore
= GetForegroundColour();
1009 wxBrush
* pBackgroundBrush
= wxTheBrushList
->FindOrCreateBrush( GetBackgroundColour()
1015 HBRUSH hBrush
= NULLHANDLE
;
1019 if (GetParent()->GetTransparentBackground())
1020 ::GpiSetBackMix(hPS
, BM_LEAVEALONE
);
1022 ::GpiSetBackMix(hPS
, BM_OVERPAINT
);
1023 if (!IsEnabled() && (GetWindowStyle() & wxTE_MULTILINE
) == 0)
1024 vColBack
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
1025 ::GpiSetBackColor(hPS
, vColBack
.GetPixel());
1026 ::GpiSetColor(hPS
, vColFore
.GetPixel());
1027 return (WXHBRUSH
)pBackgroundBrush
->GetResourceHandle();
1028 } // end of wxTextCtrl::OnCtlColor
1030 bool wxTextCtrl::OS2ShouldPreProcessMessage(
1034 return wxControl::OS2ShouldPreProcessMessage(pMsg
);
1035 } // end of wxTextCtrl::OS2ShouldPreProcessMessage
1037 void wxTextCtrl::OnChar(
1041 switch (rEvent
.GetKeyCode())
1044 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
1046 wxCommandEvent
vEvent(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1048 vEvent
.SetEventObject(this);
1049 if ( GetEventHandler()->ProcessEvent(vEvent
))
1052 //else: multiline controls need Enter for themselves
1057 // always produce navigation event - even if we process TAB
1058 // ourselves the fact that we got here means that the user code
1059 // decided to skip processing of this TAB - probably to let it
1060 // do its default job.
1062 // NB: Notice that Ctrl-Tab is handled elsewhere and Alt-Tab is
1063 // handled by Windows
1065 wxNavigationKeyEvent vEventNav
;
1067 vEventNav
.SetDirection(!rEvent
.ShiftDown());
1068 vEventNav
.SetWindowChange(FALSE
);
1069 vEventNav
.SetEventObject(this);
1071 if ( GetEventHandler()->ProcessEvent(vEventNav
) )
1077 } // end of wxTextCtrl::OnChar
1079 bool wxTextCtrl::OS2Command(
1081 , WXWORD
WXUNUSED(vId
)
1089 wxFocusEvent
vEvent( uParam
== EN_KILLFOCUS
? wxEVT_KILL_FOCUS
1094 vEvent
.SetEventObject(this);
1095 GetEventHandler()->ProcessEvent(vEvent
);
1101 wxCommandEvent
vEvent( wxEVT_COMMAND_TEXT_UPDATED
1105 InitCommandEvent(vEvent
);
1106 vEvent
.SetString((char*)GetValue().c_str());
1107 ProcessCommand(vEvent
);
1113 // The text size limit has been hit - increase it
1119 case EN_INSERTMODETOGGLE
:
1130 } // end of wxTextCtrl::OS2Command
1132 void wxTextCtrl::AdjustSpaceLimit()
1134 unsigned int uLen
= 0;
1135 unsigned int uLimit
= 0;
1137 uLen
= ::WinQueryWindowTextLength(GetHwnd());
1140 uLimit
= (unsigned int)::WinSendMsg( GetHwnd()
1151 vParams
.fsStatus
= WPM_CBCTLDATA
;
1152 vParams
.pCtlData
= &Efd
;
1153 vParams
.cbCtlData
= sizeof(ENTRYFDATA
);
1155 if (::WinSendMsg( GetHwnd()
1156 ,WM_QUERYWINDOWPARAMS
1160 uLimit
= (unsigned int)Efd
.cchEditLimit
;
1162 uLimit
= 32; //PM's default
1166 uLimit
= uLen
+ 0x8000; // 32Kb
1167 if (uLimit
> 0xffff)
1172 ::WinSendMsg(GetHwnd(), MLM_SETTEXTLIMIT
, MPFROMLONG(uLimit
), 0);
1174 ::WinSendMsg(GetHwnd(), EM_SETTEXTLIMIT
, MPFROMSHORT(uLimit
), 0);
1176 } // end of wxTextCtrl::AdjustSpaceLimit
1178 bool wxTextCtrl::AcceptsFocus() const
1181 // We don't want focus if we can't be edited unless we're a multiline
1182 // control because then it might be still nice to get focus from keyboard
1183 // to be able to scroll it without mouse
1185 return (IsEditable() || IsMultiLine()) && wxControl::AcceptsFocus();
1186 } // end of wxTextCtrl::Command
1188 wxSize
wxTextCtrl::DoGetBestSize() const
1193 wxGetCharSize(GetHWND(), &nCx
, &nCy
, (wxFont
*)&GetFont());
1195 int wText
= DEFAULT_ITEM_WIDTH
;
1196 int hText
= (int)(EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy
) * .8);
1198 if (m_windowStyle
& wxTE_MULTILINE
)
1200 hText
*= wxMax(GetNumberOfLines(), 5);
1202 //else: for single line control everything is ok
1203 return wxSize(wText
, hText
);
1204 } // end of wxTextCtrl::DoGetBestSize
1206 // ----------------------------------------------------------------------------
1207 // standard handlers for standard edit menu events
1208 // ----------------------------------------------------------------------------
1210 void wxTextCtrl::OnCut(
1211 wxCommandEvent
& rEvent
1215 } // end of wxTextCtrl::OnCut
1217 void wxTextCtrl::OnCopy(
1218 wxCommandEvent
& rEvent
1222 } // end of wxTextCtrl::OnCopy
1224 void wxTextCtrl::OnPaste(
1225 wxCommandEvent
& rEvent
1229 } // end of wxTextCtrl::OnPaste
1231 void wxTextCtrl::OnUndo(
1232 wxCommandEvent
& rEvent
1236 } // end of wxTextCtrl::OnUndo
1238 void wxTextCtrl::OnRedo(
1239 wxCommandEvent
& rEvent
1243 } // end of wxTextCtrl::OnRedo
1245 void wxTextCtrl::OnDelete(
1246 wxCommandEvent
& rEvent
1252 GetSelection( &lFrom
1255 if (lFrom
!= -1 && lTo
!= -1)
1259 } // end of wxTextCtrl::OnDelete
1261 void wxTextCtrl::OnSelectAll(
1262 wxCommandEvent
& rEvent
1265 SetSelection(-1, -1);
1266 } // end of wxTextCtrl::OnSelectAll
1268 void wxTextCtrl::OnUpdateCut(
1269 wxUpdateUIEvent
& rEvent
1272 rEvent
.Enable(CanCut());
1273 } // end of wxTextCtrl::OnUpdateCut
1275 void wxTextCtrl::OnUpdateCopy(
1276 wxUpdateUIEvent
& rEvent
1279 rEvent
.Enable(CanCopy());
1280 } // end of wxTextCtrl::OnUpdateCopy
1282 void wxTextCtrl::OnUpdatePaste(
1283 wxUpdateUIEvent
& rEvent
1286 rEvent
.Enable(CanPaste());
1287 } // end of wxTextCtrl::OnUpdatePaste
1289 void wxTextCtrl::OnUpdateUndo(
1290 wxUpdateUIEvent
& rEvent
1293 rEvent
.Enable(CanUndo());
1294 } // end of wxTextCtrl::OnUpdateUndo
1296 void wxTextCtrl::OnUpdateRedo(
1297 wxUpdateUIEvent
& rEvent
1300 rEvent
.Enable(CanRedo());
1301 } // end of wxTextCtrl::OnUpdateRedo
1303 void wxTextCtrl::OnUpdateDelete(
1304 wxUpdateUIEvent
& rEvent
1310 GetSelection( &lFrom
1313 rEvent
.Enable( lFrom
!= -1L && lTo
!= -1L && lFrom
!= lTo
&& IsEditable()) ;
1314 } // end of wxTextCtrl::OnUpdateDelete
1316 void wxTextCtrl::OnUpdateSelectAll(
1317 wxUpdateUIEvent
& rEvent
1320 rEvent
.Enable(GetLastPosition() > 0);
1321 } // end of wxTextCtrl::OnUpdateSelectAll
1323 bool wxTextCtrl::SetBackgroundColour(
1324 const wxColour
& rColour
1328 ::WinSendMsg(GetHwnd(), MLM_SETBACKCOLOR
, (MPARAM
)rColour
.GetPixel(), MLE_INDEX
);
1330 } // end of wxTextCtrl::SetBackgroundColour
1332 bool wxTextCtrl::SetForegroundColour(
1333 const wxColour
& rColour
1337 ::WinSendMsg(GetHwnd(), MLM_SETTEXTCOLOR
, (MPARAM
)rColour
.GetPixel(), MLE_INDEX
);
1339 } // end of wxTextCtrl::SetForegroundColour
1341 bool wxTextCtrl::SetStyle(
1344 , const wxTextAttr
& rStyle
1347 HWND hWnd
= GetHwnd();
1358 // We can only change the format of the selection, so select the range we
1359 // want and restore the old selection later
1364 GetSelection( &lStartOld
1369 // But do we really have to change the selection?
1371 bool bChangeSel
= lStart
!= lStartOld
||
1377 ::WinSendMsg(hWnd
, MLM_SETSEL
, MPFROM2SHORT((USHORT
)lStart
, (USHORT
)lEnd
), 0);
1379 ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lStart
, (USHORT
)lEnd
), 0);
1383 // TODO:: finish this part
1386 } // end of wxTextCtrl::SetStyle