Текущий архив: 2006.01.29;
Скачать: CL | DM;
Вниз
Скопировать компонент в Clipboard Найти похожие ветки
← →
w666w (2005-12-21 17:30) [0]Есть следующая проблема: необходимо компонент преобразовать в строку и скопировать в буфер обмена, как текст. Эта функция:
эта функция
function SaveComponentToString(aComponent : TComponent) : string;
var AStrStream: TStringStream;
fResult : string;
begin
fResult := "";
AStrStream := TStringStream.Create("");
try
AStrStream.WriteComponent(aComponent);
fResult := AStrStream.DataString;
finally
AStrStream.Free;
Result := fResult;
end;
end;
Дает нам строку, но в буфер обмена КАК ТЕКСТ она не может быть помещена как текст, потому как после преобразования в строку в ней содержатся спецсимволы (мясо).
Когда то я смог преобразовать компонент в строку в виде (не претендую на правильность написания, потому как точно не помню)
<component>
<var1 type=boolean value="false">
<var2 type=integer value="15">
и т.д. Это не XML, это какой-то внутренний формат делфи, чтобы не советовали применять оный.
Подскажите:
1. Как получить ТАКОЕ представление компонента? Оно легко может быть скопировано в Clipboard, так как не содержит спецсимволы. Помню что было элементарно просто, но потерял нить...
2. можно ли строку, полученную в приведенной выше функции скопировать в буфер обмена без потери данных? Если да, приведите плиз пример кода. Насколько я понимаю там надо будет регистрировать свой тип данных для Clipboard и т.п.
Заранее большое спасибо.
← →
w666w (2005-12-21 17:52) [1]Кстати копирование UNICODE в буфер функцией
procedure MoveUnicodeStrToClipboard(aStr: WideString);
var aLen: Integer;
hMem: HGLOBAL;
aMem: Pointer;
begin
Win32Check(OpenClipboard(0));
try
aLen := Length(aStr) * 2 + 2;
hMem := GlobalAlloc(GMEM_MOVEABLE OR GMEM_DDESHARE, aLen);
Win32Check(hMem <> 0);
try
aMem := GlobalLock(hMem);
Move(PWideChar(aStr)^, aMem^, aLen);
GlobalUnlock(hMem);
Win32Check(EmptyClipboard);
Win32Check(SetClipboardData(CF_UNICODETEXT, hMem) <> 0);
finally
Win32Check(GlobalFree(hMem) = 0);
end;
finally
CloseClipboard;
end;
end;
Также не помогает, потому как полученное "мясо" не подходит под INICODE.
← →
Юрий Зотов © (2005-12-22 01:26) [2]ObjectBinaryToText, ObjectTextToBinary
← →
w666w (2005-12-22 01:34) [3]Нашел решение:
function ComponentToString(Component: TComponent): string;
var
BinStream:TMemoryStream;
StrStream: TStringStream;
s: string;
begin
BinStream := TMemoryStream.Create;
try
StrStream := TStringStream.Create(s);
try
BinStream.WriteComponent(Component);
BinStream.Seek(0, soFromBeginning);
ObjectBinaryToText(BinStream, StrStream);
StrStream.Seek(0, soFromBeginning);
Result:= StrStream.DataString;
finally
StrStream.Free;
end;
finally
BinStream.Free
end;
end;
function StringToComponent(Value: string): TComponent;
var
StrStream:TStringStream;
BinStream: TMemoryStream;
begin
StrStream := TStringStream.Create(Value);
try
BinStream := TMemoryStream.Create;
try
ObjectTextToBinary(StrStream, BinStream);
BinStream.Seek(0, soFromBeginning);
Result := BinStream.ReadComponent(nil);
finally
BinStream.Free;
end;
finally
StrStream.Free;
end;
end;
Но возникла другая проблема. Например есть свой класс
TAccountsList = class(TComponent)
со своими свойствами , методами и т.д. Запись всех его public свойств в строку работает отлично:
var fAccounts : TAccountList;
...
fString := ComponentToString(fAccounts)
а вот при чтении:
TComponent(fAccounts) := StringToComponent(fString);
Вылезает ошибка EClassNotFound с сообщением "Class TAccountList not found"
Что не так?
← →
Юрий Зотов © (2005-12-22 03:41) [4]См. RegisterClass
Страницы: 1 вся ветка
Текущий архив: 2006.01.29;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.032 c