Требуется вставить одну строку в другую после получения текста из буфера обмена.

ВВЕДЕНИЕ И СООТВЕТСТВУЮЩАЯ ИНФОРМАЦИЯ:

у меня есть edit control который должен принимать только десятичные числа со знаком (что-то вроде -12.35).

Я решил реализовать это через subclassing,

WM_CHAR кажется, что обработчик работает хорошо, и мне нужно обработать несколько других сообщений, чтобы полностью защитить пользователя от ввода неверного текста. Одно из таких сообщений WM_PASTE,

До сих пор я смог правильно получить текст из clipboard и отменить или передать сообщение в зависимости от того, является ли скопированная строка действительно десятичным числом.

Элемент редактирования имеет ограниченный ввод до 12 символов. Это делается через EM_SETLIMITTEXT сообщение.

я использую pure Winapi а также C++, Нет таких библиотек, как boost и т. д. разрешены.

ПРОБЛЕМА:

До сих пор я тестировал случай, когда контроль редактирования пуст, и я отказываюсь от вставки, если содержимое недействительно. Однако пользователь может выбрать часть текста в элементе управления редактирования и затем выполнить вставку. Примерно так (серые символы обозначают выделение):

Текст в редакторе: 12345678,9

Текст буфера обмена: -1A

Результирующая строка, если я позволю вставлять, будет 123-1A78.9, что является недопустимым форматом.

В этой части мне нужна помощь:

Мой анализ правильно распознает допустимый формат, но я не знаю, как правильно объединить две строки в одну, чтобы я мог проверить это.

ВОПРОСЫ:

  1. Как правильно сформировать полученную строку из вставки, чтобы я мог проверить ее правильность?

  2. Есть ли функция, которая может сделать тест на достоверность для меня (она должна быть в курсе локали!)?

Примечание: я не против разбора текста самостоятельно, но зачем "изобретать велосипед", если в этом нет необходимости?

МОИ УСИЛИЯ ДЛЯ РЕШЕНИЯ ЭТОГО:

  1. Просматривая через интернет я нашел много std:: функции, которые объединяют / обрезают строку / etc, но ни одна из них, кажется, не удовлетворяет моим потребностям для формирования результирующей строки. Самая близкая вещь, которую я нашел, была string:: insert(...) но я не знаю, как его использовать.

  2. Что касается второго вопроса, я нашел std:: strtod просматривая вопросы Stackru, и кажется, что его можно использовать для проверки правильности строки. И кажется, что это также известно на местном уровне, но я не уверен, что это то, что я ищу.

Чтобы этот пост был как можно более кратким, я привожу ссылку на мой вопрос с соответствующими фрагментами кода.

Спасибо за ваше время и помощь.

Если потребуется дополнительная информация, я обновлю сообщение.

С наилучшими пожеланиями.

1 ответ

Решение

Попробуйте что-то вроде этого:

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;
}
Другие вопросы по тегам