Я знаю как можно работать напрямую с файловыми и QUEUE структурами

Я знаю как можно работать напрямую с файловыми и QUEUE структурами. Т.е. можно использовать их динамическое формирование/изменение/удаление.

Очередь в памяти представлена практически так-же как и описание файла.
Например, тип FILE — это указатель на область памяти, которую назовем, например, «заголовок файла». Формат этого заголовка остался практически неизменным со времен CDD30. Несколько изменились лишь типы некоторых полей и в C5 добавились несколько полей, назначение которых неясно:

TPointer        ULONG
TPtr            LIKE(TPointer)                ! Указатель
TStrPtr         LIKE(TPtr)                    ! Указатель на строку

FileGrp         GROUP
FilePtr           &FILE
                END

FileAddress     LIKE(TPtr),OVER(FileGrp) ! Адрес "заголовка файла"
FileHeader      GROUP
DriverPtr         LIKE(TPtr)        ! указатель на точку входа драйвера файла
NamePtr           LIKE(TStrPtr)     ! имя файла
NameSize          ULONG             ! длина имени файла
DrvInitPtr        LIKE(TStrPtr)     ! строка инициализации драйвера
DrvInitSize       ULONG             ! длина строки инициализации
PasswordPtr       LIKE(TStrPtr)     ! пароль файла
PassSize          ULONG             ! длина пароля
Status            BYTE              ! статус файла
KeyCount          BYTE              ! количество ключей
MemoCount         BYTE              ! количество MEMO-полей
RecordSize        ULONG             ! размер записи (буфера записи)
FieldsDefPt       LIKE(TPtr)        ! описание полей записи файла
KeysDefPtr        LIKE(TPtr)        ! описание ключей файла
MemosDefPtr       LIKE(TPtr)        ! описание MEMO-полей
RecordPtr         LIKE(TPtr)        ! указатель на буфер (RECORD)
Reserved          ULONG             ! резерв (всегда = 0)
Res1              BYTE              ! ???
Res2              BYTE              ! ???
                END

Для заполнения данной группы надо выполнить что-то типа:
FileGrp.FilePtr &= MyFile
PEEK(FileAddress,FileHeader)
Кстати, можно увидеть, что довольно легко добраться до драйвера файла и, при необходимости, легко можно его сменить по ходу программы! Только заранее надо позаботиться, что-бы нужный драйвер был прилинкован к проге. Проще всего написать файлы-пустышки для всех нужных драйверов и, при необходимости, просто вытаскивать из них готовый адрес нужного драйвера и вставлять в заголовок своего файла.
Формат описания полей, ключей, MEMO-полей так-же известен. Даю его в отдельном файле. Делал его еще для CDD30, но дальше тестов так и не пошло. В CW не проверял, но, думаю, что эти форматы не изменились.
Кстати! Сейчас пришла в голову мысль, что поле Reserved вполне может быть указателем на блок описания BLOB-полей!? По аналогии с MEMO-полями.
Так вот, насчет формата описаний. Я довольно нормально их описывал. Так что, при желании, разобраться можно. Если чего будет не понятно — пиши. Я еще помню все это, так как повозился с этим делом тогда порядочно!
Теперь, что касается очереди.
Здесь почти полная аналогия с файлами. Тип QUEUE — опять-же, просто указатель на так называемый «заголовок очереди». Для CW я его не «копал». Но не думаю, что он очень сильно изменился со времен CDD30:

QueueGrp        GROUP
QueuePtr         &QUEUE
                END

QueueAddress    LIKE(TPtr),OVER(QueueGrp) ! Адрес "заголовка очереди"
QueueHeader     GROUP
RecordPtr         LIKE(TPtr)        ! указатель на буфер (QUEUE)
FieldsDefPt       LIKE(TPtr)        ! описание полей записи очереди
ControlPtr        ULONG             ! служебный указатель ?
RecordSize        SHORT             ! размер записи (буфера записи)
                                    ! в CW, возможно, ULONG
FirstRecPtr       LIKE(TPtr)        ! указатель на первую запись
LastRecPtr        LIKE(TPtr)        ! указатель на последнюю запись
                                    ! вначале оба = 0
RecsCount         ULONG             ! количество записей
                END

