Skip to content

Commit dc0266c

Browse files
committed
Cleanup of the accessibility COM objects (#53)
Fixed issue related to the cleanup of the accessibility COM objects that may cause Explorer to crash. Submitted by Ivo Beltchev. Fixes #53
1 parent 3df484d commit dc0266c

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

ClassicStartSrc/ClassicStartMenu/ClassicStartMenuDLL/MenuContainer.cpp

+37-4
Original file line numberDiff line numberDiff line change
@@ -4426,13 +4426,28 @@ LRESULT CMenuContainer::OnCreate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
44264426
if (m_Options&CONTAINER_SEARCH)
44274427
s_SearchMenu=m_hWnd;
44284428
s_HotPos=GetMessagePos();
4429+
m_pAccessible=NULL;
44294430
if (GetSettingBool(L"EnableAccessibility"))
44304431
{
4431-
m_pAccessible=new CMenuAccessible(this);
4432+
if (SUCCEEDED(m_pAccessibleContext.CoCreateInstance(CLSID_ContextSwitcher)))
4433+
{
4434+
CreateAccessibleData createData={this};
4435+
ComCallData callData={};
4436+
callData.pUserDefined=&createData;
4437+
if (SUCCEEDED(m_pAccessibleContext->ContextCallback(CreateAccessible,&callData,IID_IAccessible,4,NULL)))
4438+
{
4439+
if (FAILED(CoGetInterfaceAndReleaseStream(createData.pStream,IID_IAccessible,(void**)&m_pAccessible)))
4440+
{
4441+
m_pAccessibleContext=NULL;
4442+
}
4443+
}
4444+
else
4445+
{
4446+
m_pAccessibleContext=NULL;
4447+
}
4448+
}
44324449
NotifyWinEvent(EVENT_SYSTEM_MENUPOPUPSTART,m_hWnd,OBJID_CLIENT,CHILDID_SELF);
44334450
}
4434-
else
4435-
m_pAccessible=NULL;
44364451
m_pDropTargetProxy=new CDropTargetProxy(this);
44374452
RegisterDragDrop(m_hWnd,m_pDropTargetProxy);
44384453
if (!m_bSubMenu && s_pFrameworkInputPane)
@@ -4441,6 +4456,23 @@ LRESULT CMenuContainer::OnCreate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
44414456
return 0;
44424457
}
44434458

4459+
HRESULT __stdcall CMenuContainer::CreateAccessible( ComCallData *pData )
4460+
{
4461+
CreateAccessibleData *pCreateData=(CreateAccessibleData*)pData->pUserDefined;
4462+
CComPtr<CMenuAccessible> pAccessible=new CMenuAccessible(pCreateData->pMenu);
4463+
HRESULT hr=CoMarshalInterThreadInterfaceInStream(IID_IAccessible,pAccessible,&pCreateData->pStream);
4464+
if (FAILED(hr))
4465+
{
4466+
pAccessible->Reset();
4467+
}
4468+
return hr;
4469+
}
4470+
4471+
HRESULT __stdcall CMenuContainer::ReleaseAccessible( ComCallData *pData )
4472+
{
4473+
return CoDisconnectContext(INFINITE);
4474+
}
4475+
44444476
bool CMenuContainer::GetItemRect( int index, RECT &rc )
44454477
{
44464478
if (index>=0 && index<(int)m_Items.size())
@@ -6111,7 +6143,8 @@ LRESULT CMenuContainer::OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL
61116143
if (m_pAccessible)
61126144
{
61136145
NotifyWinEvent(EVENT_SYSTEM_MENUPOPUPEND,m_hWnd,OBJID_CLIENT,CHILDID_SELF);
6114-
m_pAccessible->Reset();
6146+
m_pAccessibleContext->ContextCallback(ReleaseAccessible,NULL,IID_IAccessible,4,NULL);
6147+
m_pAccessibleContext=NULL;
61156148
m_pAccessible=NULL;
61166149
}
61176150
if (m_pDropTargetHelper && m_pDragObject)

ClassicStartSrc/ClassicStartMenu/ClassicStartMenuDLL/MenuContainer.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "TouchHelper.h"
1313
#include <vector>
1414
#include <map>
15+
#include <ctxtcall.h>
1516

1617
//#define PREVENT_CLOSING // define this to prevent the menu from closing when it is deactivated (useful for debugging)
1718
//#define REPEAT_ITEMS 10 // define this to repeat each menu item (useful to simulate large menus)
@@ -628,7 +629,8 @@ class CMenuContainer: public IDropTarget, public IFrameworkInputPaneHandler, pub
628629
CAbsolutePidl m_Path2[2];
629630
CComPtr<IShellItem> m_pDropFolder[2]; // the primary folder (used only as a drop target)
630631
CComPtr<IShellView> m_pShellView; // keep the view alive because some buggy namespace extensions clean up if there is no view
631-
CComPtr<CMenuAccessible> m_pAccessible;
632+
CComPtr<IContextCallback> m_pAccessibleContext;
633+
CComPtr<IAccessible> m_pAccessible;
632634
CComPtr<CDropTargetProxy> m_pDropTargetProxy;
633635
DWORD m_InputCookie;
634636
std::vector<int> m_ColumnOffsets;
@@ -983,6 +985,14 @@ class CMenuContainer: public IDropTarget, public IFrameworkInputPaneHandler, pub
983985
};
984986
static void CloseSubMenus( int flags, CMenuContainer *pAfter );
985987

988+
struct CreateAccessibleData
989+
{
990+
CMenuContainer *pMenu;
991+
IStream *pStream;
992+
};
993+
static HRESULT __stdcall CreateAccessible( ComCallData *pData );
994+
static HRESULT __stdcall ReleaseAccessible( ComCallData *pData );
995+
986996
// To control the placement of the start menu, send ClassicStartMenu.StartMenuMsg message right after the start menu is created but before it is displayed
987997
// The lParam must point to StartMenuParams
988998
// monitorRect - the entire area available to the start menu (sub-menus will use it). It is usually the monitor area but can be less if the Desktop app is docked in Win8

0 commit comments

Comments
 (0)