зеркало из https://github.com/mozilla/gecko-dev.git
Bug 591874 - windows screen readers are broken due to post-130078 changes in the native widget structure, r=marcoz, davidb, a=blocking
This commit is contained in:
Родитель
a554f1f1f7
Коммит
67cc22e9ac
|
@ -93,7 +93,7 @@ nsIAtom *nsDocAccessible::gLastFocusedFrameType = nsnull;
|
|||
nsDocAccessible::
|
||||
nsDocAccessible(nsIDocument *aDocument, nsIContent *aRootContent,
|
||||
nsIWeakReference *aShell) :
|
||||
nsHyperTextAccessibleWrap(aRootContent, aShell), mWnd(nsnull),
|
||||
nsHyperTextAccessibleWrap(aRootContent, aShell),
|
||||
mDocument(aDocument), mScrollPositionChangedTicks(0), mIsLoaded(PR_FALSE)
|
||||
{
|
||||
// XXX aaronl should we use an algorithm for the initial cache size?
|
||||
|
@ -103,17 +103,6 @@ nsDocAccessible::
|
|||
if (!mDocument)
|
||||
return;
|
||||
|
||||
// Initialize mWnd
|
||||
nsCOMPtr<nsIPresShell> shell(do_QueryReferent(mWeakShell));
|
||||
nsIViewManager* vm = shell->GetViewManager();
|
||||
if (vm) {
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
vm->GetRootWidget(getter_AddRefs(widget));
|
||||
if (widget) {
|
||||
mWnd = widget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
}
|
||||
}
|
||||
|
||||
// nsAccDocManager creates document accessible when scrollable frame is
|
||||
// available already, it should be safe time to add scroll listener.
|
||||
AddScrollListener();
|
||||
|
@ -473,7 +462,8 @@ NS_IMETHODIMP nsDocAccessible::GetNameSpaceURIForID(PRInt16 aNameSpaceID, nsAStr
|
|||
|
||||
NS_IMETHODIMP nsDocAccessible::GetWindowHandle(void **aWindow)
|
||||
{
|
||||
*aWindow = mWnd;
|
||||
NS_ENSURE_ARG_POINTER(aWindow);
|
||||
*aWindow = GetNativeWindow();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1335,6 +1325,20 @@ nsDocAccessible::HandleAccEvent(AccEvent* aAccEvent)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Public members
|
||||
|
||||
void*
|
||||
nsDocAccessible::GetNativeWindow() const
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> shell(do_QueryReferent(mWeakShell));
|
||||
nsIViewManager* vm = shell->GetViewManager();
|
||||
if (vm) {
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
vm->GetRootWidget(getter_AddRefs(widget));
|
||||
if (widget)
|
||||
return widget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsAccessible*
|
||||
nsDocAccessible::GetCachedAccessibleInSubtree(void* aUniqueID)
|
||||
{
|
||||
|
|
|
@ -141,6 +141,11 @@ public:
|
|||
*/
|
||||
void MarkAsLoaded() { mIsLoaded = PR_TRUE; }
|
||||
|
||||
/**
|
||||
* Return a native window handler or pointer depending on platform.
|
||||
*/
|
||||
virtual void* GetNativeWindow() const;
|
||||
|
||||
/**
|
||||
* Return the parent document.
|
||||
*/
|
||||
|
@ -363,7 +368,6 @@ protected:
|
|||
*/
|
||||
nsAccessibleHashtable mAccessibleCache;
|
||||
|
||||
void *mWnd;
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
nsCOMPtr<nsITimer> mScrollWatchTimer;
|
||||
PRUint16 mScrollPositionChangedTicks; // Used for tracking scroll events
|
||||
|
|
|
@ -594,9 +594,13 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
nsAccessibleWrap *accWrap = static_cast<nsAccessibleWrap*>(mGeckoAccessible);
|
||||
|
||||
// Get a pointer to the native window (NSWindow) we reside in.
|
||||
NSWindow *nativeWindow = nil;
|
||||
accWrap->GetNativeWindow ((void**)&nativeWindow);
|
||||
|
||||
nsDocAccessible* docAcc = accWrap->GetDocAccessible();
|
||||
if (docAcc)
|
||||
nativeWindow = static_cast<NSWindow*>(docAcc->GetNativeWindow());
|
||||
|
||||
NSAssert1(nativeWindow, @"Could not get native window for %@", self);
|
||||
return nativeWindow;
|
||||
|
||||
|
|
|
@ -71,10 +71,7 @@ class nsAccessibleWrap : public nsAccessible
|
|||
// should be instantied with. used on runtime to determine the
|
||||
// right type for this accessible's associated native object.
|
||||
virtual objc_class* GetNativeType ();
|
||||
|
||||
// returns a pointer to the native window for this accessible tree.
|
||||
void GetNativeWindow (void **aOutNativeWindow);
|
||||
|
||||
|
||||
virtual void Shutdown ();
|
||||
virtual void InvalidateChildren();
|
||||
|
||||
|
|
|
@ -86,17 +86,6 @@ nsAccessibleWrap::GetNativeInterface (void **aOutInterface)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// get the native NSWindow we reside in.
|
||||
void
|
||||
nsAccessibleWrap::GetNativeWindow (void **aOutNativeWindow)
|
||||
{
|
||||
*aOutNativeWindow = nsnull;
|
||||
|
||||
nsDocAccessible *docAcc = GetDocAccessible();
|
||||
if (docAcc)
|
||||
docAcc->GetWindowHandle (aOutNativeWindow);
|
||||
}
|
||||
|
||||
// overridden in subclasses to create the right kind of object. by default we create a generic
|
||||
// 'mozAccessible' node.
|
||||
objc_class*
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "nsApplicationAccessibleWrap.h"
|
||||
#include "nsCoreUtils.h"
|
||||
#include "nsRootAccessible.h"
|
||||
#include "nsWinUtils.h"
|
||||
|
||||
#include "nsAttrName.h"
|
||||
#include "nsIDocument.h"
|
||||
|
@ -63,6 +64,7 @@
|
|||
HINSTANCE nsAccessNodeWrap::gmAccLib = nsnull;
|
||||
HINSTANCE nsAccessNodeWrap::gmUserLib = nsnull;
|
||||
LPFNACCESSIBLEOBJECTFROMWINDOW nsAccessNodeWrap::gmAccessibleObjectFromWindow = nsnull;
|
||||
LPFNLRESULTFROMOBJECT nsAccessNodeWrap::gmLresultFromObject = NULL;
|
||||
LPFNNOTIFYWINEVENT nsAccessNodeWrap::gmNotifyWinEvent = nsnull;
|
||||
LPFNGETGUITHREADINFO nsAccessNodeWrap::gmGetGUIThreadInfo = nsnull;
|
||||
|
||||
|
@ -569,7 +571,14 @@ void nsAccessNodeWrap::InitAccessibility()
|
|||
}
|
||||
|
||||
DoATSpecificProcessing();
|
||||
|
||||
|
||||
// Register window class that'll be used for document accessibles associated
|
||||
// with tabs.
|
||||
if (nsWinUtils::IsWindowEmulationEnabled()) {
|
||||
nsWinUtils::RegisterNativeWindow(kClassNameTabContent);
|
||||
sHWNDCache.Init(4);
|
||||
}
|
||||
|
||||
nsAccessNode::InitXPAccessibility();
|
||||
}
|
||||
|
||||
|
@ -578,6 +587,11 @@ void nsAccessNodeWrap::ShutdownAccessibility()
|
|||
NS_IF_RELEASE(gTextEvent);
|
||||
::DestroyCaret();
|
||||
|
||||
// Unregister window call that's used for document accessibles associated
|
||||
// with tabs.
|
||||
if (nsWinUtils::IsWindowEmulationEnabled())
|
||||
::UnregisterClassW(kClassNameTabContent, GetModuleHandle(NULL));
|
||||
|
||||
nsAccessNode::ShutdownXPAccessibility();
|
||||
}
|
||||
|
||||
|
@ -624,7 +638,7 @@ GetHRESULT(nsresult aResult)
|
|||
|
||||
PRBool nsAccessNodeWrap::IsOnlyMsaaCompatibleJawsPresent()
|
||||
{
|
||||
HMODULE jhookhandle = ::GetModuleHandleW(L"jhook");
|
||||
HMODULE jhookhandle = ::GetModuleHandleW(kJAWSModuleHandle);
|
||||
if (!jhookhandle)
|
||||
return PR_FALSE; // No JAWS, or some other screen reader, use IA2
|
||||
|
||||
|
@ -655,10 +669,10 @@ PRBool nsAccessNodeWrap::IsOnlyMsaaCompatibleJawsPresent()
|
|||
|
||||
void nsAccessNodeWrap::TurnOffNewTabSwitchingForJawsAndWE()
|
||||
{
|
||||
HMODULE srHandle = ::GetModuleHandleW(L"jhook");
|
||||
HMODULE srHandle = ::GetModuleHandleW(kJAWSModuleHandle);
|
||||
if (!srHandle) {
|
||||
// No JAWS, try Window-Eyes
|
||||
srHandle = ::GetModuleHandleW(L"gwm32inc");
|
||||
srHandle = ::GetModuleHandleW(kWEModuleHandle);
|
||||
if (!srHandle) {
|
||||
// no screen reader we're interested in. Bail out.
|
||||
return;
|
||||
|
@ -694,3 +708,49 @@ void nsAccessNodeWrap::DoATSpecificProcessing()
|
|||
|
||||
TurnOffNewTabSwitchingForJawsAndWE();
|
||||
}
|
||||
|
||||
nsRefPtrHashtable<nsVoidPtrHashKey, nsDocAccessible> nsAccessNodeWrap::sHWNDCache;
|
||||
|
||||
LRESULT CALLBACK
|
||||
nsAccessNodeWrap::WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_GETOBJECT:
|
||||
{
|
||||
if (lParam == OBJID_CLIENT) {
|
||||
nsDocAccessible* document = sHWNDCache.GetWeak(static_cast<void*>(hWnd));
|
||||
if (document) {
|
||||
IAccessible* msaaAccessible = NULL;
|
||||
document->GetNativeInterface((void**)&msaaAccessible); // does an addref
|
||||
if (msaaAccessible) {
|
||||
LRESULT result = LresultFromObject(IID_IAccessible, wParam,
|
||||
msaaAccessible); // does an addref
|
||||
msaaAccessible->Release(); // release extra addref
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ::DefWindowProcW(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(LRESULT)
|
||||
nsAccessNodeWrap::LresultFromObject(REFIID riid, WPARAM wParam, LPUNKNOWN pAcc)
|
||||
{
|
||||
// open the dll dynamically
|
||||
if (!gmAccLib)
|
||||
gmAccLib =::LoadLibraryW(L"OLEACC.DLL");
|
||||
|
||||
if (gmAccLib) {
|
||||
if (!gmLresultFromObject)
|
||||
gmLresultFromObject = (LPFNLRESULTFROMOBJECT)GetProcAddress(gmAccLib,"LresultFromObject");
|
||||
|
||||
if (gmLresultFromObject)
|
||||
return gmLresultFromObject(riid, wParam, pAcc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -68,6 +68,8 @@
|
|||
#include "nsICrashReporter.h"
|
||||
#endif
|
||||
|
||||
#include "nsRefPtrHashtable.h"
|
||||
|
||||
typedef LRESULT (STDAPICALLTYPE *LPFNNOTIFYWINEVENT)(DWORD event,HWND hwnd,LONG idObjectType,LONG idObject);
|
||||
typedef LRESULT (STDAPICALLTYPE *LPFNGETGUITHREADINFO)(DWORD idThread, GUITHREADINFO* pgui);
|
||||
|
||||
|
@ -154,6 +156,7 @@ public: // construction, destruction
|
|||
static HINSTANCE gmAccLib;
|
||||
static HINSTANCE gmUserLib;
|
||||
static LPFNACCESSIBLEOBJECTFROMWINDOW gmAccessibleObjectFromWindow;
|
||||
static LPFNLRESULTFROMOBJECT gmLresultFromObject;
|
||||
static LPFNNOTIFYWINEVENT gmNotifyWinEvent;
|
||||
static LPFNGETGUITHREADINFO gmGetGUIThreadInfo;
|
||||
|
||||
|
@ -165,6 +168,13 @@ public: // construction, destruction
|
|||
|
||||
static void DoATSpecificProcessing();
|
||||
|
||||
static STDMETHODIMP_(LRESULT) LresultFromObject(REFIID riid, WPARAM wParam, LPUNKNOWN pAcc);
|
||||
|
||||
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg,
|
||||
WPARAM WParam, LPARAM lParam);
|
||||
|
||||
static nsRefPtrHashtable<nsVoidPtrHashKey, nsDocAccessible> sHWNDCache;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "nsAccUtils.h"
|
||||
#include "nsCoreUtils.h"
|
||||
#include "nsRelUtils.h"
|
||||
#include "nsWinUtils.h"
|
||||
|
||||
#include "nsIAccessibleDocument.h"
|
||||
#include "nsIAccessibleEvent.h"
|
||||
|
@ -193,58 +194,23 @@ STDMETHODIMP nsAccessibleWrap::get_accParent( IDispatch __RPC_FAR *__RPC_FAR *pp
|
|||
{
|
||||
__try {
|
||||
*ppdispParent = NULL;
|
||||
if (!mWeakShell)
|
||||
return E_FAIL; // We've been shut down
|
||||
|
||||
nsIFrame *frame = GetFrame();
|
||||
HWND hwnd = 0;
|
||||
if (frame) {
|
||||
nsIView *view = frame->GetViewExternal();
|
||||
if (view) {
|
||||
// This code is essentially our implementation of WindowFromAccessibleObject,
|
||||
// because MSAA iterates get_accParent() until it sees an object of ROLE_WINDOW
|
||||
// to know where the window for a given accessible is. We must expose the native
|
||||
// window accessible that MSAA creates for us. This must be done for the document
|
||||
// object as well as any layout that creates its own window (e.g. via overflow: scroll)
|
||||
nsIWidget *widget = view->GetWidget();
|
||||
if (widget) {
|
||||
hwnd = (HWND)widget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
NS_ASSERTION(hwnd, "No window handle for window");
|
||||
if (IsDefunct())
|
||||
return E_FAIL;
|
||||
|
||||
nsIViewManager* viewManager = view->GetViewManager();
|
||||
if (!viewManager)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
nsIView *rootView;
|
||||
viewManager->GetRootView(rootView);
|
||||
if (rootView == view) {
|
||||
// If the client accessible (OBJID_CLIENT) has a window but its window
|
||||
// was created by an outer window then we want the native accessible
|
||||
// for that outer window. If the accessible was created for outer
|
||||
// window (if the outer window has inner windows then they share the
|
||||
// same client accessible with it) then return native accessible for
|
||||
// the outer window.
|
||||
HWND parenthwnd = ::GetParent(hwnd);
|
||||
if (parenthwnd)
|
||||
hwnd = parenthwnd;
|
||||
|
||||
NS_ASSERTION(hwnd, "No window handle for window");
|
||||
}
|
||||
nsRefPtr<nsDocAccessible> doc(do_QueryObject(this));
|
||||
if (doc) {
|
||||
// Return window system accessible object for root document and tab document
|
||||
// accessibles.
|
||||
if (!doc->ParentDocument() ||
|
||||
nsWinUtils::IsWindowEmulationEnabled() &&
|
||||
nsWinUtils::IsTabDocument(doc->GetDocumentNode())) {
|
||||
HWND hwnd = static_cast<HWND>(doc->GetNativeWindow());
|
||||
if (hwnd && SUCCEEDED(AccessibleObjectFromWindow(hwnd, OBJID_WINDOW,
|
||||
IID_IAccessible,
|
||||
(void**)ppdispParent))) {
|
||||
return S_OK;
|
||||
}
|
||||
else {
|
||||
// If a frame is a scrollable frame, then it has one window for the client area,
|
||||
// not an extra parent window for just the scrollbars
|
||||
nsIScrollableFrame *scrollFrame = do_QueryFrame(frame);
|
||||
if (scrollFrame) {
|
||||
hwnd = (HWND)scrollFrame->GetScrolledFrame()->GetNearestWidget()->GetNativeData(NS_NATIVE_WINDOW);
|
||||
NS_ASSERTION(hwnd, "No window handle for window");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hwnd && SUCCEEDED(AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAccessible,
|
||||
(void**)ppdispParent))) {
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1668,45 +1634,11 @@ PRInt32 nsAccessibleWrap::GetChildIDFor(nsIAccessible* aAccessible)
|
|||
HWND
|
||||
nsAccessibleWrap::GetHWNDFor(nsAccessible *aAccessible)
|
||||
{
|
||||
HWND hWnd = 0;
|
||||
if (!aAccessible)
|
||||
return hWnd;
|
||||
return 0;
|
||||
|
||||
nsIFrame *frame = aAccessible->GetFrame();
|
||||
if (frame) {
|
||||
nsIWidget *window = frame->GetNearestWidget();
|
||||
PRBool isVisible;
|
||||
window->IsVisible(isVisible);
|
||||
if (isVisible) {
|
||||
// Short explanation:
|
||||
// If HWND for frame is inside a hidden window, fire the event on the
|
||||
// containing document's visible window.
|
||||
//
|
||||
// Long explanation:
|
||||
// This is really just to fix combo boxes with JAWS. Window-Eyes already
|
||||
// worked with combo boxes because they use the value change event in
|
||||
// the closed combo box case. JAWS will only pay attention to the focus
|
||||
// events on the list items. The JAWS developers haven't fixed that, so
|
||||
// we'll use the focus events to make JAWS work. However, JAWS is
|
||||
// ignoring events on a hidden window. So, in order to fix the bug where
|
||||
// JAWS doesn't echo the current option as it changes in a closed
|
||||
// combo box, we need to use an ensure that we never fire an event with
|
||||
// an HWND for a hidden window.
|
||||
hWnd = (HWND)frame->GetNearestWidget()->GetNativeData(NS_NATIVE_WINDOW);
|
||||
}
|
||||
}
|
||||
|
||||
if (!hWnd) {
|
||||
void* handle = nsnull;
|
||||
nsDocAccessible *accessibleDoc = aAccessible->GetDocAccessible();
|
||||
if (!accessibleDoc)
|
||||
return 0;
|
||||
|
||||
accessibleDoc->GetWindowHandle(&handle);
|
||||
hWnd = (HWND)handle;
|
||||
}
|
||||
|
||||
return hWnd;
|
||||
nsDocAccessible* document = aAccessible->GetDocAccessible();
|
||||
return document ? static_cast<HWND>(document->GetNativeWindow()) : 0;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
#include "nsDocAccessibleWrap.h"
|
||||
#include "ISimpleDOMDocument_i.c"
|
||||
#include "nsIAccessibilityService.h"
|
||||
#include "nsRootAccessible.h"
|
||||
#include "nsWinUtils.h"
|
||||
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeNode.h"
|
||||
#include "nsIFrame.h"
|
||||
|
@ -60,7 +63,7 @@
|
|||
nsDocAccessibleWrap::
|
||||
nsDocAccessibleWrap(nsIDocument *aDocument, nsIContent *aRootContent,
|
||||
nsIWeakReference *aShell) :
|
||||
nsDocAccessible(aDocument, aRootContent, aShell)
|
||||
nsDocAccessible(aDocument, aRootContent, aShell), mHWND(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -245,3 +248,53 @@ STDMETHODIMP nsDocAccessibleWrap::get_accValue(
|
|||
|
||||
return get_URL(pszValue);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessNode
|
||||
|
||||
PRBool
|
||||
nsDocAccessibleWrap::Init()
|
||||
{
|
||||
if (nsWinUtils::IsWindowEmulationEnabled()) {
|
||||
// Create window for tab document.
|
||||
if (nsWinUtils::IsTabDocument(mDocument)) {
|
||||
nsRefPtr<nsRootAccessible> root = GetRootAccessible();
|
||||
mHWND = nsWinUtils::CreateNativeWindow(kClassNameTabContent,
|
||||
static_cast<HWND>(root->GetNativeWindow()));
|
||||
|
||||
nsAccessibleWrap::sHWNDCache.Put(mHWND, this);
|
||||
|
||||
} else {
|
||||
nsDocAccessible* parentDocument = ParentDocument();
|
||||
if (parentDocument)
|
||||
mHWND = parentDocument->GetNativeWindow();
|
||||
}
|
||||
}
|
||||
|
||||
return nsDocAccessible::Init();
|
||||
}
|
||||
|
||||
void
|
||||
nsDocAccessibleWrap::Shutdown()
|
||||
{
|
||||
if (nsWinUtils::IsWindowEmulationEnabled()) {
|
||||
// Destroy window created for root document.
|
||||
if (nsWinUtils::IsTabDocument(mDocument)) {
|
||||
nsAccessibleWrap::sHWNDCache.Remove(mHWND);
|
||||
::DestroyWindow(static_cast<HWND>(mHWND));
|
||||
}
|
||||
|
||||
mHWND = nsnull;
|
||||
}
|
||||
|
||||
nsDocAccessible::Shutdown();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsDocAccessible
|
||||
|
||||
void*
|
||||
nsDocAccessibleWrap::GetNativeWindow() const
|
||||
{
|
||||
return mHWND ? mHWND : nsDocAccessible::GetNativeWindow();
|
||||
}
|
||||
|
|
|
@ -89,8 +89,18 @@ public:
|
|||
/* [optional][in] */ VARIANT varChild,
|
||||
/* [retval][out] */ BSTR __RPC_FAR *pszValue);
|
||||
|
||||
// nsAccessNode
|
||||
virtual PRBool Init();
|
||||
virtual void Shutdown();
|
||||
|
||||
// nsAccessibleWrap
|
||||
virtual nsAccessible *GetXPAccessibleFor(const VARIANT& varChild);
|
||||
|
||||
// nsDocAccessible
|
||||
virtual void* GetNativeWindow() const;
|
||||
|
||||
protected:
|
||||
void* mHWND;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "nsAccessibleWrap.h"
|
||||
#include "nsIWinAccessNode.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
|
||||
HRESULT
|
||||
nsWinUtils::ConvertToIA2Array(nsIArray *aGeckoArray, IUnknown ***aIA2Array,
|
||||
|
@ -96,3 +97,56 @@ nsWinUtils::ConvertToIA2Array(nsIArray *aGeckoArray, IUnknown ***aIA2Array,
|
|||
*aIA2ArrayLen = length;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsWinUtils::RegisterNativeWindow(LPCWSTR aWindowClass)
|
||||
{
|
||||
WNDCLASSW wc;
|
||||
wc.style = CS_GLOBALCLASS;
|
||||
wc.lpfnWndProc = nsAccessNodeWrap::WindowProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = GetModuleHandle(NULL);
|
||||
wc.hIcon = NULL;
|
||||
wc.hCursor = NULL;
|
||||
wc.hbrBackground = NULL;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = aWindowClass;
|
||||
::RegisterClassW(&wc);
|
||||
}
|
||||
|
||||
HWND
|
||||
nsWinUtils::CreateNativeWindow(LPCWSTR aWindowClass, HWND aParentWnd)
|
||||
{
|
||||
return ::CreateWindowW(aWindowClass,
|
||||
L"NetscapeDispatchWnd",
|
||||
WS_CHILD | WS_VISIBLE,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
0, 0,
|
||||
aParentWnd,
|
||||
NULL,
|
||||
GetModuleHandle(NULL),
|
||||
NULL);
|
||||
}
|
||||
|
||||
bool
|
||||
nsWinUtils::IsWindowEmulationEnabled()
|
||||
{
|
||||
return ::GetModuleHandleW(kJAWSModuleHandle) ||
|
||||
::GetModuleHandleW(kWEModuleHandle);
|
||||
}
|
||||
|
||||
bool
|
||||
nsWinUtils::IsTabDocument(nsIDocument* aDocumentNode)
|
||||
{
|
||||
nsCOMPtr<nsISupports> container = aDocumentNode->GetContainer();
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container));
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
|
||||
treeItem->GetParent(getter_AddRefs(parentTreeItem));
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
|
||||
treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
|
||||
|
||||
return parentTreeItem == rootTreeItem;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,14 @@
|
|||
#include "Accessible2.h"
|
||||
|
||||
#include "nsIArray.h"
|
||||
#include "nsIDocument.h"
|
||||
|
||||
const LPCWSTR kClassNameRoot = L"MozillaUIWindowClass";
|
||||
const LPCWSTR kClassNameTabContent = L"MozillaContentWindowClass";
|
||||
|
||||
const LPCWSTR kJAWSModuleHandle = L"jhook";
|
||||
const LPCWSTR kWEModuleHandle = L"gwm32inc";
|
||||
const LPCWSTR kNVDAModuleHandle = L"VBufBackend_gecko_ia2";
|
||||
|
||||
class nsWinUtils
|
||||
{
|
||||
|
@ -54,6 +62,26 @@ public:
|
|||
*/
|
||||
static HRESULT ConvertToIA2Array(nsIArray *aCollection,
|
||||
IUnknown ***aAccessibles, long *aCount);
|
||||
|
||||
/**
|
||||
* Helper to register window class.
|
||||
*/
|
||||
static void RegisterNativeWindow(LPCWSTR aWindowClass);
|
||||
|
||||
/**
|
||||
* Helper to create a window.
|
||||
*/
|
||||
static HWND CreateNativeWindow(LPCWSTR aWindowClass, HWND aParentWnd);
|
||||
|
||||
/**
|
||||
* Return true if window emulation is enabled.
|
||||
*/
|
||||
static bool IsWindowEmulationEnabled();
|
||||
|
||||
/**
|
||||
* Return true if the given document node is for tab document accessible.
|
||||
*/
|
||||
static bool IsTabDocument(nsIDocument* aDocumentNode);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче