Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.01.2013, 19:13   #1
nik2009nik
 
Регистрация: 11.02.2012
Сообщений: 6
По умолчанию Неверное копирование в буфер обмена русских букв ANSI

Дорого времени суток!!!
Ситуация такая.

Раньше при написании своих программ, когда мне нужно было текстовое поле, использовал стандартный "EDIT" - он имеет все основные функции редактирования, удобен и т.д.

Но при копировании русских букв в буфер обмена и последующей вставке текста в любой обычный редактор, например, блокнот, ИНОГДА вместо русских букв вставлялись латинские буквы с точками и крючками сверху. Думаю, многие с таким сталкивались.

Чтобы исправить эту проблему я написал свое текстовое поле. Код копирования в буфер обмена взял стандартный - во многих статьях один и тот же описан.

Но даже в этом случае проблема не ушла.

Подскажите, пожалуйста, как это решить на уровне своей программы, чтобы не трогать настройки Windows и подобные внешние вещи. Ведь как-то блокнот и другие редакторы нормально справляются с данной задачей.

вот код, который я использую для копирования в буфер обмена:
Код:
bool textToClipBoard(const char *a, HWND hwnd)
{
    long size = strlen(a) + 1;
    if(size<=1)
        return false;

    if(!OpenClipboard(hwnd))
        return false;

    EmptyClipboard();

    HGLOBAL hGlobal = GlobalAlloc(GMEM_DDESHARE, size);
    if (!hGlobal)
    {
        CloseClipboard();
        return false;
    }

    void* pointer = GlobalLock(hGlobal);
    memcpy(pointer,a,size);
    GlobalUnlock(hGlobal);

    SetClipboardData(CF_TEXT,hGlobal);
    CloseClipboard();
    return true;
}
в итоге такая картина:
Изображения
Тип файла: gif text.gif (2.2 Кб, 199 просмотров)

Последний раз редактировалось nik2009nik; 11.01.2013 в 19:23. Причина: добавление рисунка
nik2009nik вне форума Ответить с цитированием
Старый 11.01.2013, 19:48   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

при копировании должна быть русскач раскладка.
или же использовать юникод.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 11.01.2013, 22:15   #3
nik2009nik
 
Регистрация: 11.02.2012
Сообщений: 6
По умолчанию

Цитата:
при копировании должна быть русская раскладка.
или же использовать юникод.
Менять раскладку вручную или автоматически при копировании - не самый лучший вариант.
Юникод - идеальный вариант, но я хотел найти вариант именно с однобайтовыми ANSI символами, чтобы не перекодировать при каждом копировании.

И я нашел решение.
Сканирование буфера обмена показало, в чем была причина - CF_LOCALE - строка из 3-х символов, означающая текущую языковую кодировку текста. Для кириллицы нужно, чтобы CF_LOCALE была равна (25, 4 и завершающий символ 0). Устанавливая при копировании в буфер обмена этот параметр, все будет работать, как надо.

вот какой теперь стала функция копирования в буфер обмена:
Код:
bool textToClipBoard(const char *a, HWND hwnd)
{
    long size = strlen(a) + 1;
    if(size<=1)
        return false;

    if(!OpenClipboard(hwnd))
        return false;

    EmptyClipboard();

    HGLOBAL hGlobal = GlobalAlloc(GMEM_DDESHARE, size);
    if (!hGlobal)
    {
        CloseClipboard();
        return false;
    }

    void* pointer = GlobalLock(hGlobal);
    memcpy(pointer,a,size);
    GlobalUnlock(hGlobal);

    SetClipboardData(CF_TEXT,hGlobal);

   //чтобы кодировка была русской всегда
    static char rus[3]{25,4,0}; 
    hGlobal = GlobalAlloc(GMEM_DDESHARE, 3);
    if (!hGlobal)
    {
        CloseClipboard();
        return false;
    }

    pointer = GlobalLock(hGlobal);
    memcpy(pointer,rus,3);
    GlobalUnlock(hGlobal);

    SetClipboardData(CF_LOCALE,hGlobal);

    CloseClipboard();
    return true;
}
Может, кому пригодится.
Этот вариант с ANSI подходит для простых приложений, для русских версий Windows,
но для более качественной и универсальной работы приложения необходимо использовать Юникод (CF_UNICODETEXT)

Последний раз редактировалось nik2009nik; 11.01.2013 в 22:18.
nik2009nik вне форума Ответить с цитированием
Старый 02.09.2019, 14:42   #4
Viktor12
 
Регистрация: 05.03.2015
Сообщений: 8
По умолчанию

ДА !
Viktor12 вне форума Ответить с цитированием
Старый 02.09.2019, 14:44   #5
Viktor12
 
Регистрация: 05.03.2015
Сообщений: 8
По умолчанию

ЭТО САМОЕ ТО ! Перед копированием сменил раскладку с Енг на Рус и теперь нет крякозяблей.
С кодом программы разбираться не стану, хватает и того.
Огромное спасибо ! Вот Вы маг программирования ! Огромнейший ПЛЮС Вам !!! СПАСИБО !
Viktor12 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Копирование сообщения в буфер обмена sseaar Общие вопросы Delphi 1 28.09.2012 06:01
Копирование в буфер обмена Abuhamed JavaScript, Ajax 2 05.02.2012 02:20
Копирование в буфер обмена motorway JavaScript, Ajax 1 10.04.2011 07:36
Копирование в буфер обмена Xanex Общие вопросы Delphi 5 18.05.2009 23:13
Копирование структуры в буфер обмена bill Общие вопросы Delphi 14 20.11.2007 17:22