C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Русский в клипбоард
Deem
Отправлено: 15.07.2005, 17:18


Мастер участка

Группа: Участник
Сообщений: 327



Использую TClipboard, но с апишными функциями тож самое.

Сохраняю в Clipboard:
Clipboard()->SetTextBuf("Ура!");

Достаю (вставить в винде):

???!

Чево делать? Если обсуждали ранее, не пинайте сильно. Пятница, знаетели, вечер. Некогда искать.

ДА, вопросы — это в инете получились. Были вполне приличные крокозяблы.

Отредактировано Deem — 15/07/2005, 17:21
Deem
Отправлено: 15.07.2005, 17:28


Мастер участка

Группа: Участник
Сообщений: 327



Вот еще штука: если вставлять из клипбоарда в моей же проге — русский нормальный. А при вставке в другой проге или винде — кракозяблы. Как бороться?
Gedeon
Отправлено: 15.07.2005, 18:32


Ветеран

Группа: Модератор
Сообщений: 1742



Не помню где, но читал, надо сказать буферу, что он в юникоде.
Deem
Отправлено: 18.07.2005, 10:24


Мастер участка

Группа: Участник
Сообщений: 327



Попробую.
Димыч
Отправлено: 18.07.2005, 12:57


Дежурный стрелочник

Группа: Участник
Сообщений: 38



А как ему это сказать?
Deem
Отправлено: 18.07.2005, 13:27


Мастер участка

Группа: Участник
Сообщений: 327



Вот, кое-что подсмотрел у братьев меньших — дельфийцев:

CODE

void BufferToClipboard(String Buffer)
{
 WideString WideBuffer;
 Cardinal BuffSize;
 THandle Data;
 void *DataPtr;

 if (Buffer != "")
   {

     WideBuffer = Buffer.c_str();
     BuffSize = Buffer.Length() * sizeof(WideChar);
     Data = (THandle)GlobalAlloc(GMEM_MOVEABLE+GMEM_DDESHARE+GMEM_ZEROINIT, BuffSize + 2);
     DataPtr = GlobalLock((void*)Data);
     Move(WideBuffer, DataPtr, BuffSize);
     GlobalUnlock((void*)Data);
     TClipboard* CB;
     CB = Clipboard();
 
     CB->SetAsHandle(CF_UNICODETEXT, Data);
     GlobalFree((void*)Data);
 
     if (!(CB->GetAsHandle(CF_UNICODETEXT)))
       {
         Data = (THandle)GlobalAlloc(GMEM_MOVEABLE+GMEM_DDESHARE+GMEM_ZEROINIT, BuffSize + 2);
         DataPtr = GlobalLock((void*)Data);
         Move(WideBuffer, DataPtr, BuffSize);
         GlobalUnlock((void*)Data);
         CB->SetAsHandle(CF_UNICODETEXT, Data);
         GlobalFree((void*)Data);
       }
   }
}



К слову: Data лучше делать не THandle, т.к. чаще приходится к void* преобразовывать. Кинул по-быстрому.


Примечательно, что без куска после if (!(CB->GetAsHandle(CF_UNICODETEXT))), копирование происходит через раз. Каждый второй раз после копирования клипбоард ваще пустой!
Хотелось бы знать, почему. Потому как приведенный выход — извращение. smile.gif
Gedeon
Отправлено: 18.07.2005, 14:43


Ветеран

Группа: Модератор
Сообщений: 1742



Вот так у меня работает нормально, все вставляет.
CODE

void __fastcall TForm1::SetClip(AnsiString Text)
{
   int len = (Text.Length()+1)*2;
   HGLOBAL  Data = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, len);
   void *  DataPtr = GlobalLock(Data);

   Move(WideString(Text).c_bstr(),DataPtr,len);

   OpenClipboard(NULL);
   EmptyClipboard();
   SetClipboardData(CF_UNICODETEXT, DataPtr);
   GlobalUnlock(Data);
   CloseClipboard();
}
Admin
Отправлено: 18.07.2005, 14:52


Владимир

Группа: Администратор
Сообщений: 1190



CODE

void __fastcall TForm1::Button2Click(TObject *Sender)
{
AnsiString S = Edit1->Text;

int len = (S.Length()+1)*2;
HGLOBAL P = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, len);
void* MX = GlobalLock(P);
Move(WideString(S).c_bstr(), MX, len);
GlobalUnlock(P);
Clipboard()->Clear();
Clipboard()->SetAsHandle(CF_UNICODETEXT, (unsigned int)P);
}


Отредактировано Admin — 18/07/2005, 15:01
Deem
Отправлено: 19.07.2005, 16:04


Мастер участка

Группа: Участник
Сообщений: 327



Ну и классно!

Вернуться в Вопросы программирования в C++Builder