Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Копирование массива в памяти


Автор: Svetkin 22.12.2009, 10:25
Суть проблемы следующая:

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

собственно вот регистрируем

Код

initialization
CF_CXDATA := RegisterClipboardFormat('Format for DevExpress');


далее определяем тип данных

Код

type
  TcxCopy = array of array of string;

...
public
    ArrayField: TcxCopy;



выделяем память под массив
Код

Data := GlobalAlloc(GMEM_MOVEABLE,GlobalSize(ArrayField)) /* Вот здесь первая проблем как узнать размер заполненного массива, 
ведь GloballSize требует handle, а как его получить на память где фактически находится массив????*/


дальше копируем данные из массива в память и заносим их зарегистрированным форматом
Код

DataPtr := GlobalLock(Data);
CopyMemory(DataPtr, ArrayField, GlobalSize(Data));
Clipboard.Open;
Clipboard.SetAsHandle(CF_CXDATA, Data);


ну и вставка данных делается так
Код

Data := Clipboard.GetAsHandle(CF_CXDATA);  //Получаем данные заданного формата
  if Data = 0 then exit;

  DataPtr := GlobalLock(Data);
  Move(DataPtr^, ArrayField, GlobalSize(Data));

и вторая проблем даже если поставить в определении типа фиксированный массив и соответственно копировать соответственное количество данных то при копировании происходит искажение данных массива отсюда вопрос можно ли вообще так обращаться с массивами?????

и с динамическими в частности?????

Автор: dvamaster 28.12.2009, 07:03
Цитата(Svetkin @  22.12.2009,  13:25 Найти цитируемый пост)
и с динамическими в частности?????

Динамический массив кроме данных содержит служебную информацию о длине, так что врядли

Автор: sCreator 28.12.2009, 09:51
Похоже идея Ваша не сработает.
GlobalSize(ArrayField) выдает размер памяти, выделенной функцией GlobalAlloc.
TcxCopy = array of array of string; по сути объявление указателя на массив указателей на массив указателей строк.
Например
Код

type
  TcxCopy = array of array of string;
var
  tc: TcxCopy;
begin
  SetLength(tc,3,3);

если остановиться после SetLength то получим:
sizeOf(tc) = 4 байта ( tc - указатель на TcxCopy )
sizeOf(tc[0]) = 4 байта ( tc[0] - указатель на array of string)
sizeOf(tc[0,0]) = 4 байта ( tc[0,0] - указатель на string)

Т.е. Вам надо расчитать требуемый размер буфера ( с учетом записи в него размерностей массивов и длин строк).
Выделить ему память и собрать в него все свои ячейки.

Из буфера обратный порядок.

Может проще собирать ячейки в одну строку? ( вычитал недавно:
Цитата

формат строки, где в качестве разделителя ячеек используется символ табуляции, а в качестве разделителя строк -- символ перевода строки, могут воспринимать и другие приложения, в том числе Microsoft Excel. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)