Как я могу вставить произвольные данные в TMemo?
Копировать и вставлять текст достаточно просто, поскольку он встроен в TMemo, но кажется, что он может обрабатывать только текст. Мне кажется, что любой вид данных может быть представлен в виде строки. Если я скопирую произвольные данные из другой программы и захочу вставить их в TMemo, как мне заставить Delphi принять их как необработанную строку?
4 ответа
"Если я скопирую некоторые произвольные данные из другой программы и захочу вставить их в TMemo, как мне заставить Delphi принять их как необработанную строку?" Итак, чтобы уточнить ваш вопрос, вы:
- Хотите использовать любое другое приложение (для которого у вас нет кода, обычное приложение) и скопировать в него что-нибудь
- Хотите вставить эти скопированные данные, которые могут быть любого формата, включая нетекстовые, как текст в заметке.
Это верно? Если это так, вы не можете использовать Clipboard.AsText
- это возвращает текст, только если есть данные с CF_TEXT
формат в буфере обмена. Вам нужно будет напрямую использовать API буфера обмена. Буфер обмена содержит данные с кодом формата, и вы можете получить указатель на эти данные и размер, и обрабатывать их как строку или как вам угодно.
Так:
- Выясните, какой формат вы хотите вставить. Вы можете перебирать все форматы, которые в данный момент находятся в буфере обмена,
EnumClipboardFormats
или используйте одну из предопределенных констант (для текста, изображений, аудио и т. д.). Буфер обмена может хранить данные во многих форматах одновременно, поэтому вы можете выбрать, какой из множества вы используете. - Если данные в этом формате находятся в буфере обмена, откройте их. Убедитесь, что вы завернули этот код в
try/finally
и закройте буфер обмена вfinally
пункт. Если вы не закроете буфер обмена, никакое другое приложение не сможет его использовать, поэтому вы хотите, чтобы он был закрыт, даже если ваше приложение вылетает. - Вызов
GetClipboardData
чтобы получить доступ к данным в этом формате. Данные (или переданные, если вы позже внедрите Copy) распределяются черезGlobalAlloc
, поэтому вам нужно заблокировать дескриптор, чтобы получить указатель на него черезGlobalLock
(и после того, как сделано, разблокировать сGlobalUnlock
.) Данные принадлежат буферу обмена, поэтому не освобождайте их после использования. Чтобы найти размер этих данных в байтах, используйтеGlobalSize
, - Это дает вам указатель на данные известного размера. На этом этапе вы можете делать с ней все, что захотите. Рассматривать это как строку - один из вариантов. Поскольку ваше приложение не владеет данными, вы должны скопировать их, а не напрямую манипулировать ими.
Ваш код должен знать, что данные имеют определенный размер и, вероятно, не будут заканчиваться нулем (или могут содержать нули), поэтому при преобразовании в строку убедитесь, что вы не переполняете буфер. Вы можете закодировать это, чтобы избежать NULL
s и т. д. Если вы хотите получить более подробную информацию о чем-то подобном, вероятно, стоит задать другой вопрос (или выполнить поиск для кодирования произвольных данных в виде строки). Самое простое, что можно сделать, - это скопировать данные в буфер размера +1, установить последний от байта к нулю, перебирайте каждый байт, кроме самого последнего, и для непечатаемых символов (значение байта < 32) измените его на "." или какой-то другой персонаж. Затем передайте указатель на этот буфер AnsiString
конструктор, снимаемый как PAnsiChar
, (Это гарантирует, что ваши данные обрабатываются как строка символов байтового размера - имейте в виду, если вы используете D2009+, поскольку собственный тип строки - Unicode.) Альтернативный тип строки для использования: RawByteString
, Когда у вас есть строка, добавьте ее в заметку.
Есть хороший пример (на С, извините) вставки данных определенного формата в MSDN. Вы можете использовать это в качестве отправной точки, добавляя свою собственную обработку данных. Вставка в виде строки, вероятно, не лучший способ просмотра произвольных двоичных данных - вы можете использовать компонент шестнадцатеричного редактора или другой визуализатор, чтобы лучше просматривать данные.
Мейсон, я не уверен, что понимаю твой ответ, но да, ты можешь использовать Clipboard.AsText, как сказал авар, просто добавь clipbrd к пункту использования. Обратите внимание, что если у вас есть нулевой символ где-то в вашей строке, то KAZAM ваша строка будет вставлена с начала до нулевого символа #0. Другим подходом может быть использование отображенных в памяти файлов или сообщений для передачи данных между приложениями.
Вы пытались использовать clipbaord.astext между вашим tmemo и "другой программой"
Я не уверен, что ваше утверждение "любые данные могут быть представлены в виде строки" имеет смысл. Двоичные данные могут иметь встроенные нули, что может помешать обработке данных в виде строки. А какое значение имеет строковое представление, например, растрового изображения?
Это зависит от приложения, которое устанавливает буфер обмена, чтобы определить формат для информации буфера обмена. Если приложение достаточно продуманно, чтобы предоставить текстовое представление нетекстовой информации (например, имя файла изображения, если оно есть), вы можете использовать эту строковую информацию. В противном случае, не ясно, что будет означать вставка этой информации в TMemo.