~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/shell32/autocomplete.c

Version: ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  *      AutoComplete interfaces implementation.
  3  *
  4  *      Copyright 2004  Maxime Bellengé <maxime.bellenge@laposte.net>
  5  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 /*
 22   Implemented:
 23   - ACO_AUTOAPPEND style
 24   - ACO_AUTOSUGGEST style
 25   - ACO_UPDOWNKEYDROPSLIST style
 26 
 27   - Handle pwzsRegKeyPath and pwszQuickComplete in Init
 28 
 29   TODO:
 30   - implement ACO_SEARCH style
 31   - implement ACO_FILTERPREFIXES style
 32   - implement ACO_USETAB style
 33   - implement ACO_RTLREADING style
 34   - implement ResetEnumerator
 35   - string compares should be case-insensitive, the content of the list should be sorted
 36   
 37  */
 38 #include "config.h"
 39 
 40 #include <stdarg.h>
 41 #include <stdlib.h>
 42 #include <string.h>
 43 
 44 #define COBJMACROS
 45 
 46 #include "wine/debug.h"
 47 #include "windef.h"
 48 #include "winbase.h"
 49 #include "winreg.h"
 50 #include "undocshell.h"
 51 #include "shlwapi.h"
 52 #include "winerror.h"
 53 #include "objbase.h"
 54 
 55 #include "pidl.h"
 56 #include "shlobj.h"
 57 #include "shldisp.h"
 58 #include "debughlp.h"
 59 #include "shell32_main.h"
 60 
 61 #include "wine/unicode.h"
 62 
 63 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 64 
 65 typedef struct
 66 {
 67     IAutoComplete2 IAutoComplete2_iface;
 68     IAutoCompleteDropDown IAutoCompleteDropDown_iface;
 69     LONG ref;
 70     BOOL initialized;
 71     BOOL enabled;
 72     HWND hwndEdit;
 73     HWND hwndListBox;
 74     WNDPROC wpOrigEditProc;
 75     WNDPROC wpOrigLBoxProc;
 76     WCHAR *txtbackup;
 77     WCHAR *quickComplete;
 78     IEnumString *enumstr;
 79     AUTOCOMPLETEOPTIONS options;
 80 } IAutoCompleteImpl;
 81 
 82 static const WCHAR autocomplete_propertyW[] = {'W','i','n','e',' ','A','u','t','o',
 83                                                'c','o','m','p','l','e','t','e',' ',
 84                                                'c','o','n','t','r','o','l',0};
 85 
 86 static inline IAutoCompleteImpl *impl_from_IAutoComplete2(IAutoComplete2 *iface)
 87 {
 88     return CONTAINING_RECORD(iface, IAutoCompleteImpl, IAutoComplete2_iface);
 89 }
 90 
 91 static inline IAutoCompleteImpl *impl_from_IAutoCompleteDropDown(IAutoCompleteDropDown *iface)
 92 {
 93     return CONTAINING_RECORD(iface, IAutoCompleteImpl, IAutoCompleteDropDown_iface);
 94 }
 95 
 96 /*
 97   Window procedure for autocompletion
 98  */
 99 static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
