2 * Copyright 2014 Piotr Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "oleacc_private.h"
25 #include "wine/debug.h"
26 #include "wine/heap.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(oleacc
);
30 typedef struct win_class_vtbl win_class_vtbl
;
32 IAccessible IAccessible_iface
;
33 IOleWindow IOleWindow_iface
;
34 IEnumVARIANT IEnumVARIANT_iface
;
42 const win_class_vtbl
*vtbl
;
45 struct win_class_vtbl
{
46 void (*init
)(Client
*);
47 HRESULT (*get_state
)(Client
*, VARIANT
, VARIANT
*);
48 HRESULT (*get_name
)(Client
*, VARIANT
, BSTR
*);
49 HRESULT (*get_kbd_shortcut
)(Client
*, VARIANT
, BSTR
*);
50 HRESULT (*get_value
)(Client
*, VARIANT
, BSTR
*);
51 HRESULT (*put_value
)(Client
*, VARIANT
, BSTR
);
54 static HRESULT
win_get_name(HWND hwnd
, BSTR
*name
)
59 len
= SendMessageW(hwnd
, WM_GETTEXT
, ARRAY_SIZE(buf
), (LPARAM
)buf
);
63 for(i
=0; i
<len
; i
++) {
66 memmove(buf
+i
, buf
+i
+1, (len
-i
)*sizeof(WCHAR
));
71 *name
= SysAllocStringLen(buf
, len
);
72 return *name
? S_OK
: E_OUTOFMEMORY
;
75 static HRESULT
win_get_kbd_shortcut(HWND hwnd
, BSTR
*shortcut
)
80 len
= SendMessageW(hwnd
, WM_GETTEXT
, ARRAY_SIZE(buf
), (LPARAM
)buf
);
84 for(i
=0; i
<len
; i
++) {
91 *shortcut
= SysAllocString(L
"Alt+!");
94 (*shortcut
)[4] = buf
[i
+1];
98 static inline Client
* impl_from_Client(IAccessible
*iface
)
100 return CONTAINING_RECORD(iface
, Client
, IAccessible_iface
);
103 static HRESULT WINAPI
Client_QueryInterface(IAccessible
*iface
, REFIID riid
, void **ppv
)
105 Client
*This
= impl_from_Client(iface
);
107 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
109 if(IsEqualIID(riid
, &IID_IAccessible
) ||
110 IsEqualIID(riid
, &IID_IDispatch
) ||
111 IsEqualIID(riid
, &IID_IUnknown
)) {
113 }else if(IsEqualIID(riid
, &IID_IOleWindow
)) {
114 *ppv
= &This
->IOleWindow_iface
;
115 }else if(IsEqualIID(riid
, &IID_IEnumVARIANT
)) {
116 *ppv
= &This
->IEnumVARIANT_iface
;
118 WARN("no interface: %s\n", debugstr_guid(riid
));
120 return E_NOINTERFACE
;
123 IAccessible_AddRef(iface
);
127 static ULONG WINAPI
Client_AddRef(IAccessible
*iface
)
129 Client
*This
= impl_from_Client(iface
);
130 ULONG ref
= InterlockedIncrement(&This
->ref
);
132 TRACE("(%p) ref = %u\n", This
, ref
);
136 static ULONG WINAPI
Client_Release(IAccessible
*iface
)
138 Client
*This
= impl_from_Client(iface
);
139 ULONG ref
= InterlockedDecrement(&This
->ref
);
141 TRACE("(%p) ref = %u\n", This
, ref
);
148 static HRESULT WINAPI
Client_GetTypeInfoCount(IAccessible
*iface
, UINT
*pctinfo
)
150 Client
*This
= impl_from_Client(iface
);
151 FIXME("(%p)->(%p)\n", This
, pctinfo
);
155 static HRESULT WINAPI
Client_GetTypeInfo(IAccessible
*iface
,
156 UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
158 Client
*This
= impl_from_Client(iface
);
159 FIXME("(%p)->(%u %x %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
163 static HRESULT WINAPI
Client_GetIDsOfNames(IAccessible
*iface
, REFIID riid
,
164 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
166 Client
*This
= impl_from_Client(iface
);
167 FIXME("(%p)->(%s %p %u %x %p)\n", This
, debugstr_guid(riid
),
168 rgszNames
, cNames
, lcid
, rgDispId
);
172 static HRESULT WINAPI
Client_Invoke(IAccessible
*iface
, DISPID dispIdMember
,
173 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
174 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
176 Client
*This
= impl_from_Client(iface
);
177 FIXME("(%p)->(%x %s %x %x %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
178 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
182 static HRESULT WINAPI
Client_get_accParent(IAccessible
*iface
, IDispatch
**ppdispParent
)
184 Client
*This
= impl_from_Client(iface
);
186 TRACE("(%p)->(%p)\n", This
, ppdispParent
);
188 return AccessibleObjectFromWindow(This
->hwnd
, OBJID_WINDOW
,
189 &IID_IDispatch
, (void**)ppdispParent
);
192 static HRESULT WINAPI
Client_get_accChildCount(IAccessible
*iface
, LONG
*pcountChildren
)
194 Client
*This
= impl_from_Client(iface
);
197 TRACE("(%p)->(%p)\n", This
, pcountChildren
);
200 for(cur
= GetWindow(This
->hwnd
, GW_CHILD
); cur
; cur
= GetWindow(cur
, GW_HWNDNEXT
))
206 static HRESULT WINAPI
Client_get_accChild(IAccessible
*iface
,
207 VARIANT varChildID
, IDispatch
**ppdispChild
)
209 Client
*This
= impl_from_Client(iface
);
211 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varChildID
), ppdispChild
);
217 static HRESULT WINAPI
Client_get_accName(IAccessible
*iface
, VARIANT id
, BSTR
*name
)
219 Client
*This
= impl_from_Client(iface
);
221 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&id
), name
);
224 if(This
->vtbl
&& This
->vtbl
->get_name
)
225 return This
->vtbl
->get_name(This
, id
, name
);
227 if(convert_child_id(&id
) != CHILDID_SELF
|| !IsWindow(This
->hwnd
))
230 return win_get_name(This
->hwnd
, name
);
233 static HRESULT WINAPI
Client_get_accValue(IAccessible
*iface
, VARIANT id
, BSTR
*value
)
235 Client
*This
= impl_from_Client(iface
);
237 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&id
), value
);
240 if(This
->vtbl
&& This
->vtbl
->get_value
)
241 return This
->vtbl
->get_value(This
, id
, value
);
243 if(convert_child_id(&id
) != CHILDID_SELF
)
248 static HRESULT WINAPI
Client_get_accDescription(IAccessible
*iface
,
249 VARIANT varID
, BSTR
*pszDescription
)
251 Client
*This
= impl_from_Client(iface
);
253 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pszDescription
);
255 *pszDescription
= NULL
;
256 if(convert_child_id(&varID
) != CHILDID_SELF
)
261 static HRESULT WINAPI
Client_get_accRole(IAccessible
*iface
, VARIANT varID
, VARIANT
*pvarRole
)
263 Client
*This
= impl_from_Client(iface
);
265 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pvarRole
);
267 if(convert_child_id(&varID
) != CHILDID_SELF
) {
268 V_VT(pvarRole
) = VT_EMPTY
;
272 V_VT(pvarRole
) = VT_I4
;
273 V_I4(pvarRole
) = This
->role
;
277 static HRESULT
client_get_state(Client
*client
, VARIANT id
, VARIANT
*state
)
282 if(convert_child_id(&id
) != CHILDID_SELF
) {
283 V_VT(state
) = VT_EMPTY
;
290 style
= GetWindowLongW(client
->hwnd
, GWL_STYLE
);
291 if(style
& WS_DISABLED
)
292 V_I4(state
) |= STATE_SYSTEM_UNAVAILABLE
;
293 else if(IsWindow(client
->hwnd
))
294 V_I4(state
) |= STATE_SYSTEM_FOCUSABLE
;
296 info
.cbSize
= sizeof(info
);
297 if(GetGUIThreadInfo(0, &info
) && info
.hwndFocus
== client
->hwnd
)
298 V_I4(state
) |= STATE_SYSTEM_FOCUSED
;
299 if(!(style
& WS_VISIBLE
))
300 V_I4(state
) |= STATE_SYSTEM_INVISIBLE
;
304 static HRESULT WINAPI
Client_get_accState(IAccessible
*iface
, VARIANT id
, VARIANT
*state
)
306 Client
*This
= impl_from_Client(iface
);
308 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&id
), state
);
310 if(This
->vtbl
&& This
->vtbl
->get_state
)
311 return This
->vtbl
->get_state(This
, id
, state
);
312 return client_get_state(This
, id
, state
);
315 static HRESULT WINAPI
Client_get_accHelp(IAccessible
*iface
, VARIANT varID
, BSTR
*pszHelp
)
317 Client
*This
= impl_from_Client(iface
);
319 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pszHelp
);
322 if(convert_child_id(&varID
) != CHILDID_SELF
)
327 static HRESULT WINAPI
Client_get_accHelpTopic(IAccessible
*iface
,
328 BSTR
*pszHelpFile
, VARIANT varID
, LONG
*pidTopic
)
330 Client
*This
= impl_from_Client(iface
);
331 FIXME("(%p)->(%p %s %p)\n", This
, pszHelpFile
, debugstr_variant(&varID
), pidTopic
);
335 static HRESULT WINAPI
Client_get_accKeyboardShortcut(IAccessible
*iface
,
336 VARIANT id
, BSTR
*shortcut
)
338 Client
*This
= impl_from_Client(iface
);
340 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&id
), shortcut
);
343 if(This
->vtbl
&& This
->vtbl
->get_kbd_shortcut
)
344 return This
->vtbl
->get_kbd_shortcut(This
, id
, shortcut
);
346 if(convert_child_id(&id
) != CHILDID_SELF
)
349 return win_get_kbd_shortcut(This
->hwnd
, shortcut
);
352 static HRESULT WINAPI
Client_get_accFocus(IAccessible
*iface
, VARIANT
*focus
)
354 Client
*This
= impl_from_Client(iface
);
357 TRACE("(%p)->(%p)\n", This
, focus
);
359 V_VT(focus
) = VT_EMPTY
;
360 info
.cbSize
= sizeof(info
);
361 if(GetGUIThreadInfo(0, &info
) && info
.hwndFocus
) {
362 if(info
.hwndFocus
== This
->hwnd
) {
364 V_I4(focus
) = CHILDID_SELF
;
366 else if(IsChild(This
->hwnd
, info
.hwndFocus
)) {
370 hr
= AccessibleObjectFromWindow(info
.hwndFocus
, OBJID_WINDOW
,
371 &IID_IDispatch
, (void**)&disp
);
377 V_VT(focus
) = VT_DISPATCH
;
378 V_DISPATCH(focus
) = disp
;
385 static HRESULT WINAPI
Client_get_accSelection(IAccessible
*iface
, VARIANT
*pvarID
)
387 Client
*This
= impl_from_Client(iface
);
388 FIXME("(%p)->(%p)\n", This
, pvarID
);
392 static HRESULT WINAPI
Client_get_accDefaultAction(IAccessible
*iface
,
393 VARIANT varID
, BSTR
*pszDefaultAction
)
395 Client
*This
= impl_from_Client(iface
);
397 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pszDefaultAction
);
399 *pszDefaultAction
= NULL
;
400 if(convert_child_id(&varID
) != CHILDID_SELF
)
405 static HRESULT WINAPI
Client_accSelect(IAccessible
*iface
, LONG flagsSelect
, VARIANT varID
)
407 Client
*This
= impl_from_Client(iface
);
408 FIXME("(%p)->(%x %s)\n", This
, flagsSelect
, debugstr_variant(&varID
));
412 static HRESULT WINAPI
Client_accLocation(IAccessible
*iface
, LONG
*pxLeft
,
413 LONG
*pyTop
, LONG
*pcxWidth
, LONG
*pcyHeight
, VARIANT varID
)
415 Client
*This
= impl_from_Client(iface
);
419 TRACE("(%p)->(%p %p %p %p %s)\n", This
, pxLeft
, pyTop
,
420 pcxWidth
, pcyHeight
, debugstr_variant(&varID
));
422 *pxLeft
= *pyTop
= *pcxWidth
= *pcyHeight
= 0;
423 if(convert_child_id(&varID
) != CHILDID_SELF
)
426 if(!GetClientRect(This
->hwnd
, &rect
))
431 MapWindowPoints(This
->hwnd
, NULL
, &pt
, 1);
437 MapWindowPoints(This
->hwnd
, NULL
, &pt
, 1);
438 *pcxWidth
= pt
.x
- *pxLeft
;
439 *pcyHeight
= pt
.y
- *pyTop
;
443 static HRESULT WINAPI
Client_accNavigate(IAccessible
*iface
,
444 LONG navDir
, VARIANT varStart
, VARIANT
*pvarEnd
)
446 Client
*This
= impl_from_Client(iface
);
447 FIXME("(%p)->(%d %s %p)\n", This
, navDir
, debugstr_variant(&varStart
), pvarEnd
);
451 static HRESULT WINAPI
Client_accHitTest(IAccessible
*iface
,
452 LONG xLeft
, LONG yTop
, VARIANT
*pvarID
)
454 Client
*This
= impl_from_Client(iface
);
458 TRACE("(%p)->(%d %d %p)\n", This
, xLeft
, yTop
, pvarID
);
460 V_VT(pvarID
) = VT_I4
;
465 if(!IsWindowVisible(This
->hwnd
) || !ScreenToClient(This
->hwnd
, &pt
))
468 child
= ChildWindowFromPointEx(This
->hwnd
, pt
, CWP_SKIPINVISIBLE
);
469 if(!child
|| child
==This
->hwnd
)
472 V_VT(pvarID
) = VT_DISPATCH
;
473 return AccessibleObjectFromWindow(child
, OBJID_WINDOW
,
474 &IID_IDispatch
, (void**)&V_DISPATCH(pvarID
));
477 static HRESULT WINAPI
Client_accDoDefaultAction(IAccessible
*iface
, VARIANT varID
)
479 Client
*This
= impl_from_Client(iface
);
480 FIXME("(%p)->(%s)\n", This
, debugstr_variant(&varID
));
484 static HRESULT WINAPI
Client_put_accName(IAccessible
*iface
, VARIANT varID
, BSTR pszName
)
486 Client
*This
= impl_from_Client(iface
);
487 FIXME("(%p)->(%s %s)\n", This
, debugstr_variant(&varID
), debugstr_w(pszName
));
491 static HRESULT WINAPI
Client_put_accValue(IAccessible
*iface
, VARIANT id
, BSTR value
)
493 Client
*This
= impl_from_Client(iface
);
495 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&id
), value
);
497 if(This
->vtbl
&& This
->vtbl
->put_value
)
498 return This
->vtbl
->put_value(This
, id
, value
);
500 if(convert_child_id(&id
) != CHILDID_SELF
)
505 static const IAccessibleVtbl ClientVtbl
= {
506 Client_QueryInterface
,
509 Client_GetTypeInfoCount
,
511 Client_GetIDsOfNames
,
513 Client_get_accParent
,
514 Client_get_accChildCount
,
518 Client_get_accDescription
,
522 Client_get_accHelpTopic
,
523 Client_get_accKeyboardShortcut
,
525 Client_get_accSelection
,
526 Client_get_accDefaultAction
,
531 Client_accDoDefaultAction
,
536 static inline Client
* impl_from_Client_OleWindow(IOleWindow
*iface
)
538 return CONTAINING_RECORD(iface
, Client
, IOleWindow_iface
);
541 static HRESULT WINAPI
Client_OleWindow_QueryInterface(IOleWindow
*iface
, REFIID riid
, void **ppv
)
543 Client
*This
= impl_from_Client_OleWindow(iface
);
544 return IAccessible_QueryInterface(&This
->IAccessible_iface
, riid
, ppv
);
547 static ULONG WINAPI
Client_OleWindow_AddRef(IOleWindow
*iface
)
549 Client
*This
= impl_from_Client_OleWindow(iface
);
550 return IAccessible_AddRef(&This
->IAccessible_iface
);
553 static ULONG WINAPI
Client_OleWindow_Release(IOleWindow
*iface
)
555 Client
*This
= impl_from_Client_OleWindow(iface
);
556 return IAccessible_Release(&This
->IAccessible_iface
);
559 static HRESULT WINAPI
Client_OleWindow_GetWindow(IOleWindow
*iface
, HWND
*phwnd
)
561 Client
*This
= impl_from_Client_OleWindow(iface
);
563 TRACE("(%p)->(%p)\n", This
, phwnd
);
569 static HRESULT WINAPI
Client_OleWindow_ContextSensitiveHelp(IOleWindow
*iface
, BOOL fEnterMode
)
571 Client
*This
= impl_from_Client_OleWindow(iface
);
572 FIXME("(%p)->(%x)\n", This
, fEnterMode
);
576 static const IOleWindowVtbl ClientOleWindowVtbl
= {
577 Client_OleWindow_QueryInterface
,
578 Client_OleWindow_AddRef
,
579 Client_OleWindow_Release
,
580 Client_OleWindow_GetWindow
,
581 Client_OleWindow_ContextSensitiveHelp
584 static inline Client
* impl_from_Client_EnumVARIANT(IEnumVARIANT
*iface
)
586 return CONTAINING_RECORD(iface
, Client
, IEnumVARIANT_iface
);
589 static HRESULT WINAPI
Client_EnumVARIANT_QueryInterface(IEnumVARIANT
*iface
, REFIID riid
, void **ppv
)
591 Client
*This
= impl_from_Client_EnumVARIANT(iface
);
592 return IAccessible_QueryInterface(&This
->IAccessible_iface
, riid
, ppv
);
595 static ULONG WINAPI
Client_EnumVARIANT_AddRef(IEnumVARIANT
*iface
)
597 Client
*This
= impl_from_Client_EnumVARIANT(iface
);
598 return IAccessible_AddRef(&This
->IAccessible_iface
);
601 static ULONG WINAPI
Client_EnumVARIANT_Release(IEnumVARIANT
*iface
)
603 Client
*This
= impl_from_Client_EnumVARIANT(iface
);
604 return IAccessible_Release(&This
->IAccessible_iface
);
607 static HRESULT WINAPI
Client_EnumVARIANT_Next(IEnumVARIANT
*iface
,
608 ULONG celt
, VARIANT
*rgVar
, ULONG
*pCeltFetched
)
610 Client
*This
= impl_from_Client_EnumVARIANT(iface
);
611 HWND cur
= This
->enum_pos
, next
;
615 TRACE("(%p)->(%u %p %p)\n", This
, celt
, rgVar
, pCeltFetched
);
624 next
= GetWindow(This
->hwnd
, GW_CHILD
);
626 next
= GetWindow(This
->enum_pos
, GW_HWNDNEXT
);
631 V_VT(rgVar
+fetched
) = VT_DISPATCH
;
632 hr
= AccessibleObjectFromWindow(cur
, OBJID_WINDOW
,
633 &IID_IDispatch
, (void**)&V_DISPATCH(rgVar
+fetched
));
635 V_VT(rgVar
+fetched
) = VT_EMPTY
;
637 VariantClear(rgVar
+fetched
-1);
648 next
= GetWindow(cur
, GW_HWNDNEXT
);
651 This
->enum_pos
= cur
;
653 *pCeltFetched
= fetched
;
654 return celt
== fetched
? S_OK
: S_FALSE
;
657 static HRESULT WINAPI
Client_EnumVARIANT_Skip(IEnumVARIANT
*iface
, ULONG celt
)
659 Client
*This
= impl_from_Client_EnumVARIANT(iface
);
662 TRACE("(%p)->(%u)\n", This
, celt
);
666 next
= GetWindow(This
->hwnd
, GW_CHILD
);
668 next
= GetWindow(This
->enum_pos
, GW_HWNDNEXT
);
672 This
->enum_pos
= next
;
679 static HRESULT WINAPI
Client_EnumVARIANT_Reset(IEnumVARIANT
*iface
)
681 Client
*This
= impl_from_Client_EnumVARIANT(iface
);
683 TRACE("(%p)\n", This
);
689 static HRESULT WINAPI
Client_EnumVARIANT_Clone(IEnumVARIANT
*iface
, IEnumVARIANT
**ppEnum
)
691 Client
*This
= impl_from_Client_EnumVARIANT(iface
);
692 FIXME("(%p)->(%p)\n", This
, ppEnum
);
696 static const IEnumVARIANTVtbl ClientEnumVARIANTVtbl
= {
697 Client_EnumVARIANT_QueryInterface
,
698 Client_EnumVARIANT_AddRef
,
699 Client_EnumVARIANT_Release
,
700 Client_EnumVARIANT_Next
,
701 Client_EnumVARIANT_Skip
,
702 Client_EnumVARIANT_Reset
,
703 Client_EnumVARIANT_Clone
706 static void edit_init(Client
*client
)
708 client
->role
= ROLE_SYSTEM_TEXT
;
711 static HRESULT
edit_get_state(Client
*client
, VARIANT id
, VARIANT
*state
)
716 hres
= client_get_state(client
, id
, state
);
720 assert(V_VT(state
) == VT_I4
);
722 style
= GetWindowLongW(client
->hwnd
, GWL_STYLE
);
723 if(style
& ES_READONLY
)
724 V_I4(state
) |= STATE_SYSTEM_READONLY
;
725 if(style
& ES_PASSWORD
)
726 V_I4(state
) |= STATE_SYSTEM_PROTECTED
;
731 * Edit control objects have their name property defined by the first static
732 * text control preceding them in the order of window creation. If one is not
733 * found, the edit has no name property. In the case of the keyboard shortcut
734 * property, the first preceding visible static text control is used.
736 static HWND
edit_find_label(HWND hwnd
, BOOL visible
)
740 for(cur
= hwnd
; cur
; cur
= GetWindow(cur
, GW_HWNDPREV
)) {
741 WCHAR class_name
[64];
743 if(!RealGetWindowClassW(cur
, class_name
, ARRAY_SIZE(class_name
)))
746 if(!wcsicmp(class_name
, WC_STATICW
)) {
747 if(visible
&& !(GetWindowLongW(cur
, GWL_STYLE
) & WS_VISIBLE
))
757 static HRESULT
edit_get_name(Client
*client
, VARIANT id
, BSTR
*name
)
761 if(convert_child_id(&id
) != CHILDID_SELF
|| !IsWindow(client
->hwnd
))
764 label
= edit_find_label(client
->hwnd
, FALSE
);
768 return win_get_name(label
, name
);
771 static HRESULT
edit_get_kbd_shortcut(Client
*client
, VARIANT id
, BSTR
*shortcut
)
775 if(convert_child_id(&id
) != CHILDID_SELF
)
778 label
= edit_find_label(client
->hwnd
, TRUE
);
782 return win_get_kbd_shortcut(label
, shortcut
);
785 static HRESULT
edit_get_value(Client
*client
, VARIANT id
, BSTR
*value_out
)
790 if(convert_child_id(&id
) != CHILDID_SELF
)
793 if(GetWindowLongW(client
->hwnd
, GWL_STYLE
) & ES_PASSWORD
)
794 return E_ACCESSDENIED
;
796 len
= SendMessageW(client
->hwnd
, WM_GETTEXTLENGTH
, 0, 0);
797 buf
= heap_alloc_zero((len
+ 1) * sizeof(*buf
));
799 return E_OUTOFMEMORY
;
801 SendMessageW(client
->hwnd
, WM_GETTEXT
, len
+ 1, (LPARAM
)buf
);
802 *value_out
= SysAllocString(buf
);
807 static HRESULT
edit_put_value(Client
*client
, VARIANT id
, BSTR value
)
809 if(convert_child_id(&id
) != CHILDID_SELF
|| !IsWindow(client
->hwnd
))
812 SendMessageW(client
->hwnd
, WM_SETTEXT
, 0, (LPARAM
)value
);
816 static const win_class_vtbl edit_vtbl
= {
820 edit_get_kbd_shortcut
,
825 static const struct win_class_data classes
[] = {
826 {WC_LISTBOXW
, 0x10000, TRUE
},
827 {L
"#32768", 0x10001, TRUE
}, /* menu */
828 {WC_BUTTONW
, 0x10002, TRUE
},
829 {WC_STATICW
, 0x10003, TRUE
},
830 {WC_EDITW
, 0x10004, FALSE
, &edit_vtbl
},
831 {WC_COMBOBOXW
, 0x10005, TRUE
},
832 {L
"#32770", 0x10006, TRUE
}, /* dialog */
833 {L
"#32771", 0x10007, TRUE
}, /* winswitcher */
834 {L
"MDIClient", 0x10008, TRUE
},
835 {L
"#32769", 0x10009, TRUE
}, /* desktop */
836 {WC_SCROLLBARW
, 0x1000a, TRUE
},
837 {STATUSCLASSNAMEW
, 0x1000b, TRUE
},
838 {TOOLBARCLASSNAMEW
, 0x1000c, TRUE
},
839 {PROGRESS_CLASSW
, 0x1000d, TRUE
},
840 {ANIMATE_CLASSW
, 0x1000e, TRUE
},
841 {WC_TABCONTROLW
, 0x1000f, TRUE
},
842 {HOTKEY_CLASSW
, 0x10010, TRUE
},
843 {WC_HEADERW
, 0x10011, TRUE
},
844 {TRACKBAR_CLASSW
, 0x10012, TRUE
},
845 {WC_LISTVIEWW
, 0x10013, TRUE
},
846 {UPDOWN_CLASSW
, 0x10016, TRUE
},
847 {TOOLTIPS_CLASSW
, 0x10018, TRUE
},
848 {WC_TREEVIEWW
, 0x10019, TRUE
},
849 {DATETIMEPICK_CLASSW
, 0, TRUE
},
850 {WC_IPADDRESSW
, 0, TRUE
},
851 {L
"RICHEDIT", 0x1001c, TRUE
},
852 {L
"RichEdit20A", 0, TRUE
},
853 {L
"RichEdit20W", 0, TRUE
},
857 HRESULT
create_client_object(HWND hwnd
, const IID
*iid
, void **obj
)
859 const struct win_class_data
*data
;
866 client
= heap_alloc_zero(sizeof(Client
));
868 return E_OUTOFMEMORY
;
870 data
= find_class_data(hwnd
, classes
);
872 client
->IAccessible_iface
.lpVtbl
= &ClientVtbl
;
873 client
->IOleWindow_iface
.lpVtbl
= &ClientOleWindowVtbl
;
874 client
->IEnumVARIANT_iface
.lpVtbl
= &ClientEnumVARIANTVtbl
;
877 client
->enum_pos
= 0;
878 client
->role
= ROLE_SYSTEM_CLIENT
;
881 client
->vtbl
= data
->vtbl
;
882 if(client
->vtbl
&& client
->vtbl
->init
)
883 client
->vtbl
->init(client
);
885 hres
= IAccessible_QueryInterface(&client
->IAccessible_iface
, iid
, obj
);
886 IAccessible_Release(&client
->IAccessible_iface
);