xref: /MusicPlayer2/MusicPlayer2/IconMgr.cpp (revision ba5c72e4b2a0da2a9d0a434aa7cfdd1e3f4bc68b)
1 #include "stdafx.h"
2 #include "IconMgr.h"
3 #include "MusicPlayer2.h"
4 #include "WinVersionHelper.h"
5 
IconMgr()6 IconMgr::IconMgr() {}
7 
~IconMgr()8 IconMgr::~IconMgr() {}
9 
GetHICON(IconType type,IconStyle style,IconSize size)10 HICON IconMgr::GetHICON(IconType type, IconStyle style, IconSize size)
11 {
12     if (type == IT_NO_ICON)
13         return NULL;
14     int key = MakeKey(type, style, size);
15     {   // 加读锁查找缓存的HICON
16         std::shared_lock<std::shared_mutex> readLock(m_shared_mutex);
17         auto iter = m_icon_map.find(key);
18         if (iter != m_icon_map.end())
19             return iter->second;
20     }
21     {   // 缓存中不存在时加写锁加载HICON
22         std::unique_lock<std::shared_mutex> writeLock(m_shared_mutex);
23         auto iter = m_icon_map.find(key);   // 避免并发问题此处需要先再次检查
24         if (iter != m_icon_map.end())
25             return iter->second;
26 
27         auto [id_dark, id_light, id_filled, id_color] = GetIconID(type);
28         UINT id{};
29         switch (style)
30         {
31         case IconMgr::IS_OutlinedDark: id = id_dark; break;
32         case IconMgr::IS_OutlinedLight: id = id_light; break;
33         case IconMgr::IS_Filled: id = id_filled; break;
34         case IconMgr::IS_Color: id = id_color; break;
35         default: break;
36         }
37         // 没有要求的风格时fallback到其他风格
38         if (!id) id = id_color;
39         if (!id) id = id_dark;
40         if (!id) id = id_light;
41         if (!id) id = id_filled;
42 
43         HICON hIcon = NULL;
44         if (id)
45         {
46             int width = GetIconWidth(size);
47             if (width)
48                 hIcon = (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(id), IMAGE_ICON, width, width, 0);
49             else
50                 hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(id));  // 全量加载所有分辨率
51         }
52         m_icon_map.emplace(key, hIcon);         // 即使hIcon为NULL也保存, 这表示当前的图标不存在
53         return hIcon;
54     }
55 }
56 
GetIconWidth(IconSize size)57 int IconMgr::GetIconWidth(IconSize size)
58 {
59     if (size == IS_ALL)
60         return 0;
61     int width;
62     switch (size)
63     {
64     case IS_DPI_16: case IS_DPI_16_Full_Screen: width = theApp.DPI(16); break;
65     case IS_DPI_20: case IS_DPI_20_Full_Screen: width = theApp.DPI(20); break;
66     case IS_DPI_32: case IS_DPI_32_Full_Screen: width = theApp.DPI(32); break;
67     case IS_ORG_512: width = 512; break;
68     default: width = theApp.DPI(16); break;  // 系统默认小图标大小 SM_CXICON * SM_CYICON
69     }
70     if (size == IS_DPI_16_Full_Screen || size == IS_DPI_20_Full_Screen || size == IS_DPI_32_Full_Screen)
71         width = static_cast<int>(width * CONSTVAL::FULL_SCREEN_ZOOM_FACTOR);
72     if (width < 32 || !CWinVersionHelper::IsWindows10OrLater()) //Win10以下的系统中,如果图标图标中没有需要的尺寸,显示效果会有锯齿,因此这里总是使用标准尺寸
73         width = CCommon::IconSizeNormalize(width);
74     return width;
75 }
76 
GetIconID(IconType type)77 std::tuple<UINT, UINT, UINT, UINT> IconMgr::GetIconID(IconType type)
78 {
79     switch (type)
80     {   // return { 深色的图标, 浅色的图标, 填充风格图标, 彩色图标 };
81     case IconMgr::IconType::IT_App:
82 #ifdef _DEBUG
83         return { NULL, NULL, NULL, IDI_APP_DEBUG };
84 #else
85         return { NULL, NULL, NULL, IDR_MAINFRAME };
86 #endif
87     case IconMgr::IconType::IT_App_Monochrome:
88         return { IDI_APP_DARK, IDI_APP_LIGHT, NULL, NULL };
89     case IconMgr::IconType::IT_Stop:
90         return { IDI_STOP_NEW_D, IDI_STOP_NEW, IDI_STOP, NULL };
91     case IconMgr::IconType::IT_Play:
92         return { IDI_PLAY_NEW_D, IDI_PLAY_NEW, IDI_PLAY, NULL };
93     case IconMgr::IconType::IT_Pause:
94         return { IDI_PAUSE_NEW_D, IDI_PAUSE_NEW, IDI_PAUSE, NULL };
95     case IconMgr::IconType::IT_Play_Pause:
96         return { IDI_PLAY_PAUSE_D, NULL, IDI_PLAY_PAUSE, NULL };
97     case IconMgr::IconType::IT_Previous:
98         return { IDI_PREVIOUS_NEW_D, IDI_PREVIOUS_NEW, IDI_PREVIOUS, NULL };
99     case IconMgr::IconType::IT_Next:
100         return { IDI_NEXT_NEW_D, IDI_NEXT_NEW, IDI_NEXT1, NULL };
101     case IconMgr::IconType::IT_Favorite_On:
102         return { IDI_FAVOURITE_D, IDI_FAVOURITE, NULL, NULL };
103     case IconMgr::IconType::IT_Favorite_Off:
104         return { NULL, NULL, NULL, IDI_HEART };
105     case IconMgr::IconType::IT_Media_Lib:
106         return { IDI_MEDIA_LIB_D, IDI_MEDIA_LIB, NULL, NULL };
107     case IconMgr::IconType::IT_Playlist:
108         return { IDI_PLAYLIST_D, IDI_PLAYLIST, NULL, NULL };
109     case IconMgr::IconType::IT_Menu:
110         return { IDI_MENU_D, IDI_MENU, NULL, NULL };
111     case IconMgr::IconType::IT_Full_Screen_On:
112         return { IDI_FULL_SCREEN1_D, IDI_FULL_SCREEN1, NULL, NULL };
113     case IconMgr::IconType::IT_Full_Screen_Off:
114         return { IDI_FULL_SCREEN_D, IDI_FULL_SCREEN, NULL, NULL };
115     case IconMgr::IconType::IT_Minimize:
116         return { IDI_MINIMIZE_D, IDI_MINIMIZE, NULL, NULL };
117     case IconMgr::IconType::IT_Maxmize_On:
118         return { IDI_MAXIMIZE_D, IDI_MAXIMIZE, NULL, NULL };
119     case IconMgr::IconType::IT_Maxmize_Off:
120         return { IDI_RESTORE_D, IDI_RESTORE, NULL, NULL };
121     case IconMgr::IconType::IT_Close:
122         return { IDI_CLOSE_D, IDI_CLOSE, NULL, NULL };
123     case IconMgr::IconType::IT_Play_Order:
124         return { IDI_PLAY_ORDER_D, IDI_PLAY_ORDER, NULL, NULL };
125     case IconMgr::IconType::IT_Loop_Playlist:
126         return { IDI_LOOP_PLAYLIST_D, IDI_LOOP_PLAYLIST, NULL, NULL };
127     case IconMgr::IconType::IT_Loop_Track:
128         return { IDI_LOOP_TRACK_D, IDI_LOOP_TRACK, NULL, NULL };
129     case IconMgr::IconType::IT_Play_Shuffle:
130         return { IDI_PLAY_SHUFFLE_D, IDI_PLAY_SHUFFLE, NULL, NULL };
131     case IconMgr::IconType::IT_Play_Random:
132         return { IDI_PLAY_RANDOM_D, IDI_PLAY_RANDOM, NULL, NULL };
133     case IconMgr::IconType::IT_Play_Track:
134         return { IDI_PLAY_TRACK_D, IDI_PLAY_TRACK, NULL, NULL };
135     case IconMgr::IconType::IT_Setting:
136         return { IDI_SETTING_D, IDI_SETTING, NULL, NULL };
137     case IconMgr::IconType::IT_Equalizer:
138         return { IDI_EQ_D, IDI_EQ, NULL, NULL };
139     case IconMgr::IconType::IT_Skin:
140         return { IDI_SKIN_D, IDI_SKIN, NULL, NULL };
141     case IconMgr::IconType::IT_Mini_On:
142         return { IDI_MINI_D, IDI_MINI, NULL, NULL };
143     case IconMgr::IconType::IT_Mini_Off:
144         return { IDI_MINI_RESTORE_D, IDI_MINI_RESTORE, NULL, NULL };
145     case IconMgr::IconType::IT_Info:
146         return { IDI_SONG_INFO_D, IDI_SONG_INFO, NULL, NULL };
147     case IconMgr::IconType::IT_Find:
148         return { IDI_FIND_SONGS_D, IDI_FIND_SONGS, NULL, NULL };
149     case IconMgr::IconType::IT_Dark_Mode_On:
150         return { IDI_DARK_MODE_D, NULL, NULL, NULL };
151     case IconMgr::IconType::IT_Dark_Mode_Off:
152         return { NULL, IDI_LIGHT_MODE, NULL, NULL };
153     case IconMgr::IconType::IT_Volume0:
154         return { IDI_VOLUME0_D, IDI_VOLUME0, NULL, NULL };
155     case IconMgr::IconType::IT_Volume1:
156         return { IDI_VOLUME1_D, IDI_VOLUME1, NULL, NULL };
157     case IconMgr::IconType::IT_Volume2:
158         return { IDI_VOLUME2_D, IDI_VOLUME2, NULL, NULL };
159     case IconMgr::IconType::IT_Volume3:
160         return { IDI_VOLUME3_D, IDI_VOLUME3, NULL, NULL };
161     case IconMgr::IconType::IT_Switch_Display:
162         return { IDI_SWITCH_D, IDI_SWITCH, NULL, NULL };
163     case IconMgr::IconType::IT_Folder:
164         return { IDI_SELECT_FOLDER_D, IDI_SELECT_FOLDER, NULL, IDI_EXPLORE_FOLDER };
165     case IconMgr::IconType::IT_Music:
166         return { IDI_MUSIC_D, NULL, NULL, NULL };
167     case IconMgr::IconType::IT_Link:
168         return { IDI_LINK_D, IDI_LINK, NULL, NULL };
169     case IconMgr::IconType::IT_Exit:
170         return { IDI_EXIT_D, NULL, NULL, NULL };
171     case IconMgr::IconType::IT_Rewind:
172         return { IDI_REW_NEW_D, NULL, IDI_REW, NULL };
173     case IconMgr::IconType::IT_Fast_Forward:
174         return { IDI_FF_NEW_D, NULL, IDI_FF, NULL };
175     case IconMgr::IconType::IT_Speed_Up:
176         return { IDI_SPEED_UP_D, NULL, NULL, NULL };
177     case IconMgr::IconType::IT_Slow_Down:
178         return { IDI_SLOW_DOWN_D, NULL, NULL, NULL };
179     case IconMgr::IconType::IT_Add:
180         return { IDI_ADD_D, IDI_ADD, NULL, NULL };
181     case IconMgr::IconType::IT_Save:
182         return { IDI_SAVE_NEW_D, NULL, NULL, NULL };
183     case IconMgr::IconType::IT_Save_As:
184         return { IDI_SAVE_AS_D, NULL, NULL, NULL };
185     case IconMgr::IconType::IT_Sort_Mode:
186         return { IDI_SORT_D, IDI_SORT, NULL, NULL };
187     case IconMgr::IconType::IT_Playlist_Display_Mode:
188         return { IDI_DISPLAY_MODE_D, IDI_DISPLAY_MODE, NULL, NULL };
189     case IconMgr::IconType::IT_Locate:
190         return { IDI_LOCATE_D, IDI_LOCATE, NULL, NULL };
191     case IconMgr::IconType::IT_Lyric:
192         return { IDI_LYRIC_D, IDI_LYRIC, NULL, NULL };
193     case IconMgr::IconType::IT_Copy:
194         return { IDI_COPY, NULL, NULL, NULL };
195     case IconMgr::IconType::IT_Edit:
196         return { IDI_EDIT_D, NULL, NULL, NULL };
197     case IconMgr::IconType::IT_Unlink:
198         return { IDI_UNLINK_D, IDI_UNLINK, NULL, NULL };
199     case IconMgr::IconType::IT_Folder_Explore:
200         return { IDI_FOLDER_EXPLORE_D, IDI_FOLDER_EXPLORE, NULL, NULL };
201     case IconMgr::IconType::IT_Internal_Lyric:
202         return { IDI_INTERNAL_LYRIC_D, NULL, NULL, NULL };
203     case IconMgr::IconType::IT_Download:
204         return { IDI_DOWNLOAD_D, NULL, NULL, NULL };
205     case IconMgr::IconType::IT_Download_Batch:
206         return { IDI_DOWNLOAD1_D, NULL, NULL, NULL };
207     case IconMgr::IconType::IT_Playlist_Dock:
208         return { IDI_PLAYLIST_DOCK_D, IDI_PLAYLIST_DOCK, NULL, NULL };
209     case IconMgr::IconType::IT_Playlist_Float:
210         return { IDI_PLAYLIST_FLOAT_D, NULL, NULL, NULL };
211     case IconMgr::IconType::IT_Pin:
212         return { IDI_PIN_D, NULL, NULL, NULL };
213     case IconMgr::IconType::IT_Convert:
214         return { IDI_CONVERT_D, NULL, NULL, NULL };
215     case IconMgr::IconType::IT_Online:
216         return { IDI_ONLINE_D, NULL, NULL, NULL };
217     case IconMgr::IconType::IT_Shortcut:
218         return { IDI_SHORTCUT_D, NULL, NULL, NULL };
219     case IconMgr::IconType::IT_Album_Cover:
220         return { IDI_ALBUM_COVER_D, IDI_ALBUM_COVER, NULL, NULL };
221     case IconMgr::IconType::IT_Statistics:
222         return { IDI_STATISTICS_D, NULL, NULL, NULL };
223     case IconMgr::IconType::IT_File_Relate:
224         return { IDI_FILE_RELATE_D, IDI_FILE_RELATE, NULL, NULL };
225     case IconMgr::IconType::IT_Help:
226         return { IDI_HELP_D, IDI_HELP, NULL, NULL };
227     case IconMgr::IconType::IT_Fix:
228         return { IDI_FIX_D, NULL, NULL, NULL };
229     case IconMgr::IconType::IT_Star:
230         return { IDI_STAR_D, IDI_STAR, NULL, NULL };
231     case IconMgr::IconType::IT_Artist:
232         return { IDI_ARTIST_D, IDI_ARTIST, NULL, NULL };
233     case IconMgr::IconType::IT_Album:
234         return { IDI_ALBUM_D, IDI_ALBUM, NULL, NULL };
235     case IconMgr::IconType::IT_Genre:
236         return { IDI_GENRE_D, IDI_GENRE, NULL, NULL };
237     case IconMgr::IconType::IT_Year:
238         return { IDI_YEAR_D, IDI_YEAR, NULL, NULL };
239     case IconMgr::IconType::IT_Bitrate:
240         return { IDI_BITRATE_D, IDI_BITRATE, NULL, NULL };
241     case IconMgr::IconType::IT_History:
242         return { IDI_RECENT_SONG_D, IDI_RECENT_SONG, NULL, NULL };
243     case IconMgr::IconType::IT_Key_Board:
244         return { IDI_HOT_KEY, NULL, NULL, NULL };
245     case IconMgr::IconType::IT_Reverb:
246         return { IDI_REVERB_D, IDI_REVERB, NULL, NULL };
247     case IconMgr::IconType::IT_Double_Line:
248         return { IDI_DOUBLE_LINE_D, NULL, NULL, NULL };
249     case IconMgr::IconType::IT_Lock:
250         return { IDI_LOCK_D, NULL, NULL, NULL };
251     case IconMgr::IconType::IT_Play_As_Next:
252         return { IDI_PLAY_AS_NEXT, NULL, NULL, NULL };
253     case IconMgr::IconType::IT_Rename:
254         return { IDI_RENAME_D, NULL, NULL, NULL };
255     case IconMgr::IconType::IT_Play_In_Playlist:
256         return { IDI_PLAY_IN_PLAYLIST_D, IDI_PLAY_IN_PLAYLIST, NULL, NULL };
257     case IconMgr::IconType::IT_Play_In_Folder:
258         return { IDI_PLAY_IN_FOLDER, NULL, NULL, NULL };
259     case IconMgr::IconType::IT_Tag:
260         return { IDI_TAG, NULL, NULL, NULL };
261     case IconMgr::IconType::IT_More:
262         return { IDI_MORE_D, NULL, NULL, NULL };
263     case IconMgr::IconType::IT_NowPlaying:
264         return { IDI_NOW_PLAYING_D, IDI_NOW_PLAYING, NULL, NULL };
265     case IconMgr::IconType::IT_Karaoke:
266         return { IDI_KARAOKE_D, IDI_KARAOKE, NULL, NULL };
267     case IconMgr::IconType::IT_Refresh:
268         return { IDI_REFRESH_D, IDI_REFRESH, NULL, NULL };
269     case IconMgr::IconType::IT_NewFolder:
270         return { IDI_NEW_FOLDER_D, IDI_NEW_FOLDER, NULL, NULL };
271     case IconMgr::IconType::IT_Background:
272         return { IDI_BACKGROUND_D, NULL, NULL, NULL };
273     case IconMgr::IconType::IT_Le_Tag_Insert:
274         return { NULL, NULL, NULL, IDI_ADD_TAG };
275     case IconMgr::IconType::IT_Le_Tag_Replace:
276         return { NULL, NULL, NULL, IDI_REPLACE_TAG };
277     case IconMgr::IconType::IT_Le_Tag_Delete:
278         return { NULL, NULL, NULL, IDI_DELETE_TAG };
279     case IconMgr::IconType::IT_Le_Save:
280         return { NULL, NULL, NULL, IDI_SAVE };
281     case IconMgr::IconType::IT_Le_Find:
282         return { NULL, NULL, NULL, IDI_FIND };
283     case IconMgr::IconType::IT_Le_Replace:
284         return { NULL, NULL, NULL, IDI_REPLACE };
285     case IconMgr::IconType::IT_Triangle_Left:
286         return { IDI_LYRIC_DELAY_D, NULL, NULL, NULL };
287     case IconMgr::IconType::IT_Triangle_Up:
288         return { IDI_UP_D, NULL, NULL, NULL };
289     case IconMgr::IconType::IT_Triangle_Right:
290         return { IDI_LYRIC_FORWARD_D, NULL, NULL, NULL };
291     case IconMgr::IconType::IT_Triangle_Down:
292         return { IDI_EXPAND_D, IDI_EXPAND, NULL, NULL };
293     case IconMgr::IconType::IT_Ok:
294         return { IDI_OK_D, NULL, NULL, NULL };
295     case IconMgr::IconType::IT_Cancel:
296         return { IDI_CLOSE_D, NULL, NULL, NULL };
297     case IconMgr::IconType::IT_TreeCollapsed:
298         return { IDI_TREE_COLLAPSED_D, IDI_TREE_COLLAPSED, NULL, NULL };
299     case IconMgr::IconType::IT_TreeExpanded:
300         return { IDI_TREE_EXPANDED_D, IDI_TREE_EXPANDED, NULL, NULL };
301     case IconMgr::IconType::IT_Default_Cover_Playing:
302         return { NULL, NULL, NULL, IDI_DEFAULT_COVER };
303     case IconMgr::IconType::IT_Default_Cover_Stopped:
304         return { NULL, NULL, NULL, IDI_DEFAULT_COVER_NOT_PLAYED };
305     default:
306         return { NULL, NULL, NULL, NULL };
307     }
308 }
309 
310