Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 2 июля!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

БОЛЬШОЙ FAQ ПО DELPHI



Как сделать закладки не только сверху, но и справа или слева?

Воспользуйтесь компонентами sohoVertTabSet из набора SohoLib,



Как показать картинку формата отличного от bmp?

Воспользоваться компонентами из набора ImageLib Suite,
hgImage из набора HighGear,
ActiveX LigthLib,
библиотекой NViewLib,



Как настроить параметры вывода даты, времени или денег?

Воспользоваться компонентами CurrencyStorage и
DateTimeStorage из набора VGLib.



Как сделать заголовок окна в Windows?

Воспользоваться компонентами RxGradientCaption из набора RxLib.



Как поместить свою иконку на Desktop?

Воспользоваться компонентой StShortcut из набора SysTools.



Как программно нажать клавиши ScrollLock, NumLock, CapsLock, Insert?

Воспользоваться компонентой hgKeyState из набора HighGear.



Как работать с COM-портом?

Воспользоваться набором компонент Async Pro.
Воспользоваться компонентой hgComm из набора HighGear.



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

Воспользоваться компонентой hgFormGradient из набора HighGear.
Воспользоваться компонентой esGradient из набора Essentials.



Как сделать чтобы размеры компонент изменялись при изменении

размера формы или разрешении экрана?
Воспользоваться компонентами hgResizer и hgFormRes из набора HighGear.



Как сделать чтобы форма сворачивалась и раскрывалась с анимацией?

Воспользоваться компонентой hgFormExplode из набора HighGear.



Как сделать чтобы в TEdit вводились только числа?

Воспользоваться компонентой CurrencyEdit из набора RXLib.
sohoEdit из набора SohoLib(на самом деле намного
круче).



Как мне работать с архивами?

Воспользоваться набором компонент TZipTV.



Как написать спектроанализатор?

Воспользоваться компонентами из набора Multimedia Tools.



Как защитить свою программу?

Воспользоваться компонентами из набора OnGuard(хороший набор для
изготовления шароварной программы),
компонентой Security95,
компонентой CyberBolt,
специализированные программы ASProtect, VBox,
аппаратные ключи HASP и др.
(Хотя это, как мне кажется и бесполезно.)



Как определить подключен ли компьютер к интернету?

Пинговать www.microsoft.com или mail.ru
или IsConnected



Можно ли на Delphi написать VBX ?

Можно. Ведь по сути дела VBX - это .dll, написанная по определенным правилам.
Однако скорее всего вам потребуется дополнительно соответствующий SDK от
компании Microsoft. Существует даже статья, где обсуждаются все аспекты такой
работы.



Если я хочу рассылать Delphi EXE файлы, какие посылать с ними?

Hикакие. Все компилируется в .EXE файл. Конечно, если вы разработали другие
файлы (HLP, данные и т.д. ), или если вы используете VBX файлы, тогда вы
должны распространять и их заодно. Если вы используете файлы VBX, то в
поставку нужно также включать BIVBX11.DLL. Если приложение использует функции
BDE, вы также должны включать Borland DataBase Engine.



Что такоe FreeIBComponents?

FreeIBComponents (далee - FIBC) - это набоp компонeнт для достyпа к
Interbase из Delphi минyя BDE. FIBC пpeдставляeт собой надстpойкy над
Interbase API и являeтся очeнь пpостым, мощным и гибким сpeдством pазpаботки
клиeнтских пpиложeний для Interbase. Совместим со стандаpтными db-aware
компонентами, входящими в состав Delphi. Поставляются с исходными тeкстами.
Автоp - Gregory Deatz (gdeatz@hlmdd.com).



Kакая вepсия FIBC - послeдняя?

Последняя версия на момeнт составлeния FAQ - от 07 Jun 1999 г.
Официально FIBC вышeл из стадии бeта-тeстиpования.



Гдe можно взять новyю вepсию FIBC?

Hовыe вepсии FIBC выкладываются по адpeсy:
http://www.interbase.com/download ,
http://ib.demo.ru



Чeм pабота чepeз FIBC лyчшe, чeм чepeз BDE?

1. Можно самостоятeльно выставлять паpамeтpы тpанзакций, дажe в runtime.
2. Можно выполнять тpанзакции на нeскольких базах данных.
3. Можно создавать "живые" запросы сразу к нескольким таблицам.
4. Пpиложeниe, использyющee FIBC нe нyждаeтся в поддepжкe BDE, eго пpощe
yстанавливать и настpаивать.
5. Пpи использовании FIBC появляeтся возможность пользоваться pолями
Interbase.



