]> git.saurik.com Git - wxWidgets.git/blame - src/msw/textentry.cpp
Upport wxMiniFrame corrections
[wxWidgets.git] / src / msw / textentry.cpp
CommitLineData
69a05ef6
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/msw/textentry.cpp
3// Purpose: wxTextEntry implementation for wxMSW
4// Author: Vadim Zeitlin
5// Created: 2007-09-26
6// RCS-ID: $Id$
7// Copyright: (c) 2007 Vadim Zeitlin <vadim@wxwindows.org>
8// Licence: wxWindows licence
9///////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
19// for compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26#ifndef WX_PRECOMP
96506d1d 27 #include "wx/arrstr.h"
c0ae6c3b 28 #include "wx/string.h"
69a05ef6
VZ
29#endif // WX_PRECOMP
30
96a4cdeb
VZ
31#if wxUSE_TEXTCTRL || wxUSE_COMBOBOX
32
69a05ef6 33#include "wx/textentry.h"
59396417 34#include "wx/dynlib.h"
69a05ef6
VZ
35
36#include "wx/msw/private.h"
37
38#define GetEditHwnd() ((HWND)(GetEditHWND()))
39
0847dca6
VZ
40// ----------------------------------------------------------------------------
41// wxIEnumString implements IEnumString interface
42// ----------------------------------------------------------------------------
43
44#if wxUSE_OLE
45
46#include "wx/msw/ole/oleutils.h"
47#include <shldisp.h>
48
96506d1d
VZ
49#if defined(__MINGW32__)
50 // needed for IID_IAutoComplete, IID_IAutoComplete2 and ACO_AUTOSUGGEST
51 #include <shlguid.h>
52#endif
53
54#ifndef ACO_UPDOWNKEYDROPSLIST
55 #define ACO_UPDOWNKEYDROPSLIST 0x20
56#endif
57
58#ifndef SHACF_FILESYS_ONLY
59 #define SHACF_FILESYS_ONLY 0x00000010
60#endif
61
0847dca6
VZ
62DEFINE_GUID(CLSID_AutoComplete,
63 0x00bb2763, 0x6a77, 0x11d0, 0xa5, 0x35, 0x00, 0xc0, 0x4f, 0xd7, 0xd0, 0x62);
64
65class wxIEnumString : public IEnumString
66{
67public:
68 wxIEnumString(const wxArrayString& strings) : m_strings(strings)
69 {
70 m_index = 0;
71 }
72
73 DECLARE_IUNKNOWN_METHODS;
74
75 virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt,
76 LPOLESTR *rgelt,
77 ULONG *pceltFetched)
78 {
79 if ( !rgelt || (!pceltFetched && celt > 1) )
80 return E_POINTER;
81
82 ULONG pceltFetchedDummy;
83 if ( !pceltFetched )
84 pceltFetched = &pceltFetchedDummy;
85
86 *pceltFetched = 0;
87
88 for ( const unsigned count = m_strings.size(); celt--; ++m_index )
89 {
90 if ( m_index == count )
91 return S_FALSE;
92
93 const wxWX2WCbuf wcbuf(m_strings[m_index].wc_str());
94 const size_t size = (wcslen(wcbuf) + 1)*sizeof(wchar_t);
95 void *olestr = CoTaskMemAlloc(size);
96 if ( !olestr )
97 return E_OUTOFMEMORY;
98
99 memcpy(olestr, wcbuf, size);
100
101 *rgelt++ = wx_static_cast(LPOLESTR, olestr);
102
103 ++(*pceltFetched);
104 }
105
106 return S_OK;
107 }
108
109 virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
110 {
111 m_index += celt;
112 if ( m_index > m_strings.size() )
113 {
114 m_index = m_strings.size();
115 return S_FALSE;
116 }
117
118 return S_OK;
119 }
120
121 virtual HRESULT STDMETHODCALLTYPE Reset()
122 {
123 m_index = 0;
124
125 return S_OK;
126 }
127
128 virtual HRESULT STDMETHODCALLTYPE Clone(IEnumString **ppEnum)
129 {
130 if ( !ppEnum )
131 return E_POINTER;
132
133 wxIEnumString *e = new wxIEnumString(m_strings);
134 e->m_index = m_index;
135
136 e->AddRef();
137 *ppEnum = e;
138
139 return S_OK;
140 }
141
142private:
3eeefdf9
VZ
143 // dtor doesn't have to be virtual as we're only ever deleted from our own
144 // Release() and are not meant to be derived form anyhow, but making it
145 // virtual silences gcc warnings; making it private makes it impossible to
146 // (mistakenly) delete us directly instead of calling Release()
147 virtual ~wxIEnumString() { }
148
149
0847dca6
VZ
150 const wxArrayString m_strings;
151 unsigned m_index;
152
153 DECLARE_NO_COPY_CLASS(wxIEnumString)
154};
155
156BEGIN_IID_TABLE(wxIEnumString)
157 ADD_IID(Unknown)
158 ADD_IID(EnumString)
159END_IID_TABLE;
160
161IMPLEMENT_IUNKNOWN_METHODS(wxIEnumString)
162
163#endif // wxUSE_OLE
164
69a05ef6
VZ
165// ============================================================================
166// wxTextEntry implementation
167// ============================================================================
168
0847dca6
VZ
169// ----------------------------------------------------------------------------
170// operations on text
171// ----------------------------------------------------------------------------
172
69a05ef6
VZ
173void wxTextEntry::WriteText(const wxString& text)
174{
175 ::SendMessage(GetEditHwnd(), EM_REPLACESEL, 0, (LPARAM)text.wx_str());
176}
177
178wxString wxTextEntry::GetValue() const
179{
180 return wxGetWindowText(GetEditHWND());
181}
182
183void wxTextEntry::Remove(long from, long to)
184{
185 DoSetSelection(from, to, SetSel_NoScroll);
186 WriteText(wxString());
187}
188
0847dca6
VZ
189// ----------------------------------------------------------------------------
190// clipboard operations
191// ----------------------------------------------------------------------------
192
69a05ef6
VZ
193void wxTextEntry::Copy()
194{
195 ::SendMessage(GetEditHwnd(), WM_COPY, 0, 0);
196}
197
198void wxTextEntry::Cut()
199{
200 ::SendMessage(GetEditHwnd(), WM_CUT, 0, 0);
201}
202
203void wxTextEntry::Paste()
204{
205 ::SendMessage(GetEditHwnd(), WM_PASTE, 0, 0);
206}
207
0847dca6
VZ
208// ----------------------------------------------------------------------------
209// undo/redo
210// ----------------------------------------------------------------------------
211
69a05ef6
VZ
212void wxTextEntry::Undo()
213{
214 ::SendMessage(GetEditHwnd(), EM_UNDO, 0, 0);
215}
216
217void wxTextEntry::Redo()
218{
3cb6eaec 219 // same as Undo, since Undo undoes the undo
69a05ef6
VZ
220 Undo();
221 return;
222}
223
224bool wxTextEntry::CanUndo() const
225{
226 return ::SendMessage(GetEditHwnd(), EM_CANUNDO, 0, 0) != 0;
227}
228
229bool wxTextEntry::CanRedo() const
230{
231 // see comment in Redo()
232 return CanUndo();
233}
234
0847dca6
VZ
235// ----------------------------------------------------------------------------
236// insertion point and selection
237// ----------------------------------------------------------------------------
238
69a05ef6
VZ
239void wxTextEntry::SetInsertionPoint(long pos)
240{
241 // be careful to call DoSetSelection() which is overridden in wxTextCtrl
242 // and not just SetSelection() here
243 DoSetSelection(pos, pos);
244}
245
246long wxTextEntry::GetInsertionPoint() const
247{
248 long from;
249 GetSelection(&from, NULL);
250 return from;
251}
252
253long wxTextEntry::GetLastPosition() const
254{
255 return ::SendMessage(GetEditHwnd(), EM_LINELENGTH, 0, 0);
256}
257
258void wxTextEntry::DoSetSelection(long from, long to, int WXUNUSED(flags))
259{
260 // if from and to are both -1, it means (in wxWidgets) that all text should
261 // be selected, translate this into Windows convention
262 if ( (from == -1) && (to == -1) )
263 {
264 from = 0;
265 }
266
267 ::SendMessage(GetEditHwnd(), EM_SETSEL, from, to);
268}
269
270void wxTextEntry::GetSelection(long *from, long *to) const
271{
272 DWORD dwStart, dwEnd;
273 ::SendMessage(GetEditHwnd(), EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd);
274
275 if ( from )
276 *from = dwStart;
277 if ( to )
278 *to = dwEnd;
279}
280
0847dca6
VZ
281// ----------------------------------------------------------------------------
282// auto-completion
283// ----------------------------------------------------------------------------
284
285#if wxUSE_OLE
286
59396417
VZ
287bool wxTextEntry::AutoCompleteFileNames()
288{
289 typedef HRESULT (WINAPI *SHAutoComplete_t)(HWND, DWORD);
290 static SHAutoComplete_t s_pfnSHAutoComplete = (SHAutoComplete_t)-1;
291 static wxDynamicLibrary s_dllShlwapi;
292 if ( s_pfnSHAutoComplete == (SHAutoComplete_t)-1 )
293 {
294 wxLogNull noLog;
295
296 if ( !s_dllShlwapi.Load(_T("shlwapi.dll"), wxDL_VERBATIM) )
297 {
298 s_pfnSHAutoComplete = NULL;
299 }
300 else
301 {
302 wxDL_INIT_FUNC(s_pfn, SHAutoComplete, s_dllShlwapi);
303 }
304 }
305
306 if ( !s_pfnSHAutoComplete )
307 return false;
308
309 HRESULT hr = (*s_pfnSHAutoComplete)(GetEditHwnd(), SHACF_FILESYS_ONLY);
310 if ( FAILED(hr) )
311 {
312 wxLogApiError(_T("SHAutoComplete()"), hr);
313
314 return false;
315 }
316
317 return true;
318}
319
0847dca6
VZ
320bool wxTextEntry::AutoComplete(const wxArrayString& choices)
321{
322 // create an object exposing IAutoComplete interface (don't go for
323 // IAutoComplete2 immediately as, presumably, it might be not available on
324 // older systems as otherwise why do we have both -- although in practice I
325 // don't know when can this happen)
326 IAutoComplete *pAutoComplete = NULL;
327 HRESULT hr = CoCreateInstance
328 (
329 CLSID_AutoComplete,
330 NULL,
331 CLSCTX_INPROC_SERVER,
332 IID_IAutoComplete,
333 wx_reinterpret_cast(void **, &pAutoComplete)
334 );
335 if ( FAILED(hr) )
336 {
337 wxLogApiError(_T("CoCreateInstance(CLSID_AutoComplete)"), hr);
338 return false;
339 }
340
341 // associate it with our strings
342 wxIEnumString *pEnumString = new wxIEnumString(choices);
343 pEnumString->AddRef();
344 hr = pAutoComplete->Init(GetEditHwnd(), pEnumString, NULL, NULL);
345 pEnumString->Release();
346 if ( FAILED(hr) )
347 {
348 wxLogApiError(_T("IAutoComplete::Init"), hr);
349 return false;
350 }
351
352 // if IAutoComplete2 is available, set more user-friendly options
353 IAutoComplete2 *pAutoComplete2 = NULL;
354 hr = pAutoComplete->QueryInterface
355 (
356 IID_IAutoComplete2,
357 wx_reinterpret_cast(void **, &pAutoComplete2)
358 );
359 if ( SUCCEEDED(hr) )
360 {
361 pAutoComplete2->SetOptions(ACO_AUTOSUGGEST | ACO_UPDOWNKEYDROPSLIST);
362 pAutoComplete2->Release();
363 }
364
365 // the docs are unclear about when can we release it but it seems safe to
366 // do it immediately, presumably the edit control itself keeps a reference
367 // to the auto completer object
368 pAutoComplete->Release();
369
370 return true;
371}
372
373#endif // wxUSE_OLE
374
375// ----------------------------------------------------------------------------
376// editable state
377// ----------------------------------------------------------------------------
378
69a05ef6
VZ
379bool wxTextEntry::IsEditable() const
380{
5ad3f0c8 381 return !(::GetWindowLong(GetEditHwnd(), GWL_STYLE) & ES_READONLY);
69a05ef6
VZ
382}
383
384void wxTextEntry::SetEditable(bool editable)
385{
386 ::SendMessage(GetEditHwnd(), EM_SETREADONLY, !editable, 0);
387}
388
0847dca6
VZ
389// ----------------------------------------------------------------------------
390// max length
391// ----------------------------------------------------------------------------
392
69a05ef6
VZ
393void wxTextEntry::SetMaxLength(unsigned long len)
394{
395 if ( len >= 0xffff )
396 {
397 // this will set it to a platform-dependent maximum (much more
398 // than 64Kb under NT)
399 len = 0;
400 }
401
402 ::SendMessage(GetEditHwnd(), EM_LIMITTEXT, len, 0);
403}
96a4cdeb
VZ
404
405#endif // wxUSE_TEXTCTRL || wxUSE_COMBOBOX