Skip to content

Commit 4f7736a

Browse files
authored
[SHELL32] Implement single-click mode in DefView (reactos#8054)
1 parent 22d077f commit 4f7736a

File tree

3 files changed

+99
-60
lines changed

3 files changed

+99
-60
lines changed

dll/win32/shell32/CDefView.cpp

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ class CDefView :
346346
LRESULT DoColumnContextMenu(LRESULT lParam);
347347
UINT GetSelections();
348348
SFGAOF GetSelectionAttributes(SFGAOF Query);
349-
HRESULT OpenSelectedItems();
349+
HRESULT OpenSelectedItems(PCSTR pszVerb = NULL);
350350
void OnDeactivate();
351351
void DoActivate(UINT uState);
352352
HRESULT drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
@@ -357,6 +357,7 @@ class CDefView :
357357
HRESULT LoadViewState();
358358
HRESULT SaveViewState(IStream *pStream);
359359
void UpdateFolderViewFlags();
360+
UINT GetItemActivateFlags();
360361

361362
DWORD GetCommDlgViewFlags()
362363
{
@@ -906,9 +907,9 @@ BOOL CDefView::CreateList()
906907
if (m_FolderSettings.fFlags & FWF_FULLROWSELECT)
907908
ListExStyle |= LVS_EX_FULLROWSELECT;
908909

909-
if ((m_FolderSettings.fFlags & FWF_SINGLECLICKACTIVATE) ||
910-
(!SHELL_GetSetting(SSF_DOUBLECLICKINWEBVIEW, fDoubleClickInWebView) && !SHELL_GetSetting(SSF_WIN95CLASSIC, fWin95Classic)))
911-
ListExStyle |= LVS_EX_TRACKSELECT | LVS_EX_ONECLICKACTIVATE;
910+
ListExStyle |= GetItemActivateFlags();
911+
if (ListExStyle & LVS_EX_ONECLICKACTIVATE)
912+
ListExStyle |= SHELL_GetIconUnderlineFlags();
912913

913914
if (m_FolderSettings.fFlags & FWF_NOCOLUMNHEADER)
914915
dwStyle |= LVS_NOCOLUMNHEADER;
@@ -2184,7 +2185,7 @@ HRESULT CDefView::InvokeContextMenuCommand(CComPtr<IContextMenu>& pCM, LPCSTR lp
21842185
return S_OK;
21852186
}
21862187

2187-
HRESULT CDefView::OpenSelectedItems()
2188+
HRESULT CDefView::OpenSelectedItems(PCSTR pszVerb)
21882189
{
21892190
HMENU hMenu;
21902191
UINT uCommand;
@@ -2213,13 +2214,15 @@ HRESULT CDefView::OpenSelectedItems()
22132214
return hResult;
22142215

22152216
uCommand = GetMenuDefaultItem(hMenu, FALSE, 0);
2216-
if (uCommand == (UINT)-1)
2217+
if (uCommand == (UINT)-1 && !pszVerb)
22172218
{
22182219
ERR("GetMenuDefaultItem returned -1\n");
22192220
return E_FAIL;
22202221
}
2222+
if (!pszVerb)
2223+
pszVerb = MAKEINTRESOURCEA(uCommand);
22212224

2222-
InvokeContextMenuCommand(pCM, MAKEINTRESOURCEA(uCommand), NULL);
2225+
InvokeContextMenuCommand(pCM, pszVerb, NULL);
22232226

22242227
return hResult;
22252228
}
@@ -2681,11 +2684,9 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
26812684
break;
26822685
case NM_DBLCLK:
26832686
TRACE("-- NM_DBLCLK %p\n", this);
2684-
OpenSelectedItems();
26852687
break;
26862688
case NM_RETURN:
26872689
TRACE("-- NM_RETURN %p\n", this);
2688-
OpenSelectedItems();
26892690
break;
26902691
case HDN_ENDTRACKW:
26912692
TRACE("-- HDN_ENDTRACKW %p\n", this);
@@ -2705,7 +2706,7 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
27052706
break;
27062707
case LVN_ITEMACTIVATE:
27072708
TRACE("-- LVN_ITEMACTIVATE %p\n", this);
2708-
OnStateChange(CDBOSC_SELCHANGE); // browser will get the IDataObject
2709+
OpenSelectedItems(((NMITEMACTIVATE *)lpnmh)->uKeyFlags & LVKF_ALT ? "properties" : NULL);
27092710
break;
27102711
case LVN_COLUMNCLICK:
27112712
{
@@ -3028,6 +3029,15 @@ LRESULT CDefView::OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL
30283029
if (wParam == SPI_SETDESKWALLPAPER || wParam == 0)
30293030
UpdateListColors();
30303031

3032+
UINT ListExMask = LVS_EX_TRACKSELECT | LVS_EX_ONECLICKACTIVATE;
3033+
UINT ListExBits = GetItemActivateFlags();
3034+
if (wParam == SPI_GETICONTITLELOGFONT ||
3035+
(lParam && !lstrcmpiW((PWSTR)lParam, REGSTR_PATH_EXPLORER L"\\IconUnderline")))
3036+
{
3037+
ListExMask |= LVS_EX_UNDERLINEHOT | LVS_EX_UNDERLINECOLD;
3038+
ListExBits |= SHELL_GetIconUnderlineFlags();
3039+
}
3040+
m_ListView.SetExtendedListViewStyle(ListExBits, ListExMask);
30313041
m_ListView.SendMessage(uMsg, wParam, lParam);
30323042
return S_OK;
30333043
}
@@ -3458,6 +3468,14 @@ void CDefView::UpdateFolderViewFlags()
34583468
UPDATEFOLDERVIEWFLAGS(m_FolderSettings.fFlags, FWF_NOGROUPING, !ListView_IsGroupViewEnabled(m_ListView.m_hWnd));
34593469
}
34603470

3471+
UINT CDefView::GetItemActivateFlags()
3472+
{
3473+
SHELLSTATE ss;
3474+
SHGetSetSettings(&ss, SSF_DOUBLECLICKINWEBVIEW | SSF_WIN95CLASSIC, FALSE);
3475+
return ((m_FolderSettings.fFlags & FWF_SINGLECLICKACTIVATE) || (!ss.fDoubleClickInWebView && !ss.fWin95Classic))
3476+
? (LVS_EX_TRACKSELECT | LVS_EX_ONECLICKACTIVATE) : 0;
3477+
}
3478+
34613479
HRESULT WINAPI CDefView::SelectItem(PCUITEMID_CHILD pidl, UINT uFlags)
34623480
{
34633481
int i;

dll/win32/shell32/dialogs/general.cpp

Lines changed: 69 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@
2323

2424
WINE_DEFAULT_DEBUG_CHANNEL (fprop);
2525

26-
static const LPCWSTR s_pszExplorerKey =
27-
L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer";
26+
static const LPCWSTR s_pszExplorerKey = REGSTR_PATH_EXPLORER;
27+
28+
enum { UNDERLINE_ON, UNDERLINE_OFF, UNDERLINE_HOVER, UNDERLINE_IE };
2829

2930
/////////////////////////////////////////////////////////////////////////////
3031
// Shell settings
@@ -60,28 +61,20 @@ SHELL32_WriteRegShellState(PREGSHELLSTATE prss)
6061
// bDoubleClick is FALSE if "Single-click to open an item (point to select)".
6162
//////////////////////////////////////////////////////////////////////////////
6263
// API Monitor:
63-
// SHLWAPI.dll RegOpenKeyExW ( 0x000000c8, NULL, 0, MAXIMUM_ALLOWED, 0x00def234 ) ERROR_SUCCESS 0.0000243
64-
// SHLWAPI.dll RegSetValueExW ( 0x000003e8, "ShellState", 0, REG_BINARY, 0x000c2050, 36 ) ERROR_SUCCESS 0.0001028
65-
// SHLWAPI.dll RegCloseKey ( 0x000003e8 ) ERROR_SUCCESS 0.0000081
66-
// Explorer.EXE SHSettingsChanged ( 0, "ShellState" ) 0.0000131
64+
// SHLWAPI.dll RegOpenKeyExW ( 0x000000c8, NULL, 0, MAXIMUM_ALLOWED, 0x00def234 ) ERROR_SUCCESS
65+
// SHLWAPI.dll RegSetValueExW ( 0x000003e8, "ShellState", 0, REG_BINARY, 0x000c2050, 36 ) ERROR_SUCCESS
66+
// SHLWAPI.dll RegCloseKey ( 0x000003e8 ) ERROR_SUCCESS
67+
// Explorer.EXE SHSettingsChanged ( 0, "ShellState" ) (WM_SETTINGCHANGE handling)
6768
static BOOL
6869
IntSetShellStateSettings(BOOL bDoubleClick, BOOL bUseCommonTasks)
6970
{
7071
SHELLSTATE shellstate;
7172
shellstate.fDoubleClickInWebView = !!bDoubleClick;
7273
shellstate.fWebView = !!bUseCommonTasks;
7374
SHGetSetSettings(&shellstate, SSF_DOUBLECLICKINWEBVIEW | SSF_WEBVIEW, TRUE);
74-
75-
// FIXME: This is not correct, it does nothing. SHGetSetSettings will broadcast it.
76-
SHSettingsChanged(0, L"ShellState");
7775
return TRUE;
7876
}
7977

80-
//////////////////////////////////////////////////////////////////////////////
81-
// API Monitor:
82-
// SHLWAPI.dll RegOpenKeyExW ( 0x000000c8, NULL, 0, MAXIMUM_ALLOWED, 0x0007e484 ) ERROR_SUCCESS 0.0000388
83-
// SHLWAPI.dll RegQueryValueExW ( 0x000005a8, "ShellState", NULL, 0x0007e474, 0x000c2050, 0x0007e4fc ) ERROR_SUCCESS 0.0000271
84-
// SHLWAPI.dll RegCloseKey ( 0x000005a8 ) ERROR_SUCCESS 0.0000112
8578
EXTERN_C BOOL
8679
SHELL32_ReadRegShellState(PREGSHELLSTATE prss)
8780
{
@@ -91,32 +84,61 @@ SHELL32_ReadRegShellState(PREGSHELLSTATE prss)
9184
return err == ERROR_SUCCESS && prss->dwSize >= REGSHELLSTATE_SIZE;
9285
}
9386

94-
// bIconUnderline is TRUE if "Underline icon titles only when I point at them".
95-
// bIconUnderline is FALSE if "Underline icon titles consistent with my browser".
87+
// bUnderlineHover is TRUE if "Underline icon titles only when I point at them".
88+
// bUnderlineHover is FALSE if "Underline icon titles consistent with my browser".
9689
//////////////////////////////////////////////////////////////////////////////
9790
// API Monitor:
98-
// SHELL32.dll SHRegGetUSValueW ( "Software\Microsoft\Windows\CurrentVersion\Explorer", "IconUnderline", NULL, 0x00d2f324, 0x00d2f328, FALSE, 0x00d2f32c, 4 ) ERROR_SUCCESS 0.0002484
99-
// SHELL32.dll IsDlgButtonChecked ( 0x0005009e, 30104 ) BST_CHECKED 0.0000212
100-
// SHELL32.dll SHRegSetUSValueW ( "Software\Microsoft\Windows\CurrentVersion\Explorer", "IconUnderline", 0, 0x00d2f314, 4, 6 ) ERROR_SUCCESS 0.0008300
101-
// Explorer.EXE SHSettingsChanged ( 0, "Software\Microsoft\Windows\CurrentVersion\Explorer\IconUnderline" ) 0.0000092
102-
static BOOL IntSetUnderlineState(BOOL bIconUnderline)
91+
// SHELL32.dll SHRegGetUSValueW ( "Software\Microsoft\Windows\CurrentVersion\Explorer", "IconUnderline", NULL, 0x00d2f324, 0x00d2f328, FALSE, 0x00d2f32c, 4 ) ERROR_SUCCESS
92+
// SHELL32.dll IsDlgButtonChecked ( 0x0005009e, 30104 ) BST_CHECKED
93+
// SHELL32.dll SHRegSetUSValueW ( "Software\Microsoft\Windows\CurrentVersion\Explorer", "IconUnderline", 0, 0x00d2f314, 4, 6 ) ERROR_SUCCESS
94+
// Explorer.EXE SHSettingsChanged ( 0, "Software\Microsoft\Windows\CurrentVersion\Explorer\IconUnderline" ) (WM_SETTINGCHANGE handling)
95+
static BOOL IntSetUnderlineState(BOOL bUnderlineHover)
10396
{
10497
LSTATUS Status;
105-
DWORD dwValue = (bIconUnderline ? 3 : 2), dwSize = sizeof(DWORD);
98+
DWORD dwValue = bUnderlineHover ? UNDERLINE_HOVER : UNDERLINE_IE;
10699
Status = SHRegSetUSValue(s_pszExplorerKey, L"IconUnderline", REG_NONE,
107-
&dwValue, dwSize, SHREGSET_FORCE_HKCU | SHREGSET_HKLM);
100+
&dwValue, sizeof(dwValue), SHREGSET_FORCE_HKCU | SHREGSET_HKLM);
108101
if (Status != ERROR_SUCCESS)
109102
return FALSE;
110103

111-
SHSendMessageBroadcastW(WM_SETTINGCHANGE, 0, (LPARAM)L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\IconUnderline");
104+
SHSendMessageBroadcastW(WM_SETTINGCHANGE, 0, (LPARAM)(REGSTR_PATH_EXPLORER L"\\IconUnderline"));
112105
return TRUE;
113106
}
114107

115-
static BOOL IntGetUnderlineState(VOID)
108+
static UINT IntGetRawIconUnderlineValue()
116109
{
117-
DWORD dwValue, dwDefault = 2, dwSize = sizeof(DWORD);
118-
SHRegGetUSValue(s_pszExplorerKey, L"IconUnderline", NULL, &dwValue, &dwSize, FALSE, &dwDefault, sizeof(DWORD));
119-
return dwValue == 3;
110+
DWORD dwValue, dwDefault = UNDERLINE_ON;
111+
DWORD dwSize = sizeof(dwValue);
112+
SHRegGetUSValue(s_pszExplorerKey, L"IconUnderline", NULL, &dwValue, &dwSize, FALSE, &dwDefault, sizeof(dwDefault));
113+
return dwValue;
114+
}
115+
116+
static UINT SHELL_GetIconUnderlineMode()
117+
{
118+
UINT mode = IntGetRawIconUnderlineValue();
119+
if (mode < UNDERLINE_IE)
120+
return mode;
121+
122+
WCHAR buf[sizeof("hoverX")];
123+
*buf = UNICODE_NULL;
124+
DWORD cb = sizeof(buf);
125+
SHRegGetUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main",
126+
L"Anchor Underline", NULL, buf, &cb, FALSE, buf, cb);
127+
if (!lstrcmpiW(buf, L"no"))
128+
return UNDERLINE_OFF;
129+
if (!lstrcmpiW(buf, L"hover"))
130+
return UNDERLINE_HOVER;
131+
return UNDERLINE_ON;
132+
}
133+
134+
UINT SHELL_GetIconUnderlineFlags()
135+
{
136+
UINT mode = SHELL_GetIconUnderlineMode();
137+
if (mode == UNDERLINE_HOVER)
138+
return LVS_EX_UNDERLINEHOT;
139+
if (mode == UNDERLINE_ON)
140+
return LVS_EX_UNDERLINEHOT | LVS_EX_UNDERLINECOLD;
141+
return 0;
120142
}
121143

122144
// bNewWindowMode is TRUE if "Open each folder in its own window".
@@ -239,17 +261,23 @@ GeneralDlg_UpdateIcons(HWND hDlg, UINT nCtrlID, PGENERAL_DIALOG pGeneral)
239261

240262
if (nCtrlID == IDC_FOLDER_OPTIONS_DOUBLECLICK)
241263
{
242-
CheckRadioButton(hDlg, IDC_FOLDER_OPTIONS_ULBROWSER, IDC_FOLDER_OPTIONS_ULPOINT, IDC_FOLDER_OPTIONS_ULBROWSER);
243264
EnableWindow(GetDlgItem(hDlg, IDC_FOLDER_OPTIONS_ULBROWSER), FALSE);
244265
EnableWindow(GetDlgItem(hDlg, IDC_FOLDER_OPTIONS_ULPOINT), FALSE);
245266
}
246267
}
247268

