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
21 #include "oleacc_private.h"
23 #include "wine/unicode.h"
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(oleacc
);
29 IAccessible IAccessible_iface
;
36 static inline Client
* impl_from_Client(IAccessible
*iface
)
38 return CONTAINING_RECORD(iface
, Client
, IAccessible_iface
);
41 static HRESULT WINAPI
Client_QueryInterface(IAccessible
*iface
, REFIID riid
, void **ppv
)
43 Client
*This
= impl_from_Client(iface
);
45 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
47 if(IsEqualIID(riid
, &IID_IAccessible
) ||
48 IsEqualIID(riid
, &IID_IDispatch
) ||
49 IsEqualIID(riid
, &IID_IUnknown
)) {
51 IAccessible_AddRef(iface
);
58 static ULONG WINAPI
Client_AddRef(IAccessible
*iface
)
60 Client
*This
= impl_from_Client(iface
);
61 ULONG ref
= InterlockedIncrement(&This
->ref
);
63 TRACE("(%p) ref = %u\n", This
, ref
);
67 static ULONG WINAPI
Client_Release(IAccessible
*iface
)
69 Client
*This
= impl_from_Client(iface
);
70 ULONG ref
= InterlockedDecrement(&This
->ref
);
72 TRACE("(%p) ref = %u\n", This
, ref
);
79 static HRESULT WINAPI
Client_GetTypeInfoCount(IAccessible
*iface
, UINT
*pctinfo
)
81 Client
*This
= impl_from_Client(iface
);
82 FIXME("(%p)->(%p)\n", This
, pctinfo
);
86 static HRESULT WINAPI
Client_GetTypeInfo(IAccessible
*iface
,
87 UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
89 Client
*This
= impl_from_Client(iface
);
90 FIXME("(%p)->(%u %x %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
94 static HRESULT WINAPI
Client_GetIDsOfNames(IAccessible
*iface
, REFIID riid
,
95 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
97 Client
*This
= impl_from_Client(iface
);
98 FIXME("(%p)->(%s %p %u %x %p)\n", This
, debugstr_guid(riid
),
99 rgszNames
, cNames
, lcid
, rgDispId
);
103 static HRESULT WINAPI
Client_Invoke(IAccessible
*iface
, DISPID dispIdMember
,
104 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
105 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
107 Client
*This
= impl_from_Client(iface
);
108 FIXME("(%p)->(%x %s %x %x %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
109 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
113 static HRESULT WINAPI
Client_get_accParent(IAccessible
*iface
, IDispatch
**ppdispParent
)
115 Client
*This
= impl_from_Client(iface
);
116 FIXME("(%p)->(%p)\n", This
, ppdispParent
);
120 static HRESULT WINAPI
Client_get_accChildCount(IAccessible
*iface
, LONG
*pcountChildren
)
122 Client
*This
= impl_from_Client(iface
);
125 TRACE("(%p)->(%p)\n", This
, pcountChildren
);
128 for(cur
= GetWindow(This
->hwnd
, GW_CHILD
); cur
; cur
= GetWindow(cur
, GW_HWNDNEXT
))
134 static HRESULT WINAPI
Client_get_accChild(IAccessible
*iface
,
135 VARIANT varChildID
, IDispatch
**ppdispChild
)
137 Client
*This
= impl_from_Client(iface
);
138 FIXME("(%p)->(%s %p)\n", This
, debugstr_variant(&varChildID
), ppdispChild
);
142 static HRESULT WINAPI
Client_get_accName(IAccessible
*iface
, VARIANT varID
, BSTR
*pszName
)
144 Client
*This
= impl_from_Client(iface
);
148 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pszName
);
151 if(convert_child_id(&varID
) != CHILDID_SELF
|| !IsWindow(This
->hwnd
))
154 len
= SendMessageW(This
->hwnd
, WM_GETTEXT
, sizeof(name
)/sizeof(WCHAR
), (LPARAM
)name
);
158 for(i
=0; i
<len
; i
++) {
161 memmove(name
+i
, name
+i
+1, (len
-i
)*sizeof(WCHAR
));
166 *pszName
= SysAllocStringLen(name
, len
);
167 return *pszName
? S_OK
: E_OUTOFMEMORY
;
170 static HRESULT WINAPI
Client_get_accValue(IAccessible
*iface
, VARIANT varID
, BSTR
*pszValue
)
172 Client
*This
= impl_from_Client(iface
);
174 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pszValue
);
177 if(convert_child_id(&varID
) != CHILDID_SELF
)
182 static HRESULT WINAPI
Client_get_accDescription(IAccessible
*iface
,
183 VARIANT varID
, BSTR
*pszDescription
)
185 Client
*This
= impl_from_Client(iface
);
187 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pszDescription
);
189 *pszDescription
= NULL
;
190 if(convert_child_id(&varID
) != CHILDID_SELF
)
195 static HRESULT WINAPI
Client_get_accRole(IAccessible
*iface
, VARIANT varID
, VARIANT
*pvarRole
)
197 Client
*This
= impl_from_Client(iface
);
199 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pvarRole
);
201 if(convert_child_id(&varID
) != CHILDID_SELF
) {
202 V_VT(pvarRole
) = VT_EMPTY
;
206 V_VT(pvarRole
) = VT_I4
;
207 V_I4(pvarRole
) = ROLE_SYSTEM_CLIENT
;
211 static HRESULT WINAPI
Client_get_accState(IAccessible
*iface
, VARIANT varID
, VARIANT
*pvarState
)
213 Client
*This
= impl_from_Client(iface
);
216 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pvarState
);
218 if(convert_child_id(&varID
) != CHILDID_SELF
) {
219 V_VT(pvarState
) = VT_EMPTY
;
223 V_VT(pvarState
) = VT_I4
;
226 style
= GetWindowLongW(This
->hwnd
, GWL_STYLE
);
227 if(style
& WS_DISABLED
)
228 V_I4(pvarState
) |= STATE_SYSTEM_UNAVAILABLE
;
229 else if(IsWindow(This
->hwnd
))
230 V_I4(pvarState
) |= STATE_SYSTEM_FOCUSABLE
;
231 if(GetFocus() == This
->hwnd
)
232 V_I4(pvarState
) |= STATE_SYSTEM_FOCUSED
;
233 if(!(style
& WS_VISIBLE
))
234 V_I4(pvarState
) |= STATE_SYSTEM_INVISIBLE
;
238 static HRESULT WINAPI
Client_get_accHelp(IAccessible
*iface
, VARIANT varID
, BSTR
*pszHelp
)
240 Client
*This
= impl_from_Client(iface
);
242 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pszHelp
);
245 if(convert_child_id(&varID
) != CHILDID_SELF
)
250 static HRESULT WINAPI
Client_get_accHelpTopic(IAccessible
*iface
,
251 BSTR
*pszHelpFile
, VARIANT varID
, LONG
*pidTopic
)
253 Client
*This
= impl_from_Client(iface
);
254 FIXME("(%p)->(%p %s %p)\n", This
, pszHelpFile
, debugstr_variant(&varID
), pidTopic
);
258 static HRESULT WINAPI
Client_get_accKeyboardShortcut(IAccessible
*iface
,
259 VARIANT varID
, BSTR
*pszKeyboardShortcut
)
261 static const WCHAR shortcut_fmt
[] = {'A','l','t','+','!',0};
262 Client
*This
= impl_from_Client(iface
);
266 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pszKeyboardShortcut
);
268 *pszKeyboardShortcut
= NULL
;
269 if(convert_child_id(&varID
) != CHILDID_SELF
)
272 len
= SendMessageW(This
->hwnd
, WM_GETTEXT
, sizeof(name
)/sizeof(WCHAR
), (LPARAM
)name
);
273 for(i
=0; i
<len
; i
++) {
280 *pszKeyboardShortcut
= SysAllocString(shortcut_fmt
);
281 if(!*pszKeyboardShortcut
)
282 return E_OUTOFMEMORY
;
284 (*pszKeyboardShortcut
)[4] = name
[i
+1];
288 static HRESULT WINAPI
Client_get_accFocus(IAccessible
*iface
, VARIANT
*pvarID
)
290 Client
*This
= impl_from_Client(iface
);
291 FIXME("(%p)->(%p)\n", This
, pvarID
);
295 static HRESULT WINAPI
Client_get_accSelection(IAccessible
*iface
, VARIANT
*pvarID
)
297 Client
*This
= impl_from_Client(iface
);
298 FIXME("(%p)->(%p)\n", This
, pvarID
);
302 static HRESULT WINAPI
Client_get_accDefaultAction(IAccessible
*iface
,
303 VARIANT varID
, BSTR
*pszDefaultAction
)
305 Client
*This
= impl_from_Client(iface
);
307 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pszDefaultAction
);
309 *pszDefaultAction
= NULL
;
310 if(convert_child_id(&varID
) != CHILDID_SELF
)
315 static HRESULT WINAPI
Client_accSelect(IAccessible
*iface
, LONG flagsSelect
, VARIANT varID
)
317 Client
*This
= impl_from_Client(iface
);
318 FIXME("(%p)->(%x %s)\n", This
, flagsSelect
, debugstr_variant(&varID
));
322 static HRESULT WINAPI
Client_accLocation(IAccessible
*iface
, LONG
*pxLeft
,
323 LONG
*pyTop
, LONG
*pcxWidth
, LONG
*pcyHeight
, VARIANT varID
)
325 Client
*This
= impl_from_Client(iface
);
326 FIXME("(%p)->(%p %p %p %p %s)\n", This
, pxLeft
, pyTop
,
327 pcxWidth
, pcyHeight
, debugstr_variant(&varID
));
331 static HRESULT WINAPI
Client_accNavigate(IAccessible
*iface
,
332 LONG navDir
, VARIANT varStart
, VARIANT
*pvarEnd
)
334 Client
*This
= impl_from_Client(iface
);
335 FIXME("(%p)->(%d %s %p)\n", This
, navDir
, debugstr_variant(&varStart
), pvarEnd
);
339 static HRESULT WINAPI
Client_accHitTest(IAccessible
*iface
,
340 LONG xLeft
, LONG yTop
, VARIANT
*pvarID
)
342 Client
*This
= impl_from_Client(iface
);
346 TRACE("(%p)->(%d %d %p)\n", This
, xLeft
, yTop
, pvarID
);
348 V_VT(pvarID
) = VT_I4
;
353 if(!IsWindowVisible(This
->hwnd
) || !ScreenToClient(This
->hwnd
, &pt
))
356 child
= ChildWindowFromPointEx(This
->hwnd
, pt
, CWP_SKIPINVISIBLE
);
357 if(!child
|| child
==This
->hwnd
)
360 V_VT(pvarID
) = VT_DISPATCH
;
361 return AccessibleObjectFromWindow(child
, OBJID_WINDOW
,
362 &IID_IDispatch
, (void**)&V_DISPATCH(pvarID
));
365 static HRESULT WINAPI
Client_accDoDefaultAction(IAccessible
*iface
, VARIANT varID
)
367 Client
*This
= impl_from_Client(iface
);
368 FIXME("(%p)->(%s)\n", This
, debugstr_variant(&varID
));
372 static HRESULT WINAPI
Client_put_accName(IAccessible
*iface
, VARIANT varID
, BSTR pszName
)
374 Client
*This
= impl_from_Client(iface
);
375 FIXME("(%p)->(%s %s)\n", This
, debugstr_variant(&varID
), debugstr_w(pszName
));
379 static HRESULT WINAPI
Client_put_accValue(IAccessible
*iface
, VARIANT varID
, BSTR pszValue
)
381 Client
*This
= impl_from_Client(iface
);
382 FIXME("(%p)->(%s %s)\n", This
, debugstr_variant(&varID
), debugstr_w(pszValue
));
386 static const IAccessibleVtbl ClientVtbl
= {
387 Client_QueryInterface
,
390 Client_GetTypeInfoCount
,
392 Client_GetIDsOfNames
,
394 Client_get_accParent
,
395 Client_get_accChildCount
,
399 Client_get_accDescription
,
403 Client_get_accHelpTopic
,
404 Client_get_accKeyboardShortcut
,
406 Client_get_accSelection
,
407 Client_get_accDefaultAction
,
412 Client_accDoDefaultAction
,
417 HRESULT
create_client_object(HWND hwnd
, const IID
*iid
, void **obj
)
425 client
= heap_alloc_zero(sizeof(Client
));
427 return E_OUTOFMEMORY
;
429 client
->IAccessible_iface
.lpVtbl
= &ClientVtbl
;
433 hres
= IAccessible_QueryInterface(&client
->IAccessible_iface
, iid
, obj
);
434 IAccessible_Release(&client
->IAccessible_iface
);