Для заполнения данной группы надо выполнить что-то типа:
QueueGrp.QueuePtr &= MyQueue
PEEK(QueueAddress,QueueHeader)
Когда игрался в CDD30 с очердью, то удалось разобраться в назначении ControlPtr. Сейчас уже не помню, но он как-то связан с указателями на первую и последнюю записи (или это мне приснилось ?:)).
Формат описания полей очереди абсолютно идентичен формату описания полей файла. По крайней мере был идентичен в CDD30. Кстати, поля FirstRecPtr и LastRecPtr это, на самом деле, указатели на «заголовок записи». К сожалению, записки по очереди где-то затерялись. Поэтому не помню точно формат этого «заголовка записи». Что-то типа:

QueueRecHdr  GROUP
PrevPtr        LIKE(TPtr) ! указатель на предыдущую запись
NextPtr        LIKE(TPtr) ! указатель на следующую запись
RecSize        ULONG      ! длина записи
RecPtr         LIKE(TPtr) ! указатель на сами данные
                          ! а может - наоборот?
             END

Зачем здесь указан еще раз RecSize?
Дело в том, что при выделении памяти под очередную запись необходимый размер вычислялся без учета концевых пробелов строки, если она — последняя в описании записи очереди. Так было до C5. В С5 стали усекать все строки, независимо от их месторасположения в записи. И это действительно так, сам проверял недавно. Таким образом, в результате, вся текущая запись может занять буфер памяти меньше, чем указано в заголовке очереди, в поле RecordSize. А уже RecSize содержит действительный размер текущей записи.
Кстати, можно догадаться, что в C5, при выделении памяти, стали работать с полями, используя их описание из FieldsDefPtr. Чего не было в ранних версиях. Там определяли размер текущей записи просто: RecSize = Len(Clip(Queue)). Соответственно, при Get/Put, в С5 опять-же идут по полям, в отличии от предыдущих версий, где было достаточно : MoveMem(RecPtr,RecordPtr).
Исходя из этого, можно предположить, что основные операции работы с очередью (Add/Get/Put) в С5 работают медленнее чем в предыдущих версиях!?
Может кто проверит, у кого есть обе версии — C4 и C5?
В принципе, используя эту инфу, можно организовать какие-либо дополнительные функции для работы с очередью, минуя штатные функции Get/Put и прочие. Хотя — зачем?
Вот, в общем-то и все!
P.S.
Еще раз напоминаю — в приложенном файле -инфа по структуре файла, как она была в CDD30!!! (см.здесь dbdrv.zip )
Так что, как пишут в лицензиях: «Если у Вас что сломается, мы за себя не отвечаем!»
Еще есть несколько «ядреных» функций, которые можно было-бы «пощупать»:

- Cla$Addqueuekey/Cla$Addqueueskey - интересно, не правда-ли?!
- Cla$SORTqueuekey/Cla$SORTqueueskey - ???
- Cla$PUTqueuekey/Cla$PUTqueueskey - ???
- Cla$POSITIONqueuekey/Cla$POSITIONqueueskey - ???
- Cla$GETqueuekey/Cla$GETqueueskey - ???
- Cla$FREEqueuekey/Cla$FREEqueueskey - ???
- Cla$NUMFIELDSqueue - довольно красноречивое название

По-моему, это — прямые функции для работы с альтернативными ключами очереди. И ключи эти, очевидно, представляют собой обычные очереди.
Есть и отдельные функции для работы с полями очереди, по аналогии с полями группы: Cla$WHOqueue/Cla$WHATqueue/Cla$WHEREqueue
Интересно, что они такого дополнительного делают, чего не делают их аналоги WHO()/WHAT()/WHERE()?
Возможно просто вытаскивают из заголовка очереди указатель на буфер очереди и уже после этого используют стандартные функции по работе с полями группы
Это так сказать для затравки!
А там, глядишь, у кого-либо зачешутся руки и этот кто-либо покопается еще во все этом. А потом еще и выложит нам результаты своих «раскопок».
И, в результате, может дойдем вместе до полного и точного описания этих «святая святых» Клариона.
Все-таки, что не говори, а реализация FILE & QUEUE (и, вероятно, еще и GROUP) — одна из основных фич Клариона, какие, собственно, и сделали его таким, каким он есть — отличным от других!