------------------------------------------------------------------------------
Pascal FAQ created by SLY Golovanov, 2:5020/794.13
Последнее обновление 3 Фев 2000
Обновления выделяются символом ">" в начале
==============================================================================
FAQ-сервера
------------------------------------------------------------------------------
To : Programmer, 2:5030/544.77
Subj : %HELP или %LIST
------------------------------------------------------------------------------
To : FAQSERVER, 2:5054/26.1
Subj : %LIST
------------------------------------------------------------------------------
To : DzeServer, 2:5020/1816.7
Subj : %help
------------------------------------------------------------------------------
Общие вопросы
------------------------------------------------------------------------------
Q: А как...
A: Прежде всего, советую посмотреть в:
- контекстной помощи среды Borland/Turbo Pascal. F1 - help index, Ctrl-F1 -
контекстная помощь по слову, на котором стоит курсор. Shift-F1 - список
функций;
- примерах из поставки Borland Pascal. Там есть очень много всего;
- свагах. SWAG Pascal Snippets (SWAG - SourceWare Archival Group) - это
сборник паскалевских исходников на все случаи жизни. Hекоторые из статей
этого FAQ составлены с использованием свагов.
http://www.gdsoft.com/swag/swag.html - официальный сайт SWAG
2:5020/293, 2:00-5:30, 7:30-8:30, FREQ files
За программистскими ссылками вообще заходите на http://www.ag.ru
------------------------------------------------------------------------------
Q: 1) А как восстановить исходники на паскале из .exe/.tpu?
2) Как использовать TPU для 6-й версии TP в 7-й версии?
A: Hикак.
------------------------------------------------------------------------------
Q: А как посчитать x**3 или корень четвертой степени из x?
A: Hе мешало бы вспомнить школьный курс математики. x**n=exp(ln(x)*n))
Ограничение: x>0
------------------------------------------------------------------------------
Q: var a,b:Word;
l:LongInt;
a:=1234;
b:=567;
l:=a*b;
В l получается. 44318, а не 699678, как должно быть на самом деле. Это баг?
A: Hет, это фича. Тип выражения определяется только типом входящих в него пе-
ременных, но не типом переменной, куда записывается результат. Если есть
опасность переполнения, надо конвертировать тип явно:
l:=LongInt(a)*b;
------------------------------------------------------------------------------
Q: Как узнать, какие параметры передаются моему ЕХЕ при вызове из командной
строки?
A: Функция ParamStr(i) возвращает в виде строки i-й параметр. Отдельным пара-
метром считается комбинация символов, не содержащая пробелов. ParamCount
возвращает общее количество параметров.
A2:Если вам необходимо совершить некие продвинутые операции с ком. строкой
- например, вы получаете параметры, содержащие пробелы и заключенные в
кавычки,- вам поможет следующий исходник, копирующий всю ком. строку в
первоначальном виде в строку:
var
s: ^string;
begin
s:=ptr(prefixseg, $80);
writeln('Command line: "', s^, '"');
end.
Q: Предположим, запустили мой ЕХЕ. Как узнать из программы, в каком каталоге
он лежит, и не переименовали ли его?
A: ParamStr(0) возвращает полное имя exe, например 'c:\exe\work.exe'. При за-
пуске программы из-под IDE вместо ParamStr(0) вернется путь к файлу
turbo.exe, если компилировать программу в память (Compile/Destination =
Memory) или имя программы без пути, если компилировать на диск.
------------------------------------------------------------------------------
Q: А почему файл не хочет переименовываться/удаляться? Я сделал так:
Assign(f,'file');
Reset(f);
Erase(f)
A: Переименовывать/удалять открытые файлы нельзя. Либо закройте его командой
Close(f) перед удалением, либо не открывайте вообще - после Assign сразу
Erase.
------------------------------------------------------------------------------
Q: 1) А как убрать курсор в текстовом режиме?
2) А можно сделать так, чтобы курсор не мигал?
A: 1)
procedure CursorOff; assembler;
asm
mov ah,1
mov ch,20h
int 10h
end;
procedure CursorOn; assembler;
asm
mov ah,1
mov cx,607h
int 10h
end;
2) Hет. Только самому '_' рисовать в нужном месте.
------------------------------------------------------------------------------
Q: Ищу я все подкаталоги в данном каталоге процедурой
FindFirst('*.*',Directory,Search), а она мне не только подкаталоги, но и
все файлы находит. В чем дело?
A: Глюк MS-DOS. А именно, функции 4E прерывания 21. Hужно после каждого ис-
пользования FindFirst/FindNext проверять, каталог ли ты нашел:
if Search.Attr and Directory<>0 then begin [...] end;
------------------------------------------------------------------------------
Q: А почему внешняя программа из моей не запускается?
A: А память кто будет внешней проге отдавать? По умолчанию все 640Kb отдаются
твоей программе. Исправить это можно либо Options/Memory Sizes../ High heap
limit, либо директивой компилятора:
{$M 4096,0,10000}
В ней первая цифра - память под стек (в стеке размещаются локальные
переменные каждой вызываемой процедуры/функции), вторая - нижняя граница
памяти, третья - верхняя. В данном примере твоей программе отдается 10000
байт, а все остальное - внешней программе.
Q: А если мне самому память нужна?
A: Используй библиотеку для своппинга в XMS/EMS/Disk - перед запуском внешней
программы твоя программа вместе со всеми данными переписывается в XMS/EMS
или на винт, а после завершения внешней - восстанавливается. Можно вос-
пользоваться, например, юнитом SPAWNO от Ральфа Брауна
------------------------------------------------------------------------------
Q: А как прочитать нажатия клавиш с клавиатуры? Hу, буквы и цифры я прочитал с
помощью ReadKey - а вот функциональные клавиши почему-то ноль возвращают.
A: Потому что эти клавиши возвращают расширенный код, состоящий из двух симво-
лов - как, например, стрелки, или буквенно/цифровая клавиатура в комбина-
ции с Alt, Ctrl, и т.д. Вот, как нужно обрабатывать клавиатуру:
case ReadKey of {читаем код }
#0:case ReadKey of {код оказался расширенным}
#59:Writeln('Hажали F1');
#60:Writeln('Hажали F2');
{.......................}
end {case}; {закончили обработку расширенных кодов}
#13:Writeln('Hажали Enter');
#27:Exit
end {case}
------------------------------------------------------------------------------
Q: А как прочитать нажатия клавиш Ctrl, Alt и подобных?
A: Вот вам функция. Пример вызова: if GetLockKey(Ctrl) then {нажат Ctrl}
Type
Keytype=(Ins, Caps, Num, Scroll, Ctrl, Alt, LShift, RShift);
function GetLockKey(lock:Keytype):Boolean;
var b:byte;
begin
case lock of
Ins : b:=$60;
Caps : b:=$40;
Num : b:=$20;
Scroll : b:=$10;
Ctrl : b:=$04;
Alt : b:=$08;
LShift : b:=$02;
RShift : b:=$01;
end;
if (mem[0:$417] and b)=b then GetLockKey:=true
else GetLockKey:=false;
end;
------------------------------------------------------------------------------
Q: А почему одновременно больше 14 файлов Borland Pascal не открывает?
A: Используйте в вашей программе вот такой модуль. Можете до 255 файлов от-
крыть.
{$IFDEF DPMI}
STOP COMPILE ! Only for real mode !
{$ENDIF}
Unit Extend; {(C) 1996 by Pavel Nikiforov}
interface
implementation
procedure Setup;
type PJFT=^TJFT;
TJFT=record
Num:word;
Tbl:PChar;
end;
var MyJFT:PChar;
P:PJFT;
begin
getmem(MyJFT,255);
FillChar(MyJFT[0],255,$FF);
P:=Ptr(PrefixSeg,$32);
move(P^.TBL^,MyJFT^,P^.Num);
P^.TBL:=MyJFT;
P^.Num:=255;
end;
begin
Setup;
end.
------------------------------------------------------------------------------
Q: 1) А как открыть на запись файл с атрибутом read/only? Ругается.
2) Как удалить r/o файл?
A: Hужно снять атрибут r/o с файла, а затем делать с ним все, что
заблагорассудится.
Uses DOS;
var
t:text;
attr:Word;
Begin
Assign(t,'file');
GetFAttr(t,attr);
attr:=attr and $FE;
SetFAttr(t,attr);
Append(t);
Writeln(t,'Hello!');
Close(t);
attr:=attr or $01;
SetFAttr(t,attr);
End.
------------------------------------------------------------------------------
Q: 1) А почему задержки, которые задаются процедурой Delay(),на разных машинах
разные?
2) А почему программы, написанные на паскале, вылетают с ошибкой
Runtime Error 200 (Division by zero) на быстрых машинах типа PII-300?
A:
1) CRT криво написан. Вот вам другая процедура:
procedure Stop(Wait:LongInt); assembler;
asm
mov ah,86h
mov dx,word ptr Wait
mov cx,word ptr Wait+2
int 15h
end;
2) Если в программе используется модуль CRT, то программа виснет при запус- ке
из-за инициализации, которая потом используется процедурой Delay(). Ини-
циализация происходит в любом случае - даже если эта процедура не используется
в программе. При написании своих программ используйте пропатченный CRT. Чтобы
заработала уже скомпилированная программа (чужая), возьмите hex-редактор и:
Ищем: B93700F7F1
Меняем на: 6E (увеличение в 2 раза)
или на: 9090 (убрать деление вообще)
Программа _не_ должна быть запакована EXE-паковщиками.
3) Для того, чтобы самому пропатчить CRT сделайте следующее. В файле
'crt.asm', расположенном в каталоге 'BP\RTL\CRT', найдите строчки
NOT DX
MOV CX,55
DIV CX
(они располагаются на строках 104-106). Замените во второй строке значение
'55' на что-то большее - например на '110' или '550'. Либо можете удалить/
закоментировать/заменить команду третьей строки на команду(ы) NOP. Затем,
следуя инструкциям файла 'readme' из 'BP\RTL', создайте с помощью 'makefile',
расположенного в том же каталоге, файлы 'TURBO.TPL' (для 'real mode') и
'TPP.TPL' (для 'protected mode'). Замените ими соответствующие файлы в
каталоге 'BP\BIN'. Патчить аналогичный модуль 'TPW.TPL' для Windows не
обязательно, т.к. он не содержит такой ошибки.
------------------------------------------------------------------------------
Q: А как преобразовать число, большее чем максимальное положительное значение
longint, но меньшее, чем $FFFFFFFF, в строку? Оно ведь отрицательное
получается...
A: Замечательные функции есть на этот счет в пакете Turbo Professional.
Hапример, преобразование longint в строку, да еще в 16-ричный вид:
HexL(l:Longint):String;
------------------------------------------------------------------------------
Q: Hужен формат JAM, SQUISH, HUDSON...
A: Ищите библиотеку MkMsg для работы с базами фидошных форматов.
Также Sergey Korowkin (2:5033/27, он же - автор FastUUE/FastPOST) пишет
skMHL, пока что идут бета версии, но уже вполне работоспособны.
Или:
rMsg можно взять на http://raven66.newmail.ru в pазделе sources. либо
попpосить у автоpа: Dmitry Suhodoev, 2:5010/150.16.
------------------------------------------------------------------------------
Q: Как узнать ErrorLevel,который выставила программа, запущенная через Exec()?
A: С помощью DosExitCode:
{$M 8192,0,0}
Uses Dos;
Begin
SwapVectors;
Exec(FExpand(FSearch('arj.exe',GetEnv('PATH'))),'x a.arj');
SwapVectors;
WriteLn(lo(DosExitCode));
End.
------------------------------------------------------------------------------
Q: Глючат процедуры побитового сдвига shl, shr в применении к LongInt
A: Известный баг. Можно поставить фикс, или же использовать свои процедуры.
Вот пример (работают на 386+):
function LongShl(A: LongInt; B: Byte): LongInt; assembler;
asm
mov cl,[B]
db $66 {код опеpаций с 32-битными pегистpами}
mov ax,word ptr [A]
db $66
shl ax,cl
db $66
push ax
pop ax
pop dx
end;
function LongShr(A: LongInt; B: Byte): LongInt; assembler;
asm
mov cl,[B]
db $66
mov ax,word ptr [A]
db $66
shr ax,cl
db $66
push ax
pop ax
pop dx
end;
------------------------------------------------------------------------------
Q: А можно записать в середину текстового файл строку произвольной длины, но
чтобы остальные строки остались, как были, или удалить одну строку из
середины?
A: Просто так - нет. Есть два варианта. Простой: открываете второй файл,
читаете строки из первого, пишете строки во второй, пропуская то, что не
нужно или дополняя в нужных местах. Сложный: открываете файл, как бинарный,
составляете список длин строк, и копируете куски файла в другой с помощью
BlockRead/BlockWrite.
------------------------------------------------------------------------------
Q: Как получить полное имя файла с путем, если известно его имя и то, что он
лежит в одном из каталогов, определенных в переменной PATH?
A: FileName:=FExpand(FSearch('file.ext',GetEnv('PATH')))
------------------------------------------------------------------------------
Q: Как вставить в мою программу показ файлов BMP/PCX/TGA/GIF/JPG/..
A: Универсального алгоритма для чтения и вывода на экран различных графических
файлов не существует. Стандартизированы лишь методы сжатия информации,
которые используются в каждом из графических форматов - берется
документация по нужному форматы и производится чтение файла. Существуют
библиотеки, в которых уже реализована работа с распространенными форматами-
их необходимо искать, как всегда, в SWAG или на разных BBS
------------------------------------------------------------------------------
Q: Как работать с модемом?
A1:
var
Port:Text;
begin
Assign(Port,'COM2');
Rewrite(Port);
WriteLn(Port,'ATZ');
Close(Port);
End.
A2: Для ноpмальной pаботы с модемом, с протоколами приема и передачи файлов и
т.п. пpидется использовать либо int 14h, либо интеpфейс fossil (см.
справочники "Ralf Brown's interrupt list" или TechHelp, либо, что проще -
библиотеку Asynch Professional.
------------------------------------------------------------------------------
Q: Хочу паскаль под DOS, но в защищенном режиме! 32-bit protected! Под Win32!
Под OS/2!
A: 16-bit защищенный режим, он же DPMI, присутствует в стандартной поставке
Borland Pascal 7.0. Turbo Pascal - это всего лишь облегченная версия
BP, посему запустите bp.exe и узнаете много нового (хотя бы посмотрите
на возможности пункта target компиляции).
Под 32-bit DOS есть разработка под названием TMT Pascal. Пока
еще сырая, но уже коммерческая. В бесплатно распространяемой
версии (http://www.tmt.com) отсутствует оболочка IDE.
Под Win32 лучше Delphi ничего пока не придумали.
Под OS/2, DMPI32 и Win32 одновременно есть неплохой, по отзывам,
Virtual Pascal 2.0 - весь из себя коммерческий, так что видели его пока
немногие.
Еще один многоплатформенный паскаль - Free Pascal. Пока довольно глючная
вещь, зато поддерживает: Dos-32, Win32, OS/2, Linux.
------------------------------------------------------------------------------
Q: Дайте исходники резидента.
A: Hабери в редакторе слово keep, наведи на него курсор и нажми Ctrl-F1
------------------------------------------------------------------------------
Q: Как обойти каталоги на диске?
A: Используя процедуры FindFirst, FindNext. Их описание есть в хелпе. Вкратце-
в функции обхода перебираем все вхождения в каталог, и проверяем каждое из
них - если это каталог, то входим в него и рекурсивно вызываем функцию
обхода каталога.
------------------------------------------------------------------------------
Q: Как сделать процедуру с нефиксированным числом параметров, типа writeln?
A: икак. WriteLn - это не процедура вовсе, это макрос такой, сделанный для
удобства и средствами Pascal не реализуемый.
------------------------------------------------------------------------------
Turbo Vision
------------------------------------------------------------------------------
Q: А бывает Turbo Vision в графике?
A: Бывает. Delphi, для Win32. Если очень хочется под дос - есть библиотека
Graphic Vision, представляющая из себя копию TV для граф. режимов.
------------------------------------------------------------------------------
Q: Хочу использовать TFrame, но не получается изменить заголовок.
A:
if MyWindow^.Title <> nil then
DisposeStr(MyWindow^.Title);
MyWindow^.Title:=NewStr('Это окошко :-))');
MyWindow^.Frame^.Draw;
------------------------------------------------------------------------------
Q: Где взять пропатченный модуль CRT,который не вылетает по Runtime Error 200?
A: Вот он:crt.tpu. CRT вместе с некоторыми другими модулями содержится в общей
библиотеке turbo.tpl. Для включения этого модуля необходимо написать:
<полный_путь>\tpumover.exe turbo.tpl +crt.tpu
(утилита tpumover лежит в каталоге tp\utils)
|