Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по Delphi (до версии 2009) - часть 5

Автор: nixmagic
Дата сообщения: 13.03.2010 18:36
Приветствую всех. Помогите, кто, чем может. Засел, как мне кажется, на ровном месте. Часто приходилось работать с базами FoxPro (DBF). Делал это через стандартный объект Table. Но вот потребовалось мне программно получить структуру таблицы. Хотел это сделать так:
Table.FieldDefs[0].Name
Table.FieldDefs[0].Size
Table.FieldDefs[0].Precision
Только вот для полей типа ftFloat возвращается значение 0 для Size и Precision. Пробовал разные способы и альтернативные компоненты, но результат тот же. Вообще какая-то ерунда. Казалось бы, простейшая задача, а ничего не получается.
Автор: Odysseos
Дата сообщения: 13.03.2010 20:43
Frodo_Torbins

tagMAGTRANSFORM = record -> tagMAGTRANSFORM = packed record

v: array[1..3, 1..3] of Single -> v: packed array[1..3, 1..3] of Single

tagMAGIMAGEHEADER = record -> tagMAGIMAGEHEADER = packed record

tagMAGCOLOREFFECT = record -> tagMAGCOLOREFFECT = packed record

transform: array[1..5, 1..5] of Single -> transform: packed array[1..5, 1..5] of Single


...Кроме того - я бы в функциях MagGetXXX var-параметры заменил на const, а в функциях MagSetXXX - var-параметры заменил на out. На уровне скомпилированного кода разницы не будет - но вот с точки зрения логики программ на Pascal/Delphi оно будет явно точней.

Добавлено:
Да - и массивы индексировать стоит от 0 до n - 1, как это в C принято - чтоб потом, сверяя собственный код с msdn (например), не маяться постоянной конверсией индексов в уме.
Автор: Frodo_Torbins
Дата сообщения: 13.03.2010 21:23
Odysseos

Цитата:
packed record

В начале моего перевода указаны директивы {$ALIGN ON} и {$MINENUMSIZE 4}. Честно признаюсь, скопипастил их из Windows.pas Мне казалось, что они там нужны именно что бы не писать packed. Хотя пожалуй все равно напишу, хуже не будет.
Автор: psa1974
Дата сообщения: 13.03.2010 23:23
Odysseos

Цитата:
Кроме того - я бы в функциях MagGetXXX var-параметры заменил на const. На уровне скомпилированного кода разницы не будет - но вот с точки зрения логики программ на Pascal/Delphi оно будет явно точней.

Позволю себе не согласиться. использование const-параметра подразумевает возможность передачи вместо указателя nil. При использовании var-параметра передача nil в качестве указателя невозможна.
Пример. Берем ф-цию BOOL WINAPI MagGetWindowSource(HWND hwnd, RECT *pRect);
ее можно абсолютно точно описать двумя способами:
а) function MagGetWindowSource(hwnd: HWND; const pRect: PRect): Boolean;
или
б) function MagGetWindowSource(hwnd: HWND; var pRect: TRect): Boolean;
Исходя из смысла, ф-ция должна что-то вернуть в параметре pRect. Оба описания работоспособны, однако вариант А допускает как вызов:
MagGetWindowSource(fhwnd, @fRect);
так и вызов:
MagGetWindowSource(fhwnd, nil);
и вот в таком случае у нас случится AV, когда ф-ция MagGetWindowSource попытается что-то в nil записать.

Однако бывают случаи, и часто, когда, согласно документации, ф-ция может принимать в качестве буфера не только указатель на выделенную память, но и nil (например, в схеме, когда первый раз ф-ция вызывается с nil и возвращает реально необходимую длину буфера, после чего мы выделяем нужную память и вызываем ф-цию второй раз, передав ей уже указатель на эту память). Обычно такой подход используется, когда буфер - строка символов. В таком случае параметр необходимо описывать именно как const-параметр.
Поэтому надо тщательно подходить к вопросу, какой тип выходного параметра использовать.

