Как сделать калькулятор в Delphi?

Delphi - объектно-ориентированный язык программирования, разработанный компанией Borland в 1995 году. Он основан на языке программирования Pascal, но имеет более расширенные возможности и добавлены новые функции.

Как Delphi реализует многоплатформенную разработку?

Delphi является интегрированной средой разработки (IDE), которая позволяет разрабатывать программное обеспечение для различных платформ, включая Windows, macOS, Android и iOS. Delphi достигает многоплатформенности с помощью...

Функция CreateProcess

По сравнению с ShellExecute, функция дает дополнительные возможности по управлению процессом: можно установить начальный приоритет первого потока процесса, выставить положение и размер окна приложения, дождаться завершения процесса, завершить процесс.

CreateProcess(lpApplicationName: PChar, // имя исполняемого модуляlpCommandLine: PChar, // строка параметров запускаемой программыlpProcessAttributes: TSecurityAttributes, // структура SECURITY_ATTRIBUTES процессаlpThreadAttributes: TSecurityAttributes, // структура SECURITY_ATTRIBUTES потокаbInheritHandles: LongBool, // флаг наследования текущего процессаdwCreationFlags: Longword, // флаги способов создания процессаlpEnvironment: Pointer, // указатель на блок средыlpCurrentDirectory: PChar, // текущий диск и каталогlpStartupInfo:TStartupInfo, // структура STARTUPINFO lpProcessInformation: TProcessInformation // структура PROCESS_INFORMATION ): LongBool;

Приведу краткое описание функции, за более полным обращайтесь в Windows SDK.

lpApplicationNameПолный путь к исполняемому модулю программы, например, c:Program FilesBorlandDelphi7BinDelphi32.exe (поиск производится только в текущей директории!). lpApplicationName может быть nil, тогда lpCommandLine должна содержать имя исполняемого модуля (если имя содержит пробелы, то оно должно быть заключено в "двойные кавычки"), отделенное от остальной строки пробелом. Если запускается 16-разрядное приложение в среде Windows NT, lpApplicationName должна быть nil, а lpCommandLine содержать имя модуля.

lpCommandLineСтрока параметров, может быть nil. Если приложение указано в lpCommandLine, то поиск производится в текущей, системной и описанных в переменной окружения PATH директориях. Если приложение указано в lpApplicationName, строка параметров должна начинаться с пробела.

lpProcessAttributesАтрибуты защиты для нового процесса. Если указать nil то система сделает это по умолчанию. В Windows 9.x, Me игнорируется.

lpThreadAttributesАтрибуты защиты для первого потока созданного приложением. nil - установка по умолчанию. В Windows 9.x, Me игнорируется.

bInheritHandlesФлаг наследования от процесса производящего запуск. Унаследованные дескрипторы имеют те же значения и права доступа, что и оригиналы. Наследуются если установлено в true.

dwCreationFlagsФлаг способа создания процесса и его приоритет:

Флаг
Описание
CREATE_DEFAULT_ERROR_MODE Новый процесс не наследует режим ошибок (error mode) вызывающего процесса.
CREATE_NEW_CONSOLE Новый процесс получает новую консоль вместо того, чтобы унаследовать родительскую.
CREATE_SUSPENDED Первичная нить процесса создается в спящем (suspended) состоянии и не выполняется до вызова функции ResumeThread.
HIGH_PRIORITY_CLASS Высокий приоритет
IDLE_PRIORITY_CLASS Поток выполняется только при простое системы
NORMAL_PRIORITY_CLASS Приоритет по умолчанию
REALTIME_PRIORITY_CLASS Наивысший приоритет

lpEnvironmentБлок среды. Если nil, то будет использован блок среды родительского процесса. Блок среды это список переменных имя=значение в виде строк с нулевым окончанием.

lpCurrentDirectoryТекущий диск и каталог. Если nil, то будет использован диск и каталог процесса родителя.

lpStartupInfoИспользуется для настройки свойств процесса, например расположения окон и заголовок..

TStartUpInfo = recordcb: Longword; lpReserved: PChar; lpDesktop: PChar; lpTitle: PChar; dwX: Longword; dwY: Longword; dwXSize: Longword; dwYSize: Longword; dwXCountChars: Longword; dwYCountChars: Longword; dwFillAttribute: Longword; dwFlags: Longword; wShowWindow: Word; cbReserved2: Word; lpReserved2: PByte; hStdInput: THandle; hStdOutput: THandle; hStdError: THandle;end;

Некоторые элементы имеют смысл, только если дочернее приложение создает перекрываемое (overlapped) окно, а другие — если это приложение осуществляет ввод-вывод на консоль. Рассмотрим только первый тип параметров.

Элемент
Описание
cb Содержит количество байтов, занимаемых структу рой TStartUpInfo. Обязательно для заполнения. Инициализируйте как SizeOf(TStartUpInfo).
lpReserved
Зарезервирован. Инициализируйте как nil
IpDesktop Идентифицирует имя рабочего стола, на котором запускается приложение.
dwX
dwY
Координаты окна в пикселях.
dwXSize dwYSize Определяют ширину и высоту (в пикселях) окна приложения.
dwFlags Содержит набор флагов, позволяющих управлять созданием дочернего процесса
wSbowWtndow Определяет как должно выглядеть окно запущенного приложения. В этот элемент можно записать любой из идентификаторов типа SW_*
cbReserved2 Зарезервирован. Инициализируйте как 0.
lpReserved2 Зарезервирован. Инициализируйте как nil.

Список допустимых флагов dwFlags:

Флаг
Описание
STARTF_USESIZE Заставляет использовать элементы dvXSize и dwYSize
STARTF_USESHOWWINDOW Заставляет использовать элемент wShowWindow
STARTF_USEPOSITION Заставляет использовать элементы dwX и dwY
STARTF_FORCEONFEEDBACK STARTF_FORCEOFFFEEDBACK Форма курсора при запуске (с "часиками" или без)

lpProcessInformationИнформация о созданном процессе. Инициализируется самой функцией.

TProcessInformation = record hProcess: THandle; // дескриптор процессаhThread: THandle; // дескриптор первого потока процессаdwProcessId: Longword; // глобальный идентификатор процессаdwThreadId: Longword; // глобальный идентификатор потокаend;

Указатели hProcess и hThread должны быть закрыты в родительском процессе функцией CloseHandle иначе произойдет утечка памяти. CloseHandle не закрывает процесс (поток), а только уменьшает счетчики открытых дескрипторов.

При удачном вызове CreateProcess возвращает true.

Если приложение Win32, то после создания процесса желательно дождаться завершения его инициализации функцией WaitForInputIdle.

Примеры использования функции.

uses Windows;...var  Rlst: LongBool;  StartUpInfo: TStartUpInfo;  ProcessInfo: TProcessInformation;  Error: integer;begin  FillChar(StartUpInfo, SizeOf(TStartUpInfo), 0);  with StartUpInfo do  begin    cb := SizeOf(TStartUpInfo);    dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;    wShowWindow := SW_SHOWNORMAL;  end;  Rlst := CreateProcess('C:WindowsSystem32 otepad.exe', ' c: eadme.txt', nil, nil, false, NORMAL_PRIORITY_CLASS, nil, nil, StartUpInfo, ProcessInfo);  if Rlst then  with ProcessInfo do begin    WaitForInputIdle(hProcess, INFINITE); // ждем завершения инициализации     CloseHandle(hThread); // закрываем дескриптор процесса    CloseHandle(hProcess); // закрываем дескриптор потока  endelse Error := GetLastError;end;

Эквивалентный вызов функции:Rlst := CreateProcess(nil, 'notepad c: eadme.txt', nil, nil, false, NORMAL_PRIORITY_CLASS,nil, nil, StartUpInfo, ProcessInfo);

Можно дождаться завершения запущенного процесса и получить код его завершения. Но в этом случае работа потока, который запустил процесс, приостанавливается:

var  Rlst: LongBool;  StartUpInfo: TStartUpInfo;  ProcessInfo: TProcessInformation;  Error: integer;  ExitCode: Cardinal;begin  FillChar(StartUpInfo, SizeOf(TStartUpInfo), 0);  with StartUpInfo do  begin    cb := SizeOf(TStartUpInfo);    dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;    wShowWindow := SW_SHOWNORMAL;  end;  Rlst := CreateProcess('C:WindowsSystem32 otepad.exe', ' c: eadme.txt', nil, nil, false, NORMAL_PRIORITY_CLASS, nil, nil, StartUpInfo, ProcessInfo);  if Rlst then  with ProcessInfo do begin    WaitForInputIdle(hProcess, INFINITE); // ждем завершения инициализации     WaitforSingleObject(ProcessInfo.hProcess, INFINITE); // ждем завершения процесса    GetExitCodeProcess(ProcessInfo.hProcess, ExitCode); // получаем код завершения    CloseHandle(hThread); // закрываем дескриптор процесса    CloseHandle(hProcess); // закрываем дескриптор потока  endelse Error := GetLastError;end;

Для принудительного завершения запущенного процесса надо вызвать функцию TerminateProcess (до вызова функции CloseHandle).

...

    WaitForInputIdle(hProcess, INFINITE); // ждем завершения инициализации    Sleep(2000);     TerminateProcess(hProcess, NO_ERROR);    CloseHandle(hThread); // закрываем дескриптор процесса    CloseHandle(hProcess); // закрываем дескриптор потока...

Рамиль Мурзин

Источник www.delphi.hostmos.ru

Категории

Статьи

Советы

Copyright © 2024 - All Rights Reserved - www.delphirus.com