Skip to content

Commit 1384d4e

Browse files
authored
Improve screen reader, keyboard, and High Contrast accessibility (#2518)
* Improve screen reader and keyboard accessibility * Fix settings page repaint regression --------- Co-authored-by: jbgrimsby <314385300+jbgrimsby@users.noreply.github.com>
1 parent da73edf commit 1384d4e

10 files changed

Lines changed: 405 additions & 17 deletions

File tree

‎Src/ClassicExplorer/ClassicExplorerSettings/ClassicExplorerSettings.cpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpstrC
135135
FARPROC proc=GetProcAddress(dll,"ShowExplorerSettings");
136136
if (!proc) return 2;
137137

138+
HRESULT comResult=CoInitialize(NULL);
138139
proc();
140+
if (SUCCEEDED(comResult)) CoUninitialize();
139141
return 0;
140142
}

‎Src/ClassicIE/ClassicIE.cpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdL
252252
return 0;
253253
}
254254

255+
HRESULT comResult=CoInitialize(NULL);
255256
ShowIESettings();
257+
if (SUCCEEDED(comResult)) CoUninitialize();
256258
return 0;
257259
}

‎Src/Lib/Lib.rc‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ BEGIN
7070
EDITTEXT IDC_EDITSEARCH,22,7,120,12,ES_AUTOHSCROLL
7171
CONTROL "Show all settings",IDC_CHECKALL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,154,7,79,12
7272
CONTROL "<a>Help...</a>",IDC_LINKHELP,"SysLink",WS_TABSTOP,348,9,26,10,WS_EX_TRANSPARENT
73-
CONTROL "",IDC_TABSETTINGS,"SysTabControl32",TCS_MULTILINE | TCS_FOCUSNEVER,7,20,367,169
73+
CONTROL "",IDC_TABSETTINGS,"SysTabControl32",TCS_MULTILINE | WS_TABSTOP,7,20,367,169
7474
CONTROL "<a>Open-Shell Homepage</a>",IDC_LINKWEB,"SysLink",WS_TABSTOP,7,195,75,10,WS_EX_TRANSPARENT
7575
CONTROL "Name of translator goes <a href=""http://www.yoursite.com"">here</a>",IDC_SYSLINKLOC,
7676
"SysLink",NOT WS_VISIBLE | WS_TABSTOP,80,195,111,10
@@ -282,7 +282,9 @@ END
282282

283283
STRINGTABLE
284284
BEGIN
285-
IDS_INITIATE_FAIL "Failed to initiate the download."
285+
IDS_SETTINGS_PAGES "Settings pages"
286+
IDS_SETTING_MODIFIED "modified"
287+
IDS_INITIATE_FAIL "Failed to initiate the download."
286288
IDS_UPDATE_TITLE "Open-Shell Update"
287289
IDS_INST_DOWNLOAD_FAIL "Failed to download the new version."
288290
IDS_INST_SAVE_FAIL "Failed to save file '%s'."

‎Src/Lib/Settings.cpp‎

Lines changed: 81 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,7 @@ class CSettingsDlg: public CResizeableDlg<CSettingsDlg>
11101110
public:
11111111
CSettingsDlg( void );
11121112
void Init( CSetting *pSettings, ICustomSettings *pCustom, int tab, const wchar_t* appId );
1113+
bool NavigateTab( bool bPrevious );
11131114

11141115
BEGIN_MSG_MAP( CSettingsDlg )
11151116
MESSAGE_HANDLER( WM_INITDIALOG, OnInitDialog )
@@ -1186,7 +1187,7 @@ class CSettingsDlg: public CResizeableDlg<CSettingsDlg>
11861187
const wchar_t* m_AppId;
11871188

11881189
void AddTabs( int name, const CSetting *pSelect=NULL );
1189-
void SetCurTab( int index, bool bReset, const CSetting *pSelect=NULL );
1190+
void SetCurTab( int index, bool bReset, const CSetting *pSelect=NULL, bool bFocusPanel=true );
11901191
bool IsTabValid( void );
11911192
void StorePlacement( void );
11921193

@@ -1312,6 +1313,7 @@ LRESULT CSettingsDlg::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOO
13121313
icon=(HICON)LoadImage(GetModuleHandle(L"shell32.dll"),MAKEINTRESOURCE(323),IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),LR_DEFAULTCOLOR);
13131314
SendDlgItemMessage(IDC_ICONSEARCH,STM_SETICON,(WPARAM)icon);
13141315
SendDlgItemMessage(IDC_EDITSEARCH,EM_SETCUEBANNER,FALSE,(LPARAM)(const wchar_t*)LoadStringEx(IDS_SEARCH_PROMPT));
1316+
SetControlAccessibleName(GetDlgItem(IDC_EDITSEARCH),LoadStringEx(IDS_SEARCH_PROMPT));
13151317
SetWindowSubclass(GetDlgItem(IDC_EDITSEARCH),SubclassSearchBoxProc,'CLSH',0);
13161318

