gdi32: Improve EMF DC cleanup when CloseEnhMetafile is not called.
[wine.git] / dlls / oleacc / window.c
blob6a7aa3d0318058e9bb8bf64bd7c28ba0f67a904a
1 /*
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 #define COBJMACROS
21 #include "oleacc_private.h"
22 #include "commctrl.h"
24 #include "wine/debug.h"
25 #include "wine/heap.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(oleacc);
29 typedef struct {
30 IAccessible IAccessible_iface;
31 IOleWindow IOleWindow_iface;
32 IEnumVARIANT IEnumVARIANT_iface;
33 IServiceProvider IServiceProvider_iface;
35 LONG ref;
37 HWND hwnd;
38 } Window;
40 static inline Window* impl_from_Window(IAccessible *iface)
42 return CONTAINING_RECORD(iface, Window, IAccessible_iface);
45 static HRESULT WINAPI Window_QueryInterface(IAccessible *iface, REFIID riid, void **ppv)
47 Window *This = impl_from_Window(iface);
49 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
51 if(IsEqualIID(riid, &IID_IAccessible) ||
52 IsEqualIID(riid, &IID_IDispatch) ||
53 IsEqualIID(riid, &IID_IUnknown)) {
54 *ppv = iface;
55 }else if(IsEqualIID(riid, &IID_IOleWindow)) {
56 *ppv = &This->IOleWindow_iface;
57 }else if(IsEqualIID(riid, &IID_IEnumVARIANT)) {
58 *ppv = &This->IEnumVARIANT_iface;
59 }else if(IsEqualIID(riid, &IID_IServiceProvider)) {
60 *ppv = &This->IServiceProvider_iface;
61 }else {
62 WARN("no interface: %s\n", debugstr_guid(riid));
63 *ppv = NULL;
64 return E_NOINTERFACE;
67 IAccessible_AddRef(iface);
68 return S_OK;
71 static ULONG WINAPI Window_AddRef(IAccessible *iface)
73 Window *This = impl_from_Window(iface);
74 ULONG ref = InterlockedIncrement(&This->ref);
76 TRACE("(%p) ref = %lu\n", This, ref);
77 return ref;
80 static ULONG WINAPI Window_Release(IAccessible *iface)
82 Window *This = impl_from_Window(iface);
83 ULONG ref = InterlockedDecrement(&This->ref);
85 TRACE("(%p) ref = %lu\n", This, ref);
87 if(!ref)
88 heap_free(This);
89 return ref;
92 static HRESULT WINAPI Window_GetTypeInfoCount(IAccessible *iface, UINT *pctinfo)
94 Window *This = impl_from_Window(iface);
95 FIXME("(%p)->(%p)\n", This, pctinfo);
96 return E_NOTIMPL;
99 static HRESULT WINAPI Window_GetTypeInfo(IAccessible *iface,
100 UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
102 Window *This = impl_from_Window(iface);
103 FIXME("(%p)->(%u %lx %p)\n", This, iTInfo, lcid, ppTInfo);
104 return E_NOTIMPL;
107 static HRESULT WINAPI Window_GetIDsOfNames(IAccessible *iface, REFIID riid,
108 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
110 Window *This = impl_from_Window(iface);
111 FIXME("(%p)->(%s %p %u %lx %p)\n", This, debugstr_guid(riid),
112 rgszNames, cNames, lcid, rgDispId);
113 return E_NOTIMPL;
116 static HRESULT WINAPI Window_Invoke(IAccessible *iface, DISPID dispIdMember,
117 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
118 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
120 Window *This = impl_from_Window(iface);
121 FIXME("(%p)->(%lx %s %lx %x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
122 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
123 return E_NOTIMPL;
126 static HRESULT WINAPI Window_get_accParent(IAccessible *iface, IDispatch **ppdispParent)
128 Window *This = impl_from_Window(iface);
129 FIXME("(%p)->(%p)\n", This, ppdispParent);
130 return E_NOTIMPL;
133 static HRESULT WINAPI Window_get_accChildCount(IAccessible *iface, LONG *pcountChildren)
135 Window *This = impl_from_Window(iface);
136 FIXME("(%p)->(%p)\n", This, pcountChildren);
137 return E_NOTIMPL;
140 static HRESULT WINAPI Window_get_accChild(IAccessible *iface,
141 VARIANT varChildID, IDispatch **ppdispChild)
143 Window *This = impl_from_Window(iface);
144 FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varChildID), ppdispChild);
145 return E_NOTIMPL;
148 static HRESULT WINAPI Window_get_accName(IAccessible *iface, VARIANT varID, BSTR *pszName)
150 Window *This = impl_from_Window(iface);
151 FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszName);
152 return E_NOTIMPL;
155 static HRESULT WINAPI Window_get_accValue(IAccessible *iface, VARIANT varID, BSTR *pszValue)
157 Window *This = impl_from_Window(iface);
158 FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszValue);
159 return E_NOTIMPL;
162 static HRESULT WINAPI Window_get_accDescription(IAccessible *iface,
163 VARIANT varID, BSTR *pszDescription)
165 Window *This = impl_from_Window(iface);
166 FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszDescription);
167 return E_NOTIMPL;
170 static HRESULT WINAPI Window_get_accRole(IAccessible *iface, VARIANT varID, VARIANT *pvarRole)
172 Window *This = impl_from_Window(iface);
173 FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pvarRole);
174 return E_NOTIMPL;
177 static HRESULT WINAPI Window_get_accState(IAccessible *iface, VARIANT varID, VARIANT *pvarState)
179 Window *This = impl_from_Window(iface);
180 FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pvarState);
181 return E_NOTIMPL;
184 static HRESULT WINAPI Window_get_accHelp(IAccessible *iface, VARIANT varID, BSTR *pszHelp)
186 Window *This = impl_from_Window(iface);
187 FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszHelp);
188 return E_NOTIMPL;
191 static HRESULT WINAPI Window_get_accHelpTopic(IAccessible *iface,
192 BSTR *pszHelpFile, VARIANT varID, LONG *pidTopic)
194 Window *This = impl_from_Window(iface);
195 FIXME("(%p)->(%p %s %p)\n", This, pszHelpFile, debugstr_variant(&varID), pidTopic);
196 return E_NOTIMPL;
199 static HRESULT WINAPI Window_get_accKeyboardShortcut(IAccessible *iface,
200 VARIANT varID, BSTR *pszKeyboardShortcut)
202 Window *This = impl_from_Window(iface);
203 FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszKeyboardShortcut);
204 return E_NOTIMPL;
207 static HRESULT WINAPI Window_get_accFocus(IAccessible *iface, VARIANT *pvarID)
209 Window *This = impl_from_Window(iface);
210 FIXME("(%p)->(%p)\n", This, pvarID);
211 return E_NOTIMPL;
214 static HRESULT WINAPI Window_get_accSelection(IAccessible *iface, VARIANT *pvarID)
216 Window *This = impl_from_Window(iface);
217 FIXME("(%p)->(%p)\n", This, pvarID);
218 return E_NOTIMPL;
221 static HRESULT WINAPI Window_get_accDefaultAction(IAccessible *iface,
222 VARIANT varID, BSTR *pszDefaultAction)
224 Window *This = impl_from_Window(iface);
225 FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszDefaultAction);
226 return E_NOTIMPL;
229 static HRESULT WINAPI Window_accSelect(IAccessible *iface, LONG flagsSelect, VARIANT varID)
231 Window *This = impl_from_Window(iface);
232 FIXME("(%p)->(%lx %s)\n", This, flagsSelect, debugstr_variant(&varID));
233 return E_NOTIMPL;
236 static HRESULT WINAPI Window_accLocation(IAccessible *iface, LONG *pxLeft,
237 LONG *pyTop, LONG *pcxWidth, LONG *pcyHeight, VARIANT varID)
239 Window *This = impl_from_Window(iface);
240 FIXME("(%p)->(%p %p %p %p %s)\n", This, pxLeft, pyTop,
241 pcxWidth, pcyHeight, debugstr_variant(&varID));
242 return E_NOTIMPL;
245 static HRESULT WINAPI Window_accNavigate(IAccessible *iface,
246 LONG navDir, VARIANT varStart, VARIANT *pvarEnd)
248 Window *This = impl_from_Window(iface);
249 FIXME("(%p)->(%ld %s %p)\n", This, navDir, debugstr_variant(&varStart), pvarEnd);
250 return E_NOTIMPL;
253 static HRESULT WINAPI Window_accHitTest(IAccessible *iface, LONG x, LONG y, VARIANT *v)
255 Window *This = impl_from_Window(iface);
256 IDispatch *disp;
257 POINT pt;
258 HRESULT hr;
259 RECT rect;
261 TRACE("(%p)->(%ld %ld %p)\n", This, x, y, v);
263 V_VT(v) = VT_EMPTY;
264 if (!GetClientRect(This->hwnd, &rect))
265 return E_FAIL;
266 if (!ClientToScreen(This->hwnd, (POINT*)&rect) ||
267 !ClientToScreen(This->hwnd, &((POINT*)&rect)[1]))
268 return E_FAIL;
269 pt.x = x;
270 pt.y = y;
271 if (PtInRect(&rect, pt))
273 hr = AccessibleObjectFromWindow(This->hwnd, OBJID_CLIENT, &IID_IDispatch, (void**)&disp);
274 if (FAILED(hr))
275 return hr;
276 if (!disp)
277 return E_FAIL;
279 V_VT(v) = VT_DISPATCH;
280 V_DISPATCH(v) = disp;
281 return S_OK;
284 FIXME("non-client area not handled yet\n");
285 return E_NOTIMPL;
288 static HRESULT WINAPI Window_accDoDefaultAction(IAccessible *iface, VARIANT varID)
290 Window *This = impl_from_Window(iface);
291 FIXME("(%p)->(%s)\n", This, debugstr_variant(&varID));
292 return E_NOTIMPL;
295 static HRESULT WINAPI Window_put_accName(IAccessible *iface, VARIANT varID, BSTR pszName)
297 Window *This = impl_from_Window(iface);
298 FIXME("(%p)->(%s %s)\n", This, debugstr_variant(&varID), debugstr_w(pszName));
299 return E_NOTIMPL;
302 static HRESULT WINAPI Window_put_accValue(IAccessible *iface, VARIANT varID, BSTR pszValue)
304 Window *This = impl_from_Window(iface);
305 FIXME("(%p)->(%s %s)\n", This, debugstr_variant(&varID), debugstr_w(pszValue));
306 return E_NOTIMPL;
309 static const IAccessibleVtbl WindowVtbl = {
310 Window_QueryInterface,
311 Window_AddRef,
312 Window_Release,
313 Window_GetTypeInfoCount,
314 Window_GetTypeInfo,
315 Window_GetIDsOfNames,
316 Window_Invoke,
317 Window_get_accParent,
318 Window_get_accChildCount,
319 Window_get_accChild,
320 Window_get_accName,
321 Window_get_accValue,
322 Window_get_accDescription,
323 Window_get_accRole,
324 Window_get_accState,
325 Window_get_accHelp,
326 Window_get_accHelpTopic,
327 Window_get_accKeyboardShortcut,
328 Window_get_accFocus,
329 Window_get_accSelection,
330 Window_get_accDefaultAction,
331 Window_accSelect,
332 Window_accLocation,
333 Window_accNavigate,
334 Window_accHitTest,
335 Window_accDoDefaultAction,
336 Window_put_accName,
337 Window_put_accValue
340 static inline Window* impl_from_Window_OleWindow(IOleWindow *iface)
342 return CONTAINING_RECORD(iface, Window, IOleWindow_iface);
345 static HRESULT WINAPI Window_OleWindow_QueryInterface(IOleWindow *iface, REFIID riid, void **ppv)
347 Window *This = impl_from_Window_OleWindow(iface);
348 return IAccessible_QueryInterface(&This->IAccessible_iface, riid, ppv);
351 static ULONG WINAPI Window_OleWindow_AddRef(IOleWindow *iface)
353 Window *This = impl_from_Window_OleWindow(iface);
354 return IAccessible_AddRef(&This->IAccessible_iface);
357 static ULONG WINAPI Window_OleWindow_Release(IOleWindow *iface)
359 Window *This = impl_from_Window_OleWindow(iface);
360 return IAccessible_Release(&This->IAccessible_iface);
363 static HRESULT WINAPI Window_OleWindow_GetWindow(IOleWindow *iface, HWND *hwnd)
365 Window *This = impl_from_Window_OleWindow(iface);
367 TRACE("(%p)->(%p)\n", This, hwnd);
369 *hwnd = This->hwnd;
370 return S_OK;
373 static HRESULT WINAPI Window_OleWindow_ContextSensitiveHelp(IOleWindow *iface, BOOL fEnterMode)
375 Window *This = impl_from_Window_OleWindow(iface);
376 FIXME("(%p)->(%x)\n", This, fEnterMode);
377 return E_NOTIMPL;
380 static const IOleWindowVtbl WindowOleWindowVtbl = {
381 Window_OleWindow_QueryInterface,
382 Window_OleWindow_AddRef,
383 Window_OleWindow_Release,
384 Window_OleWindow_GetWindow,
385 Window_OleWindow_ContextSensitiveHelp
388 static inline Window* impl_from_Window_EnumVARIANT(IEnumVARIANT *iface)
390 return CONTAINING_RECORD(iface, Window, IEnumVARIANT_iface);
393 static HRESULT WINAPI Window_EnumVARIANT_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
395 Window *This = impl_from_Window_EnumVARIANT(iface);
396 return IAccessible_QueryInterface(&This->IAccessible_iface, riid, ppv);
399 static ULONG WINAPI Window_EnumVARIANT_AddRef(IEnumVARIANT *iface)
401 Window *This = impl_from_Window_EnumVARIANT(iface);
402 return IAccessible_AddRef(&This->IAccessible_iface);
405 static ULONG WINAPI Window_EnumVARIANT_Release(IEnumVARIANT *iface)
407 Window *This = impl_from_Window_EnumVARIANT(iface);
408 return IAccessible_Release(&This->IAccessible_iface);
411 static HRESULT WINAPI Window_EnumVARIANT_Next(IEnumVARIANT *iface,
412 ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
414 Window *This = impl_from_Window_EnumVARIANT(iface);
415 FIXME("(%p)->(%lu %p %p)\n", This, celt, rgVar, pCeltFetched);
416 return E_NOTIMPL;
419 static HRESULT WINAPI Window_EnumVARIANT_Skip(IEnumVARIANT *iface, ULONG celt)
421 Window *This = impl_from_Window_EnumVARIANT(iface);
422 FIXME("(%p)->(%lu)\n", This, celt);
423 return E_NOTIMPL;
426 static HRESULT WINAPI Window_EnumVARIANT_Reset(IEnumVARIANT *iface)
428 Window *This = impl_from_Window_EnumVARIANT(iface);
429 FIXME("(%p)\n", This);
430 return E_NOTIMPL;
433 static HRESULT WINAPI Window_EnumVARIANT_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
435 Window *This = impl_from_Window_EnumVARIANT(iface);
436 FIXME("(%p)->(%p)\n", This, ppEnum);
437 return E_NOTIMPL;
440 static const IEnumVARIANTVtbl WindowEnumVARIANTVtbl = {
441 Window_EnumVARIANT_QueryInterface,
442 Window_EnumVARIANT_AddRef,
443 Window_EnumVARIANT_Release,
444 Window_EnumVARIANT_Next,
445 Window_EnumVARIANT_Skip,
446 Window_EnumVARIANT_Reset,
447 Window_EnumVARIANT_Clone
450 static inline Window* impl_from_Window_ServiceProvider(IServiceProvider *iface)
452 return CONTAINING_RECORD(iface, Window, IServiceProvider_iface);
455 static HRESULT WINAPI Window_ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
457 Window *This = impl_from_Window_ServiceProvider(iface);
458 return IAccessible_QueryInterface(&This->IAccessible_iface, riid, ppv);
461 static ULONG WINAPI Window_ServiceProvider_AddRef(IServiceProvider *iface)
463 Window *This = impl_from_Window_ServiceProvider(iface);
464 return IAccessible_AddRef(&This->IAccessible_iface);
467 static ULONG WINAPI Window_ServiceProvider_Release(IServiceProvider *iface)
469 Window *This = impl_from_Window_ServiceProvider(iface);
470 return IAccessible_Release(&This->IAccessible_iface);
473 static HRESULT WINAPI Window_ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guid_service,
474 REFIID riid, void **ppv)
476 Window *This = impl_from_Window_ServiceProvider(iface);
478 TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guid_service), debugstr_guid(riid), ppv);
480 *ppv = NULL;
481 if (IsEqualIID(guid_service, &IIS_IsOleaccProxy))
482 return IAccessible_QueryInterface(&This->IAccessible_iface, riid, ppv);
484 return E_INVALIDARG;
487 static const IServiceProviderVtbl WindowServiceProviderVtbl = {
488 Window_ServiceProvider_QueryInterface,
489 Window_ServiceProvider_AddRef,
490 Window_ServiceProvider_Release,
491 Window_ServiceProvider_QueryService
494 static const struct win_class_data classes[] = {
495 {WC_LISTBOXW, 0x10000, TRUE},
496 {L"#32768", 0x10001, TRUE}, /* menu */
497 {NULL}
500 HRESULT create_window_object(HWND hwnd, const IID *iid, void **obj)
502 Window *window;
503 HRESULT hres;
505 if(!IsWindow(hwnd))
506 return E_FAIL;
508 window = heap_alloc_zero(sizeof(Window));
509 if(!window)
510 return E_OUTOFMEMORY;
512 find_class_data(hwnd, classes);
514 window->IAccessible_iface.lpVtbl = &WindowVtbl;
515 window->IOleWindow_iface.lpVtbl = &WindowOleWindowVtbl;
516 window->IEnumVARIANT_iface.lpVtbl = &WindowEnumVARIANTVtbl;
517 window->IServiceProvider_iface.lpVtbl = &WindowServiceProviderVtbl;
518 window->ref = 1;
519 window->hwnd = hwnd;
521 hres = IAccessible_QueryInterface(&window->IAccessible_iface, iid, obj);
522 IAccessible_Release(&window->IAccessible_iface);
523 return hres;