@@ -1110,6 +1110,7 @@ class CSettingsDlg: public CResizeableDlg<CSettingsDlg>
11101110public:
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
14241428LRESULT 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
17891852LRESULT CSettingsDlg::OnSelChanging ( int idCtrl, LPNMHDR pnmh, BOOL & bHandled )
@@ -1793,7 +1856,9 @@ LRESULT CSettingsDlg::OnSelChanging( int idCtrl, LPNMHDR pnmh, BOOL& bHandled )
17931856
17941857LRESULT 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