mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
[MSUTB] Add CTipbarAccessible (#6417)
Supporting Language Bar... JIRA issue: CORE-19363 - Implement CTipbarAccessible class. - Add delay link to oleacc.dll.
This commit is contained in:
parent
b50dfbcee4
commit
c0020b6821
3 changed files with 621 additions and 14 deletions
|
@ -15,5 +15,5 @@ set_module_type(msutb win32dll)
|
|||
add_dependencies(msutb msctf psdk)
|
||||
target_link_libraries(msutb wine uuid atl_classes)
|
||||
add_importlibs(msutb user32 gdi32 advapi32 msvcrt kernel32 ntdll)
|
||||
add_delay_importlibs(msutb comctl32 msctf ole32 oleaut32 shell32)
|
||||
add_delay_importlibs(msutb comctl32 msctf ole32 oleacc oleaut32 shell32)
|
||||
add_cd_file(TARGET msutb DESTINATION reactos/system32 FOR all)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* PROJECT: ReactOS msutb.dll
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Language Bar (Tipbar)
|
||||
* COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||
* COPYRIGHT: Copyright 2023-2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
@ -14,6 +14,7 @@ UINT g_wmTaskbarCreated = 0;
|
|||
UINT g_uACP = CP_ACP;
|
||||
DWORD g_dwOSInfo = 0;
|
||||
CRITICAL_SECTION g_cs;
|
||||
LONG g_DllRefCount = 0;
|
||||
|
||||
EXTERN_C void __cxa_pure_virtual(void)
|
||||
{
|
||||
|
@ -31,12 +32,13 @@ END_OBJECT_MAP()
|
|||
CMsUtbModule gModule;
|
||||
|
||||
class CCicLibMenuItem;
|
||||
class CTipbarAccItem;
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
class CCicLibMenu : public ITfMenu
|
||||
{
|
||||
public:
|
||||
protected:
|
||||
CicArray<CCicLibMenuItem*> m_MenuItems;
|
||||
LONG m_cRefs;
|
||||
|
||||
|
@ -63,7 +65,7 @@ public:
|
|||
|
||||
class CCicLibMenuItem
|
||||
{
|
||||
public:
|
||||
protected:
|
||||
DWORD m_uId;
|
||||
DWORD m_dwFlags;
|
||||
HBITMAP m_hbmp;
|
||||
|
@ -88,6 +90,92 @@ public:
|
|||
|
||||
/***********************************************************************/
|
||||
|
||||
class CTipbarAccessible : public IAccessible
|
||||
{
|
||||
protected:
|
||||
LONG m_cRefs;
|
||||
HWND m_hWnd;
|
||||
IAccessible *m_pStdAccessible;
|
||||
ITypeInfo *m_pTypeInfo;
|
||||
BOOL m_bInitialized;
|
||||
CicArray<CTipbarAccItem*> m_AccItems;
|
||||
LONG m_cSelection;
|
||||
|
||||
public:
|
||||
CTipbarAccessible(CTipbarAccItem *pItem);
|
||||
virtual ~CTipbarAccessible();
|
||||
|
||||
HRESULT Initialize();
|
||||
|
||||
BOOL AddAccItem(CTipbarAccItem *pItem);
|
||||
HRESULT RemoveAccItem(CTipbarAccItem *pItem);
|
||||
void ClearAccItems();
|
||||
CTipbarAccItem *AccItemFromID(INT iItem);
|
||||
INT GetIDOfItem(CTipbarAccItem *pTarget);
|
||||
|
||||
LONG_PTR CreateRefToAccObj(WPARAM wParam);
|
||||
BOOL DoDefaultActionReal(INT nID);
|
||||
void NotifyWinEvent(DWORD event, CTipbarAccItem *pItem);
|
||||
void SetWindow(HWND hWnd);
|
||||
|
||||
// IUnknown methods
|
||||
STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject);
|
||||
STDMETHOD_(ULONG, AddRef)();
|
||||
STDMETHOD_(ULONG, Release)();
|
||||
|
||||
// IDispatch methods
|
||||
STDMETHOD(GetTypeInfoCount)(UINT *pctinfo);
|
||||
STDMETHOD(GetTypeInfo)(
|
||||
UINT iTInfo,
|
||||
LCID lcid,
|
||||
ITypeInfo **ppTInfo);
|
||||
STDMETHOD(GetIDsOfNames)(
|
||||
REFIID riid,
|
||||
LPOLESTR *rgszNames,
|
||||
UINT cNames,
|
||||
LCID lcid,
|
||||
DISPID *rgDispId);
|
||||
STDMETHOD(Invoke)(
|
||||
DISPID dispIdMember,
|
||||
REFIID riid,
|
||||
LCID lcid,
|
||||
WORD wFlags,
|
||||
DISPPARAMS *pDispParams,
|
||||
VARIANT *pVarResult,
|
||||
EXCEPINFO *pExcepInfo,
|
||||
UINT *puArgErr);
|
||||
|
||||
// IAccessible methods
|
||||
STDMETHOD(get_accParent)(IDispatch **ppdispParent);
|
||||
STDMETHOD(get_accChildCount)(LONG *pcountChildren);
|
||||
STDMETHOD(get_accChild)(VARIANT varChildID, IDispatch **ppdispChild);
|
||||
STDMETHOD(get_accName)(VARIANT varID, BSTR *pszName);
|
||||
STDMETHOD(get_accValue)(VARIANT varID, BSTR *pszValue);
|
||||
STDMETHOD(get_accDescription)(VARIANT varID, BSTR *description);
|
||||
STDMETHOD(get_accRole)(VARIANT varID, VARIANT *role);
|
||||
STDMETHOD(get_accState)(VARIANT varID, VARIANT *state);
|
||||
STDMETHOD(get_accHelp)(VARIANT varID, BSTR *help);
|
||||
STDMETHOD(get_accHelpTopic)(BSTR *helpfile, VARIANT varID, LONG *pidTopic);
|
||||
STDMETHOD(get_accKeyboardShortcut)(VARIANT varID, BSTR *shortcut);
|
||||
STDMETHOD(get_accFocus)(VARIANT *pvarID);
|
||||
STDMETHOD(get_accSelection)(VARIANT *pvarID);
|
||||
STDMETHOD(get_accDefaultAction)(VARIANT varID, BSTR *action);
|
||||
STDMETHOD(accSelect)(LONG flagsSelect, VARIANT varID);
|
||||
STDMETHOD(accLocation)(
|
||||
LONG *left,
|
||||
LONG *top,
|
||||
LONG *width,
|
||||
LONG *height,
|
||||
VARIANT varID);
|
||||
STDMETHOD(accNavigate)(LONG dir, VARIANT varStart, VARIANT *pvarEnd);
|
||||
STDMETHOD(accHitTest)(LONG left, LONG top, VARIANT *pvarID);
|
||||
STDMETHOD(accDoDefaultAction)(VARIANT varID);
|
||||
STDMETHOD(put_accName)(VARIANT varID, BSTR name);
|
||||
STDMETHOD(put_accValue)(VARIANT varID, BSTR value);
|
||||
};
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
class CTipbarAccItem
|
||||
{
|
||||
public:
|
||||
|
@ -98,9 +186,9 @@ public:
|
|||
{
|
||||
return SysAllocString(L"");
|
||||
}
|
||||
STDMETHOD(UnknownMethod1)() // FIXME: Name
|
||||
STDMETHOD_(BSTR, GetAccValue)()
|
||||
{
|
||||
return S_OK;
|
||||
return NULL;
|
||||
}
|
||||
STDMETHOD_(INT, GetAccRole)()
|
||||
{
|
||||
|
@ -114,17 +202,17 @@ public:
|
|||
{
|
||||
*lprc = { 0, 0, 0, 0 };
|
||||
}
|
||||
STDMETHOD(UnknownMethod2)() // FIXME: Name
|
||||
STDMETHOD_(BSTR, GetAccDefaultAction)()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
STDMETHOD(DoAccDefaultAction)()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHOD(UnknownMethod3)() // FIXME: Name
|
||||
STDMETHOD_(BOOL, DoAccDefaultActionReal)()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHOD(UnknownMethod4)() // FIXME: Name
|
||||
{
|
||||
return S_OK;
|
||||
return FALSE;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -361,6 +449,524 @@ HBITMAP CCicLibMenuItem::CreateBitmap(HANDLE hBitmap)
|
|||
return hbmMem;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CTipbarAccessible
|
||||
*/
|
||||
|
||||
CTipbarAccessible::CTipbarAccessible(CTipbarAccItem *pItem)
|
||||
{
|
||||
m_cRefs = 1;
|
||||
m_hWnd = NULL;
|
||||
m_pTypeInfo = NULL;
|
||||
m_pStdAccessible = NULL;
|
||||
m_bInitialized = FALSE;
|
||||
m_cSelection = 1;
|
||||
m_AccItems.Add(pItem);
|
||||
++g_DllRefCount;
|
||||
}
|
||||
|
||||
CTipbarAccessible::~CTipbarAccessible()
|
||||
{
|
||||
m_pTypeInfo = m_pTypeInfo;
|
||||
if (m_pTypeInfo)
|
||||
{
|
||||
m_pTypeInfo->Release();
|
||||
m_pTypeInfo = NULL;
|
||||
}
|
||||
if (m_pStdAccessible)
|
||||
{
|
||||
m_pStdAccessible->Release();
|
||||
m_pStdAccessible = NULL;
|
||||
}
|
||||
--g_DllRefCount;
|
||||
}
|
||||
|
||||
HRESULT CTipbarAccessible::Initialize()
|
||||
{
|
||||
m_bInitialized = TRUE;
|
||||
|
||||
HRESULT hr = ::CreateStdAccessibleObject(m_hWnd, OBJID_CLIENT, IID_IAccessible,
|
||||
(void **)&m_pStdAccessible);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
ITypeLib *pTypeLib;
|
||||
hr = ::LoadRegTypeLib(LIBID_Accessibility, 1, 0, 0, &pTypeLib);
|
||||
if (FAILED(hr))
|
||||
hr = ::LoadTypeLib(L"OLEACC.DLL", &pTypeLib);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = pTypeLib->GetTypeInfoOfGuid(IID_IAccessible, &m_pTypeInfo);
|
||||
pTypeLib->Release();
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
BOOL CTipbarAccessible::AddAccItem(CTipbarAccItem *pItem)
|
||||
{
|
||||
return m_AccItems.Add(pItem);
|
||||
}
|
||||
|
||||
HRESULT CTipbarAccessible::RemoveAccItem(CTipbarAccItem *pItem)
|
||||
{
|
||||
for (size_t iItem = 0; iItem < m_AccItems.size(); ++iItem)
|
||||
{
|
||||
if (m_AccItems[iItem] == pItem)
|
||||
{
|
||||
m_AccItems.Remove(iItem, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CTipbarAccessible::ClearAccItems()
|
||||
{
|
||||
m_AccItems.clear();
|
||||
}
|
||||
|
||||
CTipbarAccItem *CTipbarAccessible::AccItemFromID(INT iItem)
|
||||
{
|
||||
if (iItem < 0 || (INT)m_AccItems.size() <= iItem)
|
||||
return NULL;
|
||||
return m_AccItems[iItem];
|
||||
}
|
||||
|
||||
INT CTipbarAccessible::GetIDOfItem(CTipbarAccItem *pTarget)
|
||||
{
|
||||
for (size_t iItem = 0; iItem < m_AccItems.size(); ++iItem)
|
||||
{
|
||||
if (pTarget == m_AccItems[iItem])
|
||||
return (INT)iItem;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
LONG_PTR CTipbarAccessible::CreateRefToAccObj(WPARAM wParam)
|
||||
{
|
||||
return ::LresultFromObject(IID_IAccessible, wParam, this);
|
||||
}
|
||||
|
||||
BOOL CTipbarAccessible::DoDefaultActionReal(INT nID)
|
||||
{
|
||||
CTipbarAccItem *pItem = AccItemFromID(nID);
|
||||
if (!pItem)
|
||||
return FALSE;
|
||||
return pItem->DoAccDefaultActionReal();
|
||||
}
|
||||
|
||||
void CTipbarAccessible::NotifyWinEvent(DWORD event, CTipbarAccItem *pItem)
|
||||
{
|
||||
INT nID = GetIDOfItem(pItem);
|
||||
if (nID < 0)
|
||||
return;
|
||||
|
||||
::NotifyWinEvent(event, m_hWnd, -4, nID);
|
||||
}
|
||||
|
||||
void CTipbarAccessible::SetWindow(HWND hWnd)
|
||||
{
|
||||
m_hWnd = hWnd;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::QueryInterface(
|
||||
REFIID riid,
|
||||
void **ppvObject)
|
||||
{
|
||||
if (IsEqualIID(riid, IID_IUnknown) ||
|
||||
IsEqualIID(riid, IID_IDispatch) ||
|
||||
IsEqualIID(riid, IID_IAccessible))
|
||||
{
|
||||
*ppvObject = this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) CTipbarAccessible::AddRef()
|
||||
{
|
||||
return ::InterlockedIncrement(&m_cRefs);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) CTipbarAccessible::Release()
|
||||
{
|
||||
LONG count = ::InterlockedDecrement(&m_cRefs);
|
||||
if (count == 0)
|
||||
{
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::GetTypeInfoCount(UINT *pctinfo)
|
||||
{
|
||||
if (!pctinfo)
|
||||
return E_INVALIDARG;
|
||||
*pctinfo = (m_pTypeInfo == NULL);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::GetTypeInfo(
|
||||
UINT iTInfo,
|
||||
LCID lcid,
|
||||
ITypeInfo **ppTInfo)
|
||||
{
|
||||
if (!ppTInfo)
|
||||
return E_INVALIDARG;
|
||||
*ppTInfo = NULL;
|
||||
if (iTInfo != 0)
|
||||
return TYPE_E_ELEMENTNOTFOUND;
|
||||
if (!m_pTypeInfo)
|
||||
return E_NOTIMPL;
|
||||
*ppTInfo = m_pTypeInfo;
|
||||
m_pTypeInfo->AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::GetIDsOfNames(
|
||||
REFIID riid,
|
||||
LPOLESTR *rgszNames,
|
||||
UINT cNames,
|
||||
LCID lcid,
|
||||
DISPID *rgDispId)
|
||||
{
|
||||
if (!m_pTypeInfo)
|
||||
return E_NOTIMPL;
|
||||
return m_pTypeInfo->GetIDsOfNames(rgszNames, cNames, rgDispId);
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::Invoke(
|
||||
DISPID dispIdMember,
|
||||
REFIID riid,
|
||||
LCID lcid,
|
||||
WORD wFlags,
|
||||
DISPPARAMS *pDispParams,
|
||||
VARIANT *pVarResult,
|
||||
EXCEPINFO *pExcepInfo,
|
||||
UINT *puArgErr)
|
||||
{
|
||||
if (!m_pTypeInfo)
|
||||
return E_NOTIMPL;
|
||||
return m_pTypeInfo->Invoke(this,
|
||||
dispIdMember,
|
||||
wFlags,
|
||||
pDispParams,
|
||||
pVarResult,
|
||||
pExcepInfo,
|
||||
puArgErr);
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::get_accParent(IDispatch **ppdispParent)
|
||||
{
|
||||
return m_pStdAccessible->get_accParent(ppdispParent);
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::get_accChildCount(LONG *pcountChildren)
|
||||
{
|
||||
if (!pcountChildren)
|
||||
return E_INVALIDARG;
|
||||
INT cItems = (INT)m_AccItems.size();
|
||||
if (!cItems)
|
||||
return E_FAIL;
|
||||
*pcountChildren = cItems - 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::get_accChild(
|
||||
VARIANT varChildID,
|
||||
IDispatch **ppdispChild)
|
||||
{
|
||||
if (!ppdispChild)
|
||||
return E_INVALIDARG;
|
||||
*ppdispChild = NULL;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::get_accName(
|
||||
VARIANT varID,
|
||||
BSTR *pszName)
|
||||
{
|
||||
if (!pszName)
|
||||
return E_INVALIDARG;
|
||||
CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID));
|
||||
if (!pItem)
|
||||
return E_INVALIDARG;
|
||||
*pszName = pItem->GetAccName();
|
||||
if (!*pszName)
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::get_accValue(
|
||||
VARIANT varID,
|
||||
BSTR *pszValue)
|
||||
{
|
||||
if (!pszValue)
|
||||
return E_INVALIDARG;
|
||||
CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID));
|
||||
if (!pItem)
|
||||
return E_INVALIDARG;
|
||||
*pszValue = pItem->GetAccValue();
|
||||
if (!*pszValue)
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::get_accDescription(
|
||||
VARIANT varID,
|
||||
BSTR *description)
|
||||
{
|
||||
if (!description)
|
||||
return E_INVALIDARG;
|
||||
return m_pStdAccessible->get_accDescription(varID, description);
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::get_accRole(
|
||||
VARIANT varID,
|
||||
VARIANT *role)
|
||||
{
|
||||
if (!role)
|
||||
return E_INVALIDARG;
|
||||
CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID));
|
||||
if (!pItem)
|
||||
return E_INVALIDARG;
|
||||
V_VT(role) = VT_I4;
|
||||
V_I4(role) = pItem->GetAccRole();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::get_accState(
|
||||
VARIANT varID,
|
||||
VARIANT *state)
|
||||
{
|
||||
if (!state)
|
||||
return E_INVALIDARG;
|
||||
CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID));
|
||||
if (!pItem)
|
||||
return E_INVALIDARG;
|
||||
V_VT(state) = VT_I4;
|
||||
V_I4(state) = pItem->GetAccState();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::get_accHelp(VARIANT varID, BSTR *help)
|
||||
{
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::get_accHelpTopic(
|
||||
BSTR *helpfile,
|
||||
VARIANT varID,
|
||||
LONG *pidTopic)
|
||||
{
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::get_accKeyboardShortcut(VARIANT varID, BSTR *shortcut)
|
||||
{
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::get_accFocus(VARIANT *pvarID)
|
||||
{
|
||||
if (!pvarID)
|
||||
return E_INVALIDARG;
|
||||
V_VT(pvarID) = VT_EMPTY;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::get_accSelection(VARIANT *pvarID)
|
||||
{
|
||||
if (!pvarID)
|
||||
return E_INVALIDARG;
|
||||
|
||||
V_VT(pvarID) = VT_EMPTY;
|
||||
|
||||
INT cItems = (INT)m_AccItems.size();
|
||||
if (cItems < m_cSelection)
|
||||
return S_FALSE;
|
||||
|
||||
if (cItems > m_cSelection)
|
||||
{
|
||||
V_VT(pvarID) = VT_I4;
|
||||
V_I4(pvarID) = m_cSelection;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::get_accDefaultAction(
|
||||
VARIANT varID,
|
||||
BSTR *action)
|
||||
{
|
||||
if (!action)
|
||||
return E_INVALIDARG;
|
||||
*action = NULL;
|
||||
|
||||
if (V_VT(&varID) != VT_I4)
|
||||
return E_INVALIDARG;
|
||||
|
||||
CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID));
|
||||
if (!pItem)
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
*action = pItem->GetAccDefaultAction();
|
||||
if (!*action)
|
||||
return S_FALSE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::accSelect(
|
||||
LONG flagsSelect,
|
||||
VARIANT varID)
|
||||
{
|
||||
if ((flagsSelect & SELFLAG_ADDSELECTION) && (flagsSelect & SELFLAG_REMOVESELECTION))
|
||||
return E_INVALIDARG;
|
||||
if (flagsSelect & (SELFLAG_TAKEFOCUS | SELFLAG_ADDSELECTION | SELFLAG_EXTENDSELECTION))
|
||||
return S_FALSE;
|
||||
if (flagsSelect & SELFLAG_REMOVESELECTION)
|
||||
return S_OK;
|
||||
if (V_VT(&varID) != VT_I4)
|
||||
return E_INVALIDARG;
|
||||
if (flagsSelect & SELFLAG_TAKESELECTION)
|
||||
{
|
||||
m_cSelection = V_I4(&varID);
|
||||
return S_OK;
|
||||
}
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::accLocation(
|
||||
LONG *left,
|
||||
LONG *top,
|
||||
LONG *width,
|
||||
LONG *height,
|
||||
VARIANT varID)
|
||||
{
|
||||
if (!left || !top || !width || !height)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!V_I4(&varID))
|
||||
return m_pStdAccessible->accLocation(left, top, width, height, varID);
|
||||
|
||||
RECT rc;
|
||||
CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID));
|
||||
pItem->GetAccLocation(&rc);
|
||||
|
||||
*left = rc.left;
|
||||
*top = rc.top;
|
||||
*width = rc.right - rc.left;
|
||||
*height = rc.bottom - rc.top;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::accNavigate(
|
||||
LONG dir,
|
||||
VARIANT varStart,
|
||||
VARIANT *pvarEnd)
|
||||
{
|
||||
if (m_AccItems.size() <= 1)
|
||||
{
|
||||
V_VT(pvarEnd) = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case NAVDIR_UP:
|
||||
case NAVDIR_LEFT:
|
||||
case NAVDIR_PREVIOUS:
|
||||
V_VT(pvarEnd) = VT_I4;
|
||||
V_I4(pvarEnd) = V_I4(&varStart) - 1;
|
||||
if (V_I4(&varStart) - 1 <= 0)
|
||||
V_I4(pvarEnd) = (INT)(m_AccItems.size() - 1);
|
||||
return S_OK;
|
||||
|
||||
case NAVDIR_DOWN:
|
||||
case NAVDIR_RIGHT:
|
||||
case NAVDIR_NEXT:
|
||||
V_VT(pvarEnd) = VT_I4;
|
||||
V_I4(pvarEnd) = V_I4(&varStart) + 1;
|
||||
if ((INT)m_AccItems.size() <= V_I4(&varStart) + 1)
|
||||
V_I4(pvarEnd) = 1;
|
||||
return S_OK;
|
||||
|
||||
case NAVDIR_FIRSTCHILD:
|
||||
V_VT(pvarEnd) = VT_I4;
|
||||
V_I4(pvarEnd) = 1;
|
||||
return S_OK;
|
||||
|
||||
case NAVDIR_LASTCHILD:
|
||||
V_VT(pvarEnd) = VT_I4;
|
||||
V_I4(pvarEnd) = (INT)(m_AccItems.size() - 1);
|
||||
return S_OK;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
V_VT(pvarEnd) = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::accHitTest(LONG left, LONG top, VARIANT *pvarID)
|
||||
{
|
||||
if (!pvarID)
|
||||
return E_INVALIDARG;
|
||||
POINT Point = { left, top };
|
||||
RECT Rect;
|
||||
::ScreenToClient(m_hWnd, &Point);
|
||||
::GetClientRect(m_hWnd, &Rect);
|
||||
|
||||
if (!::PtInRect(&Rect, Point))
|
||||
{
|
||||
V_VT(pvarID) = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
V_VT(pvarID) = VT_I4;
|
||||
V_I4(pvarID) = 0;
|
||||
|
||||
for (size_t iItem = 1; iItem < m_AccItems.size(); ++iItem)
|
||||
{
|
||||
CTipbarAccItem *pItem = m_AccItems[iItem];
|
||||
if (pItem)
|
||||
{
|
||||
pItem->GetAccLocation(&Rect);
|
||||
if (::PtInRect(&Rect, Point))
|
||||
{
|
||||
V_I4(pvarID) = iItem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::accDoDefaultAction(VARIANT varID)
|
||||
{
|
||||
if (V_VT(&varID) != VT_I4)
|
||||
return E_INVALIDARG;
|
||||
CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID));
|
||||
if (!pItem)
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
return pItem->DoAccDefaultAction() == 0;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::put_accName(VARIANT varID, BSTR name)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
STDMETHODIMP CTipbarAccessible::put_accValue(VARIANT varID, BSTR value)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CTrayIconItem
|
||||
*/
|
||||
|
@ -509,7 +1115,7 @@ STDAPI DllUnregisterServer(VOID)
|
|||
STDAPI DllCanUnloadNow(VOID)
|
||||
{
|
||||
TRACE("()\n");
|
||||
return gModule.DllCanUnloadNow();
|
||||
return gModule.DllCanUnloadNow() && (g_DllRefCount == 0);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define INITGUID
|
||||
|
||||
#include <windows.h>
|
||||
#include <oleacc.h>
|
||||
#include <imm.h>
|
||||
#include <ddk/immdev.h>
|
||||
#include <cguid.h>
|
||||
|
|
Loading…
Reference in a new issue