xref: /MusicPlayer2/MusicPlayer2/PlayerToolBar.cpp (revision bdab36f8b39bc8fbd10db7970e6ea1bfffbbdfed)
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