Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WindowsUIElement.h"
#include <objbase.h>
#include <uiautomation.h>
#include <windows.h>
#include "mozilla/Maybe.h"
#include "mozilla/RefPtr.h"
#include "WindowsUIOverlayImage.h"
namespace mozilla {
WindowsUIElement::WindowsUIElement(HWND aWindow,
RefPtr<IUIAutomationElement> aElement)
: mWindow{aWindow}, mElement{aElement}, mRect{} {}
static bool IsWindowPointVisible(HWND aWindow, POINT aPoint) {
HWND topWindow{WindowFromPoint(aPoint)};
if (aWindow != topWindow && !IsChild(aWindow, topWindow)) {
return false;
}
return true;
}
static mozilla::Maybe<RECT> GetBoundingRectangle(
RefPtr<IUIAutomationElement> aElement) {
RECT rect{};
HRESULT hr{aElement->get_CurrentBoundingRectangle(&rect)};
if (FAILED(hr)) {
return mozilla::Nothing();
}
if (rect.right < rect.left || rect.bottom < rect.top) {
return mozilla::Nothing();
}
return mozilla::Some(rect);
}
bool WindowsUIElement::IsVisible() {
mozilla::Maybe<RECT> rect{GetBoundingRectangle(mElement)};
if (!rect) {
mRect = RECT{};
return false;
}
mRect = *rect;
POINT pointTopLeft{mRect.left, mRect.top};
if (!IsWindowPointVisible(mWindow, pointTopLeft)) {
return false;
}
POINT pointBottomLeft{mRect.left, mRect.bottom};
if (!IsWindowPointVisible(mWindow, pointBottomLeft)) {
return false;
}
POINT pointTopRight{mRect.right, mRect.top};
if (!IsWindowPointVisible(mWindow, pointTopRight)) {
return false;
}
POINT pointBottomRight{mRect.right, mRect.bottom};
if (!IsWindowPointVisible(mWindow, pointBottomRight)) {
return false;
}
return true;
}
mozilla::Maybe<bool> WindowsUIElement::IsMoving() {
mozilla::Maybe<RECT> rect{GetBoundingRectangle(mElement)};
if (!rect) {
mRect = RECT{};
return mozilla::Nothing();
}
if (::EqualRect(&mRect, rect.ptr())) {
return mozilla::Some(false);
}
mRect = *rect;
return mozilla::Some(true);
}
static bool EnableFocusIndicators(HWND aWindow) {
if (!::IsWindow(aWindow)) {
return false;
}
return ::PostMessageW(aWindow, WM_UPDATEUISTATE,
MAKEWPARAM(UIS_CLEAR, UISF_HIDEFOCUS | UISF_HIDEACCEL),
0);
}
void WindowsUIElement::Focus() const {
if (EnableFocusIndicators(mWindow)) {
mElement->SetFocus();
}
}
RefPtr<WindowsUIOverlayImage> WindowsUIElement::CreateOverlayImage(
WindowsUIOverlayImage::DisplayMode aDisplayMode) const {
return WindowsUIOverlayImage::Create(mWindow, mElement, aDisplayMode);
}
} // namespace mozilla