Насчет
Цитата:
а в функциях MagSetXXX - var-параметры заменил на out
- без проблем, out - это тот же var, только не инициализированный на входе в ф-цию, хотя разницу между var и out знает только компилятор Дельфи. Для вызываемой внешней ф-ции между var и out разницы нет. Да и компилятор Дельфи такие параметры по-разному воспринимает только при передаче в качестве параметров динамических переменных - строк, массивов и при вызове методов интерфейсов. В остальных случаях разница между ними чисто эстетическая
Автор: Maks150988
Дата сообщения: 14.03.2010 01:11
Odysseos
Хм, а по мне этот самый transform[5][5] будет уже отсчитываться на делфи с нуля -> transform: packed array [0..4, 0..4] of Single оно вроде так идет если не ошибаюсь.
Автор: Odysseos
Дата сообщения: 14.03.2010 11:12
psa1974

Я в курсе таких сособенностей. Если функцуия может как-то особенно реагировать на nil вместо параметра - то параметр и надо передавать как указатель, ни const, ни var, ни out не подойдут. В случае же, когда передача nil'а не имеет смысла - то const в случае неизменяемости параметра, var в случае изменяемости и out - в случае только получения значения в этот параметр. Это называется автодокументацией кода

Добавлено:
Maks150988

У вопрошавшего явно написано: v: array[1..3, 1..3] of Single и transform: array[1..5, 1..5] of Single.

Добавлено:
Frodo_Torbins

Директива {$ALIGN ON} как раз говорит, что выравнивание нужно - а модификатор packed ее отменяет.

...Я вообще предпочитаю никогда не менять параметры выравнивания директивами - с ними пробьлем больше получается, чем они решают. К примеру - захотелось перенести кусок кода с описаниями типов в другой модуль, про директивы забыли - получили массу трудноотлавливаемых ошибок на ровном месте. Поэтому - лучше явно указывать, где оно packed (в основном - либо перевод C-шных хидеров, либо передача блоков памяти другому приложению).
Автор: delover
Дата сообщения: 14.03.2010 14:14
Frodo_Torbins
А я, вообще, чего-то не заметил CALLBACK. Может переименовано, либо не существенно, либо проглядел.

Добавлено:
Автор: Maks150988
Дата сообщения: 14.03.2010 16:01
Odysseos
А, все, заметил ваше добавленное предложение где вы как раз пишите про отсчет с нуля в массиве.
Frodo_Torbins
Мне кажется что Float сишный это Double, а не Single. Вот. Но это предположение всего-лишь.
Автор: psa1974
Дата сообщения: 14.03.2010 17:03
Odysseos

Цитата:
В случае же, когда передача nil'а не имеет смысла - то const в случае неизменяемости параметра, var в случае изменяемости

Цитата:
Кроме того - я бы в функциях MagGetXXX var-параметры заменил на const.

Раз мы тут все в курсе таких особенностей, то давай все-таки будем последовательны и не будем советовать чушь - ф-ции Get всегда что-то возвращают в своих "указательных" параметрах, т.е. параметр - как раз изменяемый по определению, т.е. var. Единственный вариант сделать его const и при этом в нем что-то вернуть - описать как указатель, о чем я выше и написал и показал, на что при этом можно напороться. В любом случае, Frodo_Torbins, вероятно, эта информация будет полезна, хотя в своем варианте он сделал в данном случае все верно и без наших советов .

Ну и про индексацию массивов - однозначно с нуля.
Цитата:
У вопрошавшего явно написано
- на то он и вопрошает, что не уверен в верности своего результата и если в чем-то он ошибается, его надо поправить а не соглашаться.
Автор: Frodo_Torbins
Дата сообщения: 14.03.2010 17:05
Всем большое спасибо за помощь, большую часть замечаний я учел. И самое главное - апишный пример заработал. Теперь буду выяснять почему не работает VCL-ный.
delover
Куда девать этот CALLBACK, и для чего он вообще нужен я так и не понял. Похоже это просто определение процедурного типа.
Maks150988
На StackOverflow читал, что Float эквивалентен Single.
Автор: vetal71
Дата сообщения: 15.03.2010 17:04