248269
static void
249270
GeneralDlg_StoreToUI(HWND hwndDlg, BOOL bDoubleClick, BOOL bUseCommonTasks,
250-
BOOL bUnderline, BOOL bNewWindowMode, PGENERAL_DIALOG pGeneral)
271+
BOOL bUnderlineHover, BOOL bNewWindowMode, PGENERAL_DIALOG pGeneral)
251272
{
252-
EnableWindow(GetDlgItem(hwndDlg, IDC_FOLDER_OPTIONS_COMMONTASKS), bUseCommonTasks); // FIXME: ROS DefView does not support WebView nor the tasks pane
273+
if (SHRestricted(REST_CLASSICSHELL))
274+
{
275+
EnableWindow(GetDlgItem(hwndDlg, IDC_FOLDER_OPTIONS_SINGLECLICK), FALSE);
276+
bDoubleClick = TRUE;
277+
bUseCommonTasks = FALSE;
278+
}
279+
280+
EnableWindow(GetDlgItem(hwndDlg, IDC_FOLDER_OPTIONS_COMMONTASKS), bUseCommonTasks); // TODO: ROS DefView does not support WebView nor the tasks pane
253281

254282
if (bUseCommonTasks)
255283
CheckRadioButton(hwndDlg, IDC_FOLDER_OPTIONS_COMMONTASKS, IDC_FOLDER_OPTIONS_CLASSICFOLDERS, IDC_FOLDER_OPTIONS_COMMONTASKS);
@@ -266,21 +294,12 @@ GeneralDlg_StoreToUI(HWND hwndDlg, BOOL bDoubleClick, BOOL bUseCommonTasks,
266294
else
267295
CheckRadioButton(hwndDlg, IDC_FOLDER_OPTIONS_SAMEWINDOW, IDC_FOLDER_OPTIONS_OWNWINDOW, IDC_FOLDER_OPTIONS_SAMEWINDOW);
268296

269-
if (!bDoubleClick)
270-
{
271-
EnableWindow(GetDlgItem(hwndDlg, IDC_FOLDER_OPTIONS_ULBROWSER), TRUE);
272-
EnableWindow(GetDlgItem(hwndDlg, IDC_FOLDER_OPTIONS_ULPOINT), TRUE);
273-
if (bUnderline)
274-
CheckRadioButton(hwndDlg, IDC_FOLDER_OPTIONS_ULBROWSER, IDC_FOLDER_OPTIONS_ULPOINT, IDC_FOLDER_OPTIONS_ULPOINT);
275-
else
276-
CheckRadioButton(hwndDlg, IDC_FOLDER_OPTIONS_ULBROWSER, IDC_FOLDER_OPTIONS_ULPOINT, IDC_FOLDER_OPTIONS_ULBROWSER);
277-
}
297+
EnableWindow(GetDlgItem(hwndDlg, IDC_FOLDER_OPTIONS_ULBROWSER), !bDoubleClick);
298+
EnableWindow(GetDlgItem(hwndDlg, IDC_FOLDER_OPTIONS_ULPOINT), !bDoubleClick);
299+
if (bUnderlineHover)
300+
CheckRadioButton(hwndDlg, IDC_FOLDER_OPTIONS_ULBROWSER, IDC_FOLDER_OPTIONS_ULPOINT, IDC_FOLDER_OPTIONS_ULPOINT);
278301
else
279-
{
280-
EnableWindow(GetDlgItem(hwndDlg, IDC_FOLDER_OPTIONS_ULBROWSER), FALSE);
281-
EnableWindow(GetDlgItem(hwndDlg, IDC_FOLDER_OPTIONS_ULPOINT), FALSE);
282302
CheckRadioButton(hwndDlg, IDC_FOLDER_OPTIONS_ULBROWSER, IDC_FOLDER_OPTIONS_ULPOINT, IDC_FOLDER_OPTIONS_ULBROWSER);
283-
}
284303
}
285304

286305
static BOOL
@@ -290,10 +309,10 @@ GeneralDlg_OnInitDialog(HWND hwndDlg, PGENERAL_DIALOG pGeneral)
290309
SHGetSetSettings(&ss, SSF_DOUBLECLICKINWEBVIEW | SSF_WEBVIEW, FALSE);
291310
BOOL bDoubleClick = !!ss.fDoubleClickInWebView;
292311
BOOL bUseCommonTasks = !!ss.fWebView;
293-
BOOL bUnderline = IntGetUnderlineState();
312+
BOOL bUnderlineHover = IntGetRawIconUnderlineValue() == UNDERLINE_HOVER;
294313
BOOL bNewWindowMode = IntGetNewWindowMode();
295314

296-
GeneralDlg_StoreToUI(hwndDlg, bDoubleClick, bUseCommonTasks, bUnderline, bNewWindowMode, pGeneral);
315+
GeneralDlg_StoreToUI(hwndDlg, bDoubleClick, bUseCommonTasks, bUnderlineHover, bNewWindowMode, pGeneral);
297316
GeneralDlg_UpdateIcons(hwndDlg, 0, pGeneral);
298317

299318
return TRUE;
@@ -305,10 +324,10 @@ GeneralDlg_OnRestoreDefaults(HWND hwndDlg, PGENERAL_DIALOG pGeneral)
305324
// default values
306325
BOOL bDoubleClick = TRUE;
307326
BOOL bUseCommonTasks = TRUE;
308-
BOOL bUnderline = FALSE;
327+
BOOL bUnderlineHover = FALSE;
309328
BOOL bNewWindowMode = (_WIN32_WINNT < _WIN32_WINNT_WIN2K);
310329

311-
GeneralDlg_StoreToUI(hwndDlg, bDoubleClick, bUseCommonTasks, bUnderline, bNewWindowMode, pGeneral);
330+
GeneralDlg_StoreToUI(hwndDlg, bDoubleClick, bUseCommonTasks, bUnderlineHover, bNewWindowMode, pGeneral);
312331
GeneralDlg_UpdateIcons(hwndDlg, 0, pGeneral);
313332
}
314333

