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