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