xref: /MusicPlayer2/MusicPlayer2/SpinEdit.cpp (revision 8d117ac8d29dcd4f45707e90748a3695198e971c)
1 // SpinEdit.cpp: 实现文件
2 //
3 
4 #include "stdafx.h"
5 #include "SpinEdit.h"
6 
7 #define SPIN_ID 3100
8 // CSpinEdit
9 
IMPLEMENT_DYNAMIC(CSpinEdit,CEdit)10 IMPLEMENT_DYNAMIC(CSpinEdit, CEdit)
11 
12 CSpinEdit::CSpinEdit()
13 {
14 
15 }
16 
~CSpinEdit()17 CSpinEdit::~CSpinEdit()
18 {
19 }
20 
SetRange(short lower,short upper,short step)21 void CSpinEdit::SetRange(short lower, short upper, short step)
22 {
23     m_step = step;
24     if (m_spin.GetSafeHwnd() != NULL)
25         m_spin.SetRange(lower, upper);
26 }
27 
SetValue(int value)28 void CSpinEdit::SetValue(int value)
29 {
30     ASSERT(m_step != 0);    // 应当先设置Range
31     if (m_spin.GetSafeHwnd() != NULL)
32         m_spin.SetPos(value);
33 }
34 
GetValue()35 int CSpinEdit::GetValue()
36 {
37     if (m_spin.GetSafeHwnd() != NULL)
38         return m_spin.GetPos();
39     else
40         return 0;
41 }
42 
43 
SetMouseWheelEnable(bool enable)44 void CSpinEdit::SetMouseWheelEnable(bool enable)
45 {
46     m_mouse_wheel_enable = enable;
47 }
48 
49 
BEGIN_MESSAGE_MAP(CSpinEdit,CEdit)50 BEGIN_MESSAGE_MAP(CSpinEdit, CEdit)
51     ON_MESSAGE(WM_TABLET_QUERYSYSTEMGESTURESTATUS, &CSpinEdit::OnTabletQuerysystemgesturestatus)
52     ON_NOTIFY(UDN_DELTAPOS, SPIN_ID, &CSpinEdit::OnDeltaposSpin)
53     ON_WM_KILLFOCUS()
54     ON_WM_ENABLE()
55     ON_WM_SIZE()
56 END_MESSAGE_MAP()
57 
58 
59 
60 // CSpinEdit 消息处理程序
61 
62 void CSpinEdit::PreSubclassWindow()
63 {
64     // TODO: 在此添加专用代码和/或调用基类
65 
66     // 要求文本左对齐,右侧会被spin控件覆盖
67     // WS_CLIPCHILDREN在绘制中排除子窗口区域,避免重叠的控件绘制闪烁
68     ModifyStyle(ES_CENTER | ES_RIGHT, ES_LEFT | WS_CLIPCHILDREN);
69     // 将spin创建为edit的子控件,因为CTabDlg不一定能正常滚动动态创建的子控件(Spin)
70     // 准确的说是CWnd::ScrollWindow在窗口可见/不可见时对动态创建的子控件移动行为不一致(多半是这样)(具体参考wincore.cpp的实现)(在CTabDlg::OnTabEntered随意滚一下再滚回来窗口就能正常)
71     // 我试着在这里保持与edit为兄弟关系的spin始终跟随edit但没有成功,只好将spin作为edit的子控件(子窗口受限于父窗口的ClientRect所以不能使用UDS_ALIGNRIGHT)
72     m_spin.Create(WS_CHILD | WS_VISIBLE | UDS_ARROWKEYS | UDS_HOTTRACK | UDS_SETBUDDYINT, CRect(), this, SPIN_ID);
73     // 获取spin控件宽度
74     CRect rect;
75     m_spin.GetWindowRect(&rect);
76     m_spin_width = rect.Width();
77     // 设置spin控件区域(作为CEdit的子控件,ClientRect区域外的部分会被裁剪)
78     GetClientRect(&rect);
79     rect.left = rect.right - m_spin_width;
80     m_spin.MoveWindow(&rect);
81     // 设置Edit控件为关联控件
82     m_spin.SetBuddy(this);
83     // 设置默认范围
84     m_spin.SetRange(0, 999);
85     CEdit::PreSubclassWindow();
86 }
87 
88 
PreTranslateMessage(MSG * pMsg)89 BOOL CSpinEdit::PreTranslateMessage(MSG* pMsg)
90 {
91     // TODO: 在此添加专用代码和/或调用基类
92 
93     //如果m_mouse_wheel_enable为false,则不响应鼠标滚轮消息
94     if (pMsg->message == WM_MOUSEWHEEL && !m_mouse_wheel_enable)
95     {
96         //将鼠标滚轮消息发送给父窗口
97         CWnd* pParent = GetParent();
98         pParent->SendMessage(WM_MOUSEWHEEL, pMsg->wParam, pMsg->lParam);
99         return true;
100     }
101 
102     return CEdit::PreTranslateMessage(pMsg);
103 }
104 
105 
OnTabletQuerysystemgesturestatus(WPARAM wParam,LPARAM lParam)106 afx_msg LRESULT CSpinEdit::OnTabletQuerysystemgesturestatus(WPARAM wParam, LPARAM lParam)
107 {
108     return 0;
109 }
110 
111 
OnDeltaposSpin(NMHDR * pNMHDR,LRESULT * pResult)112 void CSpinEdit::OnDeltaposSpin(NMHDR* pNMHDR, LRESULT* pResult)
113 {
114     //这里响应微调按钮(spin button)点击上下按钮时的事件
115     LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
116 
117     int value = GetValue();
118     value += pNMUpDown->iDelta * m_step;
119     value /= m_step;
120     value *= m_step;
121     SetValue(value);
122     pNMUpDown->iDelta = 0;
123     *pResult = 0;
124 }
125 
126 
OnKillFocus(CWnd * pNewWnd)127 void CSpinEdit::OnKillFocus(CWnd* pNewWnd)
128 {
129     CEdit::OnKillFocus(pNewWnd);
130 
131     // TODO: 在此处添加消息处理程序代码
132     CString str;
133     GetWindowTextW(str);
134     int value = _ttoi(str.GetString());
135     SetValue(value);    // m_spin会检查并限制值范围以及更新CEdit控件文本
136 }
137 
138 
OnEnable(BOOL bEnable)139 void CSpinEdit::OnEnable(BOOL bEnable)
140 {
141     CEdit::OnEnable(bEnable);
142     m_spin.EnableWindow(bEnable);
143 }
144 
145 
OnSize(UINT nType,int cx,int cy)146 void CSpinEdit::OnSize(UINT nType, int cx, int cy)
147 {
148     CEdit::OnSize(nType, cx, cy);
149     CRect rect;
150     GetClientRect(&rect);
151     rect.left = rect.right - m_spin_width;
152     m_spin.MoveWindow(&rect);
153 }
154