Могy ли я использовать FIBC для pаботы с C++ Builder?

Из-за pазличий в VCL подключить FIBC к С++ Builder 1.0 пpактичeски
нeвозможно. Под C++ Builder 3.0 FIBC встают бeз пpоблeм. Для этого нeобходимо
выбpать пyнкт Component/Install new component, в полe Unit file name yказать
файл FIBDataset.pas с пyтeм, нажать Ok. Затeм надо подключить в пpоeкт
gds32.lib и выполнить компиляцию. Далee чepeз Component/Install packages
добавить package с FIBC, и всe, библиотeкой можно пользоваться.



Установил Delphi, FIBC. Почeмy нe yдаeтся подключиться к yдалeнномy сepвepy?

FIBC тpeбyeт наличия yстановлeнного клиeнта Interbase.



Почему после выполнения FIBTransaction.Commit закpываются всe датасeты?

Для чeловeка, избалованного peжимом AUTOCOMMIT в BDE можeт показаться
нeпpивычным и нeyдобным то обстоятeльство, что пpи закpытии тpанзакции
автоматичeски закpываются всe датасeты. Пpичина такого повeдeния
заключаeтся нe в FIBC, а в Interbase. Дeло в том, что всe опepации в
Interbase выполняются только в контeкстe тpанзакции. Слeдоватeльно,
пpогpаммист сам должeн позаботиться об пepeоткpытии датасeтов и
восстановлeнии тeкyщих yказатeлeй послe Commit/Rollback. Peкомeндyeм
пользоваться мeтодом TFIBTransaction.CommitRetaining, котоpый выполняeт
Commit бeз закpытия кypсоpов (стандаpтная возможность Interbase).



Каким образом организовать подключение к базе данных?

1. Это можно сделать, например, так:
with FIBDatabase do begin
DBParams.Clear;
DBParams.Add('isc_dpb_user_name=SYSDBA');
DBParams.Add('isc_dpb_password=masterkey');
UseLoginPrompt:=false;
Connected:=true;
end;
2.Или так:
Используя переменные окружения :
в Autoexec.bat
SET ISC_USER=SYSDBA
SET ISC_PASSWORD=MASTERKEY
но в TFIBDatabase.DBParams все равно требуется прописать хотя бы,например
lc_ctype=win1251.Еще одна фича(или баг: ))
Префикс isc_dpb_ у опций, прописываемых в DBParams, можно опускать.



He yдаeтся ввeсти киpилличeскиe символы в таблицy.

Во-первых, yбeдитeсь, что база данных создана с кодовой страницей
win1251. Во-вторых, пропишитe в свойство DBParams у экзeмпляpа объeкта
TFIBDatabase строку isc_dpb_lc_ctype=WIN1251. Пpeфикс isc_dpb_ можно
опyскать.



Пpи конкypeнтном измeнeнии записи БД пpогpамма зависла. Почeмy?

Потомy что таковы yстановки паpамeтpов тpанзакции по yмолчанию.
В пepвом слyчаe ожидаeтся, когда бyдeт завepшeна конкypeнтная тpанзакция,
стаpтовавшая pаньшe (peжим wait), а во втоpом слyчаe пpичина - peжим
no_rec_version запyска тpанзакции. Побоpоть вышeозначeнныe пpоблeмы можно,
напpимep, пpописав в свойство TRParams y экзeмпляpа объeкта TFIBTransaction
слeдyющиe паpамeтpы:
isc_tpb_write
isc_tpb_nowait
isc_tpb_read_committed
isc_tpb_rec_version

префикс isc_tpb_ можно также опускать.
Hастоятeльно peкомeндyeм почитать о паpамeтpах тpанзакций в Interbase
API Guide (стp. 46 книги из состава Interbase Mediakit).



При вызове FIBDataSet.Open периодически возникает ошибка

Смeнитe вepсию FIBC на болee свeжyю или заблокиpyйтe yчасток кода,
на котоpом возникаeт ошибка пyстым обpаботчиком ошибок.



Kак pаботать с blob сpeдствами FIBC?

Пpиводим пpимepы pаботы с blob-полями. FIBDatase1BLOBFIELD - полe
типа BLOB датасeта FIBDatabase1

Чтение из блоб-поля в OleContainer

var S: TStream;
begin
if not FIBDataset1BLOBFIELD.IsNull then
begin
S:=FIBDataset1.CreateBlobStream(FIBDataset1BLOBFIELD, bmRead);
try
OleContainer1.LoadFromStream(S)
finally
S.Free
end;
end;
end;

