Главная » Delphi » Заставка и номер версии в SlideShow

0

Используем полученные сведения, чтобы избавиться от таскаемой с собой картинки для заставки в нашем SlideShow, и заодно доделаем диалог пользовательских установок, как мы обещали в главе 9, а кроме того, покажем, как из ресурсов извлечь номер версии и другую информацию. Перенесем проект из главы 9 (Glava9\3) в новую папку (Glaval 1\2) и присвоим ему номер версии 1.31.

Сначала создадим текстовый файл zastavka.rc с единственной строкой:

Zastavka BITMAP "zastavka.bmp"

Скомпилируем его с помощью нашего ВАТ-файла и получим ресурсный файл zastavka.res. Теперь в текст модуля zastavka добавим строку ($r zastavka.res}, и изменим в единственной имеющейся у нас там процедуре прорисовки функцию загрузки картинки из файла на такую:

Form2.BmpImage.L,oadFromResourceName (hlnstance,’Zastavka’);

Обратим внимание, что после компиляции размер исполняемого файла, как и ожидалось, стал в два раза больше, зато теперь BMP-файл не нужен. Как видите, все просто, осталось только реализовать обещанные установки пользователя — демонстрировать заставку или нет, а также сворачивать ли приложение в иконку при минимизации и при закрытии. Для этого сделаем следующее — введем в панель установок три компонента checkBox с соответствующими заголовками И установленным В True СВОЙСТВОМ Checked (рис. 11.1).

Рис. 11.1. Панель пользовательских установок SiideShow

В тексте основной программы (SlideShow.dpr) добавим в предложении uses модули SysUtils и IniFiles, и в секцию var переменную iniFile:TiniFile;, а конец его (после определения повторного запуска) изменим так:

XniFile:=TIniFile.Create(ChangeFileExt(ParamStr(0), ‘.ini’)); {если не было – создаем, иначе открываем} with IniFile do begin

if SectionExists(‘Sets’) then

{если файл и секция в нем уже есть)

begin

if ReadBoolCSets’,’Zastavka’,True) then begin

Form2:=TForm2.Create(Application); {создаем форму-заставку)

Form2.Show; {показываем заставку)

while Form2.Timer1.Enabled do Application.ProcessMessages;

Iпустой цикл, пока таймер активен)

Form2.Free; (уничтожаем заставку) end;

and else (если секция еще не создана) begin

WriteBool(‘Sets’,’Zastavka’,True);

WriteBool{‘Sets’,’CloseWithTray’,True);

WriteBool(‘Sets’,’MinimizeWithTray’,True);

Form2:=TForm2.Create(Application); (создаем форму-заставку)

Form2.Show; (показываем заставку)

while Form2.Timer1.Enabled do Application.ProcessMessages; (пустой цикл, пока таймер активен)

Form2.Free; (уничтожаем заставку) end;

Destroy;

end;

