
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.21] |
![]() |
|
![]() |
|
|
Проблема стара, перечитав много статей так и не нашел ответа однозначного ответа. На форуме раза три точно поднималась.
В мастере создаем диалоговое приложение CMainDlg с многобайтовой кодировкой, на него кладем CEdit, вводим русский текст, потом, переключаемся на английский язык, копируется мусор. Обратно копируются вопросы. Как я понял проблема в том, что буфер обмена думает, что в буфере английский язык, хотя там русский. Естественно команды при инициализации приложения: SetThreadLocale(1049); setlocale(LC_ALL,"Russian" ); не дают никакого эффекта. Вопрос: получается у нас единственный вариант отлавливать WM_PASTE в CMainDlg? Есть еще решение? |
Сообщ.
#2
,
|
|
|
Цитата MaIron @ Обратно копируются вопросы. Как я понял проблема в том, что буфер обмена думает, что в буфере английский язык, хотя там русский. MaIron, думаю, что буфер обмена вообще ничего не думает. Какие байты ему дают, такие он хранит и обратно возвращает. --- Указанные классы я не использовал, но если смастерить эдит средствами winapi, никаких эффектов с искажениями информации мне обнаружить не удалось. |
Сообщ.
#3
,
|
|
|
Цитата MaIron @ Естественно команды при инициализации приложения: SetThreadLocale(1049); setlocale(LC_ALL,"Russian" ); не дают никакого эффекта. Чего-чего? Какая кодировка инициализируется? Я правда юзал лишь windows api и всё всегда было нормой. По идее классы всего лишь обёртка над windows api и не должны заниматся самодеятельностью. Но одно лишь SetThreadLocale(1049) Вызывает огромные подозрение. Думаю, что именно оно и даёт эффект. Ну или ваши классы вовсе не широкосимвольные, а чёрт знает какие. Ведь широкосимвольные функции перекодировкой не занимаются. И да, на всякий случай, вы всё же проверьте, ту программу, куда пытаетесь вставить свой текст. Попробуйте блокнот. Он не должен вносить искажений в текст. Насколько я знаю, к примеру wordpad может проверить буфер и по своему попытатся интерпретировать его содержимое. |
Сообщ.
#4
,
|
|
|
Нет. Все стандартно класс CEdit, копирую в блокнот, проблема в MFC. Студия 2003я Win7 64bit
|
Сообщ.
#5
,
|
|
|
Пришлось переопределять CEdit
Если кому то пригодится привожу реализацию, код сильно не тестировал. ![]() ![]() #pragma once // CCoreEdit class CCoreEdit : public CEdit { DECLARE_DYNAMIC(CCoreEdit) public: CCoreEdit(); virtual ~CCoreEdit(); public: DECLARE_MESSAGE_MAP() afx_msg LRESULT OnCopy(WPARAM, LPARAM); afx_msg LRESULT OnPaste(WPARAM, LPARAM); protected: }; ![]() ![]() // CoreEdit.cpp : implementation file // #include "stdafx.h" #include "CoreEdit.h" // CCoreEdit IMPLEMENT_DYNAMIC(CCoreEdit, CEdit) CCoreEdit::CCoreEdit() { } CCoreEdit::~CCoreEdit() { } BEGIN_MESSAGE_MAP(CCoreEdit, CExtEdit) ON_MESSAGE(WM_COPY, OnCopy) ON_MESSAGE(WM_PASTE, OnPaste) END_MESSAGE_MAP() LRESULT CCoreEdit::OnCopy(WPARAM, LPARAM) { //Размер получаемого блока int nStart = 0; int nEnd = 0; //Текущая строка CString sText; //Временная строка CString sBlock; //Получаем текст GetWindowText(sText); //Получаем выделение GetSel(nStart, nEnd); //Если не пустая стрка if(!sText.IsEmpty() && nStart > -1){ //Получаем выделенный фрагмент sBlock = sText.Right(sText.GetLength() - nStart); sBlock = sBlock.Left(nEnd-nStart); HGLOBAL hGlobal = ::GlobalAlloc( GHND, sBlock.GetLength()+ 1 ); void* mem = ::GlobalLock( hGlobal ); if ( mem ){ memcpy( mem, sBlock, sBlock.GetLength() + 1 ); ::GlobalUnlock( hGlobal ); if ( ::OpenClipboard( NULL ) ) ::EmptyClipboard(); LCID* lcid = (DWORD*) ( GlobalAlloc( GMEM_FIXED, sizeof(DWORD) ) ); *lcid = MAKELCID( MAKELANGID( LANG_RUSSIAN, SUBLANG_NEUTRAL ), SORT_DEFAULT ); ::SetClipboardData( CF_LOCALE, (HANDLE) lcid ); ::SetClipboardData( CF_TEXT, hGlobal ); ::CloseClipboard(); } } return 1; } LRESULT CCoreEdit::OnPaste(WPARAM, LPARAM) { UINT nFlag = CF_TEXT; if(!IsClipboardFormatAvailable(nFlag)) return 1; if(!OpenClipboard()) return 1; LCID* lcid = (DWORD*) ( GlobalAlloc( GMEM_FIXED, sizeof(DWORD) ) ); *lcid = MAKELCID( MAKELANGID( LANG_RUSSIAN, SUBLANG_NEUTRAL ), SORT_DEFAULT ); ::SetClipboardData( CF_LOCALE, (HANDLE) lcid ); HGLOBAL hData = GetClipboardData(nFlag); if(hData != NULL) { LPTSTR lptstr = (LPTSTR)GlobalLock(hData); if(lptstr != NULL){ ReplaceSel(lptstr, TRUE); } GlobalUnlock(hData); } CloseClipboard(); return 1; } |