@@ -317,10 +336,10 @@ GeneralDlg_OnApply(HWND hwndDlg, PGENERAL_DIALOG pGeneral)
317336
{
318337
BOOL bDoubleClick = !(IsDlgButtonChecked(hwndDlg, IDC_FOLDER_OPTIONS_SINGLECLICK) == BST_CHECKED);
319338
BOOL bUseCommonTasks = (IsDlgButtonChecked(hwndDlg, IDC_FOLDER_OPTIONS_COMMONTASKS) == BST_CHECKED);
320-
BOOL bUnderline = (IsDlgButtonChecked(hwndDlg, IDC_FOLDER_OPTIONS_ULPOINT) == BST_CHECKED);
339+
BOOL bUnderlineHover = (IsDlgButtonChecked(hwndDlg, IDC_FOLDER_OPTIONS_ULPOINT) == BST_CHECKED);
321340
BOOL bNewWindowMode = !(IsDlgButtonChecked(hwndDlg, IDC_FOLDER_OPTIONS_SAMEWINDOW) == BST_CHECKED);
322341

323-
IntSetUnderlineState(bUnderline);
342+
IntSetUnderlineState(bUnderlineHover);
324343
BOOL updateCabinets = IntSetNewWindowMode(bNewWindowMode) == S_OK;
325344
IntSetShellStateSettings(bDoubleClick, bUseCommonTasks);
326345
if (updateCabinets)

dll/win32/shell32/shfldr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,4 +207,6 @@ HRESULT inline SHSetStrRet(LPSTRRET pStrRet, DWORD resId)
207207

208208
#endif
209209

210+
UINT SHELL_GetIconUnderlineFlags();
211+
210212
#endif /* _SHFLDR_H_ */

0 commit comments

Comments
 (0)