[PATCH 0/1] MR11392: explorer: Display icons next to Start Menu items
From: Andrea Faulds <ajf@ajf.me> --- programs/explorer/startmenu.c | 51 ++++++++++++++++++++++++++++++----- programs/explorer/systray.c | 7 +++++ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/programs/explorer/startmenu.c b/programs/explorer/startmenu.c index 63120026dad..8342d9378d0 100644 --- a/programs/explorer/startmenu.c +++ b/programs/explorer/startmenu.c @@ -34,6 +34,7 @@ struct menu_item { struct list entry; LPWSTR displayname; + HICON icon; /* parent information */ struct menu_item* parent; @@ -185,19 +186,21 @@ static struct menu_item* add_shell_item(struct menu_item* parent, LPITEMIDLIST p int existing_item_count, i; BOOL match = FALSE; SFGAOF flags; + LPWSTR displayname_temp; + SHFILEINFOW sfi; item = calloc( 1, sizeof(struct menu_item) ); if (parent->pidl == NULL) { - pidl_to_shellfolder(pidl, &item->displayname, &item->folder); + pidl_to_shellfolder(pidl, &displayname_temp, &item->folder); } else { STRRET strret; if (SUCCEEDED(IShellFolder_GetDisplayNameOf(parent->folder, pidl, SHGDN_INFOLDER, &strret))) - StrRetToStrW(&strret, NULL, &item->displayname); + StrRetToStrW(&strret, NULL, &displayname_temp); flags = SFGAO_FOLDER; IShellFolder_GetAttributesOf(parent->folder, 1, (LPCITEMIDLIST*)&pidl, &flags); @@ -205,6 +208,14 @@ static struct menu_item* add_shell_item(struct menu_item* parent, LPITEMIDLIST p if (flags & SFGAO_FOLDER) IShellFolder_BindToObject(parent->folder, pidl, NULL, &IID_IShellFolder, (void *)&item->folder); } + /* Prepend a space to the display name to separate it from the icon. */ + item->displayname = malloc(wcslen(displayname_temp) + 2); + item->displayname[0] = L' '; + wcscpy(item->displayname + 1, displayname_temp); + free(displayname_temp); + + if (SHGetFileInfoW((LPCWSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_ICON|SHGFI_SMALLICON)) + item->icon = sfi.hIcon; if (item->folder && shell_folder_is_empty(item->folder)) { @@ -266,6 +277,10 @@ static struct menu_item* add_shell_item(struct menu_item* parent, LPITEMIDLIST p mii.fMask = MIIM_STRING|MIIM_DATA; mii.dwTypeData = item->displayname; mii.dwItemData = (ULONG_PTR)item; + if (item->icon) { + mii.fMask |= MIIM_BITMAP; + mii.hbmpItem = HBMMENU_CALLBACK; + } if (item->folder) { @@ -275,7 +290,8 @@ static struct menu_item* add_shell_item(struct menu_item* parent, LPITEMIDLIST p mii.hSubMenu = item->menuhandle; mi.cbSize = sizeof(mi); - mi.fMask = MIM_MENUDATA; + mi.fMask = MIM_MENUDATA|MIM_STYLE; + mi.dwStyle = MNS_NOTIFYBYPOS|MNS_CHECKORBMP; mi.dwMenuData = (ULONG_PTR)item; SetMenuInfo(item->menuhandle, &mi); } @@ -305,6 +321,8 @@ static struct menu_item* add_shell_item(struct menu_item* parent, LPITEMIDLIST p else { /* duplicate shortcut, do nothing */ free( item->displayname ); + if (item->icon) + DestroyIcon( item->icon ); free( item ); CoTaskMemFree(pidl); item = NULL; @@ -347,6 +365,9 @@ static void destroy_menus(void) if (item->folder) IShellFolder_Release(item->folder); + if (item->icon) + DestroyIcon(item->icon); + CoTaskMemFree(item->pidl); CoTaskMemFree(item->displayname); @@ -438,6 +459,22 @@ LRESULT menu_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) return 0; } + + case WM_MEASUREITEM: + ((MEASUREITEMSTRUCT*)lparam)->itemWidth = GetSystemMetrics(SM_CXSMICON); + ((MEASUREITEMSTRUCT*)lparam)->itemHeight = GetSystemMetrics(SM_CYSMICON); + return TRUE; + + case WM_DRAWITEM: + { + DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT*)lparam; + struct menu_item* item = (struct menu_item*)dis->itemData; + + DrawIconEx(dis->hDC, dis->rcItem.left, dis->rcItem.top, item->icon, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL); + return TRUE; + } } return DefWindowProcW(hwnd, msg, wparam, lparam); @@ -489,7 +526,9 @@ void do_startmenu(HWND hwnd) if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_CONTROLS, &pidl))) add_shell_item(&root_menu, pidl); - LoadStringW(NULL, IDS_RUN, label, ARRAY_SIZE(label)); + /* Prepend a space to the labels to separate them from the icons. */ + label[0] = L' '; + LoadStringW(NULL, IDS_RUN, label + 1, ARRAY_SIZE(label) - 1); mii.cbSize = sizeof(mii); mii.fMask = MIIM_STRING|MIIM_ID; mii.dwTypeData = label; @@ -500,7 +539,7 @@ void do_startmenu(HWND hwnd) mii.fType = MFT_SEPARATOR; InsertMenuItemW(root_menu.menuhandle, -1, TRUE, &mii); - LoadStringW(NULL, IDS_EXIT_LABEL, label, ARRAY_SIZE(label)); + LoadStringW(NULL, IDS_EXIT_LABEL, label + 1, ARRAY_SIZE(label) - 1); mii.fMask = MIIM_STRING|MIIM_ID; mii.dwTypeData = label; mii.wID = MENU_ID_EXIT; @@ -508,7 +547,7 @@ void do_startmenu(HWND hwnd) mi.cbSize = sizeof(mi); mi.fMask = MIM_STYLE; - mi.dwStyle = MNS_NOTIFYBYPOS; + mi.dwStyle = MNS_NOTIFYBYPOS|MNS_CHECKORBMP; SetMenuInfo(root_menu.menuhandle, &mi); GetWindowRect(hwnd, &rc); diff --git a/programs/explorer/systray.c b/programs/explorer/systray.c index a2098c808ae..69d3ec61b6a 100644 --- a/programs/explorer/systray.c +++ b/programs/explorer/systray.c @@ -1133,9 +1133,16 @@ static LRESULT WINAPI shell_traywnd_proc( HWND hwnd, UINT msg, WPARAM wparam, LP return 0; case WM_DRAWITEM: + if (((MEASUREITEMSTRUCT*)lparam)->CtlType == ODT_MENU) + return menu_wndproc(hwnd, msg, wparam, lparam); paint_taskbar_button( (const DRAWITEMSTRUCT *)lparam ); break; + case WM_MEASUREITEM: + if (((MEASUREITEMSTRUCT*)lparam)->CtlType == ODT_MENU) + return menu_wndproc(hwnd, msg, wparam, lparam); + break; + case WM_COMMAND: if (HIWORD(wparam) == BN_CLICKED) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11392
Here's how it looks in action: {width=590 height=274} {width=344 height=238} It looks better for the Control Panel than for the Programs, because `SHGetFileInfoW` (or whatever that ultimately calls) isn't resolving shortcut icons. But neither is the file browser, so I think it's some deficiency deeper in the shell implementation: {width=396 height=194} Naturally my next project is going to be fixing the icon resolving here. But in the meantime, I still think this is an æsthetic and practical improvement. The folder icons make it easier to see which menus are submenus, somehow. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11392#note_145636
participants (2)
-
Andrea Faulds -
Andrea Faulds (@hikari_no_yume)