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