Для запуска приложения порой достаточно одного клика. Но иногда время запуска оказывается больше ожидаемых одной-двух секунд, и тогда у пользователя может возникнуть ощущение, что программа зависла и что-то пошло не так. Избежать этого можно, если сократить время до появления первого окна, которое называют заставкой (англ. splash screen).

Для этого все действия по подготовке программы к работе выполняются после отображения заставки. А сама заставка становится границей, отделяющей серые будни пользователя Windows от фантастического мира вашего приложения.

Визуальная часть

Заставка – это визитная карточка приложения. Единых правил по её оформлению нет и быть не может. И если при проектировании дизайна основного приложения необходимо придерживаться определенных правил и соглашений, то при отображении заставки можно себя не сдерживать и позволить себе проявление своих творческих дарований в полной мере: используйте яркие палитры или черно-белые скетчи, добавьте анимацию или сделайте заставку полупрозрачной, откажитесь от прямоугольной формы. Но, если вы привыкли к сдержанности и экономному использованию ресурсов, я могу предложить решение, которое для своей реализации использует скрипты и файл изображения.

В качестве фонового изображения используется картинка, которая находится в папке Images\Logo, поверх фона отображается название приложения. Название имеет черную тень, которая улучшает читабельность текста. В нижнем левом углу выводится номер версии программы. Так как время инициализации приложения зависит от производительности компьютера, то желательно отображать заставку в течение указанного в настройке времени, но не более чем.

Скрипты

Для создания формы-заставки используется функция Splash_Create(). Она возвращает созданную форму в качестве результата. Параметры создания вынесены в константы.

const SPLASH_LOGO_WIDTH = 350; // Ширина изображения SPLASH_LOGO_HEIGHT = 169; // Высота изображения SPLASH_BORDER = 2; // толщина рамки вокруг изображения SPLASH_BORDER_COLOR = clBlack; // цвет рамки SPLASH_FILE_NAME = 'Images\Logo\logo_350x169.jpg'; // файл фонового изображения SPLASH_FONT_SIZE = 28; // размер шрифта для названия SPLASH_FONT_COLOR = clWhite; // цвет для названия SPLASH_SHADOW_COLOR = clBlack; // цвет тени SPLASH_VER_FONT_SIZE = 11; // размер шрифта для версии SPLASH_VER_FONT_COLOR = clWhite; // цвет шрифта для версии function Splash_Create:TForm; var tmpImage:TImage; tmpLabel:TLabel; tmpImageFileName:string; begin Result := TForm.Create(Application); with Result do begin Width := SPLASH_LOGO_WIDTH + SPLASH_BORDER*2; Height := SPLASH_LOGO_HEIGHT + SPLASH_BORDER*2; BorderStyle := bsNone; Position := poScreenCenter; Color := SPLASH_BORDER_COLOR; StyleElements := 0; end; // добавить картинку tmpImage := TImage.Create(Result); with tmpImage do begin Parent := Result; Width := SPLASH_LOGO_WIDTH; Height := SPLASH_LOGO_HEIGHT; Top := SPLASH_BORDER; Left := SPLASH_BORDER; tmpImageFileName := ExtractFilePath(Application.ExeName)+SPLASH_FILE_NAME; if not FileExists(tmpImageFileName) then RaiseException('Splash_Create() Не найден файл '+tmpImageFileName) else Picture.LoadFromFile(tmpImageFileName); end; // добавить название tmpLabel := TLabel.Create(Result); with tmpLabel do begin Name := 'AppName'; Parent := Result; Top := 0; Left := 0; Autosize := False; Width := Result.ClientWidth; Height := Result.ClientHeight; Alignment := taCenter; Layout := tlCenter; WordWrap := True; StyleElements := 0; Caption := APP_NAME; Font.Size := SPLASH_FONT_SIZE; Font.Color := SPLASH_FONT_COLOR end; Label_AddShadow( tmpLabel, SPLASH_SHADOW_COLOR ); // добавить тень // добавить номер версии tmpLabel := TLabel.Create(Result); with tmpLabel do begin Name := 'AppVer'; Parent := Result; Caption := APP_VERSION; StyleElements := 0; Font.Size := SPLASH_VER_FONT_SIZE; Font.Color := SPLASH_VER_FONT_COLOR; Left := Height div 2; Top := Result.ClientHeight - Height - (Height div 2); end; Label_AddShadow( tmpLabel, SPLASH_SHADOW_COLOR, 1 ); // добавить тень end;
Code language: Delphi (delphi)

Давайте посмотрим на него внимательно. В шестьдесят третьей строке вызывается процедура Label_AddShadow(), которая добавляет тень для указанного текста.

Тень – это точная копия компонента-метки, обычно имеющая черный цвет текста (любо заданный цвет, темнее основного). Она располагается с небольшим смещением позади заданной метки. По непонятным причинам в MVDB метод Assign() для компонента TLabel не поддерживается, поэтому для получения копии пришлось писать кучу кода:

