自旋控制 GetPos() 值被延迟 [英] Spin Control GetPos() value is delayed
问题描述
我有一个编辑控件和一个旋转控件,初始位置设置为 0.单击向上箭头时,编辑框从 0 变为 1,这很好.但是当我使用 GetPos()
时,MyValue
为 0.当旋转控件再次从 1 增加到 2 时,MyValue 变为 1.当按下向下箭头时,编辑box从2变成1,但是值变成了2.看起来MyValue
总是在spin控件后面的一个动作.
I have an edit control buddied with a spin control with the initial position set to 0. When the up arrow is clicked the edit box goes from 0 to 1, which is fine. But when I use GetPos()
the MyValue
is 0. When the spin control is incremented again from 1 to 2, the MyValue becomes 1. When down arrow is pressed the edit box goes from 2 to 1, but the value becomes 2. It seems that the MyValue
is always one action behind the spin control.
BOOL CAlphaDlg::OnInitDialog()
{
// default code left out to keep it short ...
// TODO: Add extra initialization here
// set range and initial position
mSpinControl.SetRange(0, 3600); // range
mSpinControl.SetPos(0); // inital position
MyValue = mSpinControl.GetPos();
// display initial value in buddy editcontrol
mEditControlDisplay.Format("%d", MyValue);
UpdateData(false);
return TRUE;
}
void CAlphaDlg::OnDeltaposSpin1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
// TODO: Add your control notification handler code here
UpdateData(true);
int MyValue= mSpinControl.GetPos();
std::cout << MyValue << std::endl;
*pResult = 0;
}
我尝试从编辑控件获取值,但该值表现出相同的行为.如何获取 GetPos() 的值以匹配编辑控件中显示的内容?
I have tried getting the value from the editcontrol but the value is exhibiting the same behavior. How do I get the value of the GetPos() to match what is showing in the edit control?
提前致谢.
编辑:这是完整的代码
// AlphaDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Alpha.h"
#include "AlphaDlg.h"
#include "afxdialogex.h"
#include <iostream>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CAlphaDlg dialog
CAlphaDlg::CAlphaDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_ALPHA_DIALOG, pParent)
, mEditControlDisplay(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CAlphaDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, mEditControlDisplay);
DDX_Control(pDX, IDC_SPIN1, mSpinControl);
}
BEGIN_MESSAGE_MAP(CAlphaDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN1, &CAlphaDlg::OnDeltaposSpin1)
END_MESSAGE_MAP()
// CAlphaDlg message handlers
BOOL CAlphaDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
mSpinControl.SetRange(0, 10);
mSpinControl.SetPos(0);
int MyValue = mSpinControl.GetPos();
mEditControlDisplay.Format("%d", MyValue);
UpdateData(false);
return TRUE; // return TRUE unless you set the focus to a control
}
void CAlphaDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CAlphaDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CAlphaDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CAlphaDlg::OnDeltaposSpin1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
// TODO: Add your control notification handler code here
*pResult = 0;
UpdateData(true);
int MyValue = mSpinControl.GetPos();
std::cout << mEditControlDisplay << std::endl;
std::cout << MyValue << std::endl;
}
推荐答案
首先,考虑将您的编辑框映射到 int
,然后您不需要转换为字符串.并且默认值是 0 开始,所以微调器就可以了.您也可以关闭自动好友.
Firstly, consider mapping your edit box to a int
and then you do not need to cast to a string. And the default value is 0 to begin with so the spinner will be OK. You can also switch off the auto buddy.
在 deltapos 处理程序中,您可以这样做:
In the deltapos handler you could do this:
void CMFCApplication1Dlg::OnDeltaposSpin1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
// TODO: Add your control notification handler code here
*pResult = 0;
SetDlgItemInt(IDC_EDIT1, pNMUpDown->iPos);
UpdateData(TRUE);
CString a;
a.Format(_T("%d"), iNumberValue);
AfxMessageBox(a);
}
对我来说,弹出消息和编辑控件中的结果是一样的.
For me the results in the popup message and the edit control are the same.
您可以通过查看结构来确定新值是什么:
You can workout what the new value would be by looking at the structure:
void CMFCApplication1Dlg::OnDeltaposSpin1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
int iCurrentPos = pNMUpDown->iPos;
if (pNMUpDown->iDelta > 0)
iCurrentPos++;
else
iCurrentPos--;
CString strNewValue;
strNewValue.Format(_T("%d"), iCurrentPos);
AfxMessageBox(strNewValue);
*pResult = 0;
}
供考虑
您可能想考虑一下CSpinButtonCtrl::SetAccel
用于设置旋转按钮控件的加速度.
For Consideration
You might want to give some thought to CSpinButtonCtrl::SetAccel
which sets the acceleration for a spin button control.
在您的情况下,我认为这无关紧要,因为您的范围只有 10单位.但是如果你有一个更大的范围,那么它可能会增加一个以上的单位.这只是需要记住的事情.
In your case I don't think it is going to matter because your range is only 10 units. But if you had a larger range then it is possible that it would increment by more than one unit. It is just something to keep in mind.
根据此参考UDN_DELTAPOS代码>
它说:
According to this reference for UDN_DELTAPOS
it says:
结构的 iDelta 成员是一个有符号整数,其中包含提议的位置变化.
The iDelta member of the structure is a signed integer that contains the proposed change in position.
因此,您可以基于 iDelta
值而不是 1 改进代码和递增/递减.这将影响加速.所以:
So you could improve the code and increment/decrement based on the iDelta
value instead of 1. This would factor in for acceleration. So:
int iCurrentPos = pNMUpDown->iPos + pNMUpDown->iDelta;
这篇关于自旋控制 GetPos() 值被延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!