Запись в блоб-полe из OleContainer (вызываeтся в BeforePost)

var S: TStream;
begin
S:=FIBDataSet1.CreateBlobStream(FIBDataSet1BLOBFIELD, bmReadWrite);
try
OleContainer1.SaveToStream(S)
finally
S.Free
end;
end;



Как работать с новыми, своими интерфейсами в RemoteDataModule?

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

(IDispatch(RemoteServer.AppServer) as IAnother)

Необходимо заметить, что это будет работать только, если Вы используете DCOM как транспорт.



Как использовать TClientDataSet в локальном приложении с таблицами Paradox

Вы не сможете отделаться от Провайдера (хотя бросать его на форму/модуль данных не придется), но Вы сможете использовать TClientDataSet в одно-точечном (single-tier) приложении. Для того, чтобы открыть Client DataSet, Вы должны назначить Провайдера Данных вручную.

{ CDS = TClientDataSet }
{ Table1 = TTable }
CDS.Provider := Table1.Provider;
CDS.Open;

Также Вы должны включить модуль BDEProv в предложение Uses.



Как передать UserName и Password в удаленный модуль данных (remote datamodule)?

В Удаленный Модуль Данных бросьте компонент TDatabase, затем добавьте процедуру автоматизации (пункт главного меню Edit | Add To Interface) для Login.

Убедитесь, что свойство HandleShared компонента TDatabase установлено в True.

procedure Login(UserName, Password: WideString);
begin
{ DB = TDatabase }

{ Something unique between clients }
DB.DatabaseName := UserName + 'DB';
DB.Params.Values['USER NAME'] := UserName;
DB.Params.Values['PASSWORD'] := Password;
DB.Open;
end;

После того, как Вы создали этот метод автоматизации, Вы можете вызывать его с помощью:

RemoteServer1.AppServer.Login('USERNAME','PASSWORD');



Как определить доступные сервера приложений на этой машине через Registry?

Прочитайте ключ под HKEY_CLASSES_ROOT\CLSID\*, просматривая его насчёт ключей, которые имеют подключ "Borland DataBroker". Эти вхождения и являются серверами приложений.

Ниже пример, который загружает имена доступных серверов приложений в Listbox:

uses Registry;
procedure TForm1.FormCreate(Sender: TObject);

var

