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
19 #include "oleacc_private.h"
22 IAccessible IAccessible_iface
;
23 IOleWindow IOleWindow_iface
;
30 static inline Client
* impl_from_Client(IAccessible
*iface
)
32 return CONTAINING_RECORD(iface
, Client
, IAccessible_iface
);
35 static HRESULT WINAPI
Client_QueryInterface(IAccessible
*iface
, REFIID riid
, void **ppv
)
37 Client
*This
= impl_from_Client(iface
);
39 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
41 if(IsEqualIID(riid
, &IID_IAccessible
) ||
42 IsEqualIID(riid
, &IID_IDispatch
) ||
43 IsEqualIID(riid
, &IID_IUnknown
)) {
45 }else if(IsEqualIID(riid
, &IID_IOleWindow
)) {
46 *ppv
= &This
->IOleWindow_iface
;
48 WARN("no interface: %s\n", debugstr_guid(riid
));
53 IAccessible_AddRef(iface
);
57 static ULONG WINAPI
Client_AddRef(IAccessible
*iface
)
59 Client
*This
= impl_from_Client(iface
);
60 ULONG ref
= InterlockedIncrement(&This
->ref
);
62 TRACE("(%p) ref = %u\n", This
, ref
);
66 static ULONG WINAPI
Client_Release(IAccessible
*iface
)
68 Client
*This
= impl_from_Client(iface
);
69 ULONG ref
= InterlockedDecrement(&This
->ref
);
71 TRACE("(%p) ref = %u\n", This
, ref
);
78 static HRESULT WINAPI
Client_GetTypeInfoCount(IAccessible
*iface
, UINT
*pctinfo
)
80 Client
*This
= impl_from_Client(iface
);
81 FIXME("(%p)->(%p)\n", This
, pctinfo
);
85 static HRESULT WINAPI
Client_GetTypeInfo(IAccessible
*iface
,
86 UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
88 Client
*This
= impl_from_Client(iface
);
89 FIXME("(%p)->(%u %x %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
93 static HRESULT WINAPI
Client_GetIDsOfNames(IAccessible
*iface
, REFIID riid
,
94 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
96 Client
*This
= impl_from_Client(iface
);
97 FIXME("(%p)->(%s %p %u %x %p)\n", This
, debugstr_guid(riid
),
98 rgszNames
, cNames
, lcid
, rgDispId
);
102 static HRESULT WINAPI
Client_Invoke(IAccessible
*iface
, DISPID dispIdMember
,
103 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
104 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
106 Client
*This
= impl_from_Client(iface
);
107 FIXME("(%p)->(%x %s %x %x %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
108 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
112 static HRESULT WINAPI
Client_get_accParent(IAccessible
*iface
, IDispatch
**ppdispParent
)
114 Client
*This
= impl_from_Client(iface
);
116 TRACE("(%p)->(%p)\n", This
, ppdispParent
);
118 return AccessibleObjectFromWindow(This
->hwnd
, OBJID_WINDOW
,
119 &IID_IDispatch
, (void**)ppdispParent
);
122 static HRESULT WINAPI
Client_get_accChildCount(IAccessible
*iface
, LONG
*pcountChildren
)
124 Client
*This
= impl_from_Client(iface
);
127 TRACE("(%p)->(%p)\n", This
, pcountChildren
);
130 for(cur
= GetWindow(This
->hwnd
, GW_CHILD
); cur
; cur
= GetWindow(cur
, GW_HWNDNEXT
))
136 static HRESULT WINAPI
Client_get_accChild(IAccessible
*iface
,
137 VARIANT varChildID
, IDispatch
**ppdispChild
)
139 Client
*This
= impl_from_Client(iface
);
140 FIXME("(%p)->(%s %p)\n", This
, debugstr_variant(&varChildID
), ppdispChild
);
144 static HRESULT WINAPI
Client_get_accName(IAccessible
*iface
, VARIANT varID
, BSTR
*pszName
)
146 Client
*This
= impl_from_Client(iface
);
150 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pszName
);
153 if(convert_child_id(&varID
) != CHILDID_SELF
|| !IsWindow(This
->hwnd
))
156 len
= SendMessageW(This
->hwnd
, WM_GETTEXT
, sizeof(name
)/sizeof(WCHAR
), (LPARAM
)name
);
160 for(i
=0; i
<len
; i
++) {
163 memmove(name
+i
, name
+i
+1, (len
-i
)*sizeof(WCHAR
));
168 *pszName
= SysAllocStringLen(name
, len
);
169 return *pszName
? S_OK
: E_OUTOFMEMORY
;
172 static HRESULT WINAPI
Client_get_accValue(IAccessible
*iface
, VARIANT varID
, BSTR
*pszValue
)
174 Client
*This
= impl_from_Client(iface
);
176 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pszValue
);
179 if(convert_child_id(&varID
) != CHILDID_SELF
)
184 static HRESULT WINAPI
Client_get_accDescription(IAccessible
*iface
,
185 VARIANT varID
, BSTR
*pszDescription
)
187 Client
*This
= impl_from_Client(iface
);
189 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pszDescription
);
191 *pszDescription
= NULL
;
192 if(convert_child_id(&varID
) != CHILDID_SELF
)
197 static HRESULT WINAPI
Client_get_accRole(IAccessible
*iface
, VARIANT varID
, VARIANT
*pvarRole
)
199 Client
*This
= impl_from_Client(iface
);
201 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pvarRole
);
203 if(convert_child_id(&varID
) != CHILDID_SELF
) {
204 V_VT(pvarRole
) = VT_EMPTY
;
208 V_VT(pvarRole
) = VT_I4
;
209 V_I4(pvarRole
) = ROLE_SYSTEM_CLIENT
;
213 static HRESULT WINAPI
Client_get_accState(IAccessible
*iface
, VARIANT varID
, VARIANT
*pvarState
)
215 Client
*This
= impl_from_Client(iface
);
218 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pvarState
);
220 if(convert_child_id(&varID
) != CHILDID_SELF
) {
221 V_VT(pvarState
) = VT_EMPTY
;
225 V_VT(pvarState
) = VT_I4
;
228 style
= GetWindowLongW(This
->hwnd
, GWL_STYLE
);
229 if(style
& WS_DISABLED
)
230 V_I4(pvarState
) |= STATE_SYSTEM_UNAVAILABLE
;
231 else if(IsWindow(This
->hwnd
))
232 V_I4(pvarState
) |= STATE_SYSTEM_FOCUSABLE
;
233 if(GetFocus() == This
->hwnd
)
234 V_I4(pvarState
) |= STATE_SYSTEM_FOCUSED
;
235 if(!(style
& WS_VISIBLE
))
236 V_I4(pvarState
) |= STATE_SYSTEM_INVISIBLE
;
240 static HRESULT WINAPI
Client_get_accHelp(IAccessible
*iface
, VARIANT varID
, BSTR
*pszHelp
)
242 Client
*This
= impl_from_Client(iface
);
244 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pszHelp
);
247 if(convert_child_id(&varID
) != CHILDID_SELF
)
252 static HRESULT WINAPI
Client_get_accHelpTopic(IAccessible
*iface
,
253 BSTR
*pszHelpFile
, VARIANT varID
, LONG
*pidTopic
)
255 Client
*This
= impl_from_Client(iface
);
256 FIXME("(%p)->(%p %s %p)\n", This
, pszHelpFile
, debugstr_variant(&varID
), pidTopic
);
260 static HRESULT WINAPI
Client_get_accKeyboardShortcut(IAccessible
*iface
,
261 VARIANT varID
, BSTR
*pszKeyboardShortcut
)
263 static const WCHAR shortcut_fmt
[] = {'A','l','t','+','!',0};
264 Client
*This
= impl_from_Client(iface
);
268 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pszKeyboardShortcut
);
270 *pszKeyboardShortcut
= NULL
;
271 if(convert_child_id(&varID
) != CHILDID_SELF
)
274 len
= SendMessageW(This
->hwnd
, WM_GETTEXT
, sizeof(name
)/sizeof(WCHAR
), (LPARAM
)name
);
275 for(i
=0; i
<len
; i
++) {
282 *pszKeyboardShortcut
= SysAllocString(shortcut_fmt
);
283 if(!*pszKeyboardShortcut
)
284 return E_OUTOFMEMORY
;
286 (*pszKeyboardShortcut
)[4] = name
[i
+1];
290 static HRESULT WINAPI
Client_get_accFocus(IAccessible
*iface
, VARIANT
*pvarID
)
292 Client
*This
= impl_from_Client(iface
);
293 FIXME("(%p)->(%p)\n", This
, pvarID
);
297 static HRESULT WINAPI
Client_get_accSelection(IAccessible
*iface
, VARIANT
*pvarID
)
299 Client
*This
= impl_from_Client(iface
);
300 FIXME("(%p)->(%p)\n", This
, pvarID
);
304 static HRESULT WINAPI
Client_get_accDefaultAction(IAccessible
*iface
,
305 VARIANT varID
, BSTR
*pszDefaultAction
)
307 Client
*This
= impl_from_Client(iface
);
309 TRACE("(%p)->(%s %p)\n", This
, debugstr_variant(&varID
), pszDefaultAction
);
311 *pszDefaultAction
= NULL
;
312 if(convert_child_id(&varID
) != CHILDID_SELF
)
317 static HRESULT WINAPI
Client_accSelect(IAccessible
*iface
, LONG flagsSelect
, VARIANT varID
)
319 Client
*This
= impl_from_Client(iface
);
320 FIXME("(%p)->(%x %s)\n", This
, flagsSelect
, debugstr_variant(&varID
));
324 static HRESULT WINAPI
Client_accLocation(IAccessible
*iface
, LONG
*pxLeft
,
325 LONG
*pyTop
, LONG
*pcxWidth
, LONG
*pcyHeight
, VARIANT varID
)
327 Client
*This
= impl_from_Client(iface
);
331 TRACE("(%p)->(%p %p %p %p %s)\n", This
, pxLeft
, pyTop
,
332 pcxWidth
, pcyHeight
, debugstr_variant(&varID
));
334 *pxLeft
= *pyTop
= *pcxWidth
= *pcyHeight
= 0;
335 if(convert_child_id(&varID
) != CHILDID_SELF
)
338 if(!GetClientRect(This
->hwnd
, &rect
))
343 MapWindowPoints(This
->hwnd
, NULL
, &pt
, 1);
349 MapWindowPoints(This
->hwnd
, NULL
, &pt
, 1);
350 *pcxWidth
= pt
.x
- *pxLeft
;
351 *pcyHeight
= pt
.y
- *pyTop
;
355 static HRESULT WINAPI
Client_accNavigate(IAccessible
*iface
,
356 LONG navDir
, VARIANT varStart
, VARIANT
*pvarEnd
)
358 Client
*This
= impl_from_Client(iface
);
359 FIXME("(%p)->(%d %s %p)\n", This
, navDir
, debugstr_variant(&varStart
), pvarEnd
);
363 static HRESULT WINAPI
Client_accHitTest(IAccessible
*iface
,
364 LONG xLeft
, LONG yTop
, VARIANT
*pvarID
)
366 Client
*This
= impl_from_Client(iface
);
370 TRACE("(%p)->(%d %d %p)\n", This
, xLeft
, yTop
, pvarID
);
372 V_VT(pvarID
) = VT_I4
;
377 if(!IsWindowVisible(This
->hwnd
) || !ScreenToClient(This
->hwnd
, &pt
))
380 child
= ChildWindowFromPointEx(This
->hwnd
, pt
, CWP_SKIPINVISIBLE
);
381 if(!child
|| child
==This
->hwnd
)
384 V_VT(pvarID
) = VT_DISPATCH
;
385 return AccessibleObjectFromWindow(child
, OBJID_WINDOW
,
386 &IID_IDispatch
, (void**)&V_DISPATCH(pvarID
));
389 static HRESULT WINAPI
Client_accDoDefaultAction(IAccessible
*iface
, VARIANT varID
)
391 Client
*This
= impl_from_Client(iface
);
392 FIXME("(%p)->(%s)\n", This
, debugstr_variant(&varID
));
396 static HRESULT WINAPI
Client_put_accName(IAccessible
*iface
, VARIANT varID
, BSTR pszName
)
398 Client
*This
= impl_from_Client(iface
);
399 FIXME("(%p)->(%s %s)\n", This
, debugstr_variant(&varID
), debugstr_w(pszName
));
403 static HRESULT WINAPI
Client_put_accValue(IAccessible
*iface
, VARIANT varID
, BSTR pszValue
)
405 Client
*This
= impl_from_Client(iface
);
406 FIXME("(%p)->(%s %s)\n", This
, debugstr_variant(&varID
), debugstr_w(pszValue
));
410 static const IAccessibleVtbl ClientVtbl
= {
411 Client_QueryInterface
,
414 Client_GetTypeInfoCount
,
416 Client_GetIDsOfNames
,
418 Client_get_accParent
,
419 Client_get_accChildCount
,
423 Client_get_accDescription
,
427 Client_get_accHelpTopic
,
428 Client_get_accKeyboardShortcut
,
430 Client_get_accSelection
,
431 Client_get_accDefaultAction
,
436 Client_accDoDefaultAction
,
441 static inline Client
* impl_from_Client_OleWindow(IOleWindow
*iface
)
443 return CONTAINING_RECORD(iface
, Client
, IOleWindow_iface
);
446 static HRESULT WINAPI
Client_OleWindow_QueryInterface(IOleWindow
*iface
, REFIID riid
, void **ppv
)
448 Client
*This
= impl_from_Client_OleWindow(iface
);
449 return IAccessible_QueryInterface(&This
->IAccessible_iface
, riid
, ppv
);
452 static ULONG WINAPI
Client_OleWindow_AddRef(IOleWindow
*iface
)
454 Client
*This
= impl_from_Client_OleWindow(iface
);
455 return IAccessible_AddRef(&This
->IAccessible_iface
);
458 static ULONG WINAPI
Client_OleWindow_Release(IOleWindow
*iface
)
460 Client
*This
= impl_from_Client_OleWindow(iface
);
461 return IAccessible_Release(&This
->IAccessible_iface
);
464 static HRESULT WINAPI
Client_OleWindow_GetWindow(IOleWindow
*iface
, HWND
*phwnd
)
466 Client
*This
= impl_from_Client_OleWindow(iface
);
468 TRACE("(%p)->(%p)\n", This
, phwnd
);
474 static HRESULT WINAPI
Client_OleWindow_ContextSensitiveHelp(IOleWindow
*iface
, BOOL fEnterMode
)
476 Client
*This
= impl_from_Client_OleWindow(iface
);
477 FIXME("(%p)->(%x)\n", This
, fEnterMode
);
481 static const IOleWindowVtbl ClientOleWindowVtbl
= {
482 Client_OleWindow_QueryInterface
,
483 Client_OleWindow_AddRef
,
484 Client_OleWindow_Release
,
485 Client_OleWindow_GetWindow
,
486 Client_OleWindow_ContextSensitiveHelp
489 HRESULT
create_client_object(HWND hwnd
, const IID
*iid
, void **obj
)
497 client
= heap_alloc_zero(sizeof(Client
));
499 return E_OUTOFMEMORY
;
501 client
->IAccessible_iface
.lpVtbl
= &ClientVtbl
;
502 client
->IOleWindow_iface
.lpVtbl
= &ClientOleWindowVtbl
;
506 hres
= IAccessible_QueryInterface(&client
->IAccessible_iface
, iid
, obj
);
507 IAccessible_Release(&client
->IAccessible_iface
);