Как я могу вставить произвольные данные в TMemo? - PullRequest
2 голосов
/ 14 ноября 2009

Копировать и вставлять текст достаточно просто, поскольку он встроен в TMemo, но кажется, что он может обрабатывать только текст. Мне кажется, что любой вид данных может быть представлен в виде строки, хотя. Если я скопирую некоторые произвольные данные из другой программы и захочу вставить их в TMemo, как мне заставить Delphi принять их как необработанную строку?

Ответы [ 4 ]

6 голосов
/ 15 ноября 2009

«Если я скопирую некоторые произвольные данные из другой программы и захочу вставить их в TMemo, как мне заставить Delphi принять их как необработанную строку?» Итак, чтобы прояснить свой вопрос, вы:

  • Хотите использовать любое другое приложение (для которого у вас нет кода, обычное приложение) и скопировать в него что-нибудь
  • Хотите вставить эти скопированные данные, которые могут быть любого формата, включая нетекстовые, как текст в вашей заметке.

Это правильно? Если это так, вы не можете использовать Clipboard.AsText - он возвращает текст, только если в буфере обмена есть данные с форматом CF_TEXT. Вам нужно будет напрямую использовать API буфера обмена. В буфере обмена хранятся данные с кодом формата, и вы можете получить указатель на эти данные и размер, и обрабатывать их как строку или как вам угодно.

Итак:

  • Выясните, какой формат вы хотите вставить. Вы можете перебирать все форматы, которые в настоящее время находятся в буфере обмена, с помощью EnumClipboardFormats или использовать одну из предопределенных констант (для текста, изображений, аудио и т. Д.). Буфер обмена может хранить данные во многих форматах одновременно, так что вы можете выбрать, какой из многих вы используете.
  • Если данные в этом формате находятся в буфере обмена, открыть их . Обязательно оберните этот код в try/finally и закройте буфер обмена в предложении finally. Если вы не закроете буфер обмена, никакое другое приложение не сможет его использовать, поэтому вы хотите, чтобы оно было закрыто даже в случае сбоя приложения.
  • Позвоните GetClipboardData, чтобы получить указатель на данные в этом формате. Данные о (или переданные, если вы позже внедрите Copy) распределяются через GlobalAlloc, поэтому вам нужно заблокировать дескриптор, чтобы получить указатель на него через GlobalLock ( и когда закончите, разблокируйте с помощью GlobalUnlock.) Данные принадлежат буферу обмена, поэтому не освобождайте их после использования. Чтобы найти размер этих данных в байтах, используйте GlobalSize.
  • Это дает вам указатель на данные известного размера. На этом этапе вы можете делать все, что вы хотите с ним. Рассматривать это как строку - один из вариантов. Поскольку ваше приложение не владеет данными, вы должны скопировать их, а не напрямую манипулировать ими.

Ваш код должен знать, что данные имеют определенный размер и, вероятно, не будут заканчиваться нулем (или могут содержать нули), поэтому при преобразовании в строку убедитесь, что вы не переполняете буфер. Вы можете закодировать его, чтобы избежать NULL s и т. Д. Если вы хотите получить более подробную информацию о чем-то подобном, вероятно, стоит задать другой вопрос (или выполнить поиск для кодирования произвольных данных в виде строки). Самое простое, что можно сделать, - это скопировать данные в буфер размера + 1, установите последний байт на ноль, перебирайте каждый байт, кроме самого последнего, и для непечатаемых символов (значение байта <32) измените его на «.» или какой-то другой персонаж. Затем передайте указатель на этот буфер в конструктор <code>AnsiString, приведенный как PAnsiChar. (Это гарантирует, что ваши данные обрабатываются как строка символов байтового размера - имейте в виду, если вы используете D2009 +, поскольку собственный тип строки - Unicode.) Альтернативный тип строки для использования - RawByteString. Получив строку, добавьте ее в заметку.

Есть хороший пример (на С, извините) вставки данных определенного формата в MSDN . Вы можете использовать это в качестве отправной точки, добавляя свою собственную обработку данных. Вставка в виде строки, вероятно, не лучший способ просмотра произвольных двоичных данных - вы можете использовать компонент шестнадцатеричного редактора или какой-либо другой визуализатор, чтобы лучше просматривать данные.

2 голосов
/ 14 ноября 2009

Мейсон, я не уверен, что понимаю твой ответ, но да, ты можешь использовать Clipboard.AsText, как сказал авар, просто добавь clipbrd к пункту использования. Обратите внимание, что если у вас есть нулевой символ где-то в вашей строке, то KAZAM ваша строка будет вставлена ​​с начала до нулевого символа # 0. Другим подходом может быть использование отображенных в памяти файлов или сообщений для передачи данных между приложениями.

1 голос
/ 14 ноября 2009

вы пытались использовать clipbaord.astext между вашим tmemo и "другой программой"

0 голосов
/ 15 ноября 2009

Я не уверен, что ваше утверждение «любые данные могут быть представлены в виде строки» имеет смысл. Двоичные данные могут иметь встроенные нули, что может помешать обработке данных в виде строки. А какое значение имеет строковое представление, например, растрового изображения?

Это зависит от приложения, которое устанавливает буфер обмена для определения формата информации о буфере обмена. Если приложение достаточно продуманно, чтобы предоставить текстовое представление нетекстовой информации (например, имя файла для изображения, если оно есть), вы можете использовать эту строковую информацию. Иначе не ясно, что будет означать вставка этой информации в TMemo.

...