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