Переносим программы с Turbo Pascal на Delphi
Переносим программы с Turbo Pascal на Delphi
Данная статья призвана ответить не только на вопрос «Как перенести программу, написанную на TurboPascal в среду Delphi», но и «Как комфортно писать консольные приложения ». Под словом комфортно я понимаю присутствие схожего депозитария процедур и функций как в TP.
Использовались TP7, Delphi 10 lite, (Delphi 7)
Шаг первый – О файлах
В TP у нас есть pas файл, который мы компилируем и получаем приложение. В Delphi же у нас несколько файлов проекта, во главе с Project1.dpr. Берем нашу программу и меняем у нее расширение.
MyProg.pas -> MyProg.dpr
Теперь откроем его и приступим к редактированию.
Шаг второй – Сначала самое простое.
Консольные программы на Delphi содержат директиву {$APPTYPE CONSOLE}. Она показывает компилятору, что следует генерировать консольное Win32 приложение. При запуске будет создана текстовая консоль, через которую можно взаимодействовать c вашей программой. Ввод и вывод будут автоматически ассоциированы с этим черным окошечком.
(Отсутствие этой директивы эквивалентно {$APPTYPE GUI}. В этом режиме Delphi генерирует оконные приложения)
Определять эту директиву можно только в главной программе, определение в модулях, библиотеках и пакетах недопустимо.
Пример:
program pc;
begin
writeln('Hello world');
readln;
end.
program pc;
{$APPTYPE CONSOLE}
begin
writeln('Hello world');
readln;
end.
Пример простой, но чего-то большего для пояснения, думаю не нужно.
Шаг третий – Модуль CRT
Рассмотрим только один модуль, по причине его популярности и необходимости. Остальные, например Graph и TurboVision, уже архаика и сложно представить, где их можно использовать.
Итак, CRT: чрезвычайно полезный модуль из TP и отсутствующий в Delphi. Так как это Win32 приложение то мы имеем доступ к куче WinAPI, все их можно найти в справке, прилагающейся к Delphi. Для работы с ними необходимо подключить модуль Windows.
(Если ваше приложение не использует этот модуль, то этот шаг можно пропустить.)
Пример функции очистки экрана c использованием API:
procedure Clrscr; Var Max, Coord : TCoord; ConHandle : THandle; tmp : cardinal; begin // Получаем хендл(ссылку) на стандартный вывод - это наша консоль ConHandle := GetStdHandle(STD_OUTPUT_HANDLE); // координаты ячейки, от которой будем писать символы Coord.X := 0; Coord.Y := 0; // получаем размеры нашей консоли Max := GetLargestConsoleWindowSize(ConHandle); // Заполняем консоль пробелами FillConsoleOutputCharacter(ConHandle, ' ', Max.X * Max.Y, Coord, tmp); // устанавливаем каретку в начало SetConsoleCursorPosition(ConHandle, Coord); end;
Процедура получилась громоздкой. Для сокращения кода и увеличения быстродействия можно вынести инициализацию хендла и размеров консоли из подрограмм.
Unit OurCrt; ... interface Var Max, Coord : TCoord; ConHandle : THandle; tmp : cardinal; ... procedure Clrscr; ... implementation procedure Clrscr; begin Coord.X := 0; Coord.Y := 0; FillConsoleOutputCharacter(ConHandle, ' ', Max.X * Max.Y, Coord, tmp); SetConsoleCursorPosition(ConHandle, Coord); end; ... initialization ConHandle := GetStdHandle(STD_OUTPUT_HANDLE); Max := GetLargestConsoleWindowSize(ConHandle); end.
Но не будем изобретать велосипеды. Вот (линк) найденный мной модуль на просторах Интернета. Примечателен он тем, что кроме оригинальных функций, содержит и дополнительные для работы с мышью. При переносе программы, конечно, от них никакого толку, а вот при написании приложения с нуля могут пригодиться.
(На 64 разрядной платформе компилироваться будет, если убрать {$IfDef Win32}, но работоспособность мной не проверена.)
Шаг четвертый – Кодировка
Если мы использовали русские буквы при разработке программы на TP, то, открыв файл в Delphi, мы будем лицезреть вместо них иероглифы, которые обретают вид только в приложении, после компиляции. Для удобной работы необходимо открыть файл в 866 кодировке и сохранить в 1251. Редактирование программы теперь удобней, а иероглифы перебежали в консольное окошко. Каждый раз сохранять файлы в разных кодировках очень неудобно, поэтому рассмотрим еще варианты.
Конвертирование:
WinAPI предоставляет возможность конвертировать символы кодировок OEM и ANSI: OemToChar() , CharToOem().
Пример:
program Project1;
{$APPTYPE CONSOLE}
uses
windows
//,SysUtils
;
function PR(Const a : string) : string;
begin
SetLength(result, length(a));
CharToOem(PChar(a), Pchar(result));
end;
begin
//setconsoleCp(866); //установка кодовой страницы
Writeln(PR('Привет');
readln;
end.
Использование этого способа вызывает необходимость редактирование всего текста программы, и чем больше мы выводили в консоль, тем больше дополнительных вызовов процедур.
Еще один вариант это переопределение процедур вывода. Как и в случае с модулем crt уже имеется готовая реализация – esconsole.
(Что бы работало с CRT32 нужно подключать в таком порядке
uses CRT32 in 'CRT32.pas', EsConsole in 'EsConsole.pas';
)
Шаг пятый – Типы данных
Среди целочисленных и вещественных типов разницы фактически нет, исключение является тип Integer, он увеличился в два раза(32 разрядная версия компилятора Delphi).
Со строками немного сложней в Delphi их несколько (в моей 3).
ShortString – аналог строк в ТП
AnsiString – длинные строки 8 разрядных символов
WideString – длинные строки 16 разрядных символов
(В новых версиях есть еще UnicodeString и UTF8String.)
Размер длинных строк может достигать до 2 гигабайт, и по умолчанию используются именно они (В моей AnsiString, в более новых одна из Unicode). Между строками большая разница, но работают они с одними и теми же процедурами, что позволяет компилировать TP код без модификаций. Во избежание появления артефактов необходимо компилировать код с директивой {$H-}. В этом случае все переменные, описанные как String, будут ShortString.
Пример:
program Project1;
{$APPTYPE CONSOLE}
uses
//SysUtils,
CRT32 in 'CRT32.pas',
EsConsole in 'EsConsole.pas';
{$H-}
Var s : string
begin
Clrscr;
s := 'Привет Мир!!!';
Writeln(s);
Readkey;
end.
Шаг шестой – обратно к паскалю
(Это делается в учебных целях, на практике в этом нет необходимости.)
Наш код подвергся добавлению некоторых директив, которые мы спрячем в другие директивы от TP.
Пример:
program Project1;
{$IFDEF MSWINDOWS}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
{$IFDEF MSWINDOWS}
CRT32 in 'CRT32.pas', EsConsole in 'EsConsole.pas';
{$H-}
{$ELSE}
crt;
{$ENDIF}
begin
Clrscr;
Writeln('Hello world!!!');
readkey;
end
Теперь приложение работает под Delphi и TP
The end.
Можно и реализовать, за небольшую плату…
=)
Ребят, кто может такой модуль реализовать..?
Реализовать в виде модуля набор подпрограмм для выполнения следующих операций со строками
1)Процедура удаления из строки всех символов* и подсчёта количества удалений
2)Процедура замены в строке символа* на символ+
3)Функция определения сколько раз в строке встречается заданное слово
Отличная статья! Спасиб, скачал прям готовый модуль!
\На 64 разрядной платформе компилироваться будет, если убрать {$IfDef Win32}, но работоспособность мной не проверена.\
Delphi ВООБЩЕ не может компилировать для WIN64, не проверил он, блжад.