Язык программирования Delphi. Очень полезный примерчик:
Сегодня я решил собрать несколько пришедших мне вопросов под одной прогой. Для её реализации я написал очень полезный примерчик. В нём есть работа с реестром, запуск внешних прог, создание ссылок на свой сайт, элегантная перезагрузка компьютера. И всё это очень интересно запаковано.
В качестве работы с реестром я покажу тебе как, правильно сохранять позицию и размер окна при закрытии проги. А самое главное это восстанавливать эти значения.
Рис 1. Форма
На рисунке 1 ты как всегда можешь увидеть пример формы. Если ты любишь создавать примеры полностью сам, то нарисуй себе такую же. Если нет, то в конце статьи есть ссылка на исходник. Вообще-то я советую тебе всё делать своими руками. В этом случае всё лучше воспринимается и запоминается. Если что-то не получается, то тогда обращайся к моему примеру.
Для начала рассмотрим, как я сохраняю и восстанавливаю позицию окна. Для сохранения я написал функцию SaveProgParam, которую вызываю по событию OnClose :
procedure TForm1.SaveProgParam;
var
FIniFile: TRegIniFile;
begin
FIniFile := TRegIniFile.Create('Software'); // Инициализирую реестр
FIniFile.OpenKey('VR',true); // Открываю раздел
FIniFile.OpenKey('VR-Online',true); // Открываю ещё один раздел
if WindowState=wsNormal then
begin
FIniFile.WriteInteger('Option', 'Width', Width);
FIniFile.WriteInteger('Option', 'Heigth', Height);
FIniFile.WriteInteger('Option', 'Left', Left);
FIniFile.WriteInteger('Option', 'Top', Top);
end;
FIniFile.WriteInteger('Option', 'WinState', Integer(WindowState));
FIniFile.Free; //Освобождаю реестр
end;
Как работать с реестром я уже рассказывал в ноябре 2000, поэтому сегодня я проскакиваю некоторые моменты. Если ты уже читал ноябрьский номер, то тебе достаточно будет моих комментариев к тексту. Если что-то не понял, то желательно перечитать.
Анекдот:
Хакер, тыча клавиатурой в своего кота: "Зухель, коннект!".
Кот:"Пшшшш..."
После инициализации реестра и подготовки разделов я делаю проверку, в каком состоянии находится окно. Если WindowState равно wsNormal, то я сохраняю параметры окна. Если нет, то этого делать не надо. Если у тебя стоит разрешение экрана 800х600, по при максимизированном окне значение ширины окна будет 802, а высоты 602. Эти значения больше реального разрешения и если ты установишь их при загрузке, то изменить размеры окна мышкой будет очень трудно.
После этого я сохраняю состояние окна - WindowState. Так как оно имеет тип ТwindowState, то мне приходится приводить этот тип к Integer с помощью Integer(WindowState).
Процедуру для чтения LoadProgParam я вызываю по событию OnShow и выглядит всё это так:
Здесь просто идёт последовательное считывание всех сохранённых параметров.
Теперь взглянём на мою функцию FormShow:
procedure TForm1.FormShow(Sender: TObject);
var
FIniFile: TRegIniFile;
Buffer:array[0..4] of char; //Объявляю массив из 4-х символов.
begin
LoadProgParam; // Загружаю параметры окна
FIniFile := TRegIniFile.Create('Software');
FIniFile.OpenKey('Microsoft',true);
FIniFile.OpenKey('Windows',true);
FIniFile.OpenKey('CurrentVersion',true);
FIniFile.OpenKey('Policies',true);
FIniFile.OpenKey('Explorer',true);
buffer[0]:=#0; //Обнуляю первый символ массива
FIniFile.ReadBinaryData('NoClose', Buffer, 4); //Читаю данные в массива.
if buffer[0]=#1 then //Проверяю первый символ. Если он = 1 то
CheckBox1.Checked:=true;
Со всем происходящим можно разобраться по комментариям. А теперь давай перейдём к процедуре, которая запускает внешнюю программу. Это делается с помощью ShellExecute. Microsoft рекомендует использовать CreateProcess, но я всё же использую эту, потому что она проще. Для упрощения твоего понимания я написал отдельную процедуру ExecuteFile:
function TForm1.ExecuteFile(const FileName, Params, DefaultDir: string;
ShowCmd: Integer): THandle;
var
zFileName, zParams, zDir: array[0..79] of Char;
begin
Result := ShellExecute(Application.MainForm.Handle, nil,
StrPCopy(zFileName, FileName), StrPCopy(zParams, Params),
StrPCopy(zDir, DefaultDir), ShowCmd);
end;
Теперь для запуска внешней проги достаточно написать ExecuteFile('c:\Имя программы.ехе','','',SW_SHOW). Первый параметр - полный путь проги. Второй - директория по умолчанию, третий - аргументы и последний - тип запуска. Тип запуска может быть:
SW_HIDE - невидимый
SW_MAXIMIZE - максимизированный
SW_MINIMIZE - минимизированный
SW_RESTORE - востановить
SW_SHOWDEFAULT - показать с параметрами по умолчанию
SW_SHOWMINNOACTIVE - максимизированным и неактивным
SW_SHOWNA - показать неактивным
Есть ещё несколько параметров, но они не имеют особого значения. Для использования функции ShellExecute нужно добавить в раздел uses модуль Shellapi .
И последнее, что есть в моём примере - это перезагрузка Windows, с помощью стандартного диалога. Прежде чем использовать функции, необходимо объявить несколько вещей:
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, FileUtil, StdCtrls, Shellapi, registry, ExtCtrls, RXSpin,
ToolEdit;
//Далее идут объявления необходимые для диалога перегрузки
type TkbRestartOption = (kbsdLogoff, kbsdShutdown, kbsdReboot,
kbsdRestartWindows, kbsdRebootSystem, kbsdExitAndExecApp);
const {Additional flags for RestartDialog}
EW_RESTARTWINDOWS = $42;
EW_REBOOTSYSTEM = $43;
EW_EXITANDEXECAPP = $44;
function RestartDialog(Owner: HWND; Reason: Pointer;
Flags: UINT): DWORD; stdcall;
function RestartOptionEnumToConst(RestartOption: TkbRestartOption): UINT;
//Далее идёт объявления TForm1
type
TForm1 = class(TForm)
….
И ещё одно объявление нужно сделать перед ключевым словом implementation . Вот этот отрывок из исходника:
….
var
Form1: TForm1;
//Далее идёт объявление функции
function RestartDialog; external 'shell32.dll' index 59;
implementation
….
Нам ещё понадобится вот такая функция:
function RestartOptionEnumToConst(RestartOption: TkbRestartOption): UINT;
begin
case (RestartOption) of
kbsdLogoff: Result := EWX_LOGOFF;
kbsdShutdown: Result := EWX_SHUTDOWN;
kbsdReboot: Result := EWX_REBOOT;
kbsdRestartWindows: Result := EW_RESTARTWINDOWS;
kbsdRebootSystem: Result := EW_REBOOTSYSTEM;
kbsdExitAndExecApp: Result := EW_EXITANDEXECAPP;
else Result := 0;
end;
end;
И наконец сама функция перегрузки:
procedure TForm1.RestartWindows;
const
Space = ' ';
var
ReasonString: AnsiString;
ReasonBuffer: Pointer;
begin
ReasonString := EmptyStr + Space;
GetMem(ReasonBuffer, (Length(ReasonString) + 1) * SizeOf(WideChar));
try
if (SysUtils.Win32Platform = VER_PLATFORM_WIN32_NT) then
StringToWideChar(ReasonString, PWideChar(ReasonBuffer),
(Length(ReasonString) + 1));
else
StrPCopy(PChar(ReasonBuffer), ReasonString);
RestartDialog(Application.Handle, PWideChar(ReasonBuffer),
RestartOptionEnumToConst(kbsdRestartWindows));
finally
FreeMem(ReasonBuffer);
end;
end;
Я не буду расписывать, что здесь происходит, потому что ничего интересного нет. Если ты не смог с чем-то разобраться, то просто используй этот код.