Странное поведение CSpinButtonCtrl (повтор)
От: BorisM  
Дата: 21.12.04 13:05
Оценка:
Добрый день!
(Что-то не получилось у меня первый раз отправить сообщение)
Изучая 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, и только потом начнет уменьшаться.

Почему он так себя ведет? Как с этим бороться? Неужели, прийдется извращаться в обработчике?

Заранее спасибо.
Re: Странное поведение CSpinButtonCtrl (повтор)
От: SchweinDeBurg Россия https://zarezky.spb.ru/
Дата: 21.12.04 13:11
Оценка:
Здравствуйте, 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 ]
- Искренне ваш, Поросенок Пафнутий
Re[2]: Странное поведение CSpinButtonCtrl (повтор)
От: BorisM  
Дата: 23.12.04 09:53
Оценка:
Здравствуйте, 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;
}

Может кому пригодится
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.