diff --git a/widget/src/build/makefile.win b/widget/src/build/makefile.win index 9ea3fce762c..b50071fe1e0 100644 --- a/widget/src/build/makefile.win +++ b/widget/src/build/makefile.win @@ -55,7 +55,9 @@ WIN_LIBS= \ # imm32.lib \ Uuid.lib \ ole32.lib \ - shell32.lib + shell32.lib \ + oleacc.lib \ + oleaut32.lib LLIBS= \ $(DIST)\lib\xpcom.lib \ diff --git a/widget/src/windows/Accessible.cpp b/widget/src/windows/Accessible.cpp new file mode 100644 index 00000000000..4d1ea82023b --- /dev/null +++ b/widget/src/windows/Accessible.cpp @@ -0,0 +1,600 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#include "Accessible.h" +#include "nsIAccessible.h" +#include "nsIWidget.h" +#include "nsWindow.h" +#include "nsCOMPtr.h" +#include "nsXPIDLString.h" + +//#define DEBUG_LEAKS + +#ifdef DEBUG_LEAKS +static gAccessibles = 0; +#endif + +// {61044601-A811-4e2b-BBBA-17BFABD329D7} +EXTERN_C GUID CDECL CLSID_Accessible = +{ 0x61044601, 0xa811, 0x4e2b, { 0xbb, 0xba, 0x17, 0xbf, 0xab, 0xd3, 0x29, 0xd7 } }; + +/* + * Class Accessible + */ + +#ifdef IS_ACCESSIBLE + +// accessibility only on Windows2000 and Windows98 +#ifdef OBJID_WINDOW + + +//----------------------------------------------------- +// construction +//----------------------------------------------------- +Accessible::Accessible(nsIAccessible* aAcc, HWND aWnd) +{ + mAccessible = aAcc; + mWnd = aWnd; + m_cRef = 0; + +#ifdef DEBUG_LEAKS + printf("Accessibles=%d\n", ++gAccessibles); +#endif + +} + +//----------------------------------------------------- +// destruction +//----------------------------------------------------- +Accessible::~Accessible() +{ + m_cRef = 0; +#ifdef DEBUG_LEAKS + printf("Accessibles=%d\n", --gAccessibles); +#endif + +} + + +//----------------------------------------------------- +// IUnknown interface methods - see inknown.h for documentation +//----------------------------------------------------- +STDMETHODIMP Accessible::QueryInterface(REFIID riid, void** ppv) +{ + *ppv=NULL; + + if ( (IID_IUnknown == riid) || (IID_IAccessible == riid) || (IID_IDispatch == riid)) { + *ppv = this; + AddRef(); + return S_OK; + } + + return E_NOINTERFACE; +} + +//----------------------------------------------------- +STDMETHODIMP_(ULONG) Accessible::AddRef() +{ + return ++m_cRef; +} + + +//----------------------------------------------------- +STDMETHODIMP_(ULONG) Accessible::Release() +{ + if (0 != --m_cRef) + return m_cRef; + + delete this; + + return 0; +} + +//----------------------------------------------------- +// IAccessible methods +//----------------------------------------------------- + +STDMETHODIMP Accessible::get_accParent( IDispatch __RPC_FAR *__RPC_FAR *ppdispParent) +{ + nsCOMPtr parent = nsnull; + mAccessible->GetAccParent(getter_AddRefs(parent)); + + if (parent) { + IAccessible* a = new Accessible(parent, mWnd); + a->AddRef(); + *ppdispParent = a; + return S_OK; + } + + // if we have a widget but no parent nsIAccessible then we might have a native + // widget parent that could give us a IAccessible. Lets check. + HWND pWnd = ::GetParent(mWnd); + if (pWnd) { + // get the accessible. + void* ptr = nsnull; + AccessibleObjectFromWindow(pWnd, OBJID_WINDOW, IID_IAccessible, &ptr); + IAccessible* a = (IAccessible*)ptr; + // got one? return it. + if (a) { + *ppdispParent = a; + return NS_OK; + } + } + + *ppdispParent = NULL; + return S_FALSE; +} + +STDMETHODIMP Accessible::get_accChildCount( long __RPC_FAR *pcountChildren) +{ + PRInt32 count = 0; + mAccessible->GetAccChildCount(&count); + //printf("Count=%d\n",count); + *pcountChildren = count; + return S_OK; +} + +STDMETHODIMP Accessible::get_accChild( + /* [in] */ VARIANT varChild, + /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispChild) +{ + nsCOMPtr a; + GetNSAccessibleFor(varChild,a); + + if (a) + { + // if its us return us + if (a == mAccessible) { + *ppdispChild = this; + AddRef(); + return S_OK; + } + + // create a new one. + IAccessible* ia = new Accessible(a, mWnd); + ia->AddRef(); + *ppdispChild = ia; + return S_OK; + } + + *ppdispChild = NULL; + return S_FALSE; +} + +STDMETHODIMP Accessible::get_accName( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR *pszValue) +{ + *pszValue = NULL; + nsCOMPtr a; + GetNSAccessibleFor(varChild,a); + if (a) { + nsXPIDLString name; + nsresult rv = a->GetAccName(getter_Copies(name)); + if (NS_FAILED(rv)) + return S_FALSE; + + *pszValue = ::SysAllocString(name.get()); + } + + return S_OK; +} + +STDMETHODIMP Accessible::get_accValue( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR *pszValue) +{ + *pszValue = NULL; + nsCOMPtr a; + GetNSAccessibleFor(varChild,a); + if (a) { + nsXPIDLString name; + nsresult rv = a->GetAccValue(getter_Copies(name)); + if (NS_FAILED(rv)) + return S_FALSE; + + *pszValue = ::SysAllocString(name.get()); + } + + return S_OK; +} + + +STDMETHODIMP Accessible::get_accDescription( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR *pszValue) +{ + *pszValue = NULL; + nsCOMPtr a; + GetNSAccessibleFor(varChild,a); + if (a) { + nsXPIDLString name; + nsresult rv = a->GetAccDescription(getter_Copies(name)); + if (NS_FAILED(rv)) + return S_FALSE; + + *pszValue = ::SysAllocString(name.get()); + } + + return S_OK; +} + +STDMETHODIMP Accessible::get_accRole( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ VARIANT __RPC_FAR *pvarRole) +{ + VariantInit(pvarRole); + pvarRole->vt = VT_I4; + + nsCOMPtr a; + GetNSAccessibleFor(varChild,a); + + if (!a) + return S_FALSE; + + nsXPIDLString idlrole; + nsresult rv = a->GetAccRole(getter_Copies(idlrole)); + if (NS_FAILED(rv)) + return S_FALSE; + + nsAutoString role(idlrole); + + if (role.EqualsIgnoreCase("text")) + pvarRole->lVal = ROLE_SYSTEM_TEXT; + else if (role.EqualsIgnoreCase("static text")) + pvarRole->lVal = ROLE_SYSTEM_STATICTEXT; + else if (role.EqualsIgnoreCase("graphic")) + pvarRole->lVal = ROLE_SYSTEM_GRAPHIC; + else if (role.EqualsIgnoreCase("table")) + pvarRole->lVal = ROLE_SYSTEM_TABLE; + else if (role.EqualsIgnoreCase("cell")) + pvarRole->lVal = ROLE_SYSTEM_CELL; + else if (role.EqualsIgnoreCase("row")) + pvarRole->lVal = ROLE_SYSTEM_ROW; + else if (role.EqualsIgnoreCase("text")) + pvarRole->lVal = ROLE_SYSTEM_TEXT; + else if (role.EqualsIgnoreCase("combo box")) + pvarRole->lVal = ROLE_SYSTEM_COMBOBOX; + else if (role.EqualsIgnoreCase("link")) + pvarRole->lVal = ROLE_SYSTEM_LINK; + else if (role.EqualsIgnoreCase("list")) + pvarRole->lVal = ROLE_SYSTEM_LIST; + else if (role.EqualsIgnoreCase("list item")) + pvarRole->lVal = ROLE_SYSTEM_LISTITEM; + else if (role.EqualsIgnoreCase("push button")) + pvarRole->lVal = ROLE_SYSTEM_PUSHBUTTON; + else if (role.EqualsIgnoreCase("radio button")) + pvarRole->lVal = ROLE_SYSTEM_RADIOBUTTON; + else if (role.EqualsIgnoreCase("slider")) + pvarRole->lVal = ROLE_SYSTEM_SLIDER; + else if (role.EqualsIgnoreCase("client")) + pvarRole->lVal = ROLE_SYSTEM_CLIENT; + else if (role.EqualsIgnoreCase("window")) + pvarRole->lVal = ROLE_SYSTEM_WINDOW; + else + pvarRole->lVal = ROLE_SYSTEM_ALERT; + + return S_OK; + +} + +STDMETHODIMP Accessible::get_accState( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ VARIANT __RPC_FAR *pvarState) +{ + VariantInit(pvarState); + pvarState->vt = VT_I4; + pvarState->lVal = 0; + + nsCOMPtr a; + GetNSAccessibleFor(varChild,a); + if (!a) + return S_FALSE; + + nsXPIDLString idlrole; + nsresult rv = a->GetAccRole(getter_Copies(idlrole)); + if (NS_FAILED(rv)) + return S_FALSE; + + nsXPIDLString idlstate; + rv = a->GetAccState(getter_Copies(idlstate)); + if (NS_FAILED(rv)) + return S_FALSE; + + nsAutoString state; + + // make sure we have commas at the start and end + state.AssignWithConversion(','); + state.Append(idlrole); + state.AppendWithConversion(','); + + nsAutoString role(idlrole); + + if (state.EqualsIgnoreCase("list item")) { + if (InState(state, "selectable")) + pvarState->lVal |= STATE_SYSTEM_SELECTABLE; + + if (InState(state, "selected")) + pvarState->lVal |= STATE_SYSTEM_SELECTED; + + if (InState(state, "focused")) + pvarState->lVal |= STATE_SYSTEM_FOCUSED; + } + + // is it invisible + if (InState(state, "invisible")) + pvarState->lVal |= STATE_SYSTEM_INVISIBLE; + + // is it focusable + if (InState(state, "focusable")) + pvarState->lVal |= STATE_SYSTEM_FOCUSABLE; + return S_OK; +} + +PRBool Accessible::InState(const nsString& aStates, const char* aState) +{ + return (aStates.Find(aState) == 0); +} + +STDMETHODIMP Accessible::get_accHelp( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR *pszHelp) +{ + return NULL; +} + +STDMETHODIMP Accessible::get_accHelpTopic( + /* [out] */ BSTR __RPC_FAR *pszHelpFile, + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ long __RPC_FAR *pidTopic) +{ + return S_FALSE; +} + +STDMETHODIMP Accessible::get_accKeyboardShortcut( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR *pszKeyboardShortcut) +{ + return S_FALSE; +} + +STDMETHODIMP Accessible::get_accFocus( + /* [retval][out] */ VARIANT __RPC_FAR *pvarChild) +{ + VariantInit(pvarChild); + pvarChild->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP Accessible::get_accSelection( + /* [retval][out] */ VARIANT __RPC_FAR *pvarChildren) +{ + pvarChildren->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP Accessible::get_accDefaultAction( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR *pszDefaultAction) +{ + return NULL; +} + +STDMETHODIMP Accessible::accSelect( + /* [in] */ long flagsSelect, + /* [optional][in] */ VARIANT varChild) +{ + return S_FALSE; +} + +STDMETHODIMP Accessible::accLocation( + /* [out] */ long __RPC_FAR *pxLeft, + /* [out] */ long __RPC_FAR *pyTop, + /* [out] */ long __RPC_FAR *pcxWidth, + /* [out] */ long __RPC_FAR *pcyHeight, + /* [optional][in] */ VARIANT varChild) +{ + PRInt32 x,y,w,h; + mAccessible->AccGetBounds(&x,&y,&w,&h); + + POINT cpos; + cpos.x = x; + cpos.y = y; + + ::ClientToScreen(mWnd, &cpos); + + *pxLeft = cpos.x; + *pyTop = cpos.y; + *pcxWidth = w; + *pcyHeight = h; + + return S_OK; +} + +STDMETHODIMP Accessible::accNavigate( + /* [in] */ long navDir, + /* [optional][in] */ VARIANT varStart, + /* [retval][out] */ VARIANT __RPC_FAR *pvarEndUpAt) +{ + VariantInit(pvarEndUpAt); + + nsCOMPtr acc; + + switch(navDir) { + case NAVDIR_DOWN: + mAccessible->AccNavigateDown(getter_AddRefs(acc)); + break; + case NAVDIR_FIRSTCHILD: + mAccessible->GetAccFirstChild(getter_AddRefs(acc)); + break; + case NAVDIR_LASTCHILD: + mAccessible->GetAccLastChild(getter_AddRefs(acc)); + break; + case NAVDIR_LEFT: + mAccessible->AccNavigateLeft(getter_AddRefs(acc)); + break; + case NAVDIR_NEXT: + mAccessible->GetAccNextSibling(getter_AddRefs(acc)); + break; + case NAVDIR_PREVIOUS: + mAccessible->GetAccPreviousSibling(getter_AddRefs(acc)); + break; + case NAVDIR_RIGHT: + mAccessible->AccNavigateRight(getter_AddRefs(acc)); + break; + case NAVDIR_UP: + mAccessible->AccNavigateUp(getter_AddRefs(acc)); + break; + } + + if (acc) { + IAccessible* a = new Accessible(acc,mWnd); + a->AddRef(); + pvarEndUpAt->vt = VT_DISPATCH; + pvarEndUpAt->pdispVal = a; + return NS_OK; + } else { + pvarEndUpAt->vt = VT_EMPTY; + return S_FALSE; + } +} + +STDMETHODIMP Accessible::accHitTest( + /* [in] */ long xLeft, + /* [in] */ long yTop, + /* [retval][out] */ VARIANT __RPC_FAR *pvarChild) +{ + VariantInit(pvarChild); + + // convert to window coords + nsCOMPtr a; + + POINT cpos; + cpos.x = xLeft; + cpos.y = yTop; + + ::ScreenToClient(mWnd, &cpos); + xLeft = cpos.x; + yTop = cpos.y; + + mAccessible->AccGetAt(xLeft,yTop, getter_AddRefs(a)); + + // if we got a child + if (a) + { + // if the child is us + if (a == mAccessible) { + pvarChild->vt = VT_I4; + pvarChild->lVal = CHILDID_SELF; + } else { // its not create an Accessible for it. + pvarChild->vt = VT_DISPATCH; + pvarChild->pdispVal = new Accessible(a, mWnd); + pvarChild->pdispVal->AddRef(); + } + } else { + // no child at that point + pvarChild->vt = VT_EMPTY; + return S_FALSE; + } + + return S_OK; +} + +STDMETHODIMP Accessible::accDoDefaultAction( + /* [optional][in] */ VARIANT varChild) +{ + if (NS_SUCCEEDED(mAccessible->AccDoDefaultAction())) + return S_OK; + else + return DISP_E_MEMBERNOTFOUND; +} + +STDMETHODIMP Accessible::put_accName( + /* [optional][in] */ VARIANT varChild, + /* [in] */ BSTR szName) +{ + return S_FALSE; +} + +STDMETHODIMP Accessible::put_accValue( + /* [optional][in] */ VARIANT varChild, + /* [in] */ BSTR szValue) +{ + return S_FALSE; +} + +STDMETHODIMP +Accessible::GetTypeInfoCount(UINT *p) +{ + *p = 0; + return E_NOTIMPL; +} + +STDMETHODIMP Accessible::GetTypeInfo(UINT i, LCID lcid, ITypeInfo **ppti) +{ + *ppti = 0; + return E_NOTIMPL; +} + +STDMETHODIMP +Accessible::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, + UINT cNames, LCID lcid, DISPID *rgDispId) +{ + return E_NOTIMPL; +} + +STDMETHODIMP Accessible::Invoke(DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + return E_NOTIMPL; +} + +//------- Helper methods --------- + +void Accessible::GetNSAccessibleFor(VARIANT varChild, nsCOMPtr& aAcc) +{ + if (varChild.lVal == CHILDID_SELF) + aAcc = mAccessible; + else { + long count = 1; + nsCOMPtr a; + nsCOMPtr next; + mAccessible->GetAccFirstChild(getter_AddRefs(a)); + while(a) + { + if (varChild.lVal == count) + { + aAcc = a; + return; + } + + a->GetAccNextSibling(getter_AddRefs(next)); + a = next; + count++; + } + + aAcc = nsnull; + } +} +#endif +#endif \ No newline at end of file diff --git a/widget/src/windows/Accessible.h b/widget/src/windows/Accessible.h new file mode 100644 index 00000000000..1dd50a348f8 --- /dev/null +++ b/widget/src/windows/Accessible.h @@ -0,0 +1,168 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#ifndef _Accessible_H_ +#define _Accessible_H_ + +#include "OLEIDL.H" +#include "OLEACC.H" + +#include "nsCOMPtr.h" +#include "nsIAccessible.h" + +#include "nsString.h" +//#define IS_ACCESSIBLE + +class Accessible : public IAccessible +{ +#ifdef IS_ACCESSIBLE + +// accessibility only on Windows2000 and Windows98 +#ifdef OBJID_WINDOW + + public: // construction, destruction + Accessible(nsIAccessible*, HWND aWin = 0); + ~Accessible(); + + public: // IUnknown methods - see iunknown.h for documentation + STDMETHODIMP_(ULONG) AddRef (); + STDMETHODIMP QueryInterface(REFIID, void**); + STDMETHODIMP_(ULONG) Release (); + + // Return the registered OLE class ID of this object's CfDataObj. + CLSID GetClassID() const; + + public: + + virtual /* [id][propget][hidden] */ HRESULT STDMETHODCALLTYPE get_accParent( + /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispParent); + + virtual /* [id][propget][hidden] */ HRESULT STDMETHODCALLTYPE get_accChildCount( + /* [retval][out] */ long __RPC_FAR *pcountChildren); + + virtual /* [id][propget][hidden] */ HRESULT STDMETHODCALLTYPE get_accChild( + /* [in] */ VARIANT varChild, + /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispChild); + + virtual /* [id][propget][hidden] */ HRESULT STDMETHODCALLTYPE get_accName( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR *pszName); + + virtual /* [id][propget][hidden] */ HRESULT STDMETHODCALLTYPE get_accValue( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR *pszValue); + + virtual /* [id][propget][hidden] */ HRESULT STDMETHODCALLTYPE get_accDescription( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR *pszDescription); + + virtual /* [id][propget][hidden] */ HRESULT STDMETHODCALLTYPE get_accRole( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ VARIANT __RPC_FAR *pvarRole); + + virtual /* [id][propget][hidden] */ HRESULT STDMETHODCALLTYPE get_accState( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ VARIANT __RPC_FAR *pvarState); + + virtual /* [id][propget][hidden] */ HRESULT STDMETHODCALLTYPE get_accHelp( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR *pszHelp); + + virtual /* [id][propget][hidden] */ HRESULT STDMETHODCALLTYPE get_accHelpTopic( + /* [out] */ BSTR __RPC_FAR *pszHelpFile, + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ long __RPC_FAR *pidTopic); + + virtual /* [id][propget][hidden] */ HRESULT STDMETHODCALLTYPE get_accKeyboardShortcut( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR *pszKeyboardShortcut); + + virtual /* [id][propget][hidden] */ HRESULT STDMETHODCALLTYPE get_accFocus( + /* [retval][out] */ VARIANT __RPC_FAR *pvarChild); + + virtual /* [id][propget][hidden] */ HRESULT STDMETHODCALLTYPE get_accSelection( + /* [retval][out] */ VARIANT __RPC_FAR *pvarChildren); + + virtual /* [id][propget][hidden] */ HRESULT STDMETHODCALLTYPE get_accDefaultAction( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR *pszDefaultAction); + + virtual /* [id][hidden] */ HRESULT STDMETHODCALLTYPE accSelect( + /* [in] */ long flagsSelect, + /* [optional][in] */ VARIANT varChild); + + virtual /* [id][hidden] */ HRESULT STDMETHODCALLTYPE accLocation( + /* [out] */ long __RPC_FAR *pxLeft, + /* [out] */ long __RPC_FAR *pyTop, + /* [out] */ long __RPC_FAR *pcxWidth, + /* [out] */ long __RPC_FAR *pcyHeight, + /* [optional][in] */ VARIANT varChild); + + virtual /* [id][hidden] */ HRESULT STDMETHODCALLTYPE accNavigate( + /* [in] */ long navDir, + /* [optional][in] */ VARIANT varStart, + /* [retval][out] */ VARIANT __RPC_FAR *pvarEndUpAt); + + virtual /* [id][hidden] */ HRESULT STDMETHODCALLTYPE accHitTest( + /* [in] */ long xLeft, + /* [in] */ long yTop, + /* [retval][out] */ VARIANT __RPC_FAR *pvarChild); + + virtual /* [id][hidden] */ HRESULT STDMETHODCALLTYPE accDoDefaultAction( + /* [optional][in] */ VARIANT varChild); + + virtual /* [id][propput][hidden] */ HRESULT STDMETHODCALLTYPE put_accName( + /* [optional][in] */ VARIANT varChild, + /* [in] */ BSTR szName); + + virtual /* [id][propput][hidden] */ HRESULT STDMETHODCALLTYPE put_accValue( + /* [optional][in] */ VARIANT varChild, + /* [in] */ BSTR szValue); + + + STDMETHODIMP GetTypeInfoCount(UINT *p); + STDMETHODIMP GetTypeInfo(UINT i, LCID lcid, ITypeInfo **ppti); + STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, + UINT cNames, LCID lcid, DISPID *rgDispId); + STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr); + + + + static ULONG g_cRef; // the cum reference count of all instances + ULONG m_cRef; // the reference count + nsCOMPtr mAccessible; + HWND mWnd; + + protected: + + void GetNSAccessibleFor(VARIANT varChild, nsCOMPtr& aAcc); + PRBool InState(const nsString& aStates, const char* aState); + STDMETHODIMP GetAttribute(const char* aName, VARIANT varChild, BSTR __RPC_FAR *aString); + +#endif +#endif +}; + + +#endif diff --git a/widget/src/windows/makefile.win b/widget/src/windows/makefile.win index 3f3dbb1d176..f04eb8f5f62 100644 --- a/widget/src/windows/makefile.win +++ b/widget/src/windows/makefile.win @@ -26,6 +26,7 @@ LIBRARY_NAME = raptorwidget_s DEFINES =-D_IMPL_NS_WIDGET -DMOZ_AIMM CPPSRCS = \ + Accessible.cpp \ nsFontRetrieverService.cpp \ nsFontSizeIterator.cpp \ nsNativeDragTarget.cpp \ @@ -50,6 +51,7 @@ CPPSRCS = \ MODULE=raptor OBJS = \ + .\$(OBJDIR)\Accessible.obj \ .\$(OBJDIR)\nsFontRetrieverService.obj \ .\$(OBJDIR)\nsFontSizeIterator.obj \ .\$(OBJDIR)\nsNativeDragTarget.obj \ @@ -86,7 +88,8 @@ LCFLAGS = \ $(NULL) WIN_LIBS= \ - ole32.lib + ole32.lib + include <$(DEPTH)\config\rules.mak> diff --git a/widget/src/windows/nsWindow.cpp b/widget/src/windows/nsWindow.cpp index 22eec766a3f..990ad75ec8c 100644 --- a/widget/src/windows/nsWindow.cpp +++ b/widget/src/windows/nsWindow.cpp @@ -53,6 +53,12 @@ #include "prtime.h" #include "nsIRenderingContextWin.h" +// accessibility only on Windows2000 and Windows98 +#if(WINVER >= 0x0400) +#include "nsIAccessible.h" +#include "Accessible.h" +#endif + #include #ifdef MOZ_AIMM #include "aimm.h" @@ -207,8 +213,8 @@ extern HINSTANCE g_hinst; if (nsToolkit::gAIMMApp) \ nsToolkit::gAIMMApp->GetContext(hWnd, &(hIMC)); \ else { \ - nsIMM &theIMM = nsIMM::LoadModule(); \ - hIMC = theIMM.GetContext(hWnd); \ + nsIMM& theIMM = nsIMM::LoadModule(); \ + hIMC = (HIMC)theIMM.GetContext(hWnd); \ } \ } @@ -529,6 +535,7 @@ nsWindow::~nsWindow() nsMemory::Free(mIMEReconvertUnicode); NS_IF_RELEASE(mNativeDragTarget); + } @@ -3338,6 +3345,30 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT nsServiceManager::ReleaseService(kCClipboardCID, clipboard); } break; +#ifdef IS_ACCESSIBLE + // accessibility only on Windows2000 and Windows98 +#ifdef WM_GETOBJECT + case WM_GETOBJECT: + { + if (lParam == OBJID_CLIENT) { + nsCOMPtr acc; + DispatchAccessibleEvent(NS_GETACCESSIBLE, getter_AddRefs(acc)); + + // create the COM accessible object + if (acc) + { + HWND wnd = GetWindowHandle(); + IAccessible* pAcc = new Accessible(acc, wnd); // ref is 0 + LRESULT lAcc = LresultFromObject(IID_IAccessible, wParam, pAcc); // ref 1 + *aRetValue = lAcc; + return PR_TRUE; // yes we handled it. + } + } + } + break; +#endif +#endif + default: { // Handle both flavors of mouse wheel events. if ((msg == WM_MOUSEWHEEL) || (msg == uMSH_MOUSEWHEEL)) { @@ -4097,6 +4128,41 @@ PRBool nsWindow::DispatchMouseEvent(PRUint32 aEventType, nsPoint* aPoint) return result; } +//------------------------------------------------------------------------- +// +// Deal with all sort of mouse event +// +//------------------------------------------------------------------------- +PRBool nsWindow::DispatchAccessibleEvent(PRUint32 aEventType, nsIAccessible** aAcc, nsPoint* aPoint) +{ + PRBool result = PR_FALSE; + + if (nsnull == mEventCallback) { + return result; + } + + *aAcc = nsnull; + + nsAccessibleEvent event; + InitEvent(event, aEventType, aPoint); + + event.isShift = IS_VK_DOWN(NS_VK_SHIFT); + event.isControl = IS_VK_DOWN(NS_VK_CONTROL); + event.isMeta = PR_FALSE; + event.isAlt = IS_VK_DOWN(NS_VK_ALT); + event.eventStructType = NS_ACCESSIBLE_EVENT; + event.accessible = nsnull; + + result = DispatchWindowEvent(&event); + + // if the event returned an accesssible get it. + if (event.accessible) + *aAcc = event.accessible; + + NS_RELEASE(event.widget); + + return result; +} //------------------------------------------------------------------------- // // Deal with focus messages diff --git a/widget/src/windows/nsWindow.h b/widget/src/windows/nsWindow.h index 50eb381340b..62e53050fd4 100644 --- a/widget/src/windows/nsWindow.h +++ b/widget/src/windows/nsWindow.h @@ -44,6 +44,7 @@ class nsNativeDragTarget; class nsIRollupListener; class nsIMenuBar; +struct IAccessible; #define NSRGB_2_COLOREF(color) \ RGB(NS_GET_R(color),NS_GET_G(color),NS_GET_B(color)) @@ -286,6 +287,7 @@ public: WNDPROC GetPrevWindowProc() { return mPrevWndProc; } virtual PRBool DispatchMouseEvent(PRUint32 aEventType, nsPoint* aPoint = nsnull); + virtual PRBool DispatchAccessibleEvent(PRUint32 aEventType, nsIAccessible** aAccessible, nsPoint* aPoint = nsnull); virtual PRBool AutoErase(); nsPoint* GetLastPoint() { return &mLastPoint; }