2 * AutoComplete interfaces implementation.
4 * Copyright 2004 Maxime Bellengé <maxime.bellenge@laposte.net>
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.
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.
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
23 - ACO_AUTOAPPEND style
24 - ACO_AUTOSUGGEST style
25 - ACO_UPDOWNKEYDROPSLIST style
27 - Handle pwzsRegKeyPath and pwszQuickComplete in Init
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
46 #include "wine/debug.h"
50 #include "undocshell.h"
59 #include "shell32_main.h"
61 #include "wine/unicode.h"
63 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
67 IAutoComplete2 IAutoComplete2_iface
;
68 IAutoCompleteDropDown IAutoCompleteDropDown_iface
;
74 WNDPROC wpOrigEditProc
;
75 WNDPROC wpOrigLBoxProc
;
79 AUTOCOMPLETEOPTIONS options
;
86 autoappend_flag_displayempty
89 static const WCHAR autocomplete_propertyW
[] = {'W','i','n','e',' ','A','u','t','o',
90 'c','o','m','p','l','e','t','e',' ',
91 'c','o','n','t','r','o','l',0};
93 static inline IAutoCompleteImpl
*impl_from_IAutoComplete2(IAutoComplete2
*iface
)
95 return CONTAINING_RECORD(iface
, IAutoCompleteImpl
, IAutoComplete2_iface
);
98 static inline IAutoCompleteImpl
*impl_from_IAutoCompleteDropDown(IAutoCompleteDropDown
*iface
)
100 return CONTAINING_RECORD(iface
, IAutoCompleteImpl
, IAutoCompleteDropDown_iface
);
103 static size_t format_quick_complete(WCHAR
*dst
, const WCHAR
*qc
, const WCHAR
*str
, size_t str_len
)
105 /* Replace the first %s directly without using snprintf, to avoid
106 exploits since the format string can be retrieved from the registry */
113 if (args
< 1 && qc
[1] == 's')
115 memcpy(dst
, str
, str_len
* sizeof(WCHAR
));
121 qc
+= (qc
[1] == '%');
129 static void autoappend_str(IAutoCompleteImpl
*ac
, WCHAR
*text
, UINT len
, WCHAR
*str
, HWND hwnd
)
134 /* The character capitalization can be different,
135 so merge text and str into a new string */
136 size
= len
+ strlenW(&str
[len
]) + 1;
138 if ((tmp
= heap_alloc(size
* sizeof(*tmp
))))
140 memcpy(tmp
, text
, len
* sizeof(*tmp
));
141 memcpy(&tmp
[len
], &str
[len
], (size
- len
) * sizeof(*tmp
));
145 SendMessageW(hwnd
, WM_SETTEXT
, 0, (LPARAM
)tmp
);
146 SendMessageW(hwnd
, EM_SETSEL
, len
, size
- 1);
151 static void autocomplete_text(IAutoCompleteImpl
*ac
, HWND hwnd
, enum autoappend_flag flag
)
155 UINT cpt
, size
, len
= SendMessageW(hwnd
, WM_GETTEXTLENGTH
, 0, 0);
157 if (flag
!= autoappend_flag_displayempty
&& len
== 0)
159 if (ac
->options
& ACO_AUTOSUGGEST
)
160 ShowWindow(ac
->hwndListBox
, SW_HIDE
);
165 if (!(text
= heap_alloc(size
* sizeof(WCHAR
))))
167 len
= SendMessageW(hwnd
, WM_GETTEXT
, size
, (LPARAM
)text
);
169 text
= heap_realloc(text
, (len
+ 1) * sizeof(WCHAR
));
171 SendMessageW(ac
->hwndListBox
, LB_RESETCONTENT
, 0, 0);
173 /* Set txtbackup to point to text itself (which must not be released) */
174 heap_free(ac
->txtbackup
);
175 ac
->txtbackup
= text
;
177 IEnumString_Reset(ac
->enumstr
);
180 LPOLESTR strs
= NULL
;
183 hr
= IEnumString_Next(ac
->enumstr
, 1, &strs
, &fetched
);
187 if (!strncmpiW(text
, strs
, len
))
189 if (cpt
== 0 && flag
== autoappend_flag_yes
)
191 autoappend_str(ac
, text
, len
, strs
, hwnd
);
192 if (!(ac
->options
& ACO_AUTOSUGGEST
))
199 if (ac
->options
& ACO_AUTOSUGGEST
)
200 SendMessageW(ac
->hwndListBox
, LB_ADDSTRING
, 0, (LPARAM
)strs
);
208 if (ac
->options
& ACO_AUTOSUGGEST
)
213 UINT height
= SendMessageW(ac
->hwndListBox
, LB_GETITEMHEIGHT
, 0, 0);
214 SendMessageW(ac
->hwndListBox
, LB_CARETOFF
, 0, 0);
215 GetWindowRect(hwnd
, &r
);
216 SetParent(ac
->hwndListBox
, HWND_DESKTOP
);
217 /* It seems that Windows XP displays 7 lines at most
218 and otherwise displays a vertical scroll bar */
219 SetWindowPos(ac
->hwndListBox
, HWND_TOP
,
220 r
.left
, r
.bottom
+ 1, r
.right
- r
.left
, height
* min(cpt
+ 1, 7),
224 ShowWindow(ac
->hwndListBox
, SW_HIDE
);
228 static void destroy_autocomplete_object(IAutoCompleteImpl
*ac
)
232 DestroyWindow(ac
->hwndListBox
);
233 IAutoComplete2_Release(&ac
->IAutoComplete2_iface
);
237 Helper for ACEditSubclassProc
239 static LRESULT
ACEditSubclassProc_KeyDown(IAutoCompleteImpl
*ac
, HWND hwnd
, UINT uMsg
,
240 WPARAM wParam
, LPARAM lParam
)
245 /* If quickComplete is set and control is pressed, replace the string */
246 if (ac
->quickComplete
&& (GetKeyState(VK_CONTROL
) & 0x8000))
250 UINT len
= SendMessageW(hwnd
, WM_GETTEXTLENGTH
, 0, 0);
251 if (!(text
= heap_alloc((len
+ 1) * sizeof(WCHAR
))))
253 len
= SendMessageW(hwnd
, WM_GETTEXT
, len
+ 1, (LPARAM
)text
);
254 sz
= strlenW(ac
->quickComplete
) + 1 + len
;
256 if ((buf
= heap_alloc(sz
* sizeof(WCHAR
))))
258 len
= format_quick_complete(buf
, ac
->quickComplete
, text
, len
);
259 SendMessageW(hwnd
, WM_SETTEXT
, 0, (LPARAM
)buf
);
260 SendMessageW(hwnd
, EM_SETSEL
, 0, len
);
264 if (ac
->options
& ACO_AUTOSUGGEST
)
265 ShowWindow(ac
->hwndListBox
, SW_HIDE
);
270 if (ac
->options
& ACO_AUTOSUGGEST
)
271 ShowWindow(ac
->hwndListBox
, SW_HIDE
);
276 - if the listbox is not visible and ACO_UPDOWNKEYDROPSLIST is
277 set, display it with all the entries, without selecting any
278 - if the listbox is visible, change the selection
280 if (!(ac
->options
& ACO_AUTOSUGGEST
))
283 if (!IsWindowVisible(ac
->hwndListBox
))
285 if (ac
->options
& ACO_UPDOWNKEYDROPSLIST
)
287 autocomplete_text(ac
, hwnd
, autoappend_flag_displayempty
);
294 count
= SendMessageW(ac
->hwndListBox
, LB_GETCOUNT
, 0, 0);
296 /* Change the selection */
297 sel
= SendMessageW(ac
->hwndListBox
, LB_GETCURSEL
, 0, 0);
299 sel
= ((sel
- 1) < 0) ? count
- 1 : sel
- 1;
301 sel
= ((sel
+ 1) >= count
) ? -1 : sel
+ 1;
302 SendMessageW(ac
->hwndListBox
, LB_SETCURSEL
, sel
, 0);
308 len
= SendMessageW(ac
->hwndListBox
, LB_GETTEXTLEN
, sel
, 0);
309 if (!(msg
= heap_alloc((len
+ 1) * sizeof(WCHAR
))))
311 len
= SendMessageW(ac
->hwndListBox
, LB_GETTEXT
, sel
, (LPARAM
)msg
);
312 SendMessageW(hwnd
, WM_SETTEXT
, 0, (LPARAM
)msg
);
313 SendMessageW(hwnd
, EM_SETSEL
, len
, len
);
319 SendMessageW(hwnd
, WM_SETTEXT
, 0, (LPARAM
)ac
->txtbackup
);
320 len
= strlenW(ac
->txtbackup
);
321 SendMessageW(hwnd
, EM_SETSEL
, len
, len
);
328 LRESULT ret
= CallWindowProcW(ac
->wpOrigEditProc
, hwnd
, uMsg
, wParam
, lParam
);
329 autocomplete_text(ac
, hwnd
, autoappend_flag_no
);
333 return CallWindowProcW(ac
->wpOrigEditProc
, hwnd
, uMsg
, wParam
, lParam
);
337 Window procedure for autocompletion
339 static LRESULT APIENTRY
ACEditSubclassProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
341 IAutoCompleteImpl
*This
= GetPropW(hwnd
, autocomplete_propertyW
);
344 if (!This
->enabled
) return CallWindowProcW(This
->wpOrigEditProc
, hwnd
, uMsg
, wParam
, lParam
);
348 case CB_SHOWDROPDOWN
:
349 if (This
->options
& ACO_AUTOSUGGEST
)
350 ShowWindow(This
->hwndListBox
, SW_HIDE
);
353 if ((This
->options
& ACO_AUTOSUGGEST
) && ((HWND
)wParam
!= This
->hwndListBox
))
355 ShowWindow(This
->hwndListBox
, SW_HIDE
);
357 return CallWindowProcW(This
->wpOrigEditProc
, hwnd
, uMsg
, wParam
, lParam
);
359 return ACEditSubclassProc_KeyDown(This
, hwnd
, uMsg
, wParam
, lParam
);
362 ret
= CallWindowProcW(This
->wpOrigEditProc
, hwnd
, uMsg
, wParam
, lParam
);
363 autocomplete_text(This
, hwnd
, (This
->options
& ACO_AUTOAPPEND
) && wParam
>= ' '
364 ? autoappend_flag_yes
: autoappend_flag_no
);
368 WNDPROC proc
= This
->wpOrigEditProc
;
370 SetWindowLongPtrW(hwnd
, GWLP_WNDPROC
, (LONG_PTR
)proc
);
371 RemovePropW(hwnd
, autocomplete_propertyW
);
372 destroy_autocomplete_object(This
);
373 return CallWindowProcW(proc
, hwnd
, uMsg
, wParam
, lParam
);
376 return CallWindowProcW(This
->wpOrigEditProc
, hwnd
, uMsg
, wParam
, lParam
);
382 static LRESULT APIENTRY
ACLBoxSubclassProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
384 IAutoCompleteImpl
*This
= (IAutoCompleteImpl
*)GetWindowLongPtrW(hwnd
, GWLP_USERDATA
);
390 sel
= SendMessageW(hwnd
, LB_ITEMFROMPOINT
, 0, lParam
);
391 SendMessageW(hwnd
, LB_SETCURSEL
, sel
, 0);
394 sel
= SendMessageW(hwnd
, LB_GETCURSEL
, 0, 0);
397 len
= SendMessageW(This
->hwndListBox
, LB_GETTEXTLEN
, sel
, 0);
398 if (!(msg
= heap_alloc((len
+ 1) * sizeof(WCHAR
))))
400 len
= SendMessageW(hwnd
, LB_GETTEXT
, sel
, (LPARAM
)msg
);
401 SendMessageW(This
->hwndEdit
, WM_SETTEXT
, 0, (LPARAM
)msg
);
402 SendMessageW(This
->hwndEdit
, EM_SETSEL
, 0, len
);
403 ShowWindow(hwnd
, SW_HIDE
);
407 return CallWindowProcW(This
->wpOrigLBoxProc
, hwnd
, uMsg
, wParam
, lParam
);
412 static void create_listbox(IAutoCompleteImpl
*This
)
416 hwndParent
= GetParent(This
->hwndEdit
);
418 /* FIXME : The listbox should be resizable with the mouse. WS_THICKFRAME looks ugly */
419 This
->hwndListBox
= CreateWindowExW(0, WC_LISTBOXW
, NULL
,
420 WS_BORDER
| WS_CHILD
| WS_VSCROLL
| LBS_HASSTRINGS
| LBS_NOTIFY
| LBS_NOINTEGRALHEIGHT
,
421 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
422 hwndParent
, NULL
, shell32_hInstance
, NULL
);
424 if (This
->hwndListBox
) {
425 This
->wpOrigLBoxProc
= (WNDPROC
) SetWindowLongPtrW( This
->hwndListBox
, GWLP_WNDPROC
, (LONG_PTR
) ACLBoxSubclassProc
);
426 SetWindowLongPtrW( This
->hwndListBox
, GWLP_USERDATA
, (LONG_PTR
)This
);
429 This
->options
&= ~ACO_AUTOSUGGEST
;
432 /**************************************************************************
433 * AutoComplete_QueryInterface
435 static HRESULT WINAPI
IAutoComplete2_fnQueryInterface(
436 IAutoComplete2
* iface
,
440 IAutoCompleteImpl
*This
= impl_from_IAutoComplete2(iface
);
442 TRACE("(%p)->(IID:%s,%p)\n", This
, shdebugstr_guid(riid
), ppvObj
);
445 if (IsEqualIID(riid
, &IID_IUnknown
) ||
446 IsEqualIID(riid
, &IID_IAutoComplete
) ||
447 IsEqualIID(riid
, &IID_IAutoComplete2
))
449 *ppvObj
= &This
->IAutoComplete2_iface
;
451 else if (IsEqualIID(riid
, &IID_IAutoCompleteDropDown
))
453 *ppvObj
= &This
->IAutoCompleteDropDown_iface
;
458 IUnknown_AddRef((IUnknown
*)*ppvObj
);
459 TRACE("-- Interface: (%p)->(%p)\n", ppvObj
, *ppvObj
);
462 WARN("unsupported interface: %s\n", debugstr_guid(riid
));
463 return E_NOINTERFACE
;
466 /******************************************************************************
467 * IAutoComplete2_fnAddRef
469 static ULONG WINAPI
IAutoComplete2_fnAddRef(
470 IAutoComplete2
* iface
)
472 IAutoCompleteImpl
*This
= impl_from_IAutoComplete2(iface
);
473 ULONG refCount
= InterlockedIncrement(&This
->ref
);
475 TRACE("(%p)->(%u)\n", This
, refCount
- 1);
480 /******************************************************************************
481 * IAutoComplete2_fnRelease
483 static ULONG WINAPI
IAutoComplete2_fnRelease(
484 IAutoComplete2
* iface
)
486 IAutoCompleteImpl
*This
= impl_from_IAutoComplete2(iface
);
487 ULONG refCount
= InterlockedDecrement(&This
->ref
);
489 TRACE("(%p)->(%u)\n", This
, refCount
+ 1);
492 TRACE("destroying IAutoComplete(%p)\n", This
);
493 heap_free(This
->quickComplete
);
494 heap_free(This
->txtbackup
);
496 IEnumString_Release(This
->enumstr
);
502 /******************************************************************************
503 * IAutoComplete2_fnEnable
505 static HRESULT WINAPI
IAutoComplete2_fnEnable(
506 IAutoComplete2
* iface
,
509 IAutoCompleteImpl
*This
= impl_from_IAutoComplete2(iface
);
512 TRACE("(%p)->(%s)\n", This
, (fEnable
)?"true":"false");
514 This
->enabled
= fEnable
;
519 /******************************************************************************
520 * IAutoComplete2_fnInit
522 static HRESULT WINAPI
IAutoComplete2_fnInit(
523 IAutoComplete2
* iface
,
526 LPCOLESTR pwzsRegKeyPath
,
527 LPCOLESTR pwszQuickComplete
)
529 IAutoCompleteImpl
*prev
, *This
= impl_from_IAutoComplete2(iface
);
531 TRACE("(%p)->(%p, %p, %s, %s)\n",
532 This
, hwndEdit
, punkACL
, debugstr_w(pwzsRegKeyPath
), debugstr_w(pwszQuickComplete
));
534 if (This
->options
& ACO_SEARCH
) FIXME(" ACO_SEARCH not supported\n");
535 if (This
->options
& ACO_FILTERPREFIXES
) FIXME(" ACO_FILTERPREFIXES not supported\n");
536 if (This
->options
& ACO_USETAB
) FIXME(" ACO_USETAB not supported\n");
537 if (This
->options
& ACO_RTLREADING
) FIXME(" ACO_RTLREADING not supported\n");
539 if (!hwndEdit
|| !punkACL
)
542 if (This
->initialized
)
544 WARN("Autocompletion object is already initialized\n");
545 /* This->hwndEdit is set to NULL when the edit window is destroyed. */
546 return This
->hwndEdit
? E_FAIL
: E_UNEXPECTED
;
549 if (FAILED (IUnknown_QueryInterface (punkACL
, &IID_IEnumString
, (LPVOID
*)&This
->enumstr
))) {
550 WARN("No IEnumString interface\n");
551 return E_NOINTERFACE
;
554 This
->initialized
= TRUE
;
555 This
->hwndEdit
= hwndEdit
;
557 /* If another AutoComplete object was previously assigned to this edit control,
558 release it but keep the same callback on the control, to avoid an infinite
559 recursive loop in ACEditSubclassProc while the property is set to this object */
560 prev
= GetPropW(hwndEdit
, autocomplete_propertyW
);
561 SetPropW(hwndEdit
, autocomplete_propertyW
, This
);
563 if (prev
&& prev
->initialized
) {
564 This
->wpOrigEditProc
= prev
->wpOrigEditProc
;
565 destroy_autocomplete_object(prev
);
568 This
->wpOrigEditProc
= (WNDPROC
) SetWindowLongPtrW(hwndEdit
, GWLP_WNDPROC
, (LONG_PTR
) ACEditSubclassProc
);
570 /* Keep at least one reference to the object until the edit window is destroyed */
571 IAutoComplete2_AddRef(&This
->IAutoComplete2_iface
);
573 if (This
->options
& ACO_AUTOSUGGEST
)
574 create_listbox(This
);
578 static const HKEY roots
[] = { HKEY_CURRENT_USER
, HKEY_LOCAL_MACHINE
};
587 /* pwszRegKeyPath contains the key as well as the value, so split it */
588 value
= strrchrW(pwzsRegKeyPath
, '\\');
589 len
= value
- pwzsRegKeyPath
;
591 if (value
&& (key
= heap_alloc((len
+1) * sizeof(*key
))) != NULL
)
593 memcpy(key
, pwzsRegKeyPath
, len
* sizeof(*key
));
597 for (i
= 0; i
< ARRAY_SIZE(roots
); i
++)
599 if (RegOpenKeyExW(roots
[i
], key
, 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
601 sz
= MAX_PATH
* sizeof(WCHAR
);
603 while ((qc
= heap_alloc(sz
)) != NULL
)
605 res
= RegQueryValueExW(hKey
, value
, NULL
, &type
, qc
, &sz
);
606 if (res
== ERROR_SUCCESS
&& type
== REG_SZ
)
608 This
->quickComplete
= heap_realloc(qc
, sz
);
609 i
= ARRAY_SIZE(roots
);
613 if (res
!= ERROR_MORE_DATA
|| type
!= REG_SZ
)
622 if (!This
->quickComplete
&& pwszQuickComplete
)
624 size_t len
= strlenW(pwszQuickComplete
)+1;
625 if ((This
->quickComplete
= heap_alloc(len
* sizeof(WCHAR
))) != NULL
)
626 memcpy(This
->quickComplete
, pwszQuickComplete
, len
* sizeof(WCHAR
));
632 /**************************************************************************
633 * IAutoComplete2_fnGetOptions
635 static HRESULT WINAPI
IAutoComplete2_fnGetOptions(
636 IAutoComplete2
* iface
,
639 IAutoCompleteImpl
*This
= impl_from_IAutoComplete2(iface
);
642 TRACE("(%p) -> (%p)\n", This
, pdwFlag
);
644 *pdwFlag
= This
->options
;
649 /**************************************************************************
650 * IAutoComplete2_fnSetOptions
652 static HRESULT WINAPI
IAutoComplete2_fnSetOptions(
653 IAutoComplete2
* iface
,
656 IAutoCompleteImpl
*This
= impl_from_IAutoComplete2(iface
);
659 TRACE("(%p) -> (0x%x)\n", This
, dwFlag
);
661 This
->options
= dwFlag
;
663 if ((This
->options
& ACO_AUTOSUGGEST
) && This
->hwndEdit
&& !This
->hwndListBox
)
664 create_listbox(This
);
669 /**************************************************************************
670 * IAutoComplete2 VTable
672 static const IAutoComplete2Vtbl acvt
=
674 IAutoComplete2_fnQueryInterface
,
675 IAutoComplete2_fnAddRef
,
676 IAutoComplete2_fnRelease
,
677 IAutoComplete2_fnInit
,
678 IAutoComplete2_fnEnable
,
680 IAutoComplete2_fnSetOptions
,
681 IAutoComplete2_fnGetOptions
,
685 static HRESULT WINAPI
IAutoCompleteDropDown_fnQueryInterface(IAutoCompleteDropDown
*iface
,
686 REFIID riid
, LPVOID
*ppvObj
)
688 IAutoCompleteImpl
*This
= impl_from_IAutoCompleteDropDown(iface
);
689 return IAutoComplete2_QueryInterface(&This
->IAutoComplete2_iface
, riid
, ppvObj
);
692 static ULONG WINAPI
IAutoCompleteDropDown_fnAddRef(IAutoCompleteDropDown
*iface
)
694 IAutoCompleteImpl
*This
= impl_from_IAutoCompleteDropDown(iface
);
695 return IAutoComplete2_AddRef(&This
->IAutoComplete2_iface
);
698 static ULONG WINAPI
IAutoCompleteDropDown_fnRelease(IAutoCompleteDropDown
*iface
)
700 IAutoCompleteImpl
*This
= impl_from_IAutoCompleteDropDown(iface
);
701 return IAutoComplete2_Release(&This
->IAutoComplete2_iface
);
704 /**************************************************************************
705 * IAutoCompleteDropDown_fnGetDropDownStatus
707 static HRESULT WINAPI
IAutoCompleteDropDown_fnGetDropDownStatus(
708 IAutoCompleteDropDown
*iface
,
712 IAutoCompleteImpl
*This
= impl_from_IAutoCompleteDropDown(iface
);
715 TRACE("(%p) -> (%p, %p)\n", This
, pdwFlags
, ppwszString
);
717 dropped
= IsWindowVisible(This
->hwndListBox
);
720 *pdwFlags
= (dropped
? ACDD_VISIBLE
: 0);
726 sel
= SendMessageW(This
->hwndListBox
, LB_GETCURSEL
, 0, 0);
731 len
= SendMessageW(This
->hwndListBox
, LB_GETTEXTLEN
, sel
, 0);
732 *ppwszString
= CoTaskMemAlloc((len
+1)*sizeof(WCHAR
));
733 SendMessageW(This
->hwndListBox
, LB_GETTEXT
, sel
, (LPARAM
)*ppwszString
);
745 /**************************************************************************
746 * IAutoCompleteDropDown_fnResetEnumarator
748 static HRESULT WINAPI
IAutoCompleteDropDown_fnResetEnumerator(
749 IAutoCompleteDropDown
*iface
)
751 IAutoCompleteImpl
*This
= impl_from_IAutoCompleteDropDown(iface
);
753 FIXME("(%p): stub\n", This
);
758 /**************************************************************************
759 * IAutoCompleteDropDown VTable
761 static const IAutoCompleteDropDownVtbl acdropdownvt
=
763 IAutoCompleteDropDown_fnQueryInterface
,
764 IAutoCompleteDropDown_fnAddRef
,
765 IAutoCompleteDropDown_fnRelease
,
766 IAutoCompleteDropDown_fnGetDropDownStatus
,
767 IAutoCompleteDropDown_fnResetEnumerator
,
770 /**************************************************************************
771 * IAutoComplete_Constructor
773 HRESULT WINAPI
IAutoComplete_Constructor(IUnknown
* pUnkOuter
, REFIID riid
, LPVOID
* ppv
)
775 IAutoCompleteImpl
*lpac
;
778 if (pUnkOuter
&& !IsEqualIID (riid
, &IID_IUnknown
))
779 return CLASS_E_NOAGGREGATION
;
781 lpac
= heap_alloc_zero(sizeof(*lpac
));
783 return E_OUTOFMEMORY
;
786 lpac
->IAutoComplete2_iface
.lpVtbl
= &acvt
;
787 lpac
->IAutoCompleteDropDown_iface
.lpVtbl
= &acdropdownvt
;
788 lpac
->enabled
= TRUE
;
789 lpac
->options
= ACO_AUTOAPPEND
;
791 hr
= IAutoComplete2_QueryInterface(&lpac
->IAutoComplete2_iface
, riid
, ppv
);
792 IAutoComplete2_Release(&lpac
->IAutoComplete2_iface
);
794 TRACE("-- (%p)->\n",lpac
);