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

» Вопросы по Delphi 2

Автор: Aladdinych
Дата сообщения: 20.06.2006 06:56
Есть основная программа и в ней форма. На ней Database1 с именем MyDB и компонент Table1: TTable.
И есть bpl, в которой экспортируются процедура и функция:

procedure Proc_Show_Table(Database1: Tdatabase; Tablea: TTable);
begin
try
Form2:=TForm2.Create(nil);
Form2.Label1.Caption:=tablea.DatabaseName;
Form2.ShowModal;
finally
Form2.Free;
end;
end;

function Get_Table_PTR(Tablea: TTable):TTable;
begin
result:=tablea;
end;

Из основного приложения
Подключаюсь к Database1, Table1.active:=true.
На форме есть две кнопки.
По нажатию Кнопки2 вызывается Get_Table_PTR
....
@MyFun:=GetProcAddress(MyModule, 'Get_Table_PTR');
tbl:=MyFun(form1.table1);
label1.Caption:=tbl.DatabaseName;
....
В результате после клика на кнопке в Label1 Вижу надпись 'MyDB'.

По нажатию Кнопки1 вызывается Proc_Show_Table
....
@ShowTable:=GetProcAddress(MyModule, 'Proc_Show_Table');
showtable(database1, table1);
....

В результате открывается форма а на ней в Label1 вижу абракадабру.
Очевидно, я в чем-то не прав, хотя результат должен быть совершенно одинаков на обоих формах.
В чем проблема?

Я так подозреваю, что в подгружаемые процедуры и функции передается ближний указатель на объект, а должен передаваться дальний. Можно ли как-то на это влиять?
Может я и ошибаюсь. Кто знает-подскажите.

Автор: RomanTim
Дата сообщения: 20.06.2006 08:42
Aladdinych
Попробовал сделать твой пример - работает, никакой абракадабры в лабле нету - пишет нормальное имя, адреса передаются полные безразлично в библиотеку или при вызове внутри программы (пробовал в Д10)
В пакете
Код: procedure Proc_Show_Table(Database: TDatabase; Table: TTable);
var
frm: TForm2;
begin
frm := nil;
try
frm := TForm2.Create(nil);
frm.Label1.Caption := Table.DatabaseName;
frm.ShowModal;
finally
if frm <> nil then
frm.Free;
end;
end;
Автор: RostY
Дата сообщения: 20.06.2006 10:39
Ramazan
EZH

Спасибо. Придется стирать при запуске программы.


Цитата:
В принципе, помница, их можно назначить создаваться в определенном каталоге...

Ты прав. Мну помнится, это делается примерно Session.PrivateDir:=...

Добавлено:
Тогда еще вопрос: можно ли в Ehlib'овом гриде отображать чекбоксы в футере ?
Автор: OOD
Дата сообщения: 20.06.2006 21:02
Подскажите как вшить одну программу в другую через

процедуру интегрирования в EXE-шник других файлов...
Вот процедура, но что-то не получается заставить её работать..
нужно вшить несколько других программ например calc.exe и *.dbf файлы чтобы всё было в одном экзе...

Процедура:


Код:

procedure FileToPas(FileName: string);
var
BF: file of Byte;
F: TextFile;
P, N, S: string;
BFSize: integer;
BBB: Byte;
begin
AssignFile(BF, FileName);
Reset(BF);
BFSize := FileSize(BF);
P := ExtractFilePath(FileName);
N := ExtractFileName(FileName);
N := ChangeFileExt(N, '.PAS');
AssignFile(F, N);
ReWrite(F);
Writeln(F, '(* Generated by Master BRAIN (C) 2002 *)');
Writeln(F, 'unit ' + ChangeFileExt(N, '') + ';');
Writeln(F);
Writeln(F, 'interface');
Writeln(F);
Writeln(F, 'const FileSize:integer=' + IntToStr(BFSize) + ';');
Writeln(F, 'FileData:array[0..' + IntToStr(BFSize - 1) + '] of Byte=');
Writeln(F, '(');
while not Eof(BF) do
begin
S := '';
while (not Eof(BF)) and (Length(S) < 80) do
begin
Read(BF, BBB);
S := S + IntToStr(BBB) + ',';
end;
if Eof(BF) then
Delete(S, Length(S), 1);
Writeln(F, S);
end;
CloseFile(BF);
Writeln(F, ');');
Writeln(F);
Writeln(F, 'procedure SaveToFile(FileName:String);');
Writeln(F);
Writeln(F, 'implementation');
Writeln(F);
Writeln(F, 'procedure SaveToFile(FileName:String);');
Writeln(F, 'var F:File of Byte;');
Writeln(F, ' i:integer;');
Writeln(F, 'begin');
Writeln(F, 'AssignFile(F,FileName);');
Writeln(F, 'ReWrite(F);');
Writeln(F, 'for i:=0 to FileSize-1 do Write(F,FileData[i]);');
Writeln(F, 'CloseFile(F);');
Writeln(F, 'end;');
Writeln(F);
Writeln(F, 'end.');
CloseFile(F);
end;

