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