Цитата:
Приветствую всех. Помогите, кто, чем может. Засел, как мне кажется, на ровном месте. Часто приходилось работать с базами FoxPro (DBF). Делал это через стандартный объект Table. Но вот потребовалось мне программно получить структуру таблицы. Хотел это сделать так:
Table.FieldDefs[0].Name
Table.FieldDefs[0].Size
Table.FieldDefs[0].Precision
Только вот для полей типа ftFloat возвращается значение 0 для Size и Precision. Пробовал разные способы и альтернативные компоненты, но результат тот же. Вообще какая-то ерунда. Казалось бы, простейшая задача, а ничего не получается.


присоединяюсь к просьбе nixmagic. Может кто-нибудь сталкивался с проблемой



Автор: nixmagic
Дата сообщения: 15.03.2010 18:53
Нашел в компоненте Apollo:
ApolloTable.CopyStructureExtended('structure.dbf')
Сохраняет структуру таблицы в отдельный dbf файл, тип поля, его размерность и точность. Но это какое-то извращение и лишние действия. Сам же объект ApolloTable, как и родной Table, упорно не хочет показывать параметры полей через FieldDefs.
Автор: delover
Дата сообщения: 15.03.2010 19:40
Frodo_Torbins
Ф топку его, ф топку. Ещё вариант переименовать всю структуру. Ещё вариант оформлять стубы в автодокументированном коде, но как вариант - это вовсе не для меня бы вариант. В некоторых текстах видел, что по хорошему пишут либо заглушку, либо нечто более похожее на то, что должно быть в функции обратного вызова. Иногда как оформить, чтобы слинковалось. А может когда нибудь и в паскале увидим?

Добавлено:
Чем делегат не вариант? Кроме положительных эмоций из точки нэт я ещё и новую командную строку увидел.
Автор: Man Without Face
Дата сообщения: 16.03.2010 09:41
Подскажите как dbchart перерисовать. Когда меняю значения, график перерисовывается, но если значения больше предыдущих линии вылазят за границы графика. Пробовал dbchart1.Refresh; и dbchart1.AutoRepaint := true;
и т.п. не помогает. Заранее спасибо.
Автор: greenpc
Дата сообщения: 16.03.2010 13:01
Man Without Face

Цитата:
Подскажите как dbchart перерисовать. Когда меняю значения, график перерисовывается
так в чем же вопрос
а если нужно изменить масштаб то нажимаем F1 в среде и получаем

Цитата:
TChartAxis component
Declaration
property Automatic : Boolean;
Description
If Axis.Automatic property is True, then the Maximum and Minimum values for the Axis will be calculated with all Axis dependent Series.

Автор: AviDen
Дата сообщения: 16.03.2010 13:20
nixmagic, vetal71

Цитата:
Приветствую всех. Помогите, кто, чем может. Засел, как мне кажется, на ровном месте. Часто приходилось работать с базами FoxPro (DBF). Делал это через стандартный объект Table. Но вот потребовалось мне программно получить структуру таблицы. Хотел это сделать так:
Table.FieldDefs[0].Name
Table.FieldDefs[0].Size
Table.FieldDefs[0].Precision
Только вот для полей типа ftFloat возвращается значение 0 для Size и Precision. Пробовал разные способы и альтернативные компоненты, но результат тот же. Вообще какая-то ерунда. Казалось бы, простейшая задача, а ничего не получается.