100 {
101     IAutoCompleteImpl *This = GetPropW(hwnd, autocomplete_propertyW);
102     LPOLESTR strs;
103     HRESULT hr;
104     WCHAR hwndText[255];
105     WCHAR *hwndQCText;
106     RECT r;
107     BOOL control, filled, displayall = FALSE;
108     int cpt, height, sel;
109 
110     if (!This->enabled) return CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
111 
112     switch (uMsg)
113     {
114         case CB_SHOWDROPDOWN:
115             ShowWindow(This->hwndListBox, SW_HIDE);
116             break;
117         case WM_KILLFOCUS:
118             if ((This->options & ACO_AUTOSUGGEST) && ((HWND)wParam != This->hwndListBox))
119             {
120                 ShowWindow(This->hwndListBox, SW_HIDE);
121             }
122             return CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
123         case WM_KEYUP:
124         {
125             int len;
126 
127             GetWindowTextW( hwnd, hwndText, sizeof(hwndText)/sizeof(WCHAR));
128 
129             switch(wParam) {
130                 case VK_RETURN:
131                     /* If quickComplete is set and control is pressed, replace the string */
132                     control = GetKeyState(VK_CONTROL) & 0x8000;
133                     if (control && This->quickComplete) {
134                         hwndQCText = HeapAlloc(GetProcessHeap(), 0,
135                                               (lstrlenW(This->quickComplete)+lstrlenW(hwndText))*sizeof(WCHAR));
136                         sel = sprintfW(hwndQCText, This->quickComplete, hwndText);
137                         SendMessageW(hwnd, WM_SETTEXT, 0, (LPARAM)hwndQCText);
138                         SendMessageW(hwnd, EM_SETSEL, 0, sel);
139                         HeapFree(GetProcessHeap(), 0, hwndQCText);
140                     }
141 
142                     ShowWindow(This->hwndListBox, SW_HIDE);
143                     return 0;
144                 case VK_LEFT:
145                 case VK_RIGHT:
146                     return 0;
147                 case VK_UP:
148                 case VK_DOWN:
149                     /* Two cases here :
150                        - if the listbox is not visible, displays it
151                        with all the entries if the style ACO_UPDOWNKEYDROPSLIST
152                        is present but does not select anything.
153                        - if the listbox is visible, change the selection
154                     */
155                     if ( (This->options & (ACO_AUTOSUGGEST | ACO_UPDOWNKEYDROPSLIST))
156                          && (!IsWindowVisible(This->hwndListBox) && (! *hwndText)) )
157                     {
158                          /* We must display all the entries */
159                          displayall = TRUE;
160                     } else {
161                         if (IsWindowVisible(This->hwndListBox)) {
162                             int count;
163 
164                             count = SendMessageW(This->hwndListBox, LB_GETCOUNT, 0, 0);
165                             /* Change the selection */
166                             sel = SendMessageW(This->hwndListBox, LB_GETCURSEL, 0, 0);
167                             if (wParam == VK_UP)
168                                 sel = ((sel-1) < 0) ? count-1 : sel-1;
169                             else
170                                 sel = ((sel+1) >= count) ? -1 : sel+1;
171                             SendMessageW(This->hwndListBox, LB_SETCURSEL, sel, 0);
172                             if (sel != -1) {
173                                 WCHAR *msg;
174                                 int len;
175 
176                                 len = SendMessageW(This->hwndListBox, LB_GETTEXTLEN, sel, 0);
177                                 msg = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
178                                 SendMessageW(This->hwndListBox, LB_GETTEXT, sel, (LPARAM)msg);
179                                 SendMessageW(hwnd, WM_SETTEXT, 0, (LPARAM)msg);
180                                 SendMessageW(hwnd, EM_SETSEL, lstrlenW(msg), lstrlenW(msg));
181                                 HeapFree(GetProcessHeap(), 0, msg);
182                             } else {
183                                 SendMessageW(hwnd, WM_SETTEXT, 0, (LPARAM)This->txtbackup);
184                                 SendMessageW(hwnd, EM_SETSEL, lstrlenW(This->txtbackup), lstrlenW(This->txtbackup));
185                             }
186                         }
187                         return 0;
188                     }
189                     break;
190                 case VK_BACK:
191                 case VK_DELETE:
192                     if ((! *hwndText) && (This->options & ACO_AUTOSUGGEST)) {
193                         ShowWindow(This->hwndListBox, SW_HIDE);
194                         return CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
195                     }
196                     if (This->options & ACO_AUTOAPPEND) {
197                         DWORD b;
198                         SendMessageW(hwnd, EM_GETSEL, (WPARAM)&b, 0);
199                         if (b>1) {
200                             hwndText[b-1] = '\0';
201                         } else {
202                             hwndText[0] = '\0';
203                             SetWindowTextW(hwnd, hwndText);
204                         }
205                     }
206                     break;
207                 default:
208                     ;
209             }
210 
211             SendMessageW(This->hwndListBox, LB_RESETCONTENT, 0, 0);
212 
213             HeapFree(GetProcessHeap(), 0, This->txtbackup);
214             len = strlenW(hwndText);
215             This->txtbackup = HeapAlloc(GetProcessHeap(), 0, (len + 1)*sizeof(WCHAR));
216             lstrcpyW(This->txtbackup, hwndText);
217 
218             /* Returns if there is no text to search and we doesn't want to display all the entries */
219             if ((!displayall) && (! *hwndText) )
220                 break;
221 
222             IEnumString_Reset(This->enumstr);
223             filled = FALSE;
224             for(cpt = 0;;) {
225                 ULONG fetched;
226                 hr = IEnumString_Next(This->enumstr, 1, &strs, &fetched);
227                 if (hr != S_OK)
228                     break;
229 
230                 if (!strncmpiW(hwndText, strs, len)) {
231                     if (!filled && (This->options & ACO_AUTOAPPEND)) {
232                         WCHAR buffW[255];
233 
234                         strcpyW(buffW, hwndText);
235                         strcatW(buffW, &strs[len]);
236                         SetWindowTextW(hwnd, buffW);
237                         SendMessageW(hwnd, EM_SETSEL, len, strlenW(strs));
238                         if (!(This->options & ACO_AUTOSUGGEST))
239                             break;
240                     }
241 
242                     if (This->options & ACO_AUTOSUGGEST) {
243                         SendMessageW(This->hwndListBox, LB_ADDSTRING, 0, (LPARAM)strs);
244                         cpt++;
245                     }
246 
247                     filled = TRUE;
248                 }
249             }
250 
251             if (This->options & ACO_AUTOSUGGEST) {
252                 if (filled) {
253                     height = SendMessageW(This->hwndListBox, LB_GETITEMHEIGHT, 0, 0);
254                     SendMessageW(This->hwndListBox, LB_CARETOFF, 0, 0);
255                     GetWindowRect(hwnd, &r);
256                     SetParent(This->hwndListBox, HWND_DESKTOP);
257                     /* It seems that Windows XP displays 7 lines at most
258                        and otherwise displays a vertical scroll bar */
259                     SetWindowPos(This->hwndListBox, HWND_TOP,
260                                  r.left, r.bottom + 1, r.right - r.left, min(height * 7, height*(cpt+1)),
261                                  SWP_SHOWWINDOW );
262                 } else {
263                     ShowWindow(This->hwndListBox, SW_HIDE);
264                 }
265             }
266 
267             break;
268         }
269         case WM_DESTROY:
270         {
271             WNDPROC proc = This->wpOrigEditProc;
272 
273             RemovePropW(hwnd, autocomplete_propertyW);
274             SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)proc);
275             This->hwndEdit = NULL;
276             if (This->hwndListBox)
277                     DestroyWindow(This->hwndListBox);
278             IAutoComplete2_Release(&This->IAutoComplete2_iface);
279             return CallWindowProcW(proc, hwnd, uMsg, wParam, lParam);
280         }
281         default:
282             return CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
283 
284     }
285 
286     return 0;
287 }
288 
289 static LRESULT APIENTRY ACLBoxSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
290 {
291     IAutoCompleteImpl *This = (IAutoCompleteImpl *)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
292     WCHAR *msg;
293     int sel, len;
294 
295     switch (uMsg) {
296         case WM_MOUSEMOVE:
297             sel = SendMessageW(hwnd, LB_ITEMFROMPOINT, 0, lParam);
298             SendMessageW(hwnd, LB_SETCURSEL, sel, 0);
299             break;
300         case WM_LBUTTONDOWN:
301             sel = SendMessageW(hwnd, LB_GETCURSEL, 0, 0);
302             if (sel < 0)
303                 break;
304             len = SendMessageW(This->hwndListBox, LB_GETTEXTLEN, sel, 0);
305             msg = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
306             SendMessageW(hwnd, LB_GETTEXT, sel, (LPARAM)msg);
307             SendMessageW(This->hwndEdit, WM_SETTEXT, 0, (LPARAM)msg);
308             SendMessageW(This->hwndEdit, EM_SETSEL, 0, lstrlenW(msg));
309             ShowWindow(hwnd, SW_HIDE);
310             HeapFree(GetProcessHeap(), 0, msg);
311             break;
312         default:
313             return CallWindowProcW(This->wpOrigLBoxProc, hwnd, uMsg, wParam, lParam);
314     }
315     return 0;
316 }
317 
318 static void create_listbox(IAutoCompleteImpl *This)
319 {
320     HWND hwndParent;
321 
322     hwndParent = GetParent(This->hwndEdit);
323 
324     /* FIXME : The listbox should be resizable with the mouse. WS_THICKFRAME looks ugly */
325     This->hwndListBox = CreateWindowExW(0, WC_LISTBOXW, NULL,
326                                     WS_BORDER | WS_CHILD | WS_VSCROLL | LBS_HASSTRINGS | LBS_NOTIFY | LBS_NOINTEGRALHEIGHT,
327                                     CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
328                                     hwndParent, NULL, shell32_hInstance, NULL );
329 
330     if (This->hwndListBox) {
331         This->wpOrigLBoxProc = (WNDPROC) SetWindowLongPtrW( This->hwndListBox, GWLP_WNDPROC, (LONG_PTR) ACLBoxSubclassProc);
332         SetWindowLongPtrW( This->hwndListBox, GWLP_USERDATA, (LONG_PTR)This);
333     }
334 }
335 
336 /**************************************************************************
337  *  AutoComplete_QueryInterface
338  */
339 static HRESULT WINAPI IAutoComplete2_fnQueryInterface(
340     IAutoComplete2 * iface,
341     REFIID riid,
342     LPVOID *ppvObj)
343 {
344     IAutoCompleteImpl *This = impl_from_IAutoComplete2(iface);
345 
346     TRACE("(%p)->(IID:%s,%p)\n", This, shdebugstr_guid(riid), ppvObj);
347     *ppvObj = NULL;
348 
349     if (IsEqualIID(riid, &IID_IUnknown) ||
350         IsEqualIID(riid, &IID_IAutoComplete) ||
351         IsEqualIID(riid, &IID_IAutoComplete2))
352     {
353         *ppvObj = This;
354     }
355     else if (IsEqualIID(riid, &IID_IAutoCompleteDropDown))
356     {
357         *ppvObj = &This->IAutoCompleteDropDown_iface;
358     }
359 
360     if (*ppvObj)
361     {
362         IUnknown_AddRef((IUnknown*)*ppvObj);
363         TRACE("-- Interface: (%p)->(%p)\n", ppvObj, *ppvObj);
364         return S_OK;
365     }
366     WARN("unsupported interface: %s\n", debugstr_guid(riid));
367     return E_NOINTERFACE;
368 }
369 
370 /******************************************************************************
371  * IAutoComplete2_fnAddRef
372  */
373 static ULONG WINAPI IAutoComplete2_fnAddRef(
374         IAutoComplete2 * iface)
375 {
376     IAutoCompleteImpl *This = impl_from_IAutoComplete2(iface);
377     ULONG refCount = InterlockedIncrement(&This->ref);
378 
379     TRACE("(%p)->(%u)\n", This, refCount - 1);
380 
381     return refCount;
382 }
383 
384 /******************************************************************************
385  * IAutoComplete2_fnRelease
386  */
387 static ULONG WINAPI IAutoComplete2_fnRelease(
388         IAutoComplete2 * iface)
389 {
390     IAutoCompleteImpl *This = impl_from_IAutoComplete2(iface);
391     ULONG refCount = InterlockedDecrement(&This->ref);
392 
393     TRACE("(%p)->(%u)\n", This, refCount + 1);
394 
395     if (!refCount) {
396         TRACE("destroying IAutoComplete(%p)\n", This);
397         HeapFree(GetProcessHeap(), 0, This->quickComplete);
398         HeapFree(GetProcessHeap(), 0, This->txtbackup);
399         if (This->enumstr)
400             IEnumString_Release(This->enumstr);
401         HeapFree(GetProcessHeap(), 0, This);
402     }
403     return refCount;
404 }
405 
406 /******************************************************************************
407  * IAutoComplete2_fnEnable
408  */
409 static HRESULT WINAPI IAutoComplete2_fnEnable(
410     IAutoComplete2 * iface,
411     BOOL fEnable)
412 {
413     IAutoCompleteImpl *This = impl_from_IAutoComplete2(iface);
414     HRESULT hr = S_OK;
415 
416     TRACE("(%p)->(%s)\n", This, (fEnable)?"true":"false");
417 
418     This->enabled = fEnable;
419 
420     return hr;
421 }
422 
423 /******************************************************************************
424  * IAutoComplete2_fnInit
425  */
426 static HRESULT WINAPI IAutoComplete2_fnInit(
427     IAutoComplete2 * iface,
428     HWND hwndEdit,
429     IUnknown *punkACL,
430     LPCOLESTR pwzsRegKeyPath,
431     LPCOLESTR pwszQuickComplete)
432 {
433     IAutoCompleteImpl *This = impl_from_IAutoComplete2(iface);
434 
435     TRACE("(%p)->(%p, %p, %s, %s)\n",
436           This, hwndEdit, punkACL, debugstr_w(pwzsRegKeyPath), debugstr_w(pwszQuickComplete));
437 
438     if (This->options & ACO_SEARCH) FIXME(" ACO_SEARCH not supported\n");
439     if (This->options & ACO_FILTERPREFIXES) FIXME(" ACO_FILTERPREFIXES not supported\n");
440     if (This->options & ACO_USETAB) FIXME(" ACO_USETAB not supported\n");
441     if (This->options & ACO_RTLREADING) FIXME(" ACO_RTLREADING not supported\n");
442 
443     if (!hwndEdit || !punkACL)
444         return E_INVALIDARG;
445 
446     if (This->initialized)
447     {
448         WARN("Autocompletion object is already initialized\n");
449         /* This->hwndEdit is set to NULL when the edit window is destroyed. */
450         return This->hwndEdit ? E_FAIL : E_UNEXPECTED;
451     }
452 
453     if (FAILED (IUnknown_QueryInterface (punkACL, &IID_IEnumString, (LPVOID*)&This->enumstr))) {
454         WARN("No IEnumString interface\n");
455         return E_NOINTERFACE;
456     }
457 
458     This->initialized = TRUE;
459     This->hwndEdit = hwndEdit;
460     This->wpOrigEditProc = (WNDPROC) SetWindowLongPtrW( hwndEdit, GWLP_WNDPROC, (LONG_PTR) ACEditSubclassProc);
461     /* Keep at least one reference to the object until the edit window is destroyed. */
462     IAutoComplete2_AddRef(&This->IAutoComplete2_iface);
463     SetPropW( hwndEdit, autocomplete_propertyW, This );
464 
465     if (This->options & ACO_AUTOSUGGEST)
466         create_listbox(This);
467 
468     if (pwzsRegKeyPath) {
469         WCHAR *key;
470         WCHAR result[MAX_PATH];
471         WCHAR *value;
472         HKEY hKey = 0;
473         LONG res;
474         LONG len;
475 
476         /* pwszRegKeyPath contains the key as well as the value, so we split */
477         key = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(pwzsRegKeyPath)+1)*sizeof(WCHAR));
478         strcpyW(key, pwzsRegKeyPath);
479         value = strrchrW(key, '\\');
480         *value = 0;
481         value++;
482         /* Now value contains the value and buffer the key */
483         res = RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_READ, &hKey);
484         if (res != ERROR_SUCCESS) {
485             /* if the key is not found, MSDN states we must seek in HKEY_LOCAL_MACHINE */
486             res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hKey);  
487         }
488         if (res == ERROR_SUCCESS) {
489             res = RegQueryValueW(hKey, value, result, &len);
490             if (res == ERROR_SUCCESS) {
491                 This->quickComplete = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
492                 strcpyW(This->quickComplete, result);
493             }
494             RegCloseKey(hKey);
495         }
496         HeapFree(GetProcessHeap(), 0, key);
497     }
498 
499     if ((pwszQuickComplete) && (!This->quickComplete)) {
500         This->quickComplete = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(pwszQuickComplete)+1)*sizeof(WCHAR));
501         lstrcpyW(This->quickComplete, pwszQuickComplete);
502     }
503 
504     return S_OK;
505 }
506 
507 /**************************************************************************
508  *  IAutoComplete2_fnGetOptions
509  */
510 static HRESULT WINAPI IAutoComplete2_fnGetOptions(
511     IAutoComplete2 * iface,
512     DWORD *pdwFlag)
513 {
514     IAutoCompleteImpl *This = impl_from_IAutoComplete2(iface);
515     HRESULT hr = S_OK;
516 
517     TRACE("(%p) -> (%p)\n", This, pdwFlag);
518 
519     *pdwFlag = This->options;
520 
521     return hr;
522 }
523 
524 /**************************************************************************
525  *  IAutoComplete2_fnSetOptions
526  */
527 static HRESULT WINAPI IAutoComplete2_fnSetOptions(
528     IAutoComplete2 * iface,
529     DWORD dwFlag)
530 {
531     IAutoCompleteImpl *This = impl_from_IAutoComplete2(iface);
532     HRESULT hr = S_OK;
533 
534     TRACE("(%p) -> (0x%x)\n", This, dwFlag);
535 
536     This->options = dwFlag;
537 
538     if ((This->options & ACO_AUTOSUGGEST) && This->hwndEdit && !This->hwndListBox)
539         create_listbox(This);
540 
541     return hr;
542 }
543 
544 /**************************************************************************
545  *  IAutoComplete2 VTable
546  */
547 static const IAutoComplete2Vtbl acvt =
548 {
549     IAutoComplete2_fnQueryInterface,
550     IAutoComplete2_fnAddRef,
551     IAutoComplete2_fnRelease,
552     IAutoComplete2_fnInit,
553     IAutoComplete2_fnEnable,
554     /* IAutoComplete2 */
555     IAutoComplete2_fnSetOptions,
556     IAutoComplete2_fnGetOptions,
557 };
558 
559 
560 static HRESULT WINAPI IAutoCompleteDropDown_fnQueryInterface(IAutoCompleteDropDown *iface,
561             REFIID riid, LPVOID *ppvObj)
562 {
563     IAutoCompleteImpl *This = impl_from_IAutoCompleteDropDown(iface);
564     return IAutoComplete2_fnQueryInterface(&This->IAutoComplete2_iface, riid, ppvObj);
565 }
566 
567 static ULONG WINAPI IAutoCompleteDropDown_fnAddRef(IAutoCompleteDropDown *iface)
568 {
569     IAutoCompleteImpl *This = impl_from_IAutoCompleteDropDown(iface);
570     return IAutoComplete2_fnAddRef(&This->IAutoComplete2_iface);
571 }
572 
573 static ULONG WINAPI IAutoCompleteDropDown_fnRelease(IAutoCompleteDropDown *iface)
574 {
575     IAutoCompleteImpl *This = impl_from_IAutoCompleteDropDown(iface);
576     return IAutoComplete2_fnRelease(&This->IAutoComplete2_iface);
577 }
578 
579 /**************************************************************************
580  *  IAutoCompleteDropDown_fnGetDropDownStatus
581  */
582 static HRESULT WINAPI IAutoCompleteDropDown_fnGetDropDownStatus(
583     IAutoCompleteDropDown *iface,
584     DWORD *pdwFlags,
585     LPWSTR *ppwszString)
586 {
587     IAutoCompleteImpl *This = impl_from_IAutoCompleteDropDown(iface);
588     BOOL dropped;
589 
590     TRACE("(%p) -> (%p, %p)\n", This, pdwFlags, ppwszString);
591 
592     dropped = IsWindowVisible(This->hwndListBox);
593 
594     if (pdwFlags)
595         *pdwFlags = (dropped ? ACDD_VISIBLE : 0);
596 
597     if (ppwszString) {
598         if (dropped) {
599             int sel;
600 
601             sel = SendMessageW(This->hwndListBox, LB_GETCURSEL, 0, 0);
602             if (sel >= 0)
603             {
604                 DWORD len;
605 
606                 len = SendMessageW(This->hwndListBox, LB_GETTEXTLEN, sel, 0);
607                 *ppwszString = CoTaskMemAlloc((len+1)*sizeof(WCHAR));
608                 SendMessageW(This->hwndListBox, LB_GETTEXT, sel, (LPARAM)*ppwszString);
609             }
610             else
611                 *ppwszString = NULL;
612         }
613         else
614             *ppwszString = NULL;
615     }
616 
617     return S_OK;
618 }
619 
620 /**************************************************************************
621  *  IAutoCompleteDropDown_fnResetEnumarator
622  */
623 static HRESULT WINAPI IAutoCompleteDropDown_fnResetEnumerator(
624     IAutoCompleteDropDown *iface)
625 {
626     IAutoCompleteImpl *This = impl_from_IAutoCompleteDropDown(iface);
627 
628     FIXME("(%p): stub\n", This);
629 
630     return E_NOTIMPL;
631 }
632 
633 /**************************************************************************
634  *  IAutoCompleteDropDown VTable
635  */
636 static const IAutoCompleteDropDownVtbl acdropdownvt =
637 {
638     IAutoCompleteDropDown_fnQueryInterface,
639     IAutoCompleteDropDown_fnAddRef,
640     IAutoCompleteDropDown_fnRelease,
641     IAutoCompleteDropDown_fnGetDropDownStatus,
642     IAutoCompleteDropDown_fnResetEnumerator,
643 };
644 
645 /**************************************************************************
646  *  IAutoComplete_Constructor
647  */
648 HRESULT WINAPI IAutoComplete_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
649 {
650     IAutoCompleteImpl *lpac;
651     HRESULT hr;
652 
653     if (pUnkOuter && !IsEqualIID (riid, &IID_IUnknown))
654         return CLASS_E_NOAGGREGATION;
655 
656     lpac = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAutoCompleteImpl));
657     if (!lpac)
658         return E_OUTOFMEMORY;
659 
660     lpac->ref = 1;
661     lpac->IAutoComplete2_iface.lpVtbl = &acvt;
662     lpac->IAutoCompleteDropDown_iface.lpVtbl = &acdropdownvt;
663     lpac->enabled = TRUE;
664     lpac->options = ACO_AUTOAPPEND;
665 
666     hr = IAutoComplete2_QueryInterface(&lpac->IAutoComplete2_iface, riid, ppv);
667     IAutoComplete2_Release(&lpac->IAutoComplete2_iface);
668 
669     TRACE("-- (%p)->\n",lpac);
670 
671     return hr;
672 }
673 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.