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