(создаем главную формуI Application.CreateForm(TForml, Forml) ; Application.CreateForm(TForm3, Form3); Application.Run; (запускаем приложение)

Секцию установок в lNl-файле мы создали, теперь осталось реализовать обращение к ней в основном модуле. Допишем в процедуру по событию onCreate формы Forml внутри директивы with IniFile do… перед процедурой destroy такие строки:

if SectionExists(‘Sets’) then {если файл и секция в нем уже есть! begin

CheckBoxl.Checked:=ReadBool(‘Sets’, ‘Zastavka’,True); CheckBox2.Checked:=ReadBool(‘Sets’,’CloseWithTray’,True); mayClose:= not CheckBox2.Checked; /в Tray при закрытии} CheckBox3.Checked:=ReadBool(‘Sets’,’MinimizeWithTray’,True); {в Tray при минимизации) end;

А в процедуру Button2ciick добавляем обратные действия (также перед строкой IniFile. Destroy):

IniFile.WriteBool(‘Sets’,’Zastavka’,CheckBoxl.Checked); {демонстрация заставки)

IniFile.WriteBool(‘Sets’,’CloseWithTray’,CheckBox2.Checked); mayClose:= not CheckBox2.Checked; (в Tray при закрытии) IniFile.WriteBool(‘Sets’,’MinimizeWithTray’,CheckBox3.Checked); (в Tray при минимизации}

Для того чтобы реализовать отмену и разрешение сворачивания в иконку при минимизации независимо от закрытия (сейчас у нас при минимизации вызывается метод close формы), мам придется переписать процедуру минимизации, с тем, чтобы в ней также создавать иконку и скрывать форму:

procedure TForml.OnMinimizeProc(Sender: TObject); begin

If CheckBox3.Checked then begin

FHandle := AllocateHWnd(WndProc); (получаем дескриптор окна) Hlconl:=CopyIcon(Application.Icon.Handle);

(получаем дескриптор иконки} with noIconData do begin

cbSize:=Sizeof(TNotifylconData); (размер структуры}

Wnd:=FHandle; (дескриптор окна)

uID:=0; (единственная иконка)

UFlags:=NIF_MESSAGE or NIF_ICON or NIF_TIP;

{взводим все флаги) SzTip:=’SlideShow'; (всплывающая подсказка} HIcon:=HIconl; (дескриптор иконки) uCallBackMessage:-Ico_Message; (определяемое пользователем сообщение) end;

Shell_NotifyIcon(NIM_ADD,@noIconData); (создали иконку} Formi.Hide; (скрыли окно) end;

end;

Кроме этого, придется изменить установки флага mayciose. В процедурах WndProc И PopupRestorelClick вместо mayClose: =False; Следует записать ту же самую строку:

mayClose:= not CheckBox2.Checked;

А в процедуру Popupcioseiciick надо добавить вначале строку mayciose: =True;. Теперь у нас процедуры закрытия и минимизации будут работать независимо друг от друга. Отметим, что флажок Демонстрировать заставку сейчас модно располагать на самой заставке, и я думаю, что вынести его туда читатель сможет при желании самостоятельно.

Осталось показать, как можно прочесть из ресурсов номер версии и вывести его в заголовок формы автоматически. Надо сказать, что если в Windows API и есть более запутанные вещи, то их немного. Чтобы прочитать все поля записи типа rt version, следует обратиться к структуре vs_version_ info. Ho так просто это сделать не получится, надо сначала выявить список языков, а уж затем выцарапывать номер версии в текстовом виде для самого первого в списке языка. Дело, видимо, в том, что в соответствующем поле структуры содержится полный номер версии (включая номера реализации (Release) и сборки (Build), которые мы не заполняем, см. закладку Version Info в Project | Options), и справедливо предполагается, что они могут быть разными для различных языков. Отсюда и вся "навороченность" — несомненно те, кто все это придумал, были типичными представителями высшей касты "настоящих программистов".

Так что комментировать эту совершенно неоправданно усложненную процедуру я не буду — если кому-то надо разобраться подробнее, милости просим в Интернет. Дополним начало процедуры TForml. FormCreate следующим текстом:

procedure TForml.FormCreate(Sender: TObject); var x:integer;

versize: integer; verh-.dword;

verbuffer,versionNum,P: PChar; FLangCharSet,stver:string; begin

(определение номера версии и загрузка в заголовок.-*^I

versize:-GetFileVersionInfoSize(PChar(Application.ExeName),verh);

verbuffer := StrAlloc(versize+1);

try

GetFi.leVersionInfo(PChar( Appl ice t ion. ExeN ame),

0, versize, verbuffer); VerQueryValue(verbuffer,’\VarFileInfo\Translation’,

pointer(P),verh);

x: =0 ;

StrLCopy(@x, P, 2); FLangCharSet:=IntToHex(x, A); StrLCopy(@x,P+2,2);

FLangCharSet:=FLangCharSet+IntToHex(x, 4); (строка ‘041904E3’=10491251 – язык + комовая страница}

VerQueryValue(verbuffer, pchar(‘\StringFileInfo\’+FLangCharSet+ ‘FileVersion’), pointer(versionNum), verh); (получили полный номер версии}

stver:=copy(versionNum,1,4); (получаем сокращенный номер версии/ Forml.Caption:=’SlideShow ‘+stver; (выводим в заголовок) finally StrDispose(verbuffer); end;

end;

Источник: Ревнч Ю. В.  Нестандартные приемы программирования на Delphi. — СПб.: БХВ-Петербург, 2005. — 560 е.: ил.

По теме:

  • Комментарии