Автор: FireZone
Дата сообщения: 21.06.2006 05:09
OOD
Цитата:
Вот процедура, но что-то не получается заставить её работать..
А в чём, собственно, проблема? Лучше бы показал, как заставлял работать, чем приводить здесь чужой код.
Автор: Butcher
Дата сообщения: 21.06.2006 07:54
Есть ли у кого опыт импортирования данных с html-страницы в Excel через QueryTables.Add()? Второй день бьюсь, ничего не получается.

Код:
var ExlWSheet: TExcelWorksheet;
R: ExcelRange;
AURL: string;
AQueryTbl: ExcelQueryTable;
begin
...
ExlWSheet.ConnectTo(ExlAppl.ActiveSheet as _Worksheet);
R:= ExlWsheet.Range['A1', EmptyParam];
AQueryTbl:= ExlWsheet.QueryTables.Add(AURL,R,EmptyParam);
Автор: Aladdinych
Дата сообщения: 21.06.2006 10:46
Где можно почитать, какие типы данных можно передавать в качестве параметров в процедуры и функции, вызываемые из dll, а какие нельзя? И зачем потребовался механизм обратных вызовов?
Уж очень мне хочется передать в нее указатель на объект TTable, а не получается. Я хочу из нее работать с открытым набором данных.
Автор: vserd
Дата сообщения: 21.06.2006 11:09
Aladdinych

Цитата:
И зачем потребовался механизм обратных вызовов?

Для упрощения программирования некоторых задач.
Например, тебе нужно определить список открытых окон в windows тогда ты передаешь в процедурину указатель на свою функцию, и в ней заполняешь нужные контролы или выполняешь нужные действия. Без обратных вызовов тебе пришлось бы писать код перечисления снова и снова.
Автор: FireZone
Дата сообщения: 21.06.2006 12:04
Aladdinych

Цитата:
какие типы данных можно передавать в качестве параметров в процедуры и функции, вызываемые из dll, а какие нельзя?

Нельзя передавать те, под которыми память выделяется и освобождается автоматически прозрачно для программиста. Например, в делфях это длинные строки. Это связано с тем, что dll имеет свой менеджер памяти, а программа свой. А память должна освобождаться тем менеджером, которым была выделена. В делфях обход этой проблемы сделан через модуль sharemem, который должен включаться в проект программы и проект dll. При этом и программа и dll начинают использовать общий внешний менеджер памяти, который располагается в библиотеке borlndmm.dll. В общем случае нельзя передавать и указатели на классы. Хотя бы потому, что эта dll уже не будет работать с программами, написанными на других языках.
Автор: Aladdinych
Дата сообщения: 21.06.2006 13:54
А мне и надо использовать длл написанную на дельфи из программы написанной на дельфи. Только мне надо поместить часть функций в длл, чтобы расширять функции уже готового приложения.
Автор: RomanTim
Дата сообщения: 21.06.2006 15:14
Aladdinych
Ограничения накладываются не только на среду разработки, то есть Делфи, но и на версию VCL, так как в другой версии смещения полей и методов в классе могут поменяться. Поэтому в случае смены версии делфи тебе придется сразу пересобирать и приложение и все библиотеки расширения.
Делать конечно так можно, но на мой взгляд все-таки не правильно и в будущем чревато сложностями. Когда то сам себе такие грабли подложил (только у меня TForm передавался), а так как библиотек расширения стало довольно много и не все мои, то прилось реализовывать поддержу и старого и нового - через Handle - способа вызова.
Как можно извернуться при работе через BDE не знаю - не работаю с ней, но может кто другой подскажет каким образом можно передать в библиотеку параметры, с которыми надо открыть таблицу
Автор: Aladdinych
Дата сообщения: 21.06.2006 16:09
Нужели никто не знает как можно передать в длл указатель на TTable. У меня все время Access violation!!!!!!!!
Автор: OXDBA
Дата сообщения: 21.06.2006 16:50
Aladdinych
Ну не надо Table передавать в DLL, поверь на слово.
Если ты работаешь с IB(по твоим предыдущим постам вроде 6.5), то нужно в dll передавать IBDataBase.Handle, а датасеты держать в dll(кстати для IB Table это зло)
Автор: RomanTim
Дата сообщения: 21.06.2006 17:41
Aladdinych