procedure Label_AddShadow( ALabel:TdbLabel; AColor:TColor = 0; ); var tmpLabel:TdbLabel; begin tmpLabel := TdbLabel.Create( ALabel.Owner ); // tmpLabel.Assign( ALabel ); // К сожалению, в MVDB данный метод не работает :(, поэтому прийдется скопировать все свойства вручную.... // все, что ниже, можно заменить одной командой Assign, но в MVD она не работает... tmpLabel.Parent := ALabel.Parent; tmpLabel.Name := ALabel.Name + SX_SHADOW; tmpLabel.Caption := ALabel.Caption; tmpLabel.AutoSize := ALabel.AutoSize; tmpLabel.Width := ALabel.Width; tmpLabel.Height := ALabel.Height; tmpLabel.Anchors := ALabel.Anchors; tmpLabel.Font := ALabel.Font; tmpLabel.StyleElements := ALabel.StyleElements; tmpLabel.Alignment := ALabel.Alignment; tmpLabel.Layout := ALabel.Layout; tmpLabel.WordWrap := ALabel.WordWrap; // задать смещение тени tmpLabel.Top := ALabel.Top + LABEL_SHADOW_SHIFT; tmpLabel.Left := ALabel.Left + LABEL_SHADOW_SHIFT; // задать цвет тени tmpLabel.Font.Color := AColor; ALabel.BringToFront; // поместить главную надпись перед тенью end;
Code language: Delphi (delphi)

Инициализация и запуск

Перед тем, как главная форма приложения frmMain (её название на закладке визуального конструктора отмечается красным цветом) отобразится, происходит событие OnShow, которое мы будем использовать для создания и отображения заставки, а также выполнения действий по инициализации приложения.

procedure frmMain_OnShow (Sender: TObject; Action: string); // отображение главной формы begin // отобразить в заголовке главной формы название и версию программы frmMain.Caption := APP_NAME + ' '+APP_VERSION; App_Splash_Start; frmMain.pgcMain.ActivePage := frmMain.tshNavigation; // открыть вкладку "Навигация" frmMain.pgcNavigation.ActivePage := frmMain.tshTask; // открыть вкладку "Задачи" end;
Code language: Delphi (delphi)

Для инициализации приложения с отображением заставки вызывается процедура App_Splash_Start(), в которой создается и отображается форма – заставка, а затем вызывается процедура инициализации приложения App_Start(). После её завершения производится замер затраченного на инициализацию время и, если оно не превышает заданного, то добавляется задержка ровно на столько, чтобы суммарное время отображения заставки соответствовало заданному в константе APP_SPLASH_DELAY_MIN. После чего заставка уничтожается, затем отображается основная форма frmMain.

procedure App_Splash_Start; // инициализация с заставкой var tmpForm:TForm; tmpStartTime: TTime; tmpSleepTime: integer; begin tmpForm := Splash_Create; tmpForm.Show; Application.ProcessMessages; tmpStartTime := Time(); App_Start; // гарантированная задержка, но не более указанной в APP_SPLASH_DELAY tmpSleepTime := APP_SPLASH_DELAY_MIN - Trunc( (Time() - tmpStartTime)*24*60*60*1000 ); if tmpSleepTime > 0 then Sleep(tmpSleepTime); tmpForm.Close; tmpForm.Free; end;
Code language: Delphi (delphi)

В App_Start() происходит инициализация подсистем приложения: управление картинками кнопок, стилями, горячими клавишами и т.д..

procedure App_Start; // запуск приложения begin // тут должна быть всяческая инициализация, которая может занять продолжительное время App_InitSystemVar; // инициализация системных переменных Images_Init; // инициализация подcистемы загрузки картинок Style_Init; // активация стиля Style_CreateMenu(frmMain); // добавить стили в меню UserApp_InitForm; // создать формы UserApp_InitVar; // настроить переменные // инициализация, которая идет после настройки переменных CE_Init(MainForm); // главное меню находится на главной форме, но отображается там, где нужно Hotkey_Init(MainForm); // подключить горячие клавиши UserApp_InitBase; // инициализация базы данных end;
Code language: Delphi (delphi)

Таким образом, в базовом комплекте будут две процедуры инициализации: с отображением заставки и без её отображения. Это позволит гибко подходить к выбору оптимального решения. Для лёгких приложений можно вызывать App_Start(), а если инициализация долгая, то лучше использовать App_Splash_Start();

Если вы хотите использовать статическую заставку, созданную в визуальном конструкторе My Visual Database, то откорректируйте App_Splash_Start(), вызывая в ней вашу статическую форму frmSplash:

procedure App_Splash_Start; // инициализация с заставкой var tmpStartTime: TTime; tmpSleepTime: integer; begin frmSplash.Show; Application.ProcessMessages; tmpStartTime := Time(); App_Start; // гарантированная задержка, но не более указанной в APP_SPLASH_DELAY tmpSleepTime := APP_SPLASH_DELAY_MIN - Trunc( (Time() - tmpStartTime)*24*60*60*1000 ); if tmpSleepTime > 0 then Sleep(tmpSleepTime); frmSplash.Hide; end;
Code language: Delphi (delphi)

Дополнительные улучшения

Заодно можно улучшить внешний вид формы “О программе”, заменив стандартную картинку на свою собственную. Для этого в процедуру App_InitAboutForm() добавим несколько строчек:

FindC(frmdbCoreAbout,'Image1',tmpImage); tmpImageFileName := ExtractFilePath(Application.ExeName)+ABOUT_LOGO_FILE_NAME; if not FileExists(tmpImageFileName) then RaiseException('Splash_Create() Не найден файл '+tmpImageFileName) else tmpImage.Picture.LoadFromFile(tmpImageFileName)
Code language: Delphi (delphi)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *