On Wed, Sep 22, 2021 at 07:19:44PM +0200, Piotr Caban wrote:
Hi Connor,
On 9/22/21 6:20 PM, Connor McAdams wrote:
+typedef struct { + HRESULT (*get_state)(IAccessible *, VARIANT, VARIANT *); +} WinClassVtbl; I think it's better to pass Client* as first argument. Please also avoid camel-case in new code.
-static HRESULT WINAPI Client_get_accState(IAccessible *iface, VARIANT varID, VARIANT *pvarState) +static void default_client_get_state(IAccessible *iface, VARIANT *var_state) { Client *This = impl_from_Client(iface); GUITHREADINFO info; LONG style; - TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pvarState); - - if(convert_child_id(&varID) != CHILDID_SELF) { - V_VT(pvarState) = VT_EMPTY; - return E_INVALIDARG; - } - - V_VT(pvarState) = VT_I4; - V_I4(pvarState) = 0; + V_VT(var_state) = VT_I4; + V_I4(var_state) = 0; style = GetWindowLongW(This->hwnd, GWL_STYLE); if(style & WS_DISABLED) - V_I4(pvarState) |= STATE_SYSTEM_UNAVAILABLE; + V_I4(var_state) |= STATE_SYSTEM_UNAVAILABLE; else if(IsWindow(This->hwnd)) - V_I4(pvarState) |= STATE_SYSTEM_FOCUSABLE; + V_I4(var_state) |= STATE_SYSTEM_FOCUSABLE; info.cbSize = sizeof(info); if(GetGUIThreadInfo(0, &info) && info.hwndFocus == This->hwnd) - V_I4(pvarState) |= STATE_SYSTEM_FOCUSED; + V_I4(var_state) |= STATE_SYSTEM_FOCUSED; if(!(style & WS_VISIBLE)) - V_I4(pvarState) |= STATE_SYSTEM_INVISIBLE; + V_I4(var_state) |= STATE_SYSTEM_INVISIBLE; +} + +static HRESULT WINAPI Client_get_accState(IAccessible *iface, VARIANT varID, VARIANT *pvarState) +{ + Client *This = impl_from_Client(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pvarState); + + if (This->vtbl.get_state) + return This->vtbl.get_state(iface, varID, pvarState); + + if(convert_child_id(&varID) != CHILDID_SELF) { + V_VT(pvarState) = VT_EMPTY; + return E_INVALIDARG; + } + + default_client_get_state(iface, pvarState); + return S_OK; } Isn't it enough to call vtbl.get_state near the end of the function? I'm asking about something along these lines (I've also changed get_state header): static HRESULT WINAPI Client_get_accState(IAccessible *iface, VARIANT varID, VARIANT *pvarState) { ... info.cbSize = sizeof(info); if(GetGUIThreadInfo(0, &info) && info.hwndFocus == This->hwnd) V_I4(pvarState) |= STATE_SYSTEM_FOCUSED; if(!(style & WS_VISIBLE)) V_I4(pvarState) |= STATE_SYSTEM_INVISIBLE;
if(This->vtbl.get_state) return This->vtbl.get_state(This, &V_I4(pvarState)) return S_OK; }
Oh, problem with this: Not all classes are restricted to having a varID of CHILDID_SELF for their get_accState implementation. I.e, listbox controls have individual state values for each item in the list. Not having the vtbl function called from the start would break this.