13171319
CWindow tooltip;
@@ -1364,6 +1366,7 @@ LRESULT CSettingsDlg::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOO
13641366

13651367
SIZE maxSize={0,0};
13661368
m_Tabs=GetDlgItem(IDC_TABSETTINGS);
1369+
m_Tabs.SetWindowText(LoadStringEx(IDS_SETTINGS_PAGES));
13671370
m_Panel=NULL;
13681371
int idx=0;
13691372
for (const CSetting *pSetting=m_pSettings;pSetting->name;pSetting++)
@@ -1418,7 +1421,8 @@ LRESULT CSettingsDlg::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOO
14181421
ShowWindow(SW_MAXIMIZE);
14191422
}
14201423

1421-
return TRUE;
1424+
GetDlgItem(IDC_BUTTONBACKUP).SetFocus();
1425+
return FALSE;
14221426
}
14231427

14241428
LRESULT CSettingsDlg::OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
@@ -1477,6 +1481,14 @@ void CSettingsDlg::AddTabs( int name, const CSetting *pSelect )
14771481
if (pSetting->nameID==name)
14781482
idx=i;
14791483
}
1484+
int tabCount=TabCtrl_GetItemCount(m_Tabs);
1485+
LONG_PTR tabStyle=m_Tabs.GetWindowLongPtr(GWL_STYLE);
1486+
if (tabCount<=1)
1487+
tabStyle=(tabStyle&~WS_TABSTOP)|TCS_FOCUSNEVER;
1488+
else
1489+
tabStyle=(tabStyle|WS_TABSTOP)&~TCS_FOCUSNEVER;
1490+
m_Tabs.SetWindowLongPtr(GWL_STYLE,tabStyle);
1491+
m_Tabs.SetWindowPos(NULL,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_FRAMECHANGED);
14801492
m_Index=-1;
14811493
TabCtrl_SetCurSel(m_Tabs,idx);
14821494
m_Tabs.InvalidateRect(NULL);
@@ -1499,20 +1511,23 @@ LRESULT CSettingsDlg::OnKeyDown( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
14991511
if (wParam==VK_TAB && GetKeyState(VK_CONTROL)<0)
15001512
{
15011513
int sel=TabCtrl_GetCurSel(m_Tabs);
1514+
int count=TabCtrl_GetItemCount(m_Tabs);
15021515
if (GetKeyState(VK_SHIFT)<0)
15031516
{
1504-
if (sel>0)
1517+
if (count>0)
15051518
{
1506-
TabCtrl_SetCurSel(m_Tabs,sel-1);
1507-
SetCurTab(sel-1,false);
1519+
int next=(sel+count-1)%count;
1520+
TabCtrl_SetCurSel(m_Tabs,next);
1521+
SetCurTab(next,false);
15081522
}
15091523
}
15101524
else
15111525
{
1512-
if (sel<TabCtrl_GetItemCount(m_Tabs)-1)
1526+
if (count>0)
15131527
{
1514-
TabCtrl_SetCurSel(m_Tabs,sel+1);
1515-
SetCurTab(sel+1,false);
1528+
int next=(sel+1)%count;
1529+
TabCtrl_SetCurSel(m_Tabs,next);
1530+
SetCurTab(next,false);
15161531
}
15171532
}
15181533
}
@@ -1740,6 +1755,7 @@ LRESULT CSettingsDlg::OnCheckAll( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL
17401755
{
17411756
m_bBasic=bBasic;
17421757
AddTabs(-1);
1758+
::SetFocus(hWndCtl);
17431759
}
17441760
return 0;
17451761
}
@@ -1758,7 +1774,7 @@ LRESULT CSettingsDlg::OnSearchChange( WORD wNotifyCode, WORD wID, HWND hWndCtl,
17581774
return 0;
17591775
}
17601776

1761-
void CSettingsDlg::SetCurTab( int index, bool bReset, const CSetting *pSelect )
1777+
void CSettingsDlg::SetCurTab( int index, bool bReset, const CSetting *pSelect, bool bFocusPanel )
17621778
{
17631779
if (m_Index==index && !bReset) return;
17641780
m_Index=index;
@@ -1778,12 +1794,59 @@ void CSettingsDlg::SetCurTab( int index, bool bReset, const CSetting *pSelect )
17781794
::MapWindowPoints(NULL,m_hWnd,(POINT*)&rc,2);
17791795
TabCtrl_AdjustRect(m_Tabs,FALSE,&rc);
17801796
HWND hwnd=pPanel->Activate(pGroup,rc,bReset);
1797+
CString pageTitle=LoadStringEx(pGroup->nameID);
1798+
::SetWindowText(hwnd,pageTitle);
17811799
if (hwnd!=m_Panel)
17821800
{
17831801
if (m_Panel) ::ShowWindow(m_Panel,SW_HIDE);
17841802
m_Panel=hwnd;
1785-
::SetFocus(m_Panel);
17861803
}
1804+
if (bFocusPanel) ::SetFocus(m_Panel);
1805+
}
1806+
1807+
bool CSettingsDlg::NavigateTab( bool bPrevious )
1808+
{
1809+
HWND focus=::GetFocus();
1810+
HWND firstPanel=m_Panel?::GetNextDlgTabItem(m_Panel,NULL,FALSE):NULL;
1811+
HWND lastPanel=m_Panel?::GetNextDlgTabItem(m_Panel,NULL,TRUE):NULL;
1812+
HWND targets[]={
1813+
GetDlgItem(IDC_BUTTONBACKUP),
1814+
GetDlgItem(IDC_CHECKALL),
1815+
GetDlgItem(IDC_EDITSEARCH),
1816+
GetDlgItem(IDC_TABSETTINGS),
1817+
firstPanel,
1818+
GetDlgItem(IDOK),
1819+
GetDlgItem(IDCANCEL),
1820+
GetDlgItem(IDC_LINKHELP),
1821+
GetDlgItem(IDC_LINKWEB),
1822+
};
1823+
1824+
int current=-1;
1825+
if (m_Panel && (focus==m_Panel || ::IsChild(m_Panel,focus)))
1826+
{
1827+
HWND next=::GetNextDlgTabItem(m_Panel,focus,bPrevious);
1828+
HWND wrapped=bPrevious?lastPanel:firstPanel;
1829+
if (next && next!=wrapped)
1830+
return false; // Let IsDialogMessage move within the active page.
1831+
current=4;
1832+
}
1833+
else
1834+
{
1835+
for (int i=0;i<_countof(targets);i++)
1836+
if (focus==targets[i]) { current=i; break; }
1837+
}
1838+
if (current<0) return false;
1839+
1840+
for (int step=1;step<=_countof(targets);step++)
1841+
{
1842+
int index=(current+(bPrevious?-step:step)+_countof(targets)*2)%_countof(targets);
1843+
HWND target=(index==4 && bPrevious)?lastPanel:targets[index];
1844+
if (!target || !::IsWindowVisible(target) || !::IsWindowEnabled(target)) continue;
1845+
if (index==3 && !(::GetWindowLongPtr(target,GWL_STYLE)&WS_TABSTOP)) continue;
1846+
::SetFocus(target);
1847+
return true;
1848+
}
1849+
return false;
17871850
}
17881851

17891852
LRESULT CSettingsDlg::OnSelChanging( int idCtrl, LPNMHDR pnmh, BOOL& bHandled )
@@ -1793,7 +1856,9 @@ LRESULT CSettingsDlg::OnSelChanging( int idCtrl, LPNMHDR pnmh, BOOL& bHandled )
17931856

17941857
LRESULT CSettingsDlg::OnSelChange( int idCtrl, LPNMHDR pnmh, BOOL& bHandled )
17951858
{
1796-
SetCurTab(TabCtrl_GetCurSel(m_Tabs),false);
1859+
// Mouse clicks and Left/Right navigation keep focus on the tab strip.
1860+
// Ctrl+Tab is handled separately and moves focus into the new page.
1861+
SetCurTab(TabCtrl_GetCurSel(m_Tabs),false,NULL,false);
17971862
return 0;
17981863
}
17991864

@@ -1926,6 +1991,11 @@ bool IsSettingsMessage( MSG *msg )
19261991
g_SettingsDlg.SendMessage(WM_KEYDOWN,VK_TAB,msg->lParam);
19271992
return true;
19281993
}
1994+
if (msg->message==WM_KEYDOWN && msg->wParam==VK_TAB)
1995+
{
1996+
if (g_SettingsDlg.NavigateTab(GetKeyState(VK_SHIFT)<0))
1997+
return true;
1998+
}
19291999
if (msg->message==WM_KEYDOWN && msg->wParam==VK_RETURN && GetKeyState(VK_CONTROL)<0)
19302000
{
19312001
g_SettingsDlg.SendMessage(WM_COMMAND,IDOK,0);

0 commit comments

Comments
 (0)