2009-11-14 5 views
2

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

ответ

6

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

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

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

Итак:

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

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

Существует хороший пример (на C, извините) из pasting data of a specific format on MSDN. Вы можете использовать это как отправную точку, добавив свое собственное собственное отношение к данным. Вставка в виде строки, вероятно, не самый лучший способ просмотра произвольных двоичных данных - вы можете использовать компонент шестнадцатеричного редактора или какой-либо другой визуализатор, чтобы лучше просмотреть данные.

+0

Спасибо, это сработало! –

1

вы пытались использовать clipbaord.astext между TMemo и «другой программой»

+0

Это не работает. Если содержимое буфера обмена не находится в текстовом формате, AsText возвращает пустую строку. –

2

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

+0

Это должно сработать, он просто должен избегать нулей – zz1433

+0

Как говорит Мейсон, это не сработает, если в буфере обмена нет данных формата CF_TEXT. Я думаю, он хочет получить произвольные данные (в любом формате) и рассматривать его как строку. –

0

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

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

+0

Я имел в виду, что любые данные могут быть представлены как RawByteString. Я должен был сформулировать это лучше. –