Цитата:
Нужели никто не знает как можно передать в длл указатель на TTable. У меня все время Access violation!!!!!!!!

sharemem в проекты подключил? В каком хоть месте АВ происходит - посмотри отладчиком.
Автор: vshersh
Дата сообщения: 21.06.2006 20:30
OOD
Посмотри здесь
Автор: vadson6666
Дата сообщения: 22.06.2006 06:26
RomanTim

Цитата:
так как библиотек расширения стало довольно много и не все мои, то прилось реализовывать поддержу и старого и нового - через Handle - способа вызова.

Я не знаю как у вас, но мне потребовалось передавать адрес Connecton'a и AdoStoredProc в dll, т.к. у меня в библиотеке нету даже формы, а создавать коннекции к базе лишний раз...
Кстати, а вот как заставить форму библиотеки открываться на том же телевизоре, где экзе (в случае мультимонитора)? Передачей адреса главной формы в Длл все решается просто...Естественно, и библиотека и приложение на Delphi.
Автор: RomanTim
Дата сообщения: 22.06.2006 06:57
vadson6666

Цитата:
Я не знаю как у вас, но мне потребовалось передавать адрес Connecton'a и AdoStoredProc в dll, т.к. у меня в библиотеке нету даже формы, а создавать коннекции к базе лишний раз...

У меня передается имя сервера и базы и создается лишний коннект, "так исторически сложилось" (на самом деле подобная архитектура придумана была еще до меня, а потом перешла "по наследству"). Сейчас если создается библиотека, которой нужна БД или у котрой более-менее сложный программный интерфейс - делаю через COM, через него Connection как через родную среду ходит без проблем (разве что по началу пришлось разобраться как стыковать имеющийся ADOшный COM-объект и новосоздаваемый TADOxxx)


Цитата:
Кстати, а вот как заставить форму библиотеки открываться на том же телевизоре, где экзе (в случае мультимонитора)? Передачей адреса главной формы в Длл все решается просто...Естественно, и библиотека и приложение на Delphi.

По хэндлу можно получить координаты любого окна (например GetWindowPlacement). А с передачей указателей уже устал объяснять клиентам, что их суперокшко, котрое они сейчас на VB (VC...) как нарисуют... работать не будет в принципе, или что им надо срочно где-то брать Д10, так как мы на нее перешли и в новой версии их старые библиотеки вдруг перестанут работать.
Автор: vadson6666
Дата сообщения: 22.06.2006 07:41
RomanTim

Цитата:
По хэндлу можно получить координаты любого окна (например GetWindowPlacement).

Полностью согласен, просто так "так исторически сложилось" у нас . А поводу клиентов, которые программируют под нас - у нас вообще другая политика...
Автор: RomanTim
Дата сообщения: 22.06.2006 11:25
vadson6666
Так я и не призываю переделывать уже имеющиеся вещи - Aladdinych ведь начинает писать что-то новое, а в этом случае лучше сразу постараться избежать решений, которые потом мешать станут.
Автор: 31416
Дата сообщения: 22.06.2006 20:39
Люди помогите!!! нужно получить доступ к interbas базе c помощью bde...не могу разобраться.. как это все связать?

Добавлено:
базу я создал с помощью ibconsole - она в файле base.gdb пытаюсь создать пседоним в bde administrator и не могу понять че куда там прописать...

Добавлено:
или можнт можно как нибудь без создания псевдониа - указать путь к файлу и что он interbase - и затеми работать с ним с помощью tquery?

Добавлено:
усе я понял.... тока есчо вопрос как убрать чтобы не выскакивало логин \ пароль когда tquery активизируется т.е как нить это программно задать можно?
Автор: ShIvADeSt
Дата сообщения: 23.06.2006 00:54
31416
http://forum.ru-board.com/topic.cgi?forum=33&topic=6000#lt
Автор: Aladdinych
Дата сообщения: 23.06.2006 07:24
1. У меня не IB6 а Firebird 1.0.0.338, но это я думаю не принципиально.
2. Зачем мне нужен доступ к открытым датасетам в основной программе.
Идет заполнение данных пользователем, и для автоматизации заполнения по клику на кнопке вызывается внешняя процедура. Из нее, в экранной форме пользователь вводит несколько данных, как правило выбор из списка, и по завершению по кнопке ОК должны обновляться датасеты в основной программе. Всего их пока два (датасета). При этом в первый добавляется одна запись с автозаполнением полей, а во второй могут добавляться, удаляться или модифицироваться записи опять же с автозаполнением полей. Если нельзя передавать на эти датасеты указатели во внешнюю процедуру, то надо как-то синхронизировать их со своими датасетами в этой внешеней процедуре. Мне кажется, что такая задача еще сложнее, и я не очень представляю как ее решать.
3. АВ выскакивает всякий раз, при вызове внешней процедуры. Внури этой процедуры, есть строчка типа datasource1.dataset:=table где datasource1 - компонент на форме внутри внешнего модуля, а table - как раз передаваемый параметр. Если эту строчку закомментировать то АВ исчезает.

