у меня есть edit control
который должен принимать только десятичные числа со знаком (что-то вроде -12.35
).
Я решил реализовать это через subclassing
,
WM_CHAR
кажется, что обработчик работает хорошо, и мне нужно обработать несколько других сообщений, чтобы полностью защитить пользователя от ввода неверного текста. Одно из таких сообщений WM_PASTE
,
До сих пор я смог правильно получить текст из clipboard
и отменить или передать сообщение в зависимости от того, является ли скопированная строка действительно десятичным числом.
Элемент редактирования имеет ограниченный ввод до 12 символов. Это делается через EM_SETLIMITTEXT
сообщение.
я использую pure Winapi
а также C++
, Нет таких библиотек, как boost
и т. д. разрешены.
До сих пор я тестировал случай, когда контроль редактирования пуст, и я отказываюсь от вставки, если содержимое недействительно. Однако пользователь может выбрать часть текста в элементе управления редактирования и затем выполнить вставку. Примерно так (серые символы обозначают выделение):
Текст в редакторе управления: 123456
78,9
Текст буфера обмена: -1A
Результирующая строка, если я позволю вставлять, будет 123-1A78.9, что является недопустимым форматом.
В этой части мне нужна помощь:
Мой анализ правильно распознает допустимый формат, но я не знаю, как правильно объединить две строки в одну, чтобы я мог проверить это.
Как правильно сформировать полученную строку из вставки, чтобы я мог проверить ее правильность?
Есть ли функция, которая может сделать тест на достоверность для меня ( это должно быть с учетом местных особенностей! )
Примечание: я не против разбора текста самостоятельно, но зачем «изобретать велосипед», если в этом нет необходимости?
Просматривая через интернет я нашел много std::
функции, которые объединяют / обрезают / etc строку, но ни одна из них, кажется, не удовлетворяет моим потребностям для формирования результирующей строки. Самая близкая вещь, которую я нашел, была string:: insert(...)
но я не знаю, как его использовать.
Что касается второго вопроса, я нашел 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;
}
Других решений пока нет …