From da8005c75ecabac85731dd2dd47e80dcf99ed189 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Thu, 1 May 2014 16:13:54 +0200 Subject: [PATCH] oleacc: Add default client accessible object stub. --- dlls/oleacc/Makefile.in | 3 +- dlls/oleacc/client.c | 319 +++++++++++++++++++++++++++++++++++ dlls/oleacc/main.c | 55 +++++- dlls/oleacc/oleacc_private.h | 33 ++++ 4 files changed, 404 insertions(+), 6 deletions(-) create mode 100644 dlls/oleacc/client.c create mode 100644 dlls/oleacc/oleacc_private.h diff --git a/dlls/oleacc/Makefile.in b/dlls/oleacc/Makefile.in index 0fb6eaf1d3..d33f867660 100644 --- a/dlls/oleacc/Makefile.in +++ b/dlls/oleacc/Makefile.in @@ -1,8 +1,9 @@ MODULE = oleacc.dll IMPORTLIB = oleacc -IMPORTS = ole32 user32 +IMPORTS = ole32 user32 uuid C_SRCS = \ + client.c \ main.c IDL_SRCS = oleacc_classes.idl diff --git a/dlls/oleacc/client.c b/dlls/oleacc/client.c new file mode 100644 index 0000000000..e7ff812e29 --- /dev/null +++ b/dlls/oleacc/client.c @@ -0,0 +1,319 @@ +/* + * Copyright 2014 Piotr Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "oleacc_private.h" + +#include "wine/unicode.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(oleacc); + +typedef struct { + IAccessible IAccessible_iface; + + LONG ref; + + HWND hwnd; +} Client; + +static inline Client* impl_from_Client(IAccessible *iface) +{ + return CONTAINING_RECORD(iface, Client, IAccessible_iface); +} + +static HRESULT WINAPI Client_QueryInterface(IAccessible *iface, REFIID riid, void **ppv) +{ + Client *This = impl_from_Client(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); + + if(IsEqualIID(riid, &IID_IAccessible) || + IsEqualIID(riid, &IID_IDispatch) || + IsEqualIID(riid, &IID_IUnknown)) { + *ppv = iface; + IAccessible_AddRef(iface); + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG WINAPI Client_AddRef(IAccessible *iface) +{ + Client *This = impl_from_Client(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref = %u\n", This, ref); + return ref; +} + +static ULONG WINAPI Client_Release(IAccessible *iface) +{ + Client *This = impl_from_Client(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref = %u\n", This, ref); + + if(!ref) + heap_free(This); + return ref; +} + +static HRESULT WINAPI Client_GetTypeInfoCount(IAccessible *iface, UINT *pctinfo) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%p)\n", This, pctinfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_GetTypeInfo(IAccessible *iface, + UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%u %x %p)\n", This, iTInfo, lcid, ppTInfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_GetIDsOfNames(IAccessible *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%s %p %u %x %p)\n", This, debugstr_guid(riid), + rgszNames, cNames, lcid, rgDispId); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_Invoke(IAccessible *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%x %s %x %x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_get_accParent(IAccessible *iface, IDispatch **ppdispParent) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%p)\n", This, ppdispParent); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_get_accChildCount(IAccessible *iface, LONG *pcountChildren) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%p)\n", This, pcountChildren); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_get_accChild(IAccessible *iface, + VARIANT varChildID, IDispatch **ppdispChild) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varChildID), ppdispChild); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_get_accName(IAccessible *iface, VARIANT varID, BSTR *pszName) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszName); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_get_accValue(IAccessible *iface, VARIANT varID, BSTR *pszValue) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszValue); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_get_accDescription(IAccessible *iface, + VARIANT varID, BSTR *pszDescription) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszDescription); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_get_accRole(IAccessible *iface, VARIANT varID, VARIANT *pvarRole) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pvarRole); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_get_accState(IAccessible *iface, VARIANT varID, VARIANT *pvarState) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pvarState); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_get_accHelp(IAccessible *iface, VARIANT varID, BSTR *pszHelp) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszHelp); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_get_accHelpTopic(IAccessible *iface, + BSTR *pszHelpFile, VARIANT varID, LONG *pidTopic) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%p %s %p)\n", This, pszHelpFile, debugstr_variant(&varID), pidTopic); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_get_accKeyboardShortcut(IAccessible *iface, + VARIANT varID, BSTR *pszKeyboardShortcut) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszKeyboardShortcut); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_get_accFocus(IAccessible *iface, VARIANT *pvarID) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%p)\n", This, pvarID); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_get_accSelection(IAccessible *iface, VARIANT *pvarID) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%p)\n", This, pvarID); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_get_accDefaultAction(IAccessible *iface, + VARIANT varID, BSTR *pszDefaultAction) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszDefaultAction); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_accSelect(IAccessible *iface, LONG flagsSelect, VARIANT varID) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%x %s)\n", This, flagsSelect, debugstr_variant(&varID)); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_accLocation(IAccessible *iface, LONG *pxLeft, + LONG *pyTop, LONG *pcxWidth, LONG *pcyHeight, VARIANT varID) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%p %p %p %p %s)\n", This, pxLeft, pyTop, + pcxWidth, pcyHeight, debugstr_variant(&varID)); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_accNavigate(IAccessible *iface, + LONG navDir, VARIANT varStart, VARIANT *pvarEnd) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%d %s %p)\n", This, navDir, debugstr_variant(&varStart), pvarEnd); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_accHitTest(IAccessible *iface, + LONG xLeft, LONG yTop, VARIANT *pvarID) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%d %d %p)\n", This, xLeft, yTop, pvarID); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_accDoDefaultAction(IAccessible *iface, VARIANT varID) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&varID)); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_put_accName(IAccessible *iface, VARIANT varID, BSTR pszName) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%s %s)\n", This, debugstr_variant(&varID), debugstr_w(pszName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI Client_put_accValue(IAccessible *iface, VARIANT varID, BSTR pszValue) +{ + Client *This = impl_from_Client(iface); + FIXME("(%p)->(%s %s)\n", This, debugstr_variant(&varID), debugstr_w(pszValue)); + return E_NOTIMPL; +} + +static const IAccessibleVtbl ClientVtbl = { + Client_QueryInterface, + Client_AddRef, + Client_Release, + Client_GetTypeInfoCount, + Client_GetTypeInfo, + Client_GetIDsOfNames, + Client_Invoke, + Client_get_accParent, + Client_get_accChildCount, + Client_get_accChild, + Client_get_accName, + Client_get_accValue, + Client_get_accDescription, + Client_get_accRole, + Client_get_accState, + Client_get_accHelp, + Client_get_accHelpTopic, + Client_get_accKeyboardShortcut, + Client_get_accFocus, + Client_get_accSelection, + Client_get_accDefaultAction, + Client_accSelect, + Client_accLocation, + Client_accNavigate, + Client_accHitTest, + Client_accDoDefaultAction, + Client_put_accName, + Client_put_accValue +}; + +HRESULT create_client_object(HWND hwnd, const IID *iid, void **obj) +{ + Client *client; + HRESULT hres; + + if(!IsWindow(hwnd)) + return E_FAIL; + + client = heap_alloc_zero(sizeof(Client)); + if(!client) + return E_OUTOFMEMORY; + + client->IAccessible_iface.lpVtbl = &ClientVtbl; + client->ref = 1; + client->hwnd = hwnd; + + hres = IAccessible_QueryInterface(&client->IAccessible_iface, iid, obj); + IAccessible_Release(&client->IAccessible_iface); + return hres; +} diff --git a/dlls/oleacc/main.c b/dlls/oleacc/main.c index c1e2bf82d1..63dfe991c9 100644 --- a/dlls/oleacc/main.c +++ b/dlls/oleacc/main.c @@ -25,7 +25,9 @@ #include "winbase.h" #include "winuser.h" #include "ole2.h" -#include "oleacc.h" + +#include "initguid.h" +#include "oleacc_private.h" #include "wine/unicode.h" #include "wine/debug.h" @@ -36,12 +38,55 @@ static const WCHAR lresult_atom_prefix[] = {'w','i','n','e','_','o','l','e','a', static HINSTANCE oleacc_handle = 0; -HRESULT WINAPI CreateStdAccessibleObject( HWND hwnd, LONG idObject, - REFIID riidInterface, void** ppvObject ) +const char *debugstr_variant(const VARIANT *v) { - FIXME("%p %d %s %p\n", hwnd, idObject, + if(!v) + return "(null)"; + + if(V_ISBYREF(v)) + return wine_dbg_sprintf("{V_BYREF -> %s}", debugstr_variant(V_BYREF(v))); + + switch(V_VT(v)) { + case VT_EMPTY: + return "{VT_EMPTY}"; + case VT_NULL: + return "{VT_NULL}"; + case VT_I2: + return wine_dbg_sprintf("{VT_I2: %d}", V_I2(v)); + case VT_I4: + return wine_dbg_sprintf("{VT_I4: %d}", V_I4(v)); + case VT_UI4: + return wine_dbg_sprintf("{VT_UI4: %u}", V_UI4(v)); + case VT_R8: + return wine_dbg_sprintf("{VT_R8: %lf}", V_R8(v)); + case VT_BSTR: + return wine_dbg_sprintf("{VT_BSTR: %s}", debugstr_w(V_BSTR(v))); + case VT_DISPATCH: + return wine_dbg_sprintf("{VT_DISPATCH: %p}", V_DISPATCH(v)); + case VT_BOOL: + return wine_dbg_sprintf("{VT_BOOL: %x}", V_BOOL(v)); + default: + return wine_dbg_sprintf("{vt %d}", V_VT(v)); + } +} + +HRESULT WINAPI CreateStdAccessibleObject( HWND hwnd, LONG idObject, + REFIID riidInterface, void** ppvObject ) +{ + WCHAR class_name[64]; + + TRACE("%p %d %s %p\n", hwnd, idObject, debugstr_guid( riidInterface ), ppvObject ); - return E_NOTIMPL; + if(GetClassNameW(hwnd, class_name, sizeof(class_name)/sizeof(WCHAR))) + FIXME("unhandled window class: %s\n", debugstr_w(class_name)); + + switch(idObject) { + case OBJID_CLIENT: + return create_client_object(hwnd, riidInterface, ppvObject); + default: + FIXME("unhandled object id: %d\n", idObject); + return E_NOTIMPL; + } } HRESULT WINAPI ObjectFromLresult( LRESULT result, REFIID riid, WPARAM wParam, void **ppObject ) diff --git a/dlls/oleacc/oleacc_private.h b/dlls/oleacc/oleacc_private.h new file mode 100644 index 0000000000..dbb0f8c59e --- /dev/null +++ b/dlls/oleacc/oleacc_private.h @@ -0,0 +1,33 @@ +/* + * Copyright 2014 Piotr Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +HRESULT create_client_object(HWND, const IID*, void**) DECLSPEC_HIDDEN; + +const char *debugstr_variant(const VARIANT*) DECLSPEC_HIDDEN; + +static inline void * __WINE_ALLOC_SIZE(1) heap_alloc_zero(size_t len) +{ + return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); +} + +static inline BOOL heap_free(void *mem) +{ + return HeapFree(GetProcessHeap(), 0, mem); +}