Добрый день!
(Что-то не получилось у меня первый раз отправить сообщение)
Изучая MFC, столкнулся со странным поведением Spina (VS 2003).
К примеру, есть простое приложение на основе диалога. На форме диалога два контрола: Edit и Spin.
Объявление переменных:
class CSpinDlg : public CDialog
{
...
public:
CSpinButtonCtrl m_Spin;
int m_Edit;
afx_msg void OnDeltaposSpin1(NMHDR *pNMHDR, LRESULT *pResult);
};
Инициализация:
BOOL CSpinDlg::OnInitDialog()
{
// TODO: Add extra initialization here
m_Spin.SetBuddy((CEdit*)GetDlgItem(IDC_EDIT1));
m_Spin.SetRange32(1,50);
m_Spin.SetPos32(1);
m_Edit = m_Spin.GetPos32();
return TRUE; // return TRUE unless you set the focus to a control
}
Обработчик UDN_DELTAPOS:
void CSpinDlg::OnDeltaposSpin1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
// TODO: Add your control notification handler code here
m_Edit = m_Spin.GetPos32();
UpdateData(FALSE);
*pResult = 0;
}
При первом щелчке по Spin-у для увеличения значения, ничего не происходит. При последующих щелчках, происходит увеличение значения на 1, т.е. то, что нужно. Если же теперь начать уменьшать значение, то сначала, оно увеличится на 1, и только потом начнет уменьшаться.
Почему он так себя ведет? Как с этим бороться? Неужели, прийдется извращаться в обработчике?
Заранее спасибо.
Здравствуйте, BorisM, Вы писали:
BM>Обработчик UDN_DELTAPOS:
BM>BM>void CSpinDlg::OnDeltaposSpin1(NMHDR *pNMHDR, LRESULT *pResult)
BM>{
BM> LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
BM> // TODO: Add your control notification handler code here
BM> m_Edit = m_Spin.GetPos32();
BM> UpdateData(FALSE);
BM> *pResult = 0;
BM>}
BM>
BM>При первом щелчке по Spin-у для увеличения значения, ничего не происходит. При последующих щелчках, происходит увеличение значения на 1, т.е. то, что нужно. Если же теперь начать уменьшать значение, то сначала, оно увеличится на 1, и только потом начнет уменьшаться.
BM>Почему он так себя ведет? Как с этим бороться? Неужели, прийдется извращаться в обработчике?
UDN_DELTAPOS
Sent by the operating system to the parent window of an up-down control when the position of the control is about to change. This happens when the user requests a change in the value by pressing the control's up or down arrow.
The UDN_DELTAPOS notification is sent before the WM_VSCROLL or WM_HSCROLL message, which actually changes the control's position. This lets you examine, allow, modify, or disallow the change.
То есть Вам гужно смотреть на pNMUpDown->iPos и pNMUpDown->iDelta для получения того значения, которое "будет" (а не GetPos32).
[ posted via RSDN@Home 1.1.4 beta 3 r241 ]
Здравствуйте, SchweinDeBurg, Вы писали:
SDB>То есть Вам гужно смотреть на pNMUpDown->iPos и pNMUpDown->iDelta для получения того значения, которое "будет" (а не GetPos32).
Спасибо за ответ.
Я до GetPos32() пытался получить нужное значение как: pNMUpDown->iPos + pNMUpDown->iDelta. Результат мне тоже не очень понравился. После некоторых экспериментов, окончательный вариант выглядит так:
void CSpinDlg::OnDeltaposSpin1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
int static iPrevPos = m_Spin.GetPos32(); //переменная, где хранится предыдущее значение
m_Spin.SetPos32(iPrevPos + pNMUpDown->iDelta);
m_Edit = m_Spin.GetPos32();
iPrevPos = m_Spin.GetPos32();
UpdateData(FALSE);
*pResult = 0;
}
Может кому пригодится