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 bool wxTextCtrl::Create(
92 , const wxString
& rsValue
97 , const wxValidator
& rValidator
99 , const wxString
& rsName
105 // Base initialization
107 if ( !CreateBase( pParent
119 wxPoint vPos
= rPos
; // The OS/2 position
124 pParent
->AddChild(this);
127 m_windowStyle
= lStyle
;
129 long lSstyle
= WS_VISIBLE
| WS_TABSTOP
;
132 // Single and multiline edit fields are two different controls in PM
134 if ( m_windowStyle
& wxTE_MULTILINE
)
136 lSstyle
|= MLS_BORDER
| MLS_WORDWRAP
;
139 if ((m_windowStyle
& wxTE_NO_VSCROLL
) == 0)
140 lSstyle
|= MLS_VSCROLL
;
141 if (m_windowStyle
& wxHSCROLL
)
142 lSstyle
|= MLS_HSCROLL
;
143 if (m_windowStyle
& wxTE_READONLY
)
144 lSstyle
|= MLS_READONLY
;
148 lSstyle
|= ES_LEFT
| ES_AUTOSCROLL
| ES_MARGIN
;
150 if (m_windowStyle
& wxHSCROLL
)
151 lSstyle
|= ES_AUTOSCROLL
;
152 if (m_windowStyle
& wxTE_READONLY
)
153 lSstyle
|= ES_READONLY
;
154 if (m_windowStyle
& wxTE_PASSWORD
) // hidden input
155 lSstyle
|= ES_UNREADABLE
;
158 // If the parent is a scrolled window the controls must
159 // have this style or they will overlap the scrollbars
162 if (pParent
->IsKindOf(CLASSINFO(wxScrolledWindow
)) ||
163 pParent
->IsKindOf(CLASSINFO(wxGenericScrolledWindow
)))
164 lSstyle
|= WS_CLIPSIBLINGS
;
168 m_hWnd
= (WXHWND
)::WinCreateWindow( (HWND
)GetHwndOf(pParent
) // Parent window handle
169 ,WC_MLE
// Window class
170 ,(PSZ
)rsValue
.c_str() // Initial Text
171 ,(ULONG
)lSstyle
// Style flags
172 ,(LONG
)0 // X pos of origin
173 ,(LONG
)0 // Y pos of origin
174 ,(LONG
)0 // field width
175 ,(LONG
)0 // field height
176 ,(HWND
)GetHwndOf(pParent
) // owner window handle (same as parent
177 ,HWND_TOP
// initial z position
178 ,(ULONG
)vId
// Window identifier
179 ,NULL
// no control data
180 ,NULL
// no Presentation parameters
185 m_hWnd
= (WXHWND
)::WinCreateWindow( (HWND
)GetHwndOf(pParent
) // Parent window handle
186 ,WC_ENTRYFIELD
// Window class
187 ,(PSZ
)rsValue
.c_str() // Initial Text
188 ,(ULONG
)lSstyle
// Style flags
189 ,(LONG
)0 // X pos of origin
190 ,(LONG
)0 // Y pos of origin
191 ,(LONG
)0 // field width
192 ,(LONG
)0 // field height
193 ,(HWND
)GetHwndOf(pParent
) // owner window handle (same as parent
194 ,HWND_TOP
// initial z position
195 ,(ULONG
)vId
// Window identifier
196 ,NULL
// no control data
197 ,NULL
// no Presentation parameters
206 SubclassWin(GetHWND());
209 // Set font, position, size and initial value
211 wxFont
& vFontParent
= pParent
->GetFont();
213 if (vFontParent
.Ok())
215 SetFont(vFontParent
);
219 SetFont(wxSystemSettings::GetSystemFont(wxSYS_SYSTEM_FONT
));
221 if (!rsValue
.IsEmpty())
227 // If X and/or Y are not zero the difference is the compensation value
228 // for margins for OS/2 controls.
230 ::WinQueryWindowPos(m_hWnd
, &vSwp
);
239 } // end of wxTextCtrl::Create
242 // Make sure the window style (etc.) reflects the HWND style (roughly)
244 void wxTextCtrl::AdoptAttributesFromHWND()
246 HWND hWnd
= GetHwnd();
247 LONG lStyle
= ::WinQueryWindowULong(hWnd
, QWL_STYLE
);
249 wxWindow::AdoptAttributesFromHWND();
253 m_windowStyle
|= wxTE_MULTILINE
;
254 if (lStyle
& MLS_READONLY
)
255 m_windowStyle
|= wxTE_READONLY
;
259 if (lStyle
& ES_UNREADABLE
)
260 m_windowStyle
|= wxTE_PASSWORD
;
261 if (lStyle
& ES_READONLY
)
262 m_windowStyle
|= wxTE_READONLY
;
264 } // end of wxTextCtrl::AdoptAttributesFromHWND
266 void wxTextCtrl::SetupColours()
268 wxColour vBkgndColour
;
270 vBkgndColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW
);
271 SetBackgroundColour(vBkgndColour
);
272 SetForegroundColour(GetParent()->GetForegroundColour());
275 ::WinSendMsg( GetHwnd()
277 ,(MPARAM
)GetParent()->GetForegroundColour().GetPixel()
281 } // end of wxTextCtrl::SetupColours
283 // ----------------------------------------------------------------------------
284 // set/get the controls text
285 // ----------------------------------------------------------------------------
287 wxString
wxTextCtrl::GetValue() const
289 wxString sStr
= wxGetWindowText(GetHWND());
290 char* zStr
= (char*)sStr
.c_str();
292 for ( ; *zStr
; zStr
++ )
295 // this will replace \r\n with just \n
304 } // end of wxTextCtrl::GetValue
306 void wxTextCtrl::SetValue(
307 const wxString
& rsValue
311 // If the text is long enough, it's faster to just set it instead of first
312 // comparing it with the old one (chances are that it will be different
313 // anyhow, this comparison is there to avoid flicker for small single-line
314 // edit controls mostly)
316 if ((rsValue
.length() > 0x400) || (rsValue
!= GetValue()))
318 ::WinSetWindowText(GetHwnd(), rsValue
.c_str());
321 } // end of wxTextCtrl::SetValue
323 void wxTextCtrl::WriteText(
324 const wxString
& rsValue
327 ::WinSetWindowText(GetHwnd(), rsValue
.c_str());
329 } // end of wxTextCtrl::WriteText
331 void wxTextCtrl::AppendText(
332 const wxString
& rsText
335 SetInsertionPointEnd();
337 } // end of wxTextCtrl::AppendText
339 void wxTextCtrl::Clear()
341 ::WinSetWindowText(GetHwnd(), "");
342 } // end of wxTextCtrl::Clear
344 // ----------------------------------------------------------------------------
345 // Clipboard operations
346 // ----------------------------------------------------------------------------
348 void wxTextCtrl::Copy()
352 HWND hWnd
= GetHwnd();
354 ::WinSendMsg(hWnd
, MLM_COPY
, 0, 0);
356 ::WinSendMsg(hWnd
, EM_COPY
, 0, 0);
358 } // end of wxTextCtrl::Copy
360 void wxTextCtrl::Cut()
364 HWND hWnd
= GetHwnd();
367 ::WinSendMsg(hWnd
, MLM_CUT
, 0, 0);
369 ::WinSendMsg(hWnd
, EM_CUT
, 0, 0);
371 } // end of wxTextCtrl::Cut
373 void wxTextCtrl::Paste()
377 HWND hWnd
= GetHwnd();
379 ::WinSendMsg(hWnd
, EM_PASTE
, 0, 0);
381 } // end of wxTextCtrl::Paste
383 bool wxTextCtrl::CanCopy() const
386 // Can copy if there's a selection
391 GetSelection(&lFrom
, &lTo
);
392 return (lFrom
!= lTo
);
393 } // end of wxTextCtrl::CanCopy
395 bool wxTextCtrl::CanCut() const
398 // Can cut if there's a selection
403 GetSelection(&lFrom
, &lTo
);
404 return (lFrom
!= lTo
);
405 } // end of wxTextCtrl::CanCut
407 bool wxTextCtrl::CanPaste() const
409 bool bIsTextAvailable
= FALSE
;
415 // Check for straight text on clipboard
417 if (::WinOpenClipbrd(vHabmain
))
419 bIsTextAvailable
= (::WinQueryClipbrdData(vHabmain
, CF_TEXT
) != 0);
420 ::WinCloseClipbrd(vHabmain
);
422 return bIsTextAvailable
;
423 } // end of wxTextCtrl::CanPaste
425 // ----------------------------------------------------------------------------
427 // ----------------------------------------------------------------------------
429 void wxTextCtrl::SetEditable(
433 HWND hWnd
= GetHwnd();
436 ::WinSendMsg(hWnd
, MLM_SETREADONLY
, MPFROMLONG(!bEditable
), (MPARAM
)0);
438 ::WinSendMsg(hWnd
, EM_SETREADONLY
, MPFROMLONG(!bEditable
), (MPARAM
)0);
439 } // end of wxTextCtrl::SetEditable
441 void wxTextCtrl::SetInsertionPoint(
445 HWND hWnd
= GetHwnd();
448 ::WinSendMsg(hWnd
, MLM_SETSEL
, (MPARAM
)lPos
, (MPARAM
)lPos
);
450 ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lPos
, (USHORT
)lPos
), (MPARAM
)0);
451 } // end of wxTextCtrl::SetInsertionPoint
453 void wxTextCtrl::SetInsertionPointEnd()
455 long lPos
= GetLastPosition();
457 SetInsertionPoint(lPos
);
458 } // end of wxTextCtrl::SetInsertionPointEnd
460 long wxTextCtrl::GetInsertionPoint() const
465 dwPos
= (WXDWORD
)::WinSendMsg(GetHwnd(), MLM_QUERYSEL
, (MPARAM
)MLFQS_MINSEL
, 0);
468 dwPos
= (WXDWORD
)::WinSendMsg(GetHwnd(), EM_QUERYSEL
, 0, 0);
469 dwPos
= SHORT1FROMMP((MPARAM
)dwPos
); // the first 16 bit value is the min pos
471 return (dwPos
& 0xFFFF);
472 } // end of wxTextCtrl::GetInsertionPoint
474 long wxTextCtrl::GetLastPosition() const
476 HWND hWnd
= GetHwnd();
485 // This just gets the total text length. The last will be this value
487 lLineLength
= (long)::WinSendMsg(hWnd
, MLM_QUERYTEXTLENGTH
, 0, 0);
494 vParams
.fsStatus
= WPM_CCHTEXT
;
495 if (::WinSendMsg( GetHwnd()
496 ,WM_QUERYWINDOWPARAMS
501 lLineLength
= (long)vParams
.cchText
;
506 return(lCharIndex
+ lLineLength
);
507 } // end of wxTextCtrl::GetLastPosition
509 // If the return values from and to are the same, there is no
511 void wxTextCtrl::GetSelection(
519 dwPos
= (WXDWORD
)::WinSendMsg(GetHwnd(), MLM_QUERYSEL
, (MPARAM
)MLFQS_MINSEL
, 0);
522 dwPos
= (WXDWORD
)::WinSendMsg(GetHwnd(), EM_QUERYSEL
, 0, 0);
524 *plFrom
= SHORT1FROMMP((MPARAM
)dwPos
); // the first 16 bit value is the min pos
525 *plTo
= SHORT2FROMMP((MPARAM
)dwPos
); // the first 16 bit value is the min pos
526 } // end of wxTextCtrl::GetSelection
528 bool wxTextCtrl::IsEditable() const
531 return((bool)LONGFROMMR(::WinSendMsg(GetHwnd(), MLM_QUERYREADONLY
, 0, 0)));
533 return((bool)LONGFROMMR(::WinSendMsg(GetHwnd(), EM_QUERYREADONLY
, 0, 0)));
534 } // end of wxTextCtrl::IsEditable
536 // ----------------------------------------------------------------------------
538 // ----------------------------------------------------------------------------
540 void wxTextCtrl::Replace(
543 , const wxString
& rsValue
547 HWND hWnd
= GetHwnd();
548 long lFromChar
= lFrom
;
552 // Set selection and remove it
556 ::WinSendMsg(hWnd
, MLM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0);
557 ::WinSendMsg(hWnd
, MLM_CUT
, 0, 0);
561 ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0);
562 ::WinSendMsg(hWnd
, EM_CUT
, 0, 0);
566 // Now replace with 'value', by pasting.
568 wxSetClipboardData(wxDF_TEXT
, (wxObject
*) (const wxChar
*)rsValue
, 0, 0);
570 // Paste into edit control
572 ::WinSendMsg(hWnd
, MLM_PASTE
, (MPARAM
)0, (MPARAM
)0);
574 ::WinSendMsg(hWnd
, EM_PASTE
, (MPARAM
)0, (MPARAM
)0);
576 wxFAIL_MSG("wxTextCtrl::Replace not implemented if wxUSE_CLIPBOARD is 0.");
578 } // end of wxTextCtrl::Replace
580 void wxTextCtrl::Remove(
585 HWND hWnd
= GetHwnd();
586 long lFromChar
= lFrom
;
591 ::WinSendMsg(hWnd
, MLM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0);
592 ::WinSendMsg(hWnd
, MLM_CUT
, 0, 0);
596 ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0);
597 ::WinSendMsg(hWnd
, EM_CUT
, 0, 0);
599 } // end of wxTextCtrl::Remove
601 void wxTextCtrl::SetSelection(
606 HWND hWnd
= GetHwnd();
607 long lFromChar
= lFrom
;
611 // If from and to are both -1, it means (in wxWindows) that all text should
612 // be selected. Translate into Windows convention
614 if ((lFrom
== -1L) && (lTo
== -1L))
620 ::WinSendMsg(hWnd
, MLM_SETSEL
, (MPARAM
)lFromChar
, (MPARAM
)lToChar
);
622 ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lFromChar
, (USHORT
)lToChar
), (MPARAM
)0);
623 } // end of wxTextCtrl::SetSelection
625 bool wxTextCtrl::LoadFile(
626 const wxString
& rsFile
629 if ( wxTextCtrlBase::LoadFile(rsFile
) )
632 // Update the size limit if needed
638 } // end of wxTextCtrl::LoadFile
640 bool wxTextCtrl::IsModified() const
645 bRc
= (bool)LONGFROMMR(::WinSendMsg(GetHwnd(), MLM_QUERYCHANGED
, 0, 0));
647 bRc
= (bool)LONGFROMMR(::WinSendMsg(GetHwnd(), EM_QUERYCHANGED
, 0, 0));
649 } // end of wxTextCtrl::IsModified
652 // Makes 'unmodified'
654 void wxTextCtrl::DiscardEdits()
657 ::WinSendMsg(GetHwnd(), MLM_SETCHANGED
, MPFROMLONG(FALSE
), 0);
660 // EM controls do not have a SETCHANGED but issuing a query should reset it
662 ::WinSendMsg(GetHwnd(), EM_QUERYCHANGED
, 0, 0);
663 } // end of wxTextCtrl::DiscardEdits
665 int wxTextCtrl::GetNumberOfLines() const
670 nNumLines
= (int)::WinSendMsg(GetHwnd(), MLM_QUERYLINECOUNT
, 0, 0);
674 } // end of wxTextCtrl::GetNumberOfLines
676 long wxTextCtrl::XYToPosition(
681 HWND hWnd
= GetHwnd();
682 long lCharIndex
= 0L;
687 lLen
= (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH
, 0, 0);
688 lCharIndex
= ((lLen
* lY
) + lX
);
693 } // end of wxTextCtrl::XYToPosition
695 bool wxTextCtrl::PositionToXY(
701 HWND hWnd
= GetHwnd();
706 nLineNo
= (long)::WinSendMsg(hWnd
, MLM_LINEFROMCHAR
, (MPARAM
)lPos
, 0);
717 // This gets the char index for the _beginning_ of this line
723 lLineWidth
= (long)::WinSendMsg(hWnd
, MLM_QUERYLINELENGTH
, (MPARAM
)0, (MPARAM
)0);
724 lCharIndex
= (nLineNo
+ 1) * lLineWidth
;
730 vParams
.fsStatus
= WPM_CCHTEXT
;
731 if (::WinSendMsg( hWnd
732 ,WM_QUERYWINDOWPARAMS
737 lCharIndex
= vParams
.cchText
;
743 if (lCharIndex
== -1)
749 // The X position must therefore be the difference between pos and charIndex
752 *plX
= lPos
- lCharIndex
;
757 } // end of wxTextCtrl::PositionToXY
759 void wxTextCtrl::ShowPosition(
763 HWND hWnd
= GetHwnd();
764 long lCurrentLineLineNo
= 0L;
766 // To scroll to a position, we pass the number of lines and characters
767 // to scroll *by*. This means that we need to:
768 // (1) Find the line position of the current line.
769 // (2) Find the line position of pos.
770 // (3) Scroll by (pos - current).
771 // For now, ignore the horizontal scrolling.
774 // Is this where scrolling is relative to - the line containing the caret?
775 // Or is the first visible line??? Try first visible line.
780 // In PM this is the actual char position
782 lCurrentLineLineNo
= (long)::WinSendMsg(hWnd
, MLM_QUERYFIRSTCHAR
, (MPARAM
)0, (MPARAM
)0);
785 // This will cause a scroll to the selected position
787 ::WinSendMsg(hWnd
, MLM_SETSEL
, (MPARAM
)lCurrentLineLineNo
, (MPARAM
)lCurrentLineLineNo
);
789 } // end of wxTextCtrl::ShowPosition
791 int wxTextCtrl::GetLineLength(
798 lLen
= (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH
, 0, 0);
803 vParams
.fsStatus
= WPM_CCHTEXT
;
804 if (::WinSendMsg( GetHwnd()
805 ,WM_QUERYWINDOWPARAMS
810 lLen
= vParams
.cchText
;
816 } // end ofwxTextCtrl::GetLineLength
818 wxString
wxTextCtrl::GetLineText(
822 long lLen
= (long)GetLineLength((long)lLineNo
) + 1;
827 // There must be at least enough place for the length WORD in the
830 lLen
+= sizeof(WORD
);
831 zBuf
= new char[lLen
];
838 lLen
= (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH
, 0, 0);
839 lIndex
= lLen
* lLineNo
;
841 ::WinSendMsg(GetHwnd(), MLM_SETSEL
, (MPARAM
)lIndex
, (MPARAM
)lIndex
);
842 ::WinSendMsg(GetHwnd(), MLM_SETIMPORTEXPORT
, MPFROMP(zBuf
), MPFROMSHORT((USHORT
)sizeof(zBuf
)));
843 lBuflen
= (long)::WinSendMsg(GetHwnd(), MLM_QUERYFORMATTEXTLENGTH
, MPFROMLONG(lIndex
), MPFROMLONG(-1));
844 lCopied
= (long)::WinSendMsg(GetHwnd(), MLM_EXPORT
, MPFROMP(&lIndex
), MPFROMP(&lBuflen
));
845 zBuf
[lCopied
] = '\0';
851 vParams
.fsStatus
= WPM_CCHTEXT
;
852 if (::WinSendMsg( GetHwnd()
853 ,WM_QUERYWINDOWPARAMS
857 memcpy(zBuf
, vParams
.pszText
, vParams
.cchText
);
858 zBuf
[vParams
.cchText
] = '\0';
863 } // end of wxTextCtrl::GetLineText
865 // ----------------------------------------------------------------------------
867 // ----------------------------------------------------------------------------
869 void wxTextCtrl::Undo()
874 ::WinSendMsg(GetHwnd(), MLM_UNDO
, 0, 0);
875 // Simple entryfields cannot be undone
877 } // end of wxTextCtrl::Undo
879 void wxTextCtrl::Redo()
884 ::WinSendMsg(GetHwnd(), MLM_UNDO
, 0, 0);
885 // Simple entryfields cannot be undone
887 } // end of wxTextCtrl::Redo
889 bool wxTextCtrl::CanUndo() const
894 bOk
= (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO
, 0, 0) != 0);
896 bOk
= FALSE
; // can't undo regular edit fields in PM
898 } // end of wxTextCtrl::CanUndo
900 bool wxTextCtrl::CanRedo() const
905 bOk
= (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO
, 0, 0) != 0);
907 bOk
= FALSE
; // can't undo regular edit fields in PM
909 } // end of wxTextCtrl::CanRedo
911 // ----------------------------------------------------------------------------
912 // implemenation details
913 // ----------------------------------------------------------------------------
915 void wxTextCtrl::Command(
916 wxCommandEvent
& rEvent
919 SetValue(rEvent
.GetString());
920 ProcessCommand (rEvent
);
921 } // end of wxTextCtrl::Command
923 void wxTextCtrl::OnDropFiles(
924 wxDropFilesEvent
& rEvent
927 // By default, load the first file into the text window.
928 if (rEvent
.GetNumberOfFiles() > 0)
930 LoadFile(rEvent
.GetFiles()[0]);
932 } // end of wxTextCtrl::OnDropFiles
934 WXHBRUSH
wxTextCtrl::OnCtlColor(
943 HPS hPS
= (HPS
)hWxDC
;
944 wxBrush
* pBrush
= NULL
;
945 wxColour vColBack
= GetBackgroundColour();
946 wxColour vColFore
= GetForegroundColour();
947 wxBrush
* pBackgroundBrush
= wxTheBrushList
->FindOrCreateBrush( GetBackgroundColour()
953 HBRUSH hBrush
= NULLHANDLE
;
957 if (GetParent()->GetTransparentBackground())
958 ::GpiSetBackMix(hPS
, BM_LEAVEALONE
);
960 ::GpiSetBackMix(hPS
, BM_OVERPAINT
);
961 if (!IsEnabled() && (GetWindowStyle() & wxTE_MULTILINE
) == 0)
962 vColBack
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
);
963 ::GpiSetBackColor(hPS
, vColBack
.GetPixel());
964 ::GpiSetColor(hPS
, vColFore
.GetPixel());
965 return (WXHBRUSH
)pBackgroundBrush
->GetResourceHandle();
966 } // end of wxTextCtrl::OnCtlColor
968 void wxTextCtrl::OnChar(
972 switch (rEvent
.KeyCode())
975 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
977 wxCommandEvent
vEvent(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
979 vEvent
.SetEventObject(this);
980 if ( GetEventHandler()->ProcessEvent(vEvent
))
983 //else: multiline controls need Enter for themselves
988 // always produce navigation event - even if we process TAB
989 // ourselves the fact that we got here means that the user code
990 // decided to skip processing of this TAB - probably to let it
991 // do its default job.
993 // NB: Notice that Ctrl-Tab is handled elsewhere and Alt-Tab is
994 // handled by Windows
996 wxNavigationKeyEvent vEventNav
;
998 vEventNav
.SetDirection(!rEvent
.ShiftDown());
999 vEventNav
.SetWindowChange(FALSE
);
1000 vEventNav
.SetEventObject(this);
1002 if ( GetEventHandler()->ProcessEvent(vEventNav
) )
1008 } // end of wxTextCtrl::OnChar
1010 bool wxTextCtrl::OS2Command(
1012 , WXWORD
WXUNUSED(vId
)
1020 wxFocusEvent
vEvent( uParam
== EN_KILLFOCUS
? wxEVT_KILL_FOCUS
1025 vEvent
.SetEventObject(this);
1026 GetEventHandler()->ProcessEvent(vEvent
);
1032 wxCommandEvent
vEvent( wxEVT_COMMAND_TEXT_UPDATED
1036 InitCommandEvent(vEvent
);
1037 vEvent
.SetString((char*)GetValue().c_str());
1038 ProcessCommand(vEvent
);
1044 // The text size limit has been hit - increase it
1050 case EN_INSERTMODETOGGLE
:
1061 } // end of wxTextCtrl::OS2Command
1063 void wxTextCtrl::AdjustSpaceLimit()
1065 unsigned int uLen
= 0;
1066 unsigned int uLimit
= 0;
1068 uLen
= ::WinQueryWindowTextLength(GetHwnd());
1071 uLimit
= (unsigned int)::WinSendMsg( GetHwnd()
1082 vParams
.fsStatus
= WPM_CBCTLDATA
;
1083 vParams
.cbCtlData
= sizeof(ENTRYFDATA
);
1085 if (::WinSendMsg( GetHwnd()
1086 ,WM_QUERYWINDOWPARAMS
1091 pEfd
= (ENTRYFDATA
*)vParams
.pCtlData
;
1092 uLimit
= (unsigned int)pEfd
->cchEditLimit
;
1095 uLimit
= 32; //PM's default
1099 uLimit
= uLen
+ 0x8000; // 32Kb
1100 if (uLimit
> 0xffff)
1105 ::WinSendMsg(GetHwnd(), MLM_SETTEXTLIMIT
, MPFROMLONG(uLimit
), 0);
1107 ::WinSendMsg(GetHwnd(), EM_SETTEXTLIMIT
, MPFROMLONG(uLimit
), 0);
1109 } // end of wxTextCtrl::AdjustSpaceLimit
1111 bool wxTextCtrl::AcceptsFocus() const
1114 // We don't want focus if we can't be edited
1116 return IsEditable() && wxControl::AcceptsFocus();
1117 } // end of wxTextCtrl::Command
1119 wxSize
wxTextCtrl::DoGetBestSize() const
1124 wxGetCharSize(GetHWND(), &nCx
, &nCy
, (wxFont
*)&GetFont());
1126 int wText
= DEFAULT_ITEM_WIDTH
;
1127 int hText
= (EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy
) * .8);
1129 if (m_windowStyle
& wxTE_MULTILINE
)
1131 hText
*= wxMin(GetNumberOfLines(), 5);
1133 //else: for single line control everything is ok
1134 return wxSize(wText
, hText
);
1135 } // end of wxTextCtrl::DoGetBestSize
1137 // ----------------------------------------------------------------------------
1138 // standard handlers for standard edit menu events
1139 // ----------------------------------------------------------------------------
1141 void wxTextCtrl::OnCut(
1142 wxCommandEvent
& rEvent
1146 } // end of wxTextCtrl::OnCut
1148 void wxTextCtrl::OnCopy(
1149 wxCommandEvent
& rEvent
1153 } // end of wxTextCtrl::OnCopy
1155 void wxTextCtrl::OnPaste(
1156 wxCommandEvent
& rEvent
1160 } // end of wxTextCtrl::OnPaste
1162 void wxTextCtrl::OnUndo(
1163 wxCommandEvent
& rEvent
1167 } // end of wxTextCtrl::OnUndo
1169 void wxTextCtrl::OnRedo(
1170 wxCommandEvent
& rEvent
1174 } // end of wxTextCtrl::OnRedo
1176 void wxTextCtrl::OnUpdateCut(
1177 wxUpdateUIEvent
& rEvent
1180 rEvent
.Enable(CanCut());
1181 } // end of wxTextCtrl::OnUpdateCut
1183 void wxTextCtrl::OnUpdateCopy(
1184 wxUpdateUIEvent
& rEvent
1187 rEvent
.Enable(CanCopy());
1188 } // end of wxTextCtrl::OnUpdateCopy
1190 void wxTextCtrl::OnUpdatePaste(
1191 wxUpdateUIEvent
& rEvent
1194 rEvent
.Enable(CanPaste());
1195 } // end of wxTextCtrl::OnUpdatePaste
1197 void wxTextCtrl::OnUpdateUndo(
1198 wxUpdateUIEvent
& rEvent
1201 rEvent
.Enable(CanUndo());
1202 } // end of wxTextCtrl::OnUpdateUndo
1204 void wxTextCtrl::OnUpdateRedo(
1205 wxUpdateUIEvent
& rEvent
1208 rEvent
.Enable(CanRedo());
1209 } // end of wxTextCtrl::OnUpdateRedo
1211 bool wxTextCtrl::SetBackgroundColour(
1212 const wxColour
& rColour
1216 ::WinSendMsg(GetHwnd(), MLM_SETBACKCOLOR
, (MPARAM
)rColour
.GetPixel(), MLE_INDEX
);
1218 } // end of wxTextCtrl::SetBackgroundColour
1220 bool wxTextCtrl::SetForegroundColour(
1221 const wxColour
& rColour
1225 ::WinSendMsg(GetHwnd(), MLM_SETTEXTCOLOR
, (MPARAM
)rColour
.GetPixel(), MLE_INDEX
);
1227 } // end of wxTextCtrl::SetForegroundColour
1229 bool wxTextCtrl::SetStyle(
1232 , const wxTextAttr
& rStyle
1235 HWND hWnd
= GetHwnd();
1246 // We can only change the format of the selection, so select the range we
1247 // want and restore the old selection later
1252 GetSelection( &lStartOld
1257 // But do we really have to change the selection?
1259 bool bChangeSel
= lStart
!= lStartOld
||
1265 ::WinSendMsg(hWnd
, MLM_SETSEL
, MPFROM2SHORT((USHORT
)lStart
, (USHORT
)lEnd
), 0);
1267 ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lStart
, (USHORT
)lEnd
), 0);
1271 // TODO:: finish this part
1274 } // end of wxTextCtrl::SetStyle