Добавлено:
4. И в dll и в основной программе первым модулем включен fastsharemem.
5. Основное приложение давно уже создано раньше. Его надо немного доработать так, чтобы за счет подключения внешних модулей можно было дополнять и расширять его его возможности. Использование bpl мне не нравится. Не хочу за приложением таскать кучу стандартных библиотек в виде тех же bpl. Поэтому самый очевидный выход работать с dll.
Автор: russko
Дата сообщения: 23.06.2006 08:46
Вопрос относительно формирования отчетов с помощью комопнента EMS Advanced Excel Report. Кто пользовался подскажите пожалуйста, каким образом можно получить список данных, сгруппированных таким образом, что после например 4 позиций, собранных вместе выводился итог, например суммарное кол-во. Ранее я использовал комопнент AfalinaSoft Xlreport и там достаточно было поставить слово "group".
На примере это выглядит так: допустим есть два поля: наименование товара и его количество.
В ведомости один и тот же товар может встречаться несколько раз с разным кол-ом. Нужно, чтобы в отчете выводились поочередно эти "одинаковые" наименования и после каждой такой группы итог - суммарное кол-во в данной группе

Цитата:

Наименование1 | Кол-во1
Наименование1 | Кол-во2
Наименование1 | Кол-во3
.................Итог | Сумма
Наименование2 | Кол-во1
Наименование2 | Кол-во2
Наименование2 | Кол-во3
.................Итог | Сумма
и т.д.

Спасибо.
Автор: vshersh
Дата сообщения: 23.06.2006 09:29
31416

Цитата:
чтобы не выскакивало логин \ пароль когда tquery активизируется

У TDatabase свойство LoginPrompt в False установи
Автор: 31416
Дата сообщения: 23.06.2006 11:03
Такая вот проблема:
работаю в bde с interbase базой. Создаю объект datasource и связывю с
tquery. При выполнении запроса из таблицы должно изелечся только одно поле
(т.к оно в ней одно c id=0) но мне почемуто Ds.DataSet.FieldCount выдает =3 и в
dataset заполняются обсалюто 3 одинаковых поля с id=0.. в чем тут может быть дело?

вот код:

q.SQL.Clear;
q.SQL.Add('SELECT * FROM TREE WHERE PARENT_ID=0');

ds:=tdatasource.Create(form1);
ds.DataSet:=q;
ds.Enabled:=true;
q.Active:=true;

Ds.DataSet.FieldCount //вот тут оно равно 3 а должно быть 1



Добавлено:
и причем если выполнить
dbgrid1.DataSource:=ds;
в dbgreed отображается только 1-о поле хотя Ds.DataSet.FieldCount=3....
Автор: russko
Дата сообщения: 23.06.2006 11:19
31416
Попробую перед
Цитата:
Ds.DataSet.FieldCount
поставить Ds.DataSet.FetchAll.
Такие глюки бывают в стандартных компонентах Interbase. Поэтому давно все используют FIBPlus, чего и ам желаю ))
Автор: 31416
Дата сообщения: 23.06.2006 11:24
я б тоже желал о в задание о приеме на работу стоит именно interbase через bde )))
Автор: OXDBA
Дата сообщения: 23.06.2006 11:27
31416
Как бы тебе помягче намекнуть о консерватории, даже и не знаю. Ну да ладно.
FieldCount это количество полей, select * это выбрать ВСЕ ПОЛЯ из таблицы.
WHERE PARENT_ID=0 - выбрать все ЗАПИСИ из таблицы, где поле PARENT_ID=0.
Количество записей это RecordCount.
russko
Не пугай меня так: FetchAll и FieldCount.....может все-таки RecordCount
Автор: russko
Дата сообщения: 23.06.2006 11:28
ааа, а даже не посмотрел на FieldCount )))
даже и подумать не мог )))
проуш прощения
конечно всё сказанное мной выше относится к RecordCount ))
Автор: 31416
Дата сообщения: 23.06.2006 11:29
дело было в том что обращаться нужно к ds.DataSet.RecordCount а не к Ds.DataSet.FieldCount вот так вот )))

Страницы: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667

Предыдущая тема: Событие STFilter(DBGridEh) ???


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