在 MFC 中使用编辑框处理滑块控件

问题描述

我在正确使用 Slider Control 时遇到问题,并且对值的 UpdatingData 机制有很好的理解。 这是一个非常简单的程序,应该可以帮助我理解问题。

看看我的代码

// TestDialog.cpp : implementation file
//

#include "stdafx.h"
#include "ControlsandVariables.h"
#include "TestDialog.h"
#include "afxdialogex.h"


// TestDialog dialog

IMPLEMENT_DYNAMIC(TestDialog,CDialog)

TestDialog::TestDialog(CWnd* pParent /*=NULL*/)
    : CDialog(TestDialog::IDD,pParent),editBox_value(0),slider_value(0)
{

}

TestDialog::~TestDialog()
{
}

void TestDialog::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Control(pDX,IDC_SLIDER1,slider_ctrl);
    DDX_Text(pDX,IDC_EDIT1,editBox_value);
    DDV_MinMaxInt(pDX,editBox_value,99);
    DDX_Slider(pDX,slider_value);
}


BEGIN_MESSAGE_MAP(TestDialog,CDialog)
    ON_NOTIFY(NM_CUSTOMDRAW,&TestDialog::OnNMCustomdrawSlider1)
    ON_EN_CHANGE(IDC_EDIT1,&TestDialog::OnEnChangeEdit1)
END_MESSAGE_MAP()


// TestDialog message handlers


void TestDialog::OnNMCustomdrawSlider1(NMHDR *pNMHDR,LRESULT *pResult)
{
    LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
    // Todo: Add your control notification handler code here
    
    int value = slider_ctrl.GetPos();
    editBox_value = value;
    UpdateData(TRUE);
    
    //editBox_value = slider_value;
    //UpdateData(TRUE);
    *pResult = 0;
}

我在同时更改滑块和编辑框上的值时遇到问题。 如果我使用 UpadateData(TRUE),滑块的值会发生变化,但编辑框保持不变。
另一方面,如果我设置 UpdateData (FALSE) 滑块保持不变,但编辑框值正在改变,迭代后恢复为 0。 如何实现slider和editBox都相互依赖改变值的状态。 需要说明的是,这是MFC库的WindowsEmbedded 2013版本,不适用于本地Windows。

解决方法

您必须为 CEditCSliderCtrl 创建两个控件类型变量。例子:

  • m_cedit
  • m_slider

enter image description here

enter image description here

备注:

  • CSliderCtrl 发送 WM_HSCROLL 消息
  • 确保 CEdit Number 属性设置为 True

在 Dlg 头类中添加以下函数:

afx_msg void OnHScroll(UINT nSBCode,UINT nPos,CScrollBar* pScrollBar);
afx_msg void OnEnChangeEdit();

在 CPP 中:

BEGIN_MESSAGE_MAP(CMFCSpinerDlg,CDialogEx)
    ON_WM_HSCROLL() // Called when Slider is scrolled
    ON_EN_CHANGE(IDC_EDIT1,OnEnChangeEdit) // Called when CEdit change value
END_MESSAGE_MAP()


void CMFCSpinerDlg::OnHScroll(UINT nSBCode,CScrollBar* pScrollBar)
{
    CSliderCtrl* pSlider = reinterpret_cast<CSliderCtrl*>(pScrollBar);

    // You can have multiple sliders: Check which one sent the notification  
    if (pSlider == &m_slider)
    {
        CString strSliderValue;
        int iValue = m_slider.GetPos(); // Get Slider value
        strSliderValue.Format("%d",iValue); 

        m_cedit.SetWindowText(strSliderValue); // Change CEdit Value
    }
}

void CMFCSpinerDlg::OnEnChangeEdit()
{
    CString strEditValue;
    m_cedit.GetWindowText(strEditValue);
    int iCeditValue = atoi(strEditValue);
    
    // do other check on value ...
    m_slider.SetPos(iCeditValue); // set Slider value
}

这样做:

  • 如果您更改 CSliderCtrl 值 -> CEdit 更改
  • 如果您更改 CEdit 值 -> CSliderCtrl 更改