1 // ProgressStatic.cpp : 实现文件
2 //
3
4 #include "stdafx.h"
5 #include "MusicPlayer2.h"
6 #include "PlayerToolBar.h"
7
8
9 // CPlayerToolBar
10
IMPLEMENT_DYNAMIC(CPlayerToolBar,CStatic)11 IMPLEMENT_DYNAMIC(CPlayerToolBar, CStatic)
12
13 CPlayerToolBar::CPlayerToolBar()
14 : m_theme_color(theApp.m_app_setting_data.theme_color)
15 {
16 }
17
~CPlayerToolBar()18 CPlayerToolBar::~CPlayerToolBar()
19 {
20 }
21
AddToolButton(IconMgr::IconType icon_type,LPCTSTR strText,LPCTSTR strToolTip,UINT cmdId,bool showText)22 void CPlayerToolBar::AddToolButton(IconMgr::IconType icon_type, LPCTSTR strText, LPCTSTR strToolTip, UINT cmdId, bool showText)
23 {
24 ToolBtn btn;
25 btn.cmd_id = cmdId;
26 btn.is_cmd = true;
27 btn.icon_type = icon_type;
28 if (strText != nullptr)
29 btn.text = strText;
30 btn.show_text = showText;
31 if (strToolTip != nullptr)
32 btn.tooltip_text = strToolTip;
33 m_buttons.push_back(btn);
34 }
35
AddToolButton(IconMgr::IconType icon_type,LPCTSTR strText,LPCTSTR strToolTip,CMenu * pMenu,bool showText)36 void CPlayerToolBar::AddToolButton(IconMgr::IconType icon_type, LPCTSTR strText, LPCTSTR strToolTip, CMenu * pMenu, bool showText)
37 {
38 ToolBtn btn;
39 btn.pMenu = pMenu;
40 btn.is_cmd = false;
41 btn.icon_type = icon_type;
42 if (strText != nullptr)
43 btn.text = strText;
44 btn.show_text = showText;
45 if(strToolTip != nullptr)
46 btn.tooltip_text = strToolTip;
47 m_buttons.push_back(btn);
48 }
49
ModifyToolButton(int index,IconMgr::IconType icon_type,LPCTSTR strText,LPCTSTR strToolTip,CMenu * pMenu,bool showText)50 void CPlayerToolBar::ModifyToolButton(int index, IconMgr::IconType icon_type, LPCTSTR strText, LPCTSTR strToolTip, CMenu* pMenu, bool showText /*= false*/)
51 {
52 if (index >= 0 && index < static_cast<int>(m_buttons.size()))
53 {
54 ToolBtn& btn{ m_buttons[index] };
55 btn.pMenu = pMenu;
56 btn.is_cmd = false;
57 btn.icon_type = icon_type;
58 if (strText != nullptr)
59 btn.text = strText;
60 btn.show_text = showText;
61 if (strToolTip != nullptr)
62 {
63 btn.tooltip_text = strToolTip;
64 m_tool_tip.UpdateTipText(btn.tooltip_text, this, index + 100);
65 }
66 m_btn_updated = true;
67 }
68 }
69
ModifyToolButton(int index,IconMgr::IconType icon_type,LPCTSTR strText,LPCTSTR strToolTip,UINT cmdId,bool showText)70 void CPlayerToolBar::ModifyToolButton(int index, IconMgr::IconType icon_type, LPCTSTR strText, LPCTSTR strToolTip, UINT cmdId, bool showText /*= false*/)
71 {
72 if (index >= 0 && index < static_cast<int>(m_buttons.size()))
73 {
74 ToolBtn& btn{ m_buttons[index] };
75 btn.cmd_id = cmdId;
76 btn.is_cmd = true;
77 btn.icon_type = icon_type;
78 if (strText != nullptr)
79 btn.text = strText;
80 btn.show_text = showText;
81 if (strToolTip != nullptr)
82 {
83 btn.tooltip_text = strToolTip;
84 m_tool_tip.UpdateTipText(btn.tooltip_text, this, index + 100);
85 }
86 m_btn_updated = true;
87 }
88 }
89
SetIconSize(int size)90 void CPlayerToolBar::SetIconSize(int size)
91 {
92 m_icon_size = size;
93 }
94
95
SetCmdReciveWindow(CWnd * pWnd)96 void CPlayerToolBar::SetCmdReciveWindow(CWnd* pWnd)
97 {
98 m_pCmdReciveWnd = pWnd;
99 }
100
AddToolTips()101 void CPlayerToolBar::AddToolTips()
102 {
103 for (size_t i = 0; i < m_buttons.size(); i++)
104 {
105 if(!m_buttons[i].tooltip_text.IsEmpty())
106 m_tool_tip.AddTool(this, m_buttons[i].tooltip_text, m_buttons[i].rect, i + 100);
107 }
108 }
109
UpdateToolTipsPosition()110 void CPlayerToolBar::UpdateToolTipsPosition()
111 {
112 for (size_t i = 0; i < m_buttons.size(); i++)
113 {
114 m_tool_tip.SetToolRect(this,i + 100, m_buttons[i].rect);
115 }
116 }
117
118
GetCmdReciveWindow()119 CWnd* CPlayerToolBar::GetCmdReciveWindow()
120 {
121 CWnd* pWnd;
122 if (m_pCmdReciveWnd != nullptr)
123 pWnd = m_pCmdReciveWnd;
124 else if (GetParent() != nullptr)
125 pWnd = GetParent();
126 else
127 pWnd = AfxGetMainWnd();
128 return pWnd;
129 }
130
BEGIN_MESSAGE_MAP(CPlayerToolBar,CStatic)131 BEGIN_MESSAGE_MAP(CPlayerToolBar, CStatic)
132 ON_WM_PAINT()
133 ON_WM_LBUTTONUP()
134 ON_WM_LBUTTONDOWN()
135 ON_WM_MOUSEMOVE()
136 ON_WM_MOUSELEAVE()
137 ON_WM_MOUSEHOVER()
138 ON_MESSAGE(WM_INITMENU, &CPlayerToolBar::OnInitmenu)
139 ON_WM_LBUTTONDBLCLK()
140 END_MESSAGE_MAP()
141
142
143
144 // CPlayerToolBar 消息处理程序
145
146 void CPlayerToolBar::OnPaint()
147 {
148 CPaintDC dc(this); // device context for painting
149 // TODO: 在此处添加消息处理程序代码
150 // 不为绘图消息调用 CStatic::OnPaint()
151
152 CRect rect;
153 GetClientRect(rect);
154
155 //双缓冲绘图
156 {
157 CDrawDoubleBuffer drawDoubleBuffer(&dc, rect);
158 CDrawCommon drawer;
159 drawer.Create(drawDoubleBuffer.GetMemDC(), GetFont());
160
161 //绘制背景
162 if(!theApp.m_app_setting_data.button_round_corners)
163 {
164 drawer.FillRect(rect, CColorConvert::m_gray_color.light3);
165 }
166 else
167 {
168 drawer.FillRect(rect, CONSTVAL::BACKGROUND_COLOR);
169 drawer.DrawRoundRect(rect, CColorConvert::m_gray_color.light3, theApp.DPI(4));
170 }
171
172 //绘制图标
173 CRect rc_icon = rect;
174 rc_icon.left += theApp.DPI(2);
175 rc_icon.top = (rect.Height() - m_icon_size) / 2;
176 rc_icon.right = rc_icon.left;
177 rc_icon.bottom = rc_icon.top + m_icon_size;
178
179 for (auto iter = m_buttons.begin(); iter != m_buttons.end(); iter++)
180 {
181 if (iter != m_buttons.begin())
182 {
183 rc_icon.left = (iter - 1)->rect.right + theApp.DPI(2);
184 }
185
186 bool draw_text = iter->show_text && !(iter->text.IsEmpty());
187 if (draw_text)
188 {
189 CSize text_size = drawer.GetTextExtent(iter->text);
190 rc_icon.right = rc_icon.left + m_icon_size + text_size.cx + theApp.DPI(4);
191 }
192 else
193 {
194 rc_icon.right = rc_icon.left + m_icon_size;
195 }
196
197 iter->rect = rc_icon;
198 COLORREF back_color{};
199 if(iter->hover || iter->pressed)
200 {
201 if (iter->pressed)
202 back_color = m_theme_color.light1_5;
203 else
204 back_color = m_theme_color.light2_5;
205 if (!theApp.m_app_setting_data.button_round_corners)
206 drawer.FillRect(rc_icon, back_color);
207 else
208 {
209 drawer.DrawRoundRect(rc_icon, back_color, theApp.DPI(3));
210 }
211 }
212
213 HICON hIcon= theApp.m_icon_mgr.GetHICON(iter->icon_type, IconMgr::IconStyle::IS_OutlinedDark, IconMgr::IconSize::IS_DPI_16);
214 CSize icon_size = IconMgr::GetIconSize(IconMgr::IconSize::IS_DPI_16);
215 //使图标在矩形中居中
216 CRect rc_tmp = rc_icon;
217 if (draw_text)
218 rc_tmp.left = rc_icon.left + theApp.DPI(2);
219 else
220 rc_tmp.left = rc_icon.left + (rc_icon.Width() - icon_size.cx) / 2;
221 rc_tmp.top = rc_icon.top + (rc_icon.Height() - icon_size.cy) / 2;
222 rc_tmp.right = rc_tmp.left + icon_size.cx;
223 rc_tmp.bottom = rc_tmp.top + icon_size.cy;
224 if (iter->pressed)
225 {
226 rc_tmp.MoveToX(rc_tmp.left + theApp.DPI(1));
227 rc_tmp.MoveToY(rc_tmp.top + theApp.DPI(1));
228 }
229 drawer.DrawIcon(hIcon, rc_tmp.TopLeft(), rc_tmp.Size());
230 //绘制文本
231 if (draw_text)
232 {
233 CRect rc_text = rc_icon;
234 rc_text.left = rc_tmp.right + theApp.DPI(2);
235 COLORREF text_color;
236 if (IsWindowEnabled())
237 text_color = CColorConvert::m_gray_color.dark3;
238 else
239 text_color = CColorConvert::m_gray_color.dark1;
240 if (iter->pressed)
241 rc_text.MoveToY(rc_text.top + theApp.DPI(1));
242 drawer.DrawWindowText(rc_text, iter->text, text_color);
243 }
244 }
245 }
246
247 if (m_first_draw && !m_buttons.empty())
248 {
249 AddToolTips(); //在第一次绘制完成之后添加鼠标提示,因为在绘制之前无法确定按钮矩形区域
250 m_first_draw = false;
251 }
252
253 if (m_btn_updated && !m_buttons.empty()) //如果更新过按钮,则在绘制后更新一次鼠标提示的位置
254 {
255 UpdateToolTipsPosition();
256 m_btn_updated = false;
257 }
258 }
259
260
PreSubclassWindow()261 void CPlayerToolBar::PreSubclassWindow()
262 {
263 // TODO: 在此添加专用代码和/或调用基类
264 //为控件设置SS_NOTIFY属性
265 ModifyStyle(NULL, SS_NOTIFY);
266
267 //初始化提示信息
268 m_tool_tip.Create(this, TTS_ALWAYSTIP);
269 m_tool_tip.SetMaxTipWidth(theApp.DPI(400));
270
271 CStatic::PreSubclassWindow();
272 }
273
274
OnLButtonDown(UINT nFlags,CPoint point)275 void CPlayerToolBar::OnLButtonDown(UINT nFlags, CPoint point)
276 {
277 // TODO: 在此添加消息处理程序代码和/或调用默认值
278 for (auto& btn : m_buttons)
279 {
280 if (btn.rect.PtInRect(point) != FALSE)
281 {
282 btn.pressed = true;
283 InvalidateRect(btn.rect);
284 }
285 }
286
287 CStatic::OnLButtonDown(nFlags, point);
288 }
289
290
OnLButtonUp(UINT nFlags,CPoint point)291 void CPlayerToolBar::OnLButtonUp(UINT nFlags, CPoint point)
292 {
293 // TODO: 在此添加消息处理程序代码和/或调用默认值
294 for (auto& btn : m_buttons)
295 {
296 btn.pressed = false;
297 if (btn.rect.PtInRect(point) && btn.enable)
298 {
299 if (btn.is_cmd)
300 {
301 GetCmdReciveWindow()->SendMessage(WM_COMMAND, btn.cmd_id, 0);
302 }
303 else if (btn.pMenu != nullptr)
304 {
305 CPoint point;
306 point.x = btn.rect.left;
307 point.y = btn.rect.bottom;
308 ClientToScreen(&point);
309 m_menu_poped_up = true;
310 btn.pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
311 m_menu_poped_up = false;
312 }
313 }
314 }
315 Invalidate();
316 CStatic::OnLButtonUp(nFlags, point);
317 }
318
319
OnMouseMove(UINT nFlags,CPoint point)320 void CPlayerToolBar::OnMouseMove(UINT nFlags, CPoint point)
321 {
322 // TODO: 在此添加消息处理程序代码和/或调用默认值
323 for (auto& btn : m_buttons)
324 {
325 bool hover = (btn.rect.PtInRect(point) != FALSE);
326 if(hover != btn.hover)
327 {
328 btn.hover = hover;
329 InvalidateRect(btn.rect);
330 }
331 }
332
333 TRACKMOUSEEVENT tme;
334 tme.cbSize = sizeof(tme);
335 tme.hwndTrack = m_hWnd;
336 tme.dwFlags = TME_LEAVE | TME_HOVER;
337 tme.dwHoverTime = 1;
338 _TrackMouseEvent(&tme);
339
340 CStatic::OnMouseMove(nFlags, point);
341 }
342
343
PreTranslateMessage(MSG * pMsg)344 BOOL CPlayerToolBar::PreTranslateMessage(MSG* pMsg)
345 {
346 // TODO: 在此添加专用代码和/或调用基类
347 if (m_tool_tip.GetSafeHwnd() && pMsg->message == WM_MOUSEMOVE)
348 {
349 m_tool_tip.RelayEvent(pMsg);
350 }
351
352
353 return CStatic::PreTranslateMessage(pMsg);
354 }
355
356
OnMouseLeave()357 void CPlayerToolBar::OnMouseLeave()
358 {
359 // TODO: 在此添加消息处理程序代码和/或调用默认值
360 if(!m_menu_poped_up)
361 {
362 for (auto& btn : m_buttons)
363 {
364 btn.pressed = false;
365 btn.hover = false;
366 }
367 Invalidate();
368 }
369
370 CStatic::OnMouseLeave();
371 }
372
373
OnMouseHover(UINT nFlags,CPoint point)374 void CPlayerToolBar::OnMouseHover(UINT nFlags, CPoint point)
375 {
376 // TODO: 在此添加消息处理程序代码和/或调用默认值
377
378 CStatic::OnMouseHover(nFlags, point);
379 }
380
381
OnInitmenu(WPARAM wParam,LPARAM lParam)382 afx_msg LRESULT CPlayerToolBar::OnInitmenu(WPARAM wParam, LPARAM lParam)
383 {
384 AfxGetMainWnd()->SendMessage(WM_INITMENU, wParam, lParam); //将WM_INITMENU消息转发到主窗口
385 return 0;
386 }
387
388
OnCommand(WPARAM wParam,LPARAM lParam)389 BOOL CPlayerToolBar::OnCommand(WPARAM wParam, LPARAM lParam)
390 {
391 // TODO: 在此添加专用代码和/或调用基类
392 GetCmdReciveWindow()->SendMessage(WM_COMMAND, wParam, lParam); //转发WM_COMMAND消息
393
394 return CStatic::OnCommand(wParam, lParam);
395 }
396
397
OnLButtonDblClk(UINT nFlags,CPoint point)398 void CPlayerToolBar::OnLButtonDblClk(UINT nFlags, CPoint point)
399 {
400 // TODO: 在此添加消息处理程序代码和/或调用默认值
401
402 //CStatic::OnLButtonDblClk(nFlags, point);
403 }
404