1
0
mirror of https://github.com/azure-rtos/guix.git synced 2025-02-04 07:13:17 +08:00
guix/guix_studio/resource_view_provider.cpp

362 lines
12 KiB
C++

#include "studiox_includes.h"
#include "uiautomation.h"
#include "resource_item_provider.h"
#include "resource_view_provider.h"
///////////////////////////////////////////////////////////////////////////////
resource_view_provider::resource_view_provider(resource_view* pControl)
{
m_refCount = 1;
m_pResViewControl = pControl;
m_resViewControlHwnd = pControl->GetSafeHwnd();
}
///////////////////////////////////////////////////////////////////////////////
resource_view_provider::~resource_view_provider()
{
}
///////////////////////////////////////////////////////////////////////////////
// IUnknown implementation.
//
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP_(ULONG) resource_view_provider::AddRef()
{
return InterlockedIncrement(&m_refCount);
}
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP_(ULONG) resource_view_provider::Release()
{
long val = InterlockedDecrement(&m_refCount);
if (val == 0)
{
delete this;
}
return val;
}
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP resource_view_provider::QueryInterface(REFIID riid, void** ppInterface)
{
if (riid == __uuidof(IUnknown)) *ppInterface = static_cast<IRawElementProviderSimple*>(this);
else if (riid == __uuidof(IRawElementProviderSimple)) *ppInterface = static_cast<IRawElementProviderSimple*>(this);
else if (riid == __uuidof(IRawElementProviderFragment)) *ppInterface = static_cast<IRawElementProviderFragment*>(this);
else if (riid == __uuidof(IRawElementProviderFragmentRoot)) *ppInterface = static_cast<IRawElementProviderFragmentRoot*>(this);
else if (riid == __uuidof(ISelectionProvider)) *ppInterface = static_cast<ISelectionProvider*>(this);
else
{
*ppInterface = NULL;
return E_NOINTERFACE;
}
(static_cast<IUnknown*>(*ppInterface))->AddRef();
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
// IRawElementProviderSimple implementation
//
// Implementation of IRawElementProviderSimple::get_ProviderOptions.
// Gets UI Automation provider options.
//
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP resource_view_provider::get_ProviderOptions(ProviderOptions* pRetVal)
{
*pRetVal = ProviderOptions_ServerSideProvider;
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
// Implementation of IRawElementProviderSimple::get_PatternProvider.
// Gets the object that supports ISelectionPattern.
//
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP resource_view_provider::GetPatternProvider(PATTERNID patternId, IUnknown** pRetVal)
{
*pRetVal = NULL;
if (patternId == UIA_SelectionPatternId)
{
*pRetVal = static_cast<IRawElementProviderSimple*>(this);
AddRef();
}
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
// Implementation of IRawElementProviderSimple::get_PropertyValue.
// Gets custom properties.
//
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP resource_view_provider::GetPropertyValue(PROPERTYID propertyId, VARIANT* pRetVal)
{
if (propertyId == UIA_LocalizedControlTypePropertyId)
{
pRetVal->vt = VT_BSTR;
pRetVal->bstrVal = SysAllocString(L"resource tree");
}
else if (propertyId == UIA_ControlTypePropertyId)
{
pRetVal->vt = VT_I4;
pRetVal->lVal = UIA_TreeControlTypeId;
}
else if (propertyId == UIA_IsKeyboardFocusablePropertyId)
{
pRetVal->vt = VT_BOOL;
pRetVal->boolVal = VARIANT_TRUE;
}
else
{
pRetVal->vt = VT_EMPTY;
}
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
// Implementation of IRawElementProviderSimple::get_HostRawElementProvider.
// Gets the default UI Automation provider for the host window. This provider
// supplies many properties.
//
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP resource_view_provider::get_HostRawElementProvider(IRawElementProviderSimple** pRetVal)
{
if (m_resViewControlHwnd == NULL)
{
return UIA_E_ELEMENTNOTAVAILABLE;
}
HRESULT hr = UiaHostProviderFromHwnd(m_resViewControlHwnd, pRetVal);
return hr;
}
///////////////////////////////////////////////////////////////////////////////
// IRawElementProviderFragment implementation
//
// Implementation of IRawElementProviderFragment::Navigate.
// Enables UI Automation to locate the element in the tree.
// Navigation to the parent is handled by the host window provider.
//
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP resource_view_provider::Navigate(NavigateDirection direction, IRawElementProviderFragment** pRetVal)
{
resource_item* pDest = NULL;
IRawElementProviderFragment* pFrag = NULL;
switch (direction)
{
case NavigateDirection_FirstChild:
pDest = m_pResViewControl->GetResTree()->GetRoot();
if (pDest)
{
pDest = pDest->NavigateFirst();
}
break;
case NavigateDirection_LastChild:
pDest = m_pResViewControl->GetResTree()->GetRoot();
if (pDest)
{
pDest = pDest->NavigateLast();
}
break;
}
if (pDest)
{
pFrag = pDest->GetResItemProvider();
}
if (pFrag != NULL)
{
pFrag->AddRef();
}
*pRetVal = pFrag;
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
// Implementation of IRawElementProviderFragment::GetRuntimeId.
// UI Automation gets this value from the host window provider, so supply NULL here.
//
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP resource_view_provider::GetRuntimeId(SAFEARRAY** pRetVal)
{
*pRetVal = NULL;
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
// Implementation of IRawElementProviderFragment::get_BoundingRectangle.
//
// Retrieves the screen location and size of the control. Controls hosted in
// Win32 windows can return an empty rectangle; UI Automation will
// retrieve the rectangle from the HWND provider. However, the method is
// implemented here so that it can be used by the list items to calculate
// their own bounding rectangles.
//
// UI Spy uses the bounding rectangle to draw a red border around the element.
//
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP resource_view_provider::get_BoundingRectangle(UiaRect* pRetVal)
{
RECT rect;
m_pResViewControl->GetClientRect(&rect);
m_pResViewControl->ClientToScreen(&rect);
pRetVal->left = rect.left;
pRetVal->top = rect.top;
pRetVal->width = rect.right - rect.left;
pRetVal->height = rect.bottom - rect.top;
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
// Implementation of IRawElementProviderFragment::GetEmbeddedFragmentRoots.
// Retrieves other fragment roots that may be hosted in this one.
//
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP resource_view_provider::GetEmbeddedFragmentRoots(SAFEARRAY** pRetVal)
{
*pRetVal = NULL;
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
// Implementation of IRawElementProviderFragment::SetFocus.
// Responds to the control receiving focus through a UI Automation request.
// For HWND-based controls, this is handled by the host window provider.
//
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP resource_view_provider::SetFocus()
{
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
// Implementation of IRawElementProviderFragment::get_FragmentRoot.
// Retrieves the root element of this fragment.
//
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP resource_view_provider::get_FragmentRoot(IRawElementProviderFragmentRoot** pRetVal)
{
*pRetVal = static_cast<IRawElementProviderFragmentRoot*>(this);
AddRef();
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
// IRawElementProviderFragmentRoot implementation
//
// Implementation of IRawElementProviderFragmentRoot::ElementProviderFromPoint.
// Retrieves the IRawElementProviderFragment interface for the item at the specified
// point (in client coordinates).
// UI Spy uses this to determine what element is under the cursor when Ctrl is pressed.
//
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP resource_view_provider::ElementProviderFromPoint(double x, double y, IRawElementProviderFragment** pRetVal)
{
POINT pt;
pt.x = (LONG)x;
pt.y = (LONG)y;
m_pResViewControl->ScreenToClient(&pt);
resource_tree* pResTree = m_pResViewControl->GetResTree();
resource_item* pRoot = pResTree->GetRoot();
if (!pRoot)
{
return NULL;
}
resource_item* pItem = pResTree->FindItem(pRoot, pt);
if (pItem == NULL)
{
return NULL;
}
resource_item_provider *pItemProvider = pItem->GetResItemProvider();
if (pItemProvider != NULL)
{
*pRetVal = static_cast<IRawElementProviderFragment*>(pItemProvider);
pItemProvider->AddRef();
}
else
{
*pRetVal = NULL;
}
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
// Implementation of IRawElementProviderFragmentRoot::GetFocus.
// Retrieves the provider for the list item that is selected when the control gets focus.
//
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP resource_view_provider::GetFocus(IRawElementProviderFragment** pRetVal)
{
*pRetVal = NULL;
resource_item* pSelectItem = m_pResViewControl->GetCurrentItem();
if (pSelectItem)
{
resource_item_provider* pItemProvider = pSelectItem->GetResItemProvider();
if (pItemProvider != NULL)
{
pItemProvider->AddRef();
*pRetVal = pItemProvider;
}
}
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
// ISelectionProvider implementation
//
// Implementation of ISelectionProvider::GetSelection.
// Gets the provider(s) for the items(s) selected in the list box.
// In this case, only a single item can be selected.
//
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP resource_view_provider::GetSelection(SAFEARRAY** pRetVal)
{
SAFEARRAY* psa = SafeArrayCreateVector(VT_UNKNOWN, 0, 1);
resource_item* pSelectItem = m_pResViewControl->GetCurrentItem();
if (pSelectItem)
{
resource_item_provider* pItemProvider = pSelectItem->GetResItemProvider();
if (pItemProvider != NULL)
{
LONG i = 0;
SafeArrayPutElement(psa, &i, pItemProvider);
}
}
*pRetVal = psa;
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
// Implementation of ISelectionProvider::get_CanSelectMultiple.
//
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP resource_view_provider::get_CanSelectMultiple(BOOL* pRetVal)
{
*pRetVal = FALSE;
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
// Implementation of ISelectionProvider::get_IsSelectionRequired.
//
///////////////////////////////////////////////////////////////////////////////
IFACEMETHODIMP resource_view_provider::get_IsSelectionRequired(BOOL* pRetVal)
{
*pRetVal = TRUE;
return S_OK;
}