FoxPro я уже не помню, но если тип Float там тот же, что и в Delphi, то он не может иметь ни размера, ни точности, т.к. это десятичный тип с плавающей запятой, т.е., распределение имеющихся разрядов под целую и дробную часть производится динамически, в зависимости от конкретного числа. Всё, что можно о нём сказать заранее - это максимальное кол-во значащих цифр мантиссы.
Автор: greenpc
Дата сообщения: 16.03.2010 13:44
AviDen, nixmagic, vetal71
был такой компонент
Цитата:
КОМПОНЕНТ TDBF Version 1.11 - 14.06.2004 Freeware }
{-----------------------------------------------------------------------------}
{ Copyright 2002-2004 Брусникин И.В. majar@nm.ru

пробуйте. именно им обрабатывал *.dbf . понравился больше чем apollo и им подобные
Автор: mvictor71
Дата сообщения: 16.03.2010 14:04
AviDen, nixmagic, vetal71
или Halcyon. Для работы с dbf от VFP мне подошел только он.
Правда, это варез
Автор: AviDen
Дата сообщения: 16.03.2010 14:51
greenpc, mvictor71 спасибо, мне как-то без надобности ))
Автор: lingus
Дата сообщения: 16.03.2010 15:20
Добрый день.
Не подскажите как мне лучше задавать константный информационный текст?
Например
есть ReadOnly memo
в него нужно выводить разные тексты (многострочные)
как это грамотрнее сделать?

То как я знаю
вариант1

Код: //прямо в коде
memo.stings.add('kljdfgkdgb');
memo.stings.add('kljdfgkdgb');
memo.stings.add('kljdfgkdgb');
Автор: akaGM
Дата сообщения: 16.03.2010 15:52
lingus

Цитата:
А как можно еще?

грузить из файла или длл...
медленнее, но гораздо гибче и ничего не надо перекомпилировать при любых изменениях...
Автор: SIgor33
Дата сообщения: 16.03.2010 16:07
кто нибудь использовал в delphi сишную библиотеку OpenCV
Автор: vetal71
Дата сообщения: 16.03.2010 16:25
greenpc
mvictor71
Спасибо. Вопрос снят с помощью Advantage
Автор: lingus
Дата сообщения: 16.03.2010 16:44
akaGM
Ок это тоже понянто
но такая гибкость пока не нужна
нужно удобство и гибкость на уровне кода. Только.
То есть пока все это пишется нужно что-то красивое и удобное именно для разработчика
потом буду думать о поддержке.
Автор: AviDen
Дата сообщения: 16.03.2010 17:10
lingus, используй ресурсы. Создаёшь RC-файл, прописываешь в нём необходимые константы либо непосредственно, либо как ссылки на внешние текстовый файлы. RC-шник можно либо скомпилить и в виде RES-файла подключить к проекту, но лучше (имхо) включить в проект сам RC-шник, тогда дельфя будет автоматом при компиляции проекта компилить ресурс и внедрять в экзешник.

Останется только в коде загрузить эти строки (LoadResString, если мне не изменяет память ) и заюзать.
Автор: lingus
Дата сообщения: 16.03.2010 17:30
AviDen
О! Совсем забыл про это.
А можно кратенько буквально в пару строк
как проще всего создать rc-шник
как заюзать его ресурс
и о формате rc-файла где можно глянуть?
Автор: akaGM
Дата сообщения: 16.03.2010 17:47
lingus
тогда ещё проще:
создаёшь *.inc и в него все стринги на уровне констант, сам инклудник -- как часть проекта
только какая на фиг это

Цитата:
удобство и гибкость на уровне кода.

это каждая перекомпиляция при изменении одного символа -- это самый дурной тон в использовании ресурсов
Автор: AviDen
Дата сообщения: 16.03.2010 17:55
lingus
RC-шник - обычный текстовый файл с содержимым наподобие следующего:

Код:
text_res_name_1 RCDATA res_file_1.txt
text_res_name_2 RCDATA res_file_2.txt
Автор: lingus
Дата сообщения: 16.03.2010 20:38
akaGM

Цитата:
это каждая перекомпиляция при изменении одного символа -- это самый дурной тон в использовании ресурсов

Это нужно на этапе проектирования и первичного тестирования. Пока набрасываешь скелет. Все равно постоянно пересобираешь. Что бы все тексты были в одном или ограниченном месте. И одинаково применялись.
По факту все будет в базе.
AviDen
Большое спасибо, попробуем.
Автор: akaGM
Дата сообщения: 16.03.2010 21:08
lingus
тогда я б в твоём случае инклудниками обошёлся...

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768

Предыдущая тема: Clipper 5


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.