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