Наталия Елманова
Компьютер Пресс - CD, 1999, N 2
Copyright © N.Elmanova & ComputerPress Magazine.
Этой статьей мы начинаем серию небольших советов для пользователей Delphi и С++Builder, позволяющих решить некоторые проблемы, возникающие при создании приложений и, возможно, улучшить их интерфейс или функциональность.
Нередко при запуске Windows-приложений перед работой приложения появляется заставка (в англоязычной литературе она называется Splash screen), содержащая информацию о запускаемом приложении и, возможно, иные сведения (серийный номер продукта, версию и пр.). Каким образом можно создать такую заставку?
Добавим к нашему приложению форму, свойство BorderStyle ее установим равным bsNone, поместим на нее метку и компонент TTimer. Свойство Interval компонента TTimer установим равным 1000, умноженное на число секунд, в течение которых заставка должна находиться на экране (значение 3000 соответствует 3 секундам).
Рис. 1. Форма, которая должна появиться в качестве заставки
Создадим обработчик события OnTimer компонента TTimer: В случае Delphi он выглядит так:
procedure TForm3.Timer1Timer(Sender: TObject); begin Close; end;
В случае С++Builder он имеет следующий вид:
void __fastcall TForm3::Timer1Timer(TObject *Sender) { Close(); }
В опциях проекта перенесем вновь созданную форму в раздел Available Forms.
Теперь создадим обработчик события OnCreate главной формы приложения, который в случае Delphi выглядит так:
procedure TForm1.FormCreate(Sender: TObject); begin Form3:=TForm3.Create(Application); Form3.ShowModal; Form3.Free; end;
В случае C++Builder этот же обработчик события выглядит так:
void __fastcall TForm1::FormCreate(TObject *Sender) { Form3= new TForm3(this); Form3->ShowModal(); Form3->Free(); }
Теперь перед запуском приложения на экране будет появляться заставка следующего вида:
Рис. 2. Заставка на этапе выполнения
Если запустить какое-либо из приложений MS Office 97, на появляющейся при загрузке приложения заставке можно увидеть не только сведения о самом приложении, но также и регистрационный номер и фамилию пользователя. Как известно, эти сведения вводятся пользователем в процессе установки приложения, и в настоящее время принято хранить подобные сведения в реестре Windows. Если создать дистрибутив приложения с помощью наиболее часто используемого в нашей стране для этой цели средства InstallShield (или с помощью InstallShield Express, входящего в состав старших версий Delphi и C++Builder), в реестре Windows появится раздел, похожий на представленный на рис.3:
Рис. 3. Раздел реестра, создаваемый программой установки
В данном случае приложение MyApp версии 1.0 создано компанией Splash Screen Company, и при его установке были введены серийный номер 176-99027, а также имя пользователя и имя компании, в которой данный пользователь работает.
Если инсталляционное приложение создано не с помощью InstallShield, а с помощью иных средств (например, написано на Delphi или C++Builder), наименование раздела и ключей реестра могут отличаться от приведенных выше, но в любом случае они должны быть Вам известны.
Модифицируем нашу заставку так, чтобы на ней отображались содержащиеся в реестре имя пользователя и серийный номер. С этой целью добавим на созданную ранее форму две метки.
Рис. 4. Форма заставки после внесения изменений
Создадим обработчик события, связанный с созданием формы. В случае Delphi он имеет следующий вид:
procedure TForm2.FormCreate(Sender: TObject); var key,ser,usr:string; Reg:TRegistry; begin try Reg:=TRegistry.Create; key:='SOFTWARE\Splash Screen Company\MyApp\1.0'; Reg.Rootkey:= HKEY_LOCAL_MACHINE; Reg.OpenKey(key,false); usr:=Reg.ReadString('Name'); ser:=Reg.ReadString('Serial'); Label2.Caption:='Пользователь: '+usr; Label3.Caption:='Серийный номер: '+ser; Reg.CloseKey; Reg.Destroy; except Label2.Caption:='Unregistered user'; Label3.Caption:='Please register'; end; end;
При этом в секции uses модуля, связанного с формой, следует сослаться на модуль registry.
Для С++Builder обработчик этого события выглядит так:
void __fastcall TForm1::FormCreate(TObject *Sender) {TRegistry *Reg; try { Reg=new TRegistry; Reg->RootKey=HKEY_LOCAL_MACHINE; AnsiString key="SOFTWARE\\Splash Screen Company\\MyApp\\1.0"; Reg->OpenKey(key,false); AnsiString usr=Reg->ReadString("Name"); AnsiString ser=Reg->ReadString("Serial"); Label2->Caption="Пользователь: "+usr; Label3->Caption="Серийный номер: "+ser; Reg->CloseKey(); Reg->Free(); } catch (...) { Label2->Caption="Unregistered user "; Label3->Caption="Please register "; } }
Естественно, в начале текста модуля следует вставить строку:
#include <registry.hpp>
Обратите внимание: в С++ и Pascal форматы строк, содержащих имена разделов реестра, разные.
В результате наша заставка на этапе выполнения в случае наличия в реестре соответствующего раздела приобретет следующий вид:
Рис. 5. Заставка с именем пользователя и серийным номером на этапе выполнения
Если же в реестре нет такого раздела, вместо имени пользователя и серийного номера булет выводиться сообщение о том, что пользователь не зарегистрирован.
Отметим, что при желании можно добавить в этот обработчик события код, анализирующий серийный номер и в случае, если он не удовлетворяет каким-либо заранее заданным требованиям, прекратить выполнение приложения (или запустить его демонстрационную версию).
Теперь создадим заставку, в которой будет отображаться видеофрагмент (такие заставки нередко используются разработчиками игр и мультимедиа-энциклопедий). С этой целью удалим с формы таймер (он уже не нужен, так как время существования заставки теперь определяется длительностью видеофрагмента), и уничтожим связанный с ним обработчик события OnTimer. Удалим также компонент TImage. Затем добавим компонент TPanel (он будет использоваться в качестве "экрана" для воспроизведения видеофрагмента, и компонент TMediaPlayer. Свойство Visible этого компонента установим равным false, свойство AutoOpen - раным true, а в качестве значения свойства FileName выберем имя файла, содержащего видеофрагмент.
Рис. 6. Форма заставки, воспроизводящей видеофрагмент
Изменим обработчик события, связанного с созданием формы. Теперь мы должны инициировать воспроизведение фрагмента, используя в качестве экрана компонент TPanel. При этом компонент TPanel должен располагаться равноудаленно от левого и правого краев формы и иметь размеры, соответствующие размерам кадров видеофрагмента (их можно узнать, обратившись к свойству DisplayRect компонента TMediaPlayer). В случае Delphi этот обработчик события теперь выглядит так:
procedure TForm2.FormCreate(Sender: TObject); var key,ser,usr:string; Reg:TRegistry; begin try Reg:=TRegistry.Create; key:='SOFTWARE\Splash Screen Company\MyApp\1.0'; Reg.Rootkey:= HKEY_LOCAL_MACHINE; Reg.OpenKey(key,false); usr:=Reg.ReadString('Name'); ser:=Reg.ReadString('Serial'); Label2.Caption:='Пользователь: '+usr; Label3.Caption:='Серийный номер: '+ser; Reg.CloseKey; Reg.Destroy; except Label2.Caption:='Unregistered user'; Label3.Caption:='Please register'; end; MediaPlayer1.DisplayRect:=Rect(Panel1.Left,Panel1.Top,0,0); Panel1.Width:=MediaPlayer1.DisplayRect.Right; Panel1.Height:=MediaPlayer1.Displayrect.Bottom; Panel1.Left:=Round((Form2.Width-Panel1.Width)*0.5); MediaPlayer1.Open; MediaPlayer1.Play; end;
В случае C++Builder соответствующий код имеет вид:
void __fastcall TForm2::FormCreate(TObject *Sender) {TRegistry *Reg; {TRegistry *Reg; try { Reg=new TRegistry; Reg->RootKey=HKEY_LOCAL_MACHINE; AnsiString key="SOFTWARE\\Splash Screen Company\\MyApp\\1.0"; Reg->OpenKey(key,false); AnsiString usr=Reg->ReadString("Name"); AnsiString ser=Reg->ReadString("Serial"); Label2->Caption="Пользователь: "+usr; Label3->Caption="Серийный номер: "+ser; Reg->CloseKey(); Reg->Free(); } catch (...) { Label2->Caption="Unregistered user "; Label3->Caption="Please register "; } MediaPlayer1->DisplayRect=Rect(Panel1->Left,Panel1->Top,0,0); Panel1->Width=MediaPlayer1->DisplayRect.Right; Panel1->Height=MediaPlayer1->DisplayRect.Bottom; Panel1->Left=INT((Form2->Width-Panel1->Width)*0.5); MediaPlayer1->Open(); MediaPlayer1->Play(); }
Обратите внимание: при вычислении координат левого верхнего угла компонента TPanel в приведенных выше обработчиках событий используются функции округления действительных чисел, которые имеют разные названия для Pascal и C++.
Так как мы ликвидировали обработчик события, связанный с компонентом TTimer, наша форма теперь не закроется автоматически. Очевидно, что закрытие формы в данном случае должно быть связано с моментом окончания воспроизведения видеофрагмента. С этой целью воспользуемся событием OnNotify компонента TMediaPlayer, в котором проанализируем его свойство Mode - в момент окончания воспроизведения оно изменится. Соответствующий код для Delphi имеет вид:
procedure TForm2.MediaPlayer1Notify(Sender: TObject); begin Mediaplayer1.Notify := True; if Mediaplayer1.Mode=mpStopped then Form2.Close; end;
Код для C++Builder имеет при этом следующий вид:
void __fastcall TForm1::MediaPlayer1Notify(TObject *Sender) { MediaPlayer1->Notify= true; if (MediaPlayer1->Mode==mpStopped) { Form2->Close(); } }
На этапе выполнения мы получим заставку примерно следующего вида:
Рис. 7. Заставка, воспроизводящая видеофрагмент
И, наконец, создадим заставку, воспроизводящую видеофагмент на всем экране. В этом случае надписи на форме и данные из реестра уже не нужны, но при этом нужно растянуть на весь экран и форму, и компонент TPanel. Поэтому обработчик события, связанного с созданием формы, несколько упрощается. В случае Delphi он теперь имеет вид:
procedure TForm2.FormCreate(Sender: TObject); begin Form2.Left:=0; Form2.Top:=0; Form2.Width:=Screen.Width; Form2.Height:=Screen.Height; Panel1.Align:=alClient; Mediaplayer1.Open; MediaPlayer1.DisplayRect:=Rect(0,0,Screen.Width,Screen.Height); MediaPlayer1.Play; end;
Соответственно в случае C++Builder он имеет вид:
void __fastcall TForm2::FormCreate(TObject *Sender) { Form1->Left=0; Form1->Top=0; Form1->Width=Screen->Width; Form1->Height=Screen->Height; Panel1->Align=alClient; MediaPlayer1->Open(); MediaPlayer1->DisplayRect=Rect(0,0,Screen->Width,Screen->Height); MediaPlayer1->Play(); }
Теперь форма, панель и сам видеофрагмент занимают весь экран, закрывая собой все окна, включая панель задач Windows. Тем не менее рекомендуется для полностью корректного воспроизведения подобного рода приложений установить свойство FormStyle данной формы равным fsStayOnTop.
Рис. 8. Заставка, воспроизводящая видеофрагмент на полном экране