简介及相关信息:
我有一个edit control
,只需要接受有符号的十进制数(像-12.35
)。
我决定通过subclassing
来实现这一点。
WM_CHAR
处理程序似乎工作得很好,我需要处理其他几个消息,以完全保护用户不输入无效文本。一个这样的消息是WM_PASTE
。
到目前为止,我能够正确地从clipboard
中获取文本,并根据复制的字符串是否确实是十进制数来丢弃或传递消息。
编辑控件的输入限制为12个字符。这是通过EM_SETLIMITTEXT
消息完成的。
我使用pure Winapi
和C++
。不允许使用boost
等库。
问题:
到目前为止,我测试了edit控件为空的情况,如果内容无效,则放弃粘贴。但是,用户可以在编辑控件中选择文本的一部分,然后执行粘贴。像这样(灰色字符表示选择):编辑控件中的文本: 123 456
78.9
剪贴板文本: -1A
结果字符串,如果我允许粘贴,将是123-1A78.9,这是无效的格式。
这是我需要帮助的部分:
我的解析正确识别有效格式,但我不知道如何正确地将两个字符串合并为一个,所以我可以测试它。
问题:
如何正确地形成粘贴的结果字符串,以便我可以测试其有效性?
是否有一个函数可以为我做有效性测试(它应该是地区意识!
注意:我不介意自己解析文本,但如果没有必要,为什么要"重新发明轮子"?
MY EFFORTS TO SOLVE THIS:
通过互联网浏览,我发现许多
std::
函数连接/切断/等字符串,但它们似乎都不能满足我对形成结果字符串的需求。最接近的东西我发现是string:: insert(...)
,但我不知道如何使用它。关于第二个问题,我通过浏览StackOverflow questions找到了
std:: strtod
,似乎可以用来检查字符串的有效性。而且它似乎也是区域意识的,但我不确定这是否是我所寻求的。
为了使这篇文章尽可能简短,我提供了我这个问题的链接,其中有相关的代码片段。
感谢您的时间和帮助。
如果需要进一步的信息,我会更新帖子。
问好。
试试这样:
case WM_PASTE:
{
std::wstring cbtext;
if( !OpenClipboard(hwnd) ) // open clipboard
return 0;
// get clipboard data
HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT);
if( hClipboardData )
{
// Call GlobalLock so that to retrieve a pointer
// to the data associated with the handle returned
// from GetClipboardData.
cbtext = (LPWSTR) GlobalLock(hClipboardData);
// Unlock the global memory.
GlobalUnlock(hClipboardData);
}
// Finally, when finished I simply close the Clipboard
// which has the effect of unlocking it so that other
// applications can examine or modify its contents.
CloseClipboard();
if (cbtext.empty())
return 0;
// format the new text with the clipboard data inserted as needed
int len = GetWindowTextLengthW(hwnd);
std::wstring newtext(len, 0);
if (len > 0)
GetWindowTextW(hWnd, &newtext[0], len);
DWORD start, end;
SendMessageW(hwnd, EM_GETSEL, (WPARAM)&start, (LPARAM)&end);
if (end > start)
newtext.replace(start, end-start, cbtext);
else
newtext.insert(start, cbtext);
// parse the new text for validity
// code for parsing text
if( IsTextValid )
SetWindowTextW( hwnd, newtext.c_str() );
return 0;
}