soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
SwndAccessible.cpp
1#include "souistd.h"
2#include <core/SWndAccessible.h>
3#include <atl.mini/SComCli.h>
4
5SNSBEGIN
6#ifdef SOUI_ENABLE_ACC
7#pragma comment(lib, "oleacc.lib")
8
9SAccessible::SAccessible(IWindow *pWnd)
10 : m_pWnd((SWindow *)pWnd)
11{
12}
13
14SAccessible::~SAccessible()
15{
16}
17
18HRESULT SAccessible::get_accParent(IDispatch **ppdispParent)
19{
20 if (!m_pWnd)
21 return CO_E_OBJNOTCONNECTED;
22 if (!m_pWnd->GetParent())
23 {
24 return AccessibleObjectFromWindow(m_pWnd->GetContainer()->GetHostHwnd(), (DWORD)OBJID_WINDOW, IID_IAccessible, (void **)ppdispParent);
25 }
26 SComPtr<IAccessible> pAcc = m_pWnd->GetParent()->GetAccessible();
27 if (!pAcc)
28 return E_NOINTERFACE;
29 return pAcc->QueryInterface(IID_IDispatch, (void **)ppdispParent);
30}
31
32HRESULT SAccessible::get_accChild(VARIANT varChild, IDispatch **ppdispChild)
33{
34 if (!m_pWnd)
35 return CO_E_OBJNOTCONNECTED;
36 if (varChild.vt != VT_I4 || !ppdispChild)
37 return E_INVALIDARG;
38 SWindow *pChild = m_pWnd->GetChild(varChild.lVal);
39 if (!pChild)
40 return E_INVALIDARG;
41 SComPtr<IAccessible> pAcc = pChild->GetAccessible();
42 if (!pAcc)
43 return E_NOINTERFACE;
44 return pAcc->QueryInterface(IID_IDispatch, (void **)ppdispChild);
45}
46
47HRESULT SAccessible::get_accChildCount(long *pcountChildren)
48{
49 if (!m_pWnd)
50 return CO_E_OBJNOTCONNECTED;
51 *pcountChildren = m_pWnd->GetChildrenCount();
52 return S_OK;
53}
54
55HRESULT SAccessible::get_accValue(VARIANT varChild, BSTR *pszValue)
56{
57 if (!m_pWnd)
58 return CO_E_OBJNOTCONNECTED;
59 if (varChild.vt != VT_I4 || !pszValue)
60 return E_INVALIDARG;
61 SWindow *pChild = m_pWnd->GetChild(varChild.lVal);
62 if (!pChild)
63 return E_INVALIDARG;
64 return pChild->GetAccProxy()->get_accValue(pszValue);
65}
66
67HRESULT SAccessible::put_accValue(VARIANT varChild, BSTR szValue)
68{
69 if (!m_pWnd)
70 return CO_E_OBJNOTCONNECTED;
71 if (varChild.vt != VT_I4)
72 return E_INVALIDARG;
73 SWindow *pChild = m_pWnd->GetChild(varChild.lVal);
74 if (!pChild)
75 return E_INVALIDARG;
76 return pChild->GetAccProxy()->put_accValue(szValue);
77}
78
79HRESULT SAccessible::get_accName(VARIANT varChild, BSTR *pszName)
80{
81 if (!m_pWnd)
82 return CO_E_OBJNOTCONNECTED;
83 SASSERT(SWindowMgr::GetWindow(m_pWnd->GetSwnd()) == m_pWnd);
84 if (varChild.vt != VT_I4)
85 return E_INVALIDARG;
86 SWindow *pChild = m_pWnd->GetChild(varChild.lVal);
87 if (!pChild)
88 return E_INVALIDARG;
89 return pChild->GetAccProxy()->get_accName(pszName);
90}
91
92HRESULT SAccessible::put_accName(VARIANT varChild, BSTR szName)
93{
94 if (!m_pWnd)
95 return CO_E_OBJNOTCONNECTED;
96 if (varChild.vt != VT_I4)
97 return E_INVALIDARG;
98 SWindow *pChild = m_pWnd->GetChild(varChild.lVal);
99 if (!pChild)
100 return E_INVALIDARG;
101 return pChild->GetAccProxy()->put_accName(szName);
102}
103
104HRESULT SAccessible::accDoDefaultAction(VARIANT varChild)
105{
106 if (!m_pWnd)
107 return CO_E_OBJNOTCONNECTED;
108 if (varChild.vt != VT_I4)
109 return E_INVALIDARG;
110 SWindow *pChild = m_pWnd->GetChild(varChild.lVal);
111 if (!pChild)
112 return E_INVALIDARG;
113 return pChild->GetAccProxy()->accDoDefaultAction();
114}
115
116HRESULT SAccessible::get_accDefaultAction(VARIANT varChild, BSTR *pszDefaultAction)
117{
118 if (!m_pWnd)
119 return CO_E_OBJNOTCONNECTED;
120 if (varChild.vt != VT_I4)
121 return E_INVALIDARG;
122 SWindow *pChild = m_pWnd->GetChild(varChild.lVal);
123 if (!pChild)
124 return E_INVALIDARG;
125 return pChild->GetAccProxy()->get_accDefaultAction(pszDefaultAction);
126}
127
128HRESULT SAccessible::accHitTest(long xLeft, long yTop, VARIANT *pvarChild)
129{
130 if (!m_pWnd)
131 return CO_E_OBJNOTCONNECTED;
132 if (!pvarChild)
133 return E_INVALIDARG;
134 CPoint pt(xLeft, yTop);
135 ScreenToClient(m_pWnd->GetContainer()->GetHostHwnd(), &pt);
136 m_pWnd->TransformPointEx(pt);
137 SWindow *pChild = m_pWnd->GetWindow(GSW_LASTCHILD);
138 while (pChild)
139 {
140 CPoint pt2 = pt;
141 pChild->TransformPoint(pt2);
142 if (pChild->IsVisible(TRUE) && pChild->IsContainPoint(pt2, FALSE))
143 break;
144 pChild = pChild->GetWindow(GSW_PREVSIBLING);
145 }
146 if (!pChild)
147 {
148 pvarChild->vt = VT_I4;
149 pvarChild->lVal = CHILDID_SELF;
150 }
151 else
152 {
153 pvarChild->vt = VT_DISPATCH;
154 pChild->GetAccessible()->QueryInterface(IID_IDispatch, (void **)&pvarChild->pdispVal);
155 }
156 return S_OK;
157}
158
159// --------------------------------------------------------------------------
160//
161// ValidateChild()
162//
163// The window children are the OBJID_s of the elements that compose the
164// frame. These are NEGATIVE values. Hence we override the validation.
165//
166// --------------------------------------------------------------------------
167BOOL SAccessible::accValidateNavStart(VARIANT *pvar) const
168{
169 //
170 // This validates a VARIANT parameter and translates missing/empty
171 // params.
172 //
173
174TryAgain:
175 // Missing parameter, a la VBA
176 switch (pvar->vt)
177 {
178 case VT_VARIANT | VT_BYREF:
179 VariantCopy(pvar, pvar->pvarVal);
180 goto TryAgain;
181
182 case VT_ERROR:
183 if (pvar->scode != DISP_E_PARAMNOTFOUND)
184 return (FALSE);
185 // FALL THRU
186
187 case VT_EMPTY:
188 pvar->vt = VT_I4;
189 pvar->lVal = 0;
190 break;
191 case VT_I4:
192 if ((pvar->lVal < 0) || (pvar->lVal > (LONG)m_pWnd->GetChildrenCount()))
193 return (FALSE);
194 break;
195
196 case VT_DISPATCH:
197 return TRUE;
198 default:
199 return (FALSE);
200 }
201
202 return (TRUE);
203}
204
205HRESULT SAccessible::accNavigate(long navDir, VARIANT varStart, VARIANT *pvarEndUpAt)
206{
207 if (!m_pWnd)
208 return CO_E_OBJNOTCONNECTED;
209 HRESULT hr = E_INVALIDARG;
210 pvarEndUpAt->vt = VT_EMPTY;
211 if (!accValidateNavStart(&varStart))
212 return hr;
213 switch (navDir)
214 {
215 case NAVDIR_FIRSTCHILD:
216 if (m_pWnd->GetChildrenCount() == 0)
217 break;
218 if ((varStart.vt == VT_DISPATCH && varStart.pdispVal == NULL) || (varStart.vt == VT_I4 && varStart.lVal == CHILDID_SELF))
219 {
220 pvarEndUpAt->vt = VT_I4;
221 pvarEndUpAt->lVal = 1;
222 }
223 hr = S_OK;
224 break;
225 case NAVDIR_LASTCHILD:
226 if (m_pWnd->GetChildrenCount() == 0)
227 break;
228 if ((varStart.vt == VT_DISPATCH && varStart.pdispVal == NULL) || (varStart.vt == VT_I4 && varStart.lVal == CHILDID_SELF))
229 {
230 pvarEndUpAt->vt = VT_I4;
231 pvarEndUpAt->lVal = m_pWnd->GetChildrenCount();
232 }
233 hr = S_OK;
234 break;
235 case NAVDIR_DOWN:
236 case NAVDIR_RIGHT:
237 case NAVDIR_NEXT:
238 if (varStart.vt == VT_DISPATCH)
239 {
240 SAccessible *pAcc = varStart.pdispVal ? (SAccessible *)varStart.pdispVal : this;
241 SWindow *pNext = pAcc->m_pWnd->GetWindow(GSW_NEXTSIBLING);
242 if (pNext)
243 {
244 SComPtr<IAccessible> pAcc = pNext->GetAccessible();
245 if (pAcc)
246 {
247 pvarEndUpAt->vt = VT_DISPATCH;
248 pAcc->QueryInterface(IID_IDispatch, (void **)pvarEndUpAt->pdispVal);
249 }
250 }
251 hr = S_OK;
252 }
253 else if (varStart.vt == VT_I4)
254 {
255 if (m_pWnd->GetChildrenCount() == 0)
256 break;
257 pvarEndUpAt->vt = VT_I4;
258 pvarEndUpAt->lVal = varStart.lVal + 1;
259 if (pvarEndUpAt->lVal > (int)m_pWnd->GetChildrenCount())
260 pvarEndUpAt->lVal = 1;
261 hr = S_OK;
262 }
263 break;
264 case NAVDIR_UP:
265 case NAVDIR_LEFT:
266 case NAVDIR_PREVIOUS:
267 if (varStart.vt == VT_DISPATCH)
268 {
269 SAccessible *pAcc = varStart.pdispVal ? (SAccessible *)varStart.pdispVal : this;
270 SWindow *pNext = pAcc->m_pWnd->GetWindow(GSW_PREVSIBLING);
271 if (pNext)
272 {
273 SComPtr<IAccessible> pAcc = pNext->GetAccessible();
274 if (pAcc)
275 {
276 pvarEndUpAt->vt = VT_DISPATCH;
277 pAcc->QueryInterface(IID_IDispatch, (void **)pvarEndUpAt->pdispVal);
278 }
279 }
280 hr = S_OK;
281 }
282 else if (varStart.vt == VT_I4)
283 {
284 if (m_pWnd->GetChildrenCount() == 0)
285 break;
286 pvarEndUpAt->vt = VT_I4;
287 pvarEndUpAt->lVal = varStart.lVal - 1;
288 if (pvarEndUpAt->lVal < 1)
289 pvarEndUpAt->lVal = m_pWnd->GetChildrenCount();
290 hr = S_OK;
291 }
292 break;
293 }
294 return hr;
295}
296
297HRESULT SAccessible::accLocation(long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varChild)
298{
299 if (!m_pWnd)
300 return CO_E_OBJNOTCONNECTED;
301 if (!(varChild.vt == VT_I4 && pxLeft && pyTop && pcxWidth && pcyHeight))
302 return E_INVALIDARG;
303 SWindow *pChild = m_pWnd->GetChild(varChild.lVal);
304 if (!pChild)
305 return E_INVALIDARG;
306
307 CRect rc = pChild->GetWindowRect();
308 CPoint pt = rc.TopLeft();
309 ClientToScreen(m_pWnd->GetContainer()->GetHostHwnd(), &pt);
310 *pxLeft = pt.x;
311 *pyTop = pt.y;
312 *pcxWidth = rc.Width();
313 *pcyHeight = rc.Height();
314 return S_OK;
315}
316
317HRESULT SAccessible::accSelect(long flagsSelect, VARIANT varChild)
318{
319 if (!m_pWnd)
320 return CO_E_OBJNOTCONNECTED;
321 if (varChild.vt != VT_I4)
322 return E_INVALIDARG;
323 SWindow *pChild = m_pWnd->GetChild(varChild.lVal);
324 if (!pChild)
325 return E_INVALIDARG;
326
327 return pChild->GetAccProxy()->accSelect(flagsSelect);
328}
329
330HRESULT SAccessible::get_accSelection(VARIANT *pvarChildren)
331{
332 return E_NOTIMPL;
333}
334
335HRESULT SAccessible::get_accFocus(VARIANT *pvarChild)
336{
337 if (!m_pWnd)
338 return CO_E_OBJNOTCONNECTED;
339 HWND hFocused = ::GetFocus();
340 if (hFocused == m_pWnd->GetContainer()->GetHostHwnd())
341 {
342 SWND hFocus = m_pWnd->GetContainer()->GetFocus();
343 SWindow *pFocus = SWindowMgr::GetWindow(hFocus);
344 if (pFocus)
345 {
346 if (pFocus == m_pWnd)
347 {
348 pvarChild->vt = VT_I4;
349 pvarChild->lVal = CHILDID_SELF;
350 }
351 else if (pFocus->GetParent() == m_pWnd)
352 {
353 int iChild = 0;
354 SWindow *pChild = pFocus;
355 while (pChild)
356 {
357 iChild++;
358 pChild = pChild->GetWindow(GSW_PREVSIBLING);
359 }
360 pvarChild->vt = VT_I4;
361 pvarChild->lVal = iChild;
362 }
363 else
364 {
365 pvarChild->vt = VT_DISPATCH;
366 pFocus->GetAccessible()->QueryInterface(IID_IDispatch, (void **)&pvarChild->pdispVal);
367 }
368 return S_OK;
369 }
370 else
371 {
372 return S_FALSE;
373 }
374 }
375 else
376 {
377 pvarChild->vt = VT_DISPATCH;
378 return AccessibleObjectFromWindow(hFocused, OBJID_WINDOW, IID_IAccessible, (void **)&pvarChild->pdispVal);
379 }
380}
381
382HRESULT SAccessible::get_accState(VARIANT varChild, VARIANT *pvarState)
383{
384 if (!m_pWnd)
385 return CO_E_OBJNOTCONNECTED;
386 if (varChild.vt != VT_I4)
387 return E_INVALIDARG;
388 SWindow *pChild = m_pWnd->GetChild(varChild.lVal);
389 if (!pChild)
390 return E_INVALIDARG;
391
392 return pChild->GetAccProxy()->get_accState(pvarState);
393}
394
395STDMETHODIMP SAccessible::get_accHelp(VARIANT varChild, BSTR *pszHelp)
396{
397 if (!m_pWnd)
398 return CO_E_OBJNOTCONNECTED;
399 if (varChild.vt != VT_I4)
400 return E_INVALIDARG;
401 SWindow *pChild = m_pWnd->GetChild(varChild.lVal);
402 if (!pChild)
403 return E_INVALIDARG;
404
405 return pChild->GetAccProxy()->get_accHelp(pszHelp);
406}
407
408STDMETHODIMP SAccessible::get_accHelpTopic(BSTR *pszHelpFile, VARIANT varChild, long *pidTopic)
409{
410 if (varChild.vt != VT_I4)
411 return E_INVALIDARG;
412 SWindow *pChild = m_pWnd->GetChild(varChild.lVal);
413 if (!pChild)
414 return E_INVALIDARG;
415
416 return pChild->GetAccProxy()->get_accHelpTopic(pszHelpFile, pidTopic);
417}
418
419STDMETHODIMP SAccessible::get_accKeyboardShortcut(VARIANT varChild, BSTR *pszKeyboardShortcut)
420{
421 if (!m_pWnd)
422 return CO_E_OBJNOTCONNECTED;
423 if (varChild.vt != VT_I4)
424 return E_INVALIDARG;
425 SWindow *pChild = m_pWnd->GetChild(varChild.lVal);
426 if (!pChild)
427 return E_INVALIDARG;
428
429 return pChild->GetAccProxy()->get_accKeyboardShortcut(pszKeyboardShortcut);
430}
431
432HRESULT SAccessible::get_accRole(VARIANT varChild, VARIANT *pvarRole)
433{
434 if (!m_pWnd)
435 return CO_E_OBJNOTCONNECTED;
436 if (varChild.vt != VT_I4)
437 return E_INVALIDARG;
438 SWindow *pChild = m_pWnd->GetChild(varChild.lVal);
439 if (!pChild)
440 return E_INVALIDARG;
441 IAccProxy *pAccProxy = pChild->GetAccProxy();
442 return pAccProxy->get_accRole(pvarRole);
443}
444
445HRESULT SAccessible::get_accDescription(VARIANT varChild, BSTR *pszDescription)
446{
447 if (!m_pWnd)
448 return CO_E_OBJNOTCONNECTED;
449 if (varChild.vt != VT_I4)
450 return E_INVALIDARG;
451 SWindow *pChild = m_pWnd->GetChild(varChild.lVal);
452 if (!pChild)
453 return E_INVALIDARG;
454 return pChild->GetAccProxy()->get_accDescription(pszDescription);
455}
456
457// Implement IDispatch
458STDMETHODIMP SAccessible::GetTypeInfoCount(unsigned int *pctinfo)
459{
460 return E_NOTIMPL;
461}
462
463STDMETHODIMP SAccessible::GetTypeInfo(unsigned int iTInfo, LCID lcid, ITypeInfo **ppTInfo)
464{
465 return E_NOTIMPL;
466}
467
468STDMETHODIMP SAccessible::GetIDsOfNames(REFIID riid, OLECHAR **rgszNames, unsigned int cNames, LCID lcid, DISPID *rgDispId)
469{
470 return E_NOTIMPL;
471}
472
473STDMETHODIMP SAccessible::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, unsigned int *puArgErr)
474{
475 return E_NOTIMPL;
476}
477
478#endif
479// SOUI_ENABLE_ACC
480SNSEND
@ GSW_LASTCHILD
Definition SWnd.h:196
@ GSW_PREVSIBLING
Definition SWnd.h:197
@ GSW_NEXTSIBLING
Definition SWnd.h:198
Base class for SOUI DUI windows.
Definition SWnd.h:286
SWindow * GetParent() const
Retrieves the parent window.
Definition Swnd.cpp:3488
HRESULT QueryInterface(REFGUID id, IObjRef **ppRet) OVERRIDE
Queries an interface.
Definition Swnd.cpp:3572
SWindow * GetChild(int iChild) const
Retrieves a child window by index.
Definition Swnd.cpp:3483
IAccProxy * GetAccProxy()
Retrieves the accessibility proxy for the window.
Definition Swnd.cpp:3321
BOOL IsVisible(BOOL bCheckParent=FALSE) SCONST OVERRIDE
Checks if the window is visible.
Definition Swnd.cpp:646
BOOL IsContainPoint(POINT pt, BOOL bClientOnly) SCONST OVERRIDE
Checks if the window contains a specified point.
Definition Swnd.cpp:3100
SWindow * GetWindow(int uCode) const
Retrieves a window based on a given code.
Definition Swnd.cpp:3456
void TransformPoint(CPoint &pt) const
Transforms a point based on the current window's transformation matrix.
Definition Swnd.cpp:1377
void GetWindowRect(LPRECT prect) SCONST OVERRIDE
Retrieves the bounding rectangle of the window.
static SWindow * GetWindow(SWND swnd)
Retrieves the SWindow pointer from a given handle.