]> git.saurik.com Git - wxWidgets.git/blame - src/os2/textctrl.cpp
More RTL fixes.
[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
c4955899
DW
682bool wxTextCtrl::LoadFile(
683 const wxString& rsFile
684)
0e320a79 685{
c4955899 686 if ( wxTextCtrlBase::LoadFile(rsFile) )
d90895ac 687 {
c4955899
DW
688 //
689 // Update the size limit if needed
690 //
d90895ac 691 AdjustSpaceLimit();
7d8268a1 692 return true;
d90895ac 693 }
7d8268a1 694 return false;
c4955899 695} // end of wxTextCtrl::LoadFile
0e320a79
DW
696
697bool wxTextCtrl::IsModified() const
698{
c4955899
DW
699 bool bRc;
700
701 if (m_bIsMLE)
702 bRc = (bool)LONGFROMMR(::WinSendMsg(GetHwnd(), MLM_QUERYCHANGED, 0, 0));
703 else
704 bRc = (bool)LONGFROMMR(::WinSendMsg(GetHwnd(), EM_QUERYCHANGED, 0, 0));
705 return bRc;
706} // end of wxTextCtrl::IsModified
0e320a79 707
3a9fa0d6
VZ
708void wxTextCtrl::MarkDirty()
709{
b21ec1a7
SN
710 if (m_bIsMLE)
711 ::WinSendMsg(GetHwnd(), MLM_SETCHANGED, MPFROMLONG(TRUE), 0);
712 else
713 // EM controls do not have a SETCHANGED, what can we do??
714 wxFAIL_MSG( _T("not implemented") );
3a9fa0d6
VZ
715}
716
3bd418ca 717//
0e320a79 718// Makes 'unmodified'
3bd418ca 719//
0e320a79
DW
720void wxTextCtrl::DiscardEdits()
721{
3bd418ca
DW
722 if (m_bIsMLE)
723 ::WinSendMsg(GetHwnd(), MLM_SETCHANGED, MPFROMLONG(FALSE), 0);
724 else
725 //
726 // EM controls do not have a SETCHANGED but issuing a query should reset it
727 //
728 ::WinSendMsg(GetHwnd(), EM_QUERYCHANGED, 0, 0);
729} // end of wxTextCtrl::DiscardEdits
0e320a79
DW
730
731int wxTextCtrl::GetNumberOfLines() const
732{
c4955899 733 int nNumLines;
0e320a79 734
c4955899
DW
735 if (m_bIsMLE)
736 nNumLines = (int)::WinSendMsg(GetHwnd(), MLM_QUERYLINECOUNT, 0, 0);
737 else
738 nNumLines = 1;
739 return nNumLines;
740} // end of wxTextCtrl::GetNumberOfLines
d90895ac 741
c4955899
DW
742long wxTextCtrl::XYToPosition(
743 long lX
744, long lY
745) const
746{
c4955899
DW
747 long lCharIndex = 0L;
748 long lLen;
0e320a79 749
c4955899
DW
750 if (m_bIsMLE)
751 {
752 lLen = (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH, 0, 0);
753 lCharIndex = ((lLen * lY) + lX);
754 }
755 else
756 lCharIndex = lX;
757 return lCharIndex;
758} // end of wxTextCtrl::XYToPosition
759
760bool wxTextCtrl::PositionToXY(
761 long lPos
762, long* plX
763, long* plY
764) const
0e320a79 765{
c4955899
DW
766 HWND hWnd = GetHwnd();
767 long nLineNo = -1;
768 long lCharIndex = 0;
d90895ac 769
c4955899
DW
770 if (m_bIsMLE)
771 nLineNo = (long)::WinSendMsg(hWnd, MLM_LINEFROMCHAR, (MPARAM)lPos, 0);
772 else
773 nLineNo = 0;
d90895ac 774
c4955899 775 if (nLineNo == -1)
d90895ac
DW
776 {
777 // no such line
7d8268a1 778 return false;
d90895ac
DW
779 }
780
c4955899 781 //
d90895ac 782 // This gets the char index for the _beginning_ of this line
c4955899
DW
783 //
784 long lLineWidth;
785
786 if (m_bIsMLE)
787 {
788 lLineWidth = (long)::WinSendMsg(hWnd, MLM_QUERYLINELENGTH, (MPARAM)0, (MPARAM)0);
789 lCharIndex = (nLineNo + 1) * lLineWidth;
790 }
791 else
792 {
793 WNDPARAMS vParams;
794
795 vParams.fsStatus = WPM_CCHTEXT;
796 if (::WinSendMsg( hWnd
797 ,WM_QUERYWINDOWPARAMS
798 ,&vParams
799 ,0
800 ))
801 {
802 lCharIndex = vParams.cchText;
803 }
804 else
805 lCharIndex = 32;
806 }
807
808 if (lCharIndex == -1)
d90895ac 809 {
7d8268a1 810 return false;
d90895ac
DW
811 }
812
c4955899
DW
813 //
814 // The X position must therefore be the difference between pos and charIndex
815 //
816 if (plX)
817 *plX = lPos - lCharIndex;
818 if (plY)
819 *plY = nLineNo;
d90895ac 820
7d8268a1 821 return true;
c4955899 822} // end of wxTextCtrl::PositionToXY
0e320a79 823
6670f564 824void wxTextCtrl::ShowPosition( long WXUNUSED(lPos) )
0e320a79 825{
6670f564
WS
826 HWND hWnd = GetHwnd();
827 long lCurrentLineLineNo = 0L;
d90895ac
DW
828
829 // To scroll to a position, we pass the number of lines and characters
830 // to scroll *by*. This means that we need to:
831 // (1) Find the line position of the current line.
832 // (2) Find the line position of pos.
833 // (3) Scroll by (pos - current).
834 // For now, ignore the horizontal scrolling.
835
c4955899 836 //
d90895ac
DW
837 // Is this where scrolling is relative to - the line containing the caret?
838 // Or is the first visible line??? Try first visible line.
c4955899
DW
839 //
840 if (m_bIsMLE)
841 {
842 //
843 // In PM this is the actual char position
844 //
845 lCurrentLineLineNo = (long)::WinSendMsg(hWnd, MLM_QUERYFIRSTCHAR, (MPARAM)0, (MPARAM)0);
d90895ac 846
c4955899
DW
847 //
848 // This will cause a scroll to the selected position
849 //
850 ::WinSendMsg(hWnd, MLM_SETSEL, (MPARAM)lCurrentLineLineNo, (MPARAM)lCurrentLineLineNo);
851 }
852} // end of wxTextCtrl::ShowPosition
0e320a79 853
6670f564 854int wxTextCtrl::GetLineLength( long WXUNUSED(lLineNo) ) const
0e320a79 855{
6670f564 856 long lLen = 0L;
d90895ac 857
3bd418ca 858 if (m_bIsMLE)
6670f564 859 {
3bd418ca 860 lLen = (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH, 0, 0);
6670f564 861 }
3bd418ca
DW
862 else
863 {
6670f564 864 WNDPARAMS vParams;
3bd418ca
DW
865
866 vParams.fsStatus = WPM_CCHTEXT;
867 if (::WinSendMsg( GetHwnd()
868 ,WM_QUERYWINDOWPARAMS
869 ,&vParams
870 ,0
871 ))
872 {
873 lLen = vParams.cchText;
874 }
875 else
876 lLen = 32;
877 }
878 return lLen;
c4955899 879} // end ofwxTextCtrl::GetLineLength
0e320a79 880
c4955899
DW
881wxString wxTextCtrl::GetLineText(
882 long lLineNo
883) const
0e320a79 884{
c4955899
DW
885 long lLen = (long)GetLineLength((long)lLineNo) + 1;
886 wxString sStr;
0fba44b4 887 wxChar* zBuf;
0e320a79 888
c4955899
DW
889 //
890 // There must be at least enough place for the length WORD in the
891 // buffer
892 //
893 lLen += sizeof(WORD);
0fba44b4 894 zBuf = new wxChar[lLen];
c4955899
DW
895 if (m_bIsMLE)
896 {
897 long lIndex;
898 long lBuflen;
899 long lCopied;
0e320a79 900
c4955899
DW
901 lLen = (long)::WinSendMsg(GetHwnd(), MLM_QUERYLINELENGTH, 0, 0);
902 lIndex = lLen * lLineNo;
0e320a79 903
c4955899 904 ::WinSendMsg(GetHwnd(), MLM_SETSEL, (MPARAM)lIndex, (MPARAM)lIndex);
0fba44b4 905 ::WinSendMsg(GetHwnd(), MLM_SETIMPORTEXPORT, MPFROMP(zBuf), MPFROMSHORT((USHORT)WXSIZEOF(zBuf)));
c4955899
DW
906 lBuflen = (long)::WinSendMsg(GetHwnd(), MLM_QUERYFORMATTEXTLENGTH, MPFROMLONG(lIndex), MPFROMLONG(-1));
907 lCopied = (long)::WinSendMsg(GetHwnd(), MLM_EXPORT, MPFROMP(&lIndex), MPFROMP(&lBuflen));
908 zBuf[lCopied] = '\0';
909 }
910 else
911 {
912 WNDPARAMS vParams;
913
914 vParams.fsStatus = WPM_CCHTEXT;
915 if (::WinSendMsg( GetHwnd()
916 ,WM_QUERYWINDOWPARAMS
917 ,&vParams
918 ,0
919 ))
0fba44b4 920 memcpy((char*)zBuf, vParams.pszText, vParams.cchText);
c4955899
DW
921 zBuf[vParams.cchText] = '\0';
922 }
923 sStr = zBuf;
924 delete [] zBuf;
925 return sStr;
926} // end of wxTextCtrl::GetLineText
0e320a79 927
d90895ac 928// ----------------------------------------------------------------------------
0e320a79 929// Undo/redo
d90895ac
DW
930// ----------------------------------------------------------------------------
931
0e320a79
DW
932void wxTextCtrl::Undo()
933{
d90895ac
DW
934 if (CanUndo())
935 {
c4955899
DW
936 if (m_bIsMLE)
937 ::WinSendMsg(GetHwnd(), MLM_UNDO, 0, 0);
938 // Simple entryfields cannot be undone
d90895ac 939 }
c4955899 940} // end of wxTextCtrl::Undo
0e320a79
DW
941
942void wxTextCtrl::Redo()
943{
d90895ac
DW
944 if (CanRedo())
945 {
c4955899
DW
946 if (m_bIsMLE)
947 ::WinSendMsg(GetHwnd(), MLM_UNDO, 0, 0);
948 // Simple entryfields cannot be undone
d90895ac 949 }
c4955899 950} // end of wxTextCtrl::Redo
0e320a79
DW
951
952bool wxTextCtrl::CanUndo() const
953{
3bd418ca
DW
954 bool bOk;
955
956 if (m_bIsMLE)
957 bOk = (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO, 0, 0) != 0);
958 else
7d8268a1 959 bOk = false; // can't undo regular edit fields in PM
3bd418ca
DW
960 return bOk;
961} // end of wxTextCtrl::CanUndo
0e320a79
DW
962
963bool wxTextCtrl::CanRedo() const
964{
3bd418ca
DW
965 bool bOk;
966
967 if (m_bIsMLE)
968 bOk = (::WinSendMsg(GetHwnd(), MLM_QUERYUNDO, 0, 0) != 0);
969 else
7d8268a1 970 bOk = false; // can't undo regular edit fields in PM
3bd418ca
DW
971 return bOk;
972} // end of wxTextCtrl::CanRedo
0e320a79 973
d90895ac
DW
974// ----------------------------------------------------------------------------
975// implemenation details
976// ----------------------------------------------------------------------------
0e320a79 977
c4955899
DW
978void wxTextCtrl::Command(
979 wxCommandEvent& rEvent
980)
0e320a79 981{
c4955899
DW
982 SetValue(rEvent.GetString());
983 ProcessCommand (rEvent);
984} // end of wxTextCtrl::Command
0e320a79 985
c4955899
DW
986void wxTextCtrl::OnDropFiles(
987 wxDropFilesEvent& rEvent
988)
0e320a79
DW
989{
990 // By default, load the first file into the text window.
c4955899 991 if (rEvent.GetNumberOfFiles() > 0)
0e320a79 992 {
c4955899 993 LoadFile(rEvent.GetFiles()[0]);
0e320a79 994 }
c4955899
DW
995} // end of wxTextCtrl::OnDropFiles
996
6670f564
WS
997WXHBRUSH wxTextCtrl::OnCtlColor( WXHDC hWxDC,
998 WXHWND WXUNUSED(hWnd),
999 WXUINT WXUNUSED(uCtlColor),
1000 WXUINT WXUNUSED(uMessage),
1001 WXWPARAM WXUNUSED(wParam),
1002 WXLPARAM WXUNUSED(lParam) )
d90895ac 1003{
6670f564
WS
1004 HPS hPS = (HPS)hWxDC;
1005 wxColour vColBack = GetBackgroundColour();
1006 wxColour vColFore = GetForegroundColour();
1007 wxBrush* pBackgroundBrush = wxTheBrushList->FindOrCreateBrush( vColBack, wxSOLID );
c4955899
DW
1008
1009 if (m_bUseCtl3D)
1010 {
1011 HBRUSH hBrush = NULLHANDLE;
0e320a79 1012
c4955899
DW
1013 return hBrush;
1014 }
1015 if (GetParent()->GetTransparentBackground())
1016 ::GpiSetBackMix(hPS, BM_LEAVEALONE);
1017 else
1018 ::GpiSetBackMix(hPS, BM_OVERPAINT);
1019 if (!IsEnabled() && (GetWindowStyle() & wxTE_MULTILINE) == 0)
a756f210 1020 vColBack = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
c4955899
DW
1021 ::GpiSetBackColor(hPS, vColBack.GetPixel());
1022 ::GpiSetColor(hPS, vColFore.GetPixel());
1023 return (WXHBRUSH)pBackgroundBrush->GetResourceHandle();
1024} // end of wxTextCtrl::OnCtlColor
1025
54ffa107
DW
1026bool wxTextCtrl::OS2ShouldPreProcessMessage(
1027 WXMSG* pMsg
1028)
1029{
1030 return wxControl::OS2ShouldPreProcessMessage(pMsg);
1031} // end of wxTextCtrl::OS2ShouldPreProcessMessage
1032
c4955899
DW
1033void wxTextCtrl::OnChar(
1034 wxKeyEvent& rEvent
1035)
0e320a79 1036{
9923c37d 1037 switch (rEvent.GetKeyCode())
d90895ac 1038 {
d90895ac
DW
1039 case WXK_RETURN:
1040 if ( !(m_windowStyle & wxTE_MULTILINE) )
1041 {
c4955899
DW
1042 wxCommandEvent vEvent(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
1043
1044 vEvent.SetEventObject(this);
1045 if ( GetEventHandler()->ProcessEvent(vEvent))
d90895ac
DW
1046 return;
1047 }
1048 //else: multiline controls need Enter for themselves
1049
1050 break;
1051
1052 case WXK_TAB:
1053 // always produce navigation event - even if we process TAB
1054 // ourselves the fact that we got here means that the user code
1055 // decided to skip processing of this TAB - probably to let it
1056 // do its default job.
1057 //
1058 // NB: Notice that Ctrl-Tab is handled elsewhere and Alt-Tab is
1059 // handled by Windows
1060 {
c4955899 1061 wxNavigationKeyEvent vEventNav;
d90895ac 1062
c4955899 1063 vEventNav.SetDirection(!rEvent.ShiftDown());
7d8268a1 1064 vEventNav.SetWindowChange(false);
c4955899
DW
1065 vEventNav.SetEventObject(this);
1066
1067 if ( GetEventHandler()->ProcessEvent(vEventNav) )
d90895ac
DW
1068 return;
1069 }
1070 break;
d90895ac 1071 }
c4955899
DW
1072 rEvent.Skip();
1073} // end of wxTextCtrl::OnChar
0e320a79 1074
c4955899
DW
1075bool wxTextCtrl::OS2Command(
1076 WXUINT uParam
1077, WXWORD WXUNUSED(vId)
1078)
0e320a79 1079{
c4955899 1080 switch (uParam)
d90895ac 1081 {
d90895ac
DW
1082 case EN_SETFOCUS:
1083 case EN_KILLFOCUS:
1084 {
c4955899
DW
1085 wxFocusEvent vEvent( uParam == EN_KILLFOCUS ? wxEVT_KILL_FOCUS
1086 : wxEVT_SET_FOCUS
1087 ,m_windowId
1088 );
1089
1090 vEvent.SetEventObject(this);
1091 GetEventHandler()->ProcessEvent(vEvent);
d90895ac
DW
1092 }
1093 break;
1094
1095 case EN_CHANGE:
1096 {
c4955899
DW
1097 wxCommandEvent vEvent( wxEVT_COMMAND_TEXT_UPDATED
1098 ,m_windowId
1099 );
1100
1101 InitCommandEvent(vEvent);
c4955899 1102 ProcessCommand(vEvent);
d90895ac
DW
1103 }
1104 break;
1105
c4955899
DW
1106 case EN_OVERFLOW:
1107 //
1108 // The text size limit has been hit - increase it
1109 //
d90895ac
DW
1110 AdjustSpaceLimit();
1111 break;
1112
c4955899
DW
1113 case EN_SCROLL:
1114 case EN_INSERTMODETOGGLE:
1115 case EN_MEMERROR:
7d8268a1 1116 return false;
d90895ac 1117 default:
7d8268a1 1118 return false;
d90895ac
DW
1119 }
1120
c4955899
DW
1121 //
1122 // Processed
1123 //
7d8268a1 1124 return true;
c4955899 1125} // end of wxTextCtrl::OS2Command
0e320a79 1126
d90895ac 1127void wxTextCtrl::AdjustSpaceLimit()
0e320a79 1128{
3bd418ca
DW
1129 unsigned int uLen = 0;
1130 unsigned int uLimit = 0;
d90895ac 1131
3bd418ca
DW
1132 uLen = ::WinQueryWindowTextLength(GetHwnd());
1133 if (m_bIsMLE)
1134 {
1135 uLimit = (unsigned int)::WinSendMsg( GetHwnd()
1136 ,MLM_QUERYTEXTLIMIT
1137 ,0
1138 ,0
1139 );
1140 }
1141 else
1142 {
919312f7 1143 ENTRYFDATA Efd;
3bd418ca
DW
1144 WNDPARAMS vParams;
1145
1146 vParams.fsStatus = WPM_CBCTLDATA;
7d8268a1 1147 vParams.pCtlData = &Efd;
3bd418ca
DW
1148 vParams.cbCtlData = sizeof(ENTRYFDATA);
1149
1150 if (::WinSendMsg( GetHwnd()
1151 ,WM_QUERYWINDOWPARAMS
1152 ,&vParams
1153 ,0
1154 ))
919312f7 1155 uLimit = (unsigned int)Efd.cchEditLimit;
d90895ac 1156 else
3bd418ca 1157 uLimit = 32; //PM's default
d90895ac 1158 }
3bd418ca
DW
1159 if (uLen >= uLimit)
1160 {
1161 uLimit = uLen + 0x8000; // 32Kb
1162 if (uLimit > 0xffff)
1163 {
1164 uLimit = 0L;
1165 }
1166 if (m_bIsMLE)
1167 ::WinSendMsg(GetHwnd(), MLM_SETTEXTLIMIT, MPFROMLONG(uLimit), 0);
1168 else
919312f7 1169 ::WinSendMsg(GetHwnd(), EM_SETTEXTLIMIT, MPFROMSHORT(uLimit), 0);
3bd418ca
DW
1170 }
1171} // end of wxTextCtrl::AdjustSpaceLimit
0e320a79 1172
d90895ac 1173bool wxTextCtrl::AcceptsFocus() const
0e320a79 1174{
c4955899 1175 //
57ff8a87
DW
1176 // We don't want focus if we can't be edited unless we're a multiline
1177 // control because then it might be still nice to get focus from keyboard
1178 // to be able to scroll it without mouse
c4955899 1179 //
57ff8a87 1180 return (IsEditable() || IsMultiLine()) && wxControl::AcceptsFocus();
c4955899 1181} // end of wxTextCtrl::Command
0e320a79 1182
e78c4d50 1183wxSize wxTextCtrl::DoGetBestSize() const
0e320a79 1184{
c4955899
DW
1185 int nCx;
1186 int nCy;
0d598bae 1187 wxFont vFont = (wxFont)GetFont();
0e320a79 1188
0d598bae 1189 wxGetCharSize(GetHWND(), &nCx, &nCy, &vFont);
d90895ac 1190
c4955899 1191 int wText = DEFAULT_ITEM_WIDTH;
9923c37d 1192 int hText = (int)(EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * .8);
c4955899
DW
1193
1194 if (m_windowStyle & wxTE_MULTILINE)
d90895ac 1195 {
239c2e96 1196 hText *= wxMax(GetNumberOfLines(), 5);
d90895ac
DW
1197 }
1198 //else: for single line control everything is ok
d90895ac 1199 return wxSize(wText, hText);
c4955899 1200} // end of wxTextCtrl::DoGetBestSize
0e320a79 1201
d90895ac
DW
1202// ----------------------------------------------------------------------------
1203// standard handlers for standard edit menu events
1204// ----------------------------------------------------------------------------
1205
6670f564 1206void wxTextCtrl::OnCut( wxCommandEvent& WXUNUSED(rEvent) )
0e320a79
DW
1207{
1208 Cut();
c4955899 1209} // end of wxTextCtrl::OnCut
0e320a79 1210
6670f564 1211void wxTextCtrl::OnCopy( wxCommandEvent& WXUNUSED(rEvent) )
0e320a79
DW
1212{
1213 Copy();
c4955899 1214} // end of wxTextCtrl::OnCopy
0e320a79 1215
6670f564 1216void wxTextCtrl::OnPaste( wxCommandEvent& WXUNUSED(rEvent) )
0e320a79
DW
1217{
1218 Paste();
c4955899 1219} // end of wxTextCtrl::OnPaste
0e320a79 1220
6670f564 1221void wxTextCtrl::OnUndo( wxCommandEvent& WXUNUSED(rEvent) )
0e320a79
DW
1222{
1223 Undo();
c4955899 1224} // end of wxTextCtrl::OnUndo
0e320a79 1225
6670f564 1226void wxTextCtrl::OnRedo( wxCommandEvent& WXUNUSED(rEvent) )
0e320a79
DW
1227{
1228 Redo();
c4955899 1229} // end of wxTextCtrl::OnRedo
0e320a79 1230
6670f564 1231void wxTextCtrl::OnDelete( wxCommandEvent& WXUNUSED(rEvent) )
2b5f62a0 1232{
6670f564
WS
1233 long lFrom, lTo;
1234
1235 GetSelection( &lFrom, &lTo );
2b5f62a0 1236
2b5f62a0 1237 if (lFrom != -1 && lTo != -1)
6670f564 1238 Remove( lFrom, lTo );
2b5f62a0
VZ
1239} // end of wxTextCtrl::OnDelete
1240
6670f564 1241void wxTextCtrl::OnSelectAll( wxCommandEvent& WXUNUSED(rEvent) )
2b5f62a0
VZ
1242{
1243 SetSelection(-1, -1);
1244} // end of wxTextCtrl::OnSelectAll
1245
6670f564 1246void wxTextCtrl::OnUpdateCut( wxUpdateUIEvent& rEvent )
0e320a79 1247{
c4955899
DW
1248 rEvent.Enable(CanCut());
1249} // end of wxTextCtrl::OnUpdateCut
0e320a79 1250
6670f564 1251void wxTextCtrl::OnUpdateCopy( wxUpdateUIEvent& rEvent )
0e320a79 1252{
c4955899
DW
1253 rEvent.Enable(CanCopy());
1254} // end of wxTextCtrl::OnUpdateCopy
0e320a79 1255
6670f564 1256void wxTextCtrl::OnUpdatePaste( wxUpdateUIEvent& rEvent )
0e320a79 1257{
c4955899
DW
1258 rEvent.Enable(CanPaste());
1259} // end of wxTextCtrl::OnUpdatePaste
0e320a79 1260
6670f564 1261void wxTextCtrl::OnUpdateUndo( wxUpdateUIEvent& rEvent )
0e320a79 1262{
c4955899
DW
1263 rEvent.Enable(CanUndo());
1264} // end of wxTextCtrl::OnUpdateUndo
1265
6670f564 1266void wxTextCtrl::OnUpdateRedo( wxUpdateUIEvent& rEvent )
c4955899
DW
1267{
1268 rEvent.Enable(CanRedo());
1269} // end of wxTextCtrl::OnUpdateRedo
0e320a79 1270
6670f564 1271void wxTextCtrl::OnUpdateDelete( wxUpdateUIEvent& rEvent )
2b5f62a0 1272{
6670f564 1273 long lFrom, lTo;
2b5f62a0 1274
6670f564 1275 GetSelection( &lFrom, &lTo );
2b5f62a0
VZ
1276 rEvent.Enable( lFrom != -1L && lTo != -1L && lFrom != lTo && IsEditable()) ;
1277} // end of wxTextCtrl::OnUpdateDelete
1278
6670f564 1279void wxTextCtrl::OnUpdateSelectAll( wxUpdateUIEvent& rEvent )
2b5f62a0
VZ
1280{
1281 rEvent.Enable(GetLastPosition() > 0);
1282} // end of wxTextCtrl::OnUpdateSelectAll
1283
6670f564 1284bool wxTextCtrl::SetBackgroundColour( const wxColour& rColour )
0e320a79 1285{
c4955899
DW
1286 if (m_bIsMLE)
1287 ::WinSendMsg(GetHwnd(), MLM_SETBACKCOLOR, (MPARAM)rColour.GetPixel(), MLE_INDEX);
7d8268a1 1288 return true;
c4955899
DW
1289} // end of wxTextCtrl::SetBackgroundColour
1290
6670f564 1291bool wxTextCtrl::SetForegroundColour( const wxColour& rColour )
c4955899
DW
1292{
1293 if (m_bIsMLE)
1294 ::WinSendMsg(GetHwnd(), MLM_SETTEXTCOLOR, (MPARAM)rColour.GetPixel(), MLE_INDEX);
7d8268a1 1295 return true;
c4955899 1296} // end of wxTextCtrl::SetForegroundColour
d90895ac 1297
6670f564
WS
1298bool wxTextCtrl::SetStyle( long lStart,
1299 long lEnd,
1300 const wxTextAttr& WXUNUSED(rStyle) )
39c26ef2 1301{
6670f564 1302 HWND hWnd = GetHwnd();
39c26ef2
DW
1303
1304 if (lStart > lEnd)
1305 {
6670f564 1306 long lTmp = lStart;
39c26ef2
DW
1307
1308 lStart = lEnd;
1309 lEnd = lTmp;
1310 }
1311
1312 //
1313 // We can only change the format of the selection, so select the range we
1314 // want and restore the old selection later
1315 //
6670f564 1316 long lStartOld, lEndOld;
39c26ef2 1317
6670f564 1318 GetSelection( &lStartOld, &lEndOld );
39c26ef2
DW
1319
1320 //
1321 // But do we really have to change the selection?
1322 //
6670f564
WS
1323 bool bChangeSel = lStart != lStartOld ||
1324 lEnd != lEndOld;
39c26ef2
DW
1325
1326 if (bChangeSel)
1327 {
1328 if (m_bIsMLE)
1329 ::WinSendMsg(hWnd, MLM_SETSEL, MPFROM2SHORT((USHORT)lStart, (USHORT)lEnd), 0);
1330 else
1331 ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lStart, (USHORT)lEnd), 0);
1332 }
1333
1334 //
1335 // TODO:: finish this part
1336 //
7d8268a1 1337 return true;
39c26ef2 1338} // end of wxTextCtrl::SetStyle