gpt4 book ai didi

c++ - 子类编辑控件的输入验证只接受 float

转载 作者:太空狗 更新时间:2023-10-29 23:20:38 25 4
gpt4 key购买 nike

在我当前的项目中,最近几天我一直在努力处理编辑框的子类化。到目前为止,我已经成功地对我的编辑框进行了子类化并验证了输入,使其只接受数字、逗号、减号和键盘命令。

但很长一段时间以来,我一直致力于改进输入验证。我希望我的编辑框表现如下:

  • 仅在第一个位置接受减号
  • 只接受一个前导零
  • 只接受一个逗号
  • 在前导零后强制逗号
  • 管理删除单个字符或通过“返回”、“删除”、全选然后在其上粘贴内容来选择文本的情况

我的代码在其当前形式下看起来像这样并且几乎没有提供我在上面指定的高级验证要求:

inline LRESULT CALLBACK decEditBoxProc(HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam,
UINT_PTR uIdSubclass,
DWORD_PTR dwRefData)
{
if(msg == WM_CHAR)
{
decEditBoxData* data = reinterpret_cast<decEditBoxData*>(ULongToPtr(dwRefData));

bool isDigit = (wParam >= '0' && wParam <= '9');
bool isZero = ((wParam == '0') && !data->blockZero);
bool isSign = (wParam == '-');
bool isComma = ((wParam == '.' || wParam == ',') && !data->blockComma);
bool isValidCommand = (wParam == VK_RETURN
|| wParam == VK_DELETE
|| wParam == VK_BACK);


// Restrict comma to one.
if(isComma && data->nCommas > 0)
return FALSE;
else if(isComma && data->nCommas == 0)
data->nCommas++;

// Restrict trailing zeroes to one.
if(isZero && data->nTrailingZeroes > 0)
return FALSE;
else if(isZero && data->nTrailingZeroes == 0)
data->nTrailingZeroes++;

// Filter everything but digits, commas and valid commands.
if(!isDigit && !isValidCommand && !isComma)
return FALSE;
}
return DefSubclassProc(hWnd, msg, wParam, lParam);
}

非常感谢任何关于如何通过算法解决此问题的想法。

更新

感谢 David Heffernan 和 IInspectable 的建议,我能够(几乎)解决我的问题而无需子类化编辑控件。

在对话过程中(包含编辑控件):

switch(msg)
{
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_IN_REAL:
if(HIWORD(wParam)==EN_CHANGE) onEditChange(hDlg, IDC_IN_REAL);
break;

case IDC_IN_IMAG:
if(HIWORD(wParam)==EN_CHANGE) onEditChange(hDlg, IDC_IN_IMAG);
break;
}
break;
}

使用 onEditChange:

void onEditChange(HWND hDlg, int ctrlID)
{
HWND hEdit = GetDlgItem(hDlg, ctrlID);
size_t len = GetWindowTextLength(hEdit)+1;
wchar_t* cstr = new wchar_t[len];
GetWindowText(hEdit, cstr, len);

std::wstring wstr(cstr);

if(!(tools::isFloat(wstr)))
{
EDITBALLOONTIP bln;
bln.cbStruct = sizeof(EDITBALLOONTIP);
bln.pszTitle = L"Error";
bln.pszText = L"Not a valid floating point character.\nUse '.' instead of ','";
bln.ttiIcon = TTI_ERROR;
Edit_ShowBalloonTip(hEdit, &bln);
}
delete [] cstr;
}

和 isFloat():

bool tools::isFloat(std::wstring str)
{
std::wistringstream iss(str);
float f;
wchar_t wc;
if(!(iss >> f) || iss.get(wc))
return false;
return true;
}

我可能会为用户添加更多视觉反馈,但现在这并不重要。

然而,这个问题还没有得到回答。我的意图是允许“,”作为可能的小数点。

最佳答案

你需要一个状态机。首先声明你的状态。

enum InputState
{
NoCharacters
MinusSign
LeadingZero
PreDecimalPoint
PostDecimalPoint
}
InputState mState = NoCharacters

每当用户输入字符时,使用开关 block 根据 mState 的值调用不同的验证函数。

bool ValidCharacter(char input)
{
switch (mState)
{
case NoCharacters:
return NoCharacters(input);
case MinusSign:
return MinusSign(input);
/// etc
}
}

例如,您在 mState == NoCharacters 时调用的函数将接受任何数字、小数点或减号。如果字符是减号,它会将 mState 更改为 MinusSign,如果它是零,则将其更改为 LeadingZero,等等。

关于c++ - 子类编辑控件的输入验证只接受 float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24325142/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com