VR
Virtual Reality On-line   Delphi
Новости   |     Журнал    |    Хаkер   |     Магазин   |   Проекты
[   Вход    ]
[Kарта сайтa]
[ Download  ]
[  Конкурс  ]
[  Анекдоты ]
[  Ссылки   ]
[  Реклама  ]
[ Почтальон ]
[ О проекте ]






TopList
Язык программирования Delphi.
Очень полезный примерчик
:
Logo

Сегодня я решил собрать несколько пришедших мне вопросов под одной прогой. Для её реализации я написал очень полезный примерчик. В нём есть работа с реестром, запуск внешних прог, создание ссылок на свой сайт, элегантная перезагрузка компьютера. И всё это очень интересно запаковано.

В качестве работы с реестром я покажу тебе как, правильно сохранять позицию и размер окна при закрытии проги. А самое главное это восстанавливать эти значения.
Logo
Рис 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 и выглядит всё это так:

procedure TForm1.LoadProgParam;
var
 FIniFile: TRegIniFile;
begin
 FIniFile := TRegIniFile.Create('Software');
 FIniFile.OpenKey('VR',true);
 FIniFile.OpenKey('VR-Online',true);
 Width:=FIniFile.ReadInteger('Option', 'Width', 600);
 Height:=FIniFile.ReadInteger('Option', 'Heigth', 400);
 Left:=FIniFile.ReadInteger('Option', 'Left', 10);
 Top:=FIniFile.ReadInteger('Option', 'Top', 10);
 WindowState:=TWindowState(FIniFile.ReadInteger('Option', 'WinState', 2));
 FIniFile.Free;
end;

Здесь просто идёт последовательное считывание всех сохранённых параметров.

Теперь взглянём на мою функцию 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;

Я не буду расписывать, что здесь происходит, потому что ничего интересного нет. Если ты не смог с чем-то разобраться, то просто используй этот код.

На сегодня всё!!!

 Исходники примера забирай здесь


Copyright©: Horrific aka Флёнов Михаил
Design by FMk group©