I: integer;
TempList: TStringList;
begin
TempList := TStringList.Create;
try
with TRegistry.Create do
try
RootKey := HKEY_CLASSES_ROOT;
if OpenKey('CLSID', False) then
GetKeyNames(TempList);
CloseKey;
for I := 1 to TempList.Count - 1 do
if KeyExists('CLSID\' + TempList[I] + '\Borland DataBroker') then
begin
if OpenKey('CLSID\' + TempList[I] + '\ProgID', False)
then
begin
Listbox1.Items.Add(ReadString(''));
CloseKey;
end;
end;
finally
Free;
end;
finally
TempList.Free;
end;
end;



Dbclient.dll не загружается на клиента. Как это исправить?

Ваш INF-файл должен включать в себя строки наподобие:

[Add.Code]
dbclient.dll=dbclient.dll
[dbclient.dll]
file=http://yoursite.com/dbclient.cab
clsid={9E8D2F81-591C-11D0-BF52-0020AF32BD64}
RegisterServer=yes
FileVersion=4,0,0,36
Замените "yoursite" Вашим HTTP-адресом, где находится cab-файл.

FileVersion - это версия файла в Вашем cab-файле (проверьте информацию о версии DBCLIENT, чтобы быть уверенным в соответствии).

Убедитесь, что FileVersion относится к версии Вашего DBCLIENT.DLL.

Вы можете положить dbclient.dll в cab-файл, используя утилиту CABARC, которую Вы найдете в папке delphi\bin.

Примерная команда вызова CABARC может выглядеть примерно так:

CABARC N DBCLIENT.CAB DBCLIENT.DLL



Как достучаться до методов сервера приложений из TClientDataSet?

Вот так:

RemoteServer.AppServer.MyMethod.

AppServer - свойство только для чтения, возвращающее интерфейс удаленного сервера, возвращаемый провайдером сервера приложений. Клиентские приложения могут общаться напрямую с сервером приложений через этот интерфейс.



Нужны ли мне формы в сервере приложений?

Да.

Необязательно, чтобы они были видимы, но должна присутствовать хотя бы одна. Чтобы сделать главную форму невидимой, установите

Application.ShowMainForm := False

в файле проекта.

Пример:

begin
Application.ShowMainForm := False;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.



Что я получаю от наличия ConstraintBroker (брокера ограничений)?

ConstraintBroker позволяет Вам включать проверки на ограничения в данные.

Это означает, что когда Вы запрашиваете данные, Вы получаете вместе с ними и правила, которым они дорлжны удовлетворять. Эти правила автоматически без дополнительного кода входят в силу.

Поскольку это происходит без единой строчки кода, то Вам не требуется переписывать или обновлять приложение каждый раз при изменении правил.

Фактически это простое решение задачи обновления клиентского приложения без выхода из него.

Каждое приложение, использующее ConstraintBroker, автоматически получает это качество..



Изменено строковое поле в Null. Как в обработчике OnUpdateData определить.

Используйте свойство NewValue класса TField при чтении второй записи (той, которая содержит изменения). Если возвращаемое значение (variant) пусто или не назначено, тогда поле не было модифицировано.

Здесь немного иллюстрирующего кода:

var
NewVal: Variant;

begin
NewVal := DataSet.FieldByName('MyStrField').NewValue;
if VarIsEmpty(NewVal) then
ShowMessage('Field was not edited')
else if VarIsNull(NewVal) then
ShowMessage('Field was blanked out')
else
ShowMessage('New Field Value: ' + String(NewVal));
end;
Если Вы взглянете на исходники формы RecError (в репозитории), то Вы увидите, как она использует эту информацию для вывода строки '<Unchanged>' при показе ошибок синхронизации данных.

На сервере Вы добавляете ограничения уровня записи, используя свойство Constraints Вашего TQuery/TTable или ограничения уровня поля, используя постоянные обьекты TField (с помощью FieldsEditor либо на CustomConstraint, либо ImportedConstraint).

Если Вы используете ограничения уровня поля, они вступают в силу, когда данныеотправляются в поле (например, когда Вы уходите из органа управления, связанного с этим полем (типа TDBEdit)).



В чем разница между сокетами DCOM и OLE Enterprise?

Sockets (TCP/IP):
- на клиентах и сервере требуется наличие стека TCP/IP;
- не требуется дополнительной настройки клиентов;
DCOM:
- на клиентах и серверах требуется наличие DCOM (входит в состав Windows NT 4.0, для Windows 95 доступен как опция)
- требуется настройка клиентов (DCOM Configuration Utility - DCOMCNFG.EXE);
- встроенная поддержка модели безопасности Windows NT;
- поддержка обратных вызовов (методов);
CORBA
- на клиентах и серверах требуется наличие Common Object Request Broker;
- требуется настройка клиентов;
- поддержка обратных вызовов (методов);
OLE Enterprise:
- на клиентах и серверах требуется наличие OLE Enterprise;
- требуется настройка клиентов;
- поддержка обратных вызовов (методов).



При ApplyUpdates на ClientDataSet на серверной стороне не срабатывает событие OnNewRecord.

Никак. Эти обновления идут прямо через BDE, а не через компонент набора данных.

----------------

В Delphi 4.0 (C++Builder 4.0) ситуация радикально изменилась.

Во-первых, обычному провайдеру данных (TProvider) можно указать, каким образом обновлять данные.

Во-вторых, новый тип провайдера (TDataSetProvider) работает только через соответвующие методы TDataSet.

То есть - все события при данных условиях на сервере будут отрабатываться обычным образом.

Если же Вы пользуетесь более старой версией Delphi, то, как обычно, можно посоветовать использование хранимых процедур, в данном контексте это будут методы сервера приложений. К сожалению, совет неприемлем для транспорта Sockets.



Запрос с определенной позиции из набора данных на сервере?

Наиболее приемлемым является использование TQuery и Provider.SetParams.

Но также Вы можете сделать это иначе:

Сперва на клиенте Вам нужно считать с сервера только метаданные для набора данных. Это можно сделать, установив PacketRecords в 0, и затем вызвав Open. Затем Вы должны вызвать метод сервера (Вы должны определить этот метод на сервере), который спозиционирует курсор на первую нужную запись.

И, наконец, установите PacketRecords в нужное значение, большее нуля, и вызовите GetNextPacket.



ISAPI-ориентированные библиотеки не могут обрабатывать много соединений?

Волшебник по созданию ISAPI DLL в Delphi 3 создает полностью безопасную многопоточную библиотеку, но не выставляет флаг, говорящий приложению, что эта библиотека в этом отношении безопасна.

Это легко исправить, просто добавив строчку:

IsMultiThread := TRUE;

первой строкой в Вашем блоке begin-end файла проекта (DPR).



Как осуществить минимальный тест на корректность глобального идентификатора GUID?

Вызовите CreateRemoteComObject, передав GUID интерфейса и имя компьютера, к которому Вы пытаетесь подключиться. Если функция вернет ошибку, то наличествует проблема сервера, иначе возможная проблема относится к клиенту.

const
MyGUID = '{444...111}'; //Whatever the guid is...

var
Unk: IUnknown;
Disp: IDispatch;

begin

{ Make sure this line works correctly }
Unk := CreateRemoteComObject('server1',
StringToGUID(MyGUID));

{ If it does, then cast it to a IDispatch }
Disp := Unk as IDispatch;

end;
Если этот кусок кода работает, а проблема остается, то Вам требуется шаг за шагом пройти через код клиента и найти, где он дает трещину. Если не сможете этого обнаружить, Вам придется запустить сервер под отладчиком и установить связь с клиентом, чтобы Вы могли произвести отладку рядом со местом, дающем слабину.



Как избавиться от зарегистрированного имени сервера, если не хочу использовать его далее?

Запустите исполняемый файл сервера с ключом /UNREGSERVER:

MYSERVER.EXE /UNREGSERVER

Это обычный путь разрегистрации саморегистрирующегося сервера автоматизации OLE.



Как мне выполнить команду контекстного меню Export from Table?

Как только Вы экспортировали интерфейс провайдера, эта команда контекстного меню перестает быть видимой. Чтобы снова включить ее, Вы должны удалить ассоциированное свойство в Редакторе Библиотеки Типов, и затем нажать кнопку обновления информации в Редакторе Библиотеки Типов (Type Library Editor's Refresh button).

Вы могли бы также удалить точку вхождения "Get_XXX" в исходном тексте RemoteDataModule.



Что такое LZCopy?

Вот простой пример копирования файла (сжатого или нет):

----------
Var
srcHandle, destHandle: Integer;
srcBuf, destBuf: TOFStruct;

srcHandle := LZOpenFile( f_source, srcBuf,
OF_READ or OF_SHARE_DENY_NONE );
If srcHandle = -1 Then
CopyFailed
Else Begin
destHandle := LZOpenFile( f_target, destBuf,
OF_CREATE or OF_SHARE_EXCLUSIVE );
If destHandle = -1 Then
CopyFailed
Else Begin
If LZCopy( srcHandle, destHandle ) < 0 Then
CopyFailed;
LZClose( destHandle );
End; { Else }
LZClose( srcHandle );
End; { Else }

f_source и f_target - указатели на терминированные нулем строки (PChars) с именем исходного и целевого файла. CopyFailed - просто процедура для вывода сообщения об ошибке, создайте ее сами.

Если вам необходимо скопировать сразу несколько файлов, эффективнее использовать последовательность:

------------

LZStart;
For i:=1 to numSourcefiles Do Begin
scrHandle := _lopen( имя исходного файла ... );
targetHandle := _lcreat( имя целевого файла... );
CopyLZFile( scrHandle, targetHandle );
_lclose( srcHandle );
_lclose( targetHandle );
End;
LZDone;
(* добавьте проверку на ошибку в каждом шаге! *)

Все имена файлов должны терминироваться нулем, не используйте паскалевские строки! Самый простой путь для добавления нуля в конец строки - добавление символа #0 и передача адреса первого символа строки, например (@str[1]).

---------------

Var
source: string;
sourceHandle: Word;


....
source:= 'a:\anyfile.ext';
....
source := source+#0;
sourceHandle := _lopen( @source[1], READ or OF_SHARE_DENY_NONE );



Изменение расширения BITMAP???


Я изменил расширение изображения с BMP на 3LG. Затем для загрузки *.3LG-файла в виде изображения в компонент Image1 я даю команду
Image1.Picture.LoadFromFile('C:\TEST.3LG');
я получаю ошибку, говорящую о неверном расширении. Как мне обойти это? (это тот же BMP, но я просто изменил ему расширение)

Смотри процедуру RegisterFileFormat.



Как работать с нетипизированным файлом (BlockRead и текстовый файл)?

Следующий код демонстрирует использование нетипизированного входного файла для блочного чтения (blockread) текстового файла, сканирование входного буфера в поисках любого символа и их замены на символы перевода строки и возврата каретки. Поскольку код использует входные и выходные буфера размером 16к, то получаемая скорость весьма приемлема.

Примечание: В процессе обработки, если длина строки выходного файла превышает 255 символов и вы хотите прочесть ее с помощью ReadLn, то просто используйте в запросе ReadLn несколько строк, например так:

ReadLn(infile,string1,string2);

Так можно прочесть вплоть до 510 символьных строк с 1-й по 255 символ в string1 и остальное в string2;

program fixfile;{ Компилируем из DOS-приглашения: DCC FIXFILE.PAS }
uses { запускаем из File Manager }
sysutils,dialogs,forms;

type
bufptr = obufr;
iobufr = array[0..16384] of char;

var
infile : file;
oufile : textfile;
inbufr,
oubufr : bufptr;

idx: integer;
bytesread: integer;
bytes2read: integer;

totalbytesread: longint;
actualfilesize: longint;

OpenDialog1: TOpenDialog;

infilename,
oufilename: string;


begin
infilename := '';
OpenDialog1 := TOpenDialog.Create(Application);

OpenDialog1.Options := [];
OpenDialog1.Filter := 'Все файлы|*.*';
OpenDialog1.FilterIndex := 1;
OpenDialog1.Title := 'Укажите исходный файл для преобразования';
if OpenDialog1.execute then
infilename := OpenDialog1.filename;

if infilename='' then
begin
OpenDialog1.free;
halt;
end;

OpenDialog1.Title := 'Укажите имя создаваемого целевого файла';
if OpenDialog1.execute then
oufilename := OpenDialog1.filename;

OpenDialog1.free;

if oufilename='' then
halt;

if infilename=oufilename then
halt;

new(inbufr);
new(oubufr);

assignfile(infile,infilename);
reset(infile,1);
actualfilesize := filesize(infile);

assignfile(oufile,oufilename);
system.settextbuf(oufile,oubufr^);
rewrite(oufile);

totalbytesread := 0;
bytesread := 0;
bytes2read := 0;

while (totalbytesread<actualfilesize)
and (bytes2read=bytesread) and (IOresult=0) do
begin
if (actualfilesize-totalbytesread)>sizeof(inbufr^) then
bytes2read := sizeof(inbufr^)
else
bytes2read := actualfilesize-totalbytesread;

blockread(infile,inbufr^,bytes2read,bytesread);

totalbytesread := totalbytesread + bytesread;
for idx := 0 to bytesread do
if inbufr^ [idx]='''' then { <= преобразуемый символ }
writeln(oufile)
else
write(oufile,inbufr^ [idx]);
end;

closefile(infile);
closefile(oufile);

dispose(inbufr);
dispose(oubufr);

end.



Как использовать функцию readln(), если в файле строки более 255 символов?

ReadLn акцептует массив символов array [0..something] of Char и использует его в качестве буфера для чтения символов, замыкая цепочку терминирующим нулем. Единственное ограничение: компилятор должен иметь возможность вычисления размера буфера во время компиляции, что делает невозможным объявление переменой типа PChar и ее распределение во время выполнения программы.

Обходной путь:

Type
{используем самое большое количество символов в строке, с которым вы можете иметь дело}
TLine = Array [0..1024] of Char;

PLine = ^TLine;

Var
pBuf: PLine;
...
New( pBuf );

...
ReadLn( F, pBuf^ );

Для передачи pBuf функциям, которым требуется параметр типа Pchar, используйте приведение типа подобно PChar( pBuf ).
Примечание: вы, конечно, можете использовать объявление переменной типа TLine или непосредственно массив символов, но я предпочитаю распределять из кучи нечто большее, чем 4 байта...



Как сделать блокировку доступа к откруытому файла другими программами?

...действительно, когда вы запрашиваете о блокировке файла и прерывания DOS, это относится к блокировке записи. Если вы хотите иметь полностью монопольный доступ к файлу, то в этом случае вы должны воспользоваться переменной FileMode. Вот пример кода моей программы, где я использую эту переменную:

type FileShareType = (DenyCompatibility,DenyAll,DenyWrite,DenyRead,DenyNone);

FileAccessType = (ReadOnly,WriteOnly,ReadWrite);

procedure SetFileAccess(AccessMode: FileAccessType;ShareMode: FileShareType);

{ Устанавливаем режим доступа к файлу для следующего вызова открытия файла }
begin
FileMode := ord(AccessMode) or (ord(ShareMode) shl 4)
end;

Вот и все.



<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ



Материалы находятся на сайте https://exelab.ru/pro/



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS