TMS 패키지에 TAdvSmoothSplashScreen이라는 컴포넌트가 있습니다.
그리고 TGDIPPictureContainer에는 사용할 이미지를 넣어두고 TAdvSmoothSplashScreen에 PictureContainer를 설정하시면 됩니다.
아래는 제가 사용했던 소스입니다.
저도 한 지가 오래라 다시 보니 좀 헷갈리긴 하지만 어느 정도 이해하실 거라 생각되네요.
Fade In과 Out은 자동으로 해주고 TSplashListItem의 html 값만 바꿔 주면 됩니다.
SetupSplashItem Procedure에서 기본 위치 값을 설정했습니다.
TMS 버전은 5.2입니다.
소스는 환경이 맞지 않아 컴파일 되지 않을 것 같아 실행 파일 첨부합니다.
동작하는 것 보시면 적응 가능한지 여부를 판단하실 수 있을 것 같네요.
unit ufMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, AdvSmoothSplashScreen, GDIPPictureContainer, ImgList, ExtCtrls, jpeg,
ZipMstr;
type
TForm1 = class(TForm)
AdvSmoothSplashScreen1: TAdvSmoothSplashScreen;
GDIPPictureContainer1: TGDIPPictureContainer;
Timer1: TTimer;
ZipMaster1: TZipMaster;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
procedure UpdateProgress(Progress: Double);
procedure AddSplashItem(Html: String);
procedure CopyProgramFiles(TargetDir: String);
procedure RemoveProgramFiles(Dir: String);
procedure StartSplashScreen;
public
{ Public declarations }
procedure SetupSplashItem;
procedure FinishSplashScreen;
end;
var
Form1: TForm1;
procedure LaunchFalshFile;
implementation
{$R *.dfm}
uses
StrUtils, Registry, ShellAPI, SysConst, uSetupFunctions, DateUtils, uVista;
const
RequiredDlls: Array[0..2] of String = ('snucat01.dll', 'vb6ko.dll', 'WINSKKO.DLL');
RegisteredFiles: Array[0..7] of String = (
'AudioCtl.dll', 'btn32a20.ocx',
'ctlTextBox.ocx', 'eslsmmo.ocx',
'Mswinsck.ocx', 'richtx32.ocx',
'SYSINFO.OCX', 'THREED32.OCX'
);
ProgramSetupPath = 'c:\program files\swcd';
var
ProgressStep: Double;
function MakeDirectory(Dir: String): Boolean;
var
sa: SECURITY_ATTRIBUTES;
sd: SECURITY_DESCRIPTOR;
begin
InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(@sd, TRUE, nil, FALSE);
SetSecurityDescriptorGroup(@sd, nil, FALSE );
SetSecurityDescriptorSacl(@sd, FALSE, nil, FALSE );
sa.nLength:= sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor:= @sd;
sa.bInheritHandle:= TRUE;
Result:= CreateDirectory(PChar(Dir), @sa);
end;
function ForceDirs(Dir: string): Boolean;
var
E: EInOutError;
begin
Result := True;
if Dir = '' then
begin
E := EInOutError.CreateRes(@SCannotCreateDir);
E.ErrorCode := 3;
raise E;
end;
Dir := ExcludeTrailingPathDelimiter(Dir);
if (Length(Dir) < 3) or DirectoryExists(Dir)
or (ExtractFilePath(Dir) = Dir) then Exit; // avoid 'xyz:\' problem.
Result := ForceDirs(ExtractFilePath(Dir)) and MakeDirectory(Dir);
end;
procedure TForm1.SetupSplashItem;
begin
AdvSmoothSplashScreen1.BasicProgramInfo.CopyRight := WideChar($00A9) +' 2009 by Korea Toeic Committee';
AdvSmoothSplashScreen1.BasicProgramInfo.CopyRightLocation := ilCustom;
AdvSmoothSplashScreen1.BasicProgramInfo.CopyRightPosY := 500;
AdvSmoothSplashScreen1.BasicProgramInfo.CopyRightPosX := 890;
AdvSmoothSplashScreen1.ListItemsSettings.Rect.Left := 400;
AdvSmoothSplashScreen1.ListItemsSettings.Rect.Top := 300;
AdvSmoothSplashScreen1.ListItemsSettings.Rect.Height := 50;
AdvSmoothSplashScreen1.ListItemsSettings.Rect.Width:= 800;
AdvSmoothSplashScreen1.Show;
AdvSmoothSplashScreen1.BeginUpdate;
AdvSmoothSplashScreen1.BasicProgramInfo.ProgramName.Text:= Caption;
AdvSmoothSplashScreen1.BasicProgramInfo.ProgramName.PosY := 230;
AdvSmoothSplashScreen1.BasicProgramInfo.ProgramName.PosX := 750;
AdvSmoothSplashScreen1.BasicProgramInfo.ProgramVersion.Text := 'Realeased: 2009.08';//'Version: ' + GetAppVersion;
AdvSmoothSplashScreen1.BasicProgramInfo.ProgramVersion.Location := ilCustom;
AdvSmoothSplashScreen1.BasicProgramInfo.ProgramVersion.PosY := 270;
AdvSmoothSplashScreen1.BasicProgramInfo.ProgramVersion.PosX := 1050;
AdvSmoothSplashScreen1.ProgressBar.Maximum:= 300;
AdvSmoothSplashScreen1.EndUpdate;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
SetupSplashItem;
StartSplashScreen;
end;
procedure TForm1.UpdateProgress(Progress: Double);
begin
AdvSmoothSplashScreen1.ProgressBar.Position:= AdvSmoothSplashScreen1.ProgressBar.Position + Progress;
end;
procedure LaunchFalshFile;
begin
if ProgramUninstall then
begin
//ShellExecute(0, 'OPEN', 'cmd', 'rmdir /s /q "C:\Program Files\swcd"', nil, SW_HIDE);
Exit;
end;
if Not IsProcessRunning('toeic.exe') then
begin
//if Not FindToeicSpeakingCDKey then
// MessageDlg('TOEIC Speaking 1회 정기시험 기출문제 테스트를 진행 하시려면 CD를 삽입하셔야 합니다.', mtInformation, [mbOk], 0);
//if IsWindowsVista then
// RunAsAdmin(Application.Handle, ProgramSetupPath + '\toeic.exe', ProgramSetupPath, '')
//ShellExecute(0, 'RUNAS', PChar(ProgramSetupPath + '\toeic.exe'), nil, PChar(ProgramSetupPath), SW_SHOWNORMAL)
//else
ShellExecute(0, 'OPEN', PChar(ProgramSetupPath + '\toeic.exe'), nil, PChar(ProgramSetupPath), SW_SHOWNORMAL);
end else
ShowFindWindow(FindWindow('ShockwaveFlash', nil));
end;
procedure GetFileCount(var FileCount: Integer; var DirCount: Integer; Dir: String;
const SubDir: Boolean = True; const FileExt: String = '*');
var
sr: TSearchRec;
fi: Integer;
begin
Dir:= IncludeTrailingPathDelimiter(Dir);
if SubDir then
fi:= FindFirst(Dir + FileExt, faAnyFile, sr)
else
fi:= FindFirst(Dir + FileExt, faArchive, sr);
while fi = 0 do
begin
if sr.Attr and faDirectory = faDirectory then
begin
if Not SubDir or SameText(sr.Name, '.') or SameText(sr.Name, '..') then
begin
fi:= FindNext(sr);
Continue;
end;
inc(DirCount);
if SubDir then
GetFileCount(FileCount, DirCount, Dir + sr.Name, SubDir, FileExt);
end else
inc(FileCount);
fi:= FindNext(sr);
end;
FindClose(sr);
end;
function ZipFileCompare(ZipMaster: TZipMaster; ZipFile, LocalFile: String): Boolean;
var
sr: TSearchRec;
LocalTime, LocalSize: Integer;
i: Integer;
ze: pZipDirEntry;
SrcDateTime, LocalDateTime: TDateTime;
year, month, day, hour, min, sec, msec: Word;
begin
Result:= False;
if Not FileExists(LocalFile) then
begin
Result:= True;
Exit;
end;
ze:= nil;
for i:= 0 to ZipMaster.Count -1 do
with ZipDirEntry(ZipMaster.ZipContents[i]^) do
if SameText(ZipFile, FileName) then
begin
ze:= ZipMaster.ZipContents[i];
Break;
end;
if Not Assigned(ze) then
Exit;
LocalTime:= -1;
LocalSize:= 0;
if FindFirst(LocalFile, faArchive or faHidden, sr) = 0 then
begin
LocalSize:= sr.Size;
LocalTime:= sr.Time;
end;
if LocalTime = -1 then
begin
Result:= True;
Exit;
end;
FindClose(sr);
SrcDateTime:= FileDateToDateTime(ze^.DateTime);
LocalDateTime:= FileDateToDateTime(LocalTime);
DecodeDateTime(SrcDateTime, year, month, day, hour, min, sec, msec);
SrcDateTime:= EncodeDateTime(year, month, day, hour, min, sec, 0);
DecodeDateTime(LocalDateTime, year, month, day, hour, min, sec, msec);
LocalDateTime:= EncodeDateTime(year, month, day, hour, min, sec, 0);
//분까지 비교
if ze^.DateTime = LocalTime then
Result:= ze^.UncompressedSize <> LocalSize
else
Result:= ze^.DateTime > LocalTime;
end;
procedure ZipStreamToFile(ZipMaster: TZipMaster; ZipFile, SaveFile: String; const RaiseError: Boolean = False);
var
zs: TZipStream;
begin
zs:= ZipMaster.ExtractFileToStream(ZipFile);
// if zs.Size > 0 then
try
zs.SaveToFile(SaveFile);
zs.Clear;
except
on E: Exception do
begin
zs.Clear;
if RaiseError then
Raise Exception.Create(E.Message);
end;
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if Assigned(Sender) then
TTimer(Timer1).Enabled:= False;
WriteAppVersion;
Close;
end;
procedure TForm1.AddSplashItem(Html: String);
var
SplashItem: TSplashListItem;
begin
with AdvSmoothSplashScreen1 do
begin
if ListItems.Count = 0 then
SplashItem:= ListItems.Add
else
SplashItem:= ListItems.Items[0];
with SplashItem do
begin
BeginUpdate;
HTMLText := Html;
EndUpdate;
end;
end;
Application.ProcessMessages;
//AdvSmoothSplashScreen1.Hide;
end;
procedure TForm1.CopyProgramFiles(TargetDir: String);
var
i, lc: Integer;
OnlyFileName, DestDir, TargetFile: String;
begin
TargetDir:= IncludeTrailingPathDelimiter(TargetDir);
for i:= 0 to ZipMaster1.Count -1 do
begin
with ZipDirEntry(ZipMaster1.ZipContents[i]^) do
begin
OnlyFileName:= ExtractFileName(FileName);
DestDir:= TargetDir + ExtractFilePath(FileName);
TargetFile:= DestDir + OnlyFileName;
if Not DirectoryExists(DestDir) then
begin
AddSplashItem(Format('
create directory %s ...<
', [DestDir]));
if Not ForceDirs(DestDir) then
Raise Exception.Create(Format('%s 폴더 생성 실패', [DestDir]));
end;
AddSplashItem(Format('
checking %s ...<
', [OnlyFileName]));
if FileExists(TargetFile) and SameText(ExtractFileExt(OnlyFileName), '.exe') and IsProcessRunning(OnlyFileName) then
begin
lc:= 0;
AddSplashItem(Format('
terminate process %s ...<
', [OnlyFileName]));
while IsProcessRunning(OnlyFileName) do
begin
KillTask(OnlyFileName);
Sleep(10);
Application.ProcessMessages;
inc(lc);
if lc > 1000 then
Break;
end;
end;
if Not FileExists(TargetFile) or ZipFileCompare(ZipMaster1, FileName, TargetFile) then
begin
AddSplashItem(Format('
copying %s ...<
', [OnlyFileName]));
ZipStreamToFile(ZipMaster1, FileName, TargetFile);
end;
end;
UpdateProgress(ProgressStep);
end;
if Not FileExists(TargetFile) or IsNewFile(Application.ExeName, TargetDir + ExtractFileName(Application.ExeName)) then
begin
AddSplashItem(Format('
copying %s ...<
', [ExtractFileName(Application.ExeName)]));
CopyFile(PChar(Application.ExeName), PChar(TargetDir + ExtractFileName(Application.ExeName)), False)
end;
end;
procedure TForm1.RemoveProgramFiles(Dir: String);
var
fi, lc: Integer;
FileName: String;
sr: TSearchRec;
begin
Dir:= IncludeTrailingPathDelimiter(Dir);
fi:= FindFirst(Dir + '*', faAnyFile, sr);
while fi = 0 do
begin
if sr.Attr and faDirectory = faDirectory then
begin
if SameText(sr.Name, '.') or SameText(sr.Name, '..') then
begin
fi:= FindNext(sr);
Continue;
end;
RemoveProgramFiles(Dir + sr.Name);
AddSplashItem(Format('
remove program directory %s ...<
', [sr.Name]));
DeleteDirectory(Dir + sr.Name);
end else
begin
FileName:= Dir + sr.Name;
if Not SameText(FileName, Application.ExeName) then
begin
if SameText(ExtractFileExt(sr.Name), '.exe') and IsProcessRunning(sr.Name) then
begin
AddSplashItem(Format('
terminate process %s ...<
', [sr.Name]));
lc:= 0;
while IsProcessRunning(sr.Name) do
begin
KillTask(sr.Name);
Sleep(10);
Application.ProcessMessages;
inc(lc);
if lc > 1000 then
Break;
end;
end;
AddSplashItem(Format('
deleting %s ...<
', [sr.Name]));
DeleteFile(PChar(FileName));
end;
end;
fi:= FindNext(sr);
UpdateProgress(ProgressStep);
end;
FindClose(sr);
end;
procedure TForm1.StartSplashScreen;
var
i, SetupCount, FileCount, DirCount: integer;
DestFile: String;
zs: TZipStream;
begin
FileCount:= 0;
DirCount:= 0;
if ProgramUninstall or (Not DirectLaunch and FileExists(AppDirectory + 'system files.zip')) then
begin
if FileExists(AppDirectory + 'system files.zip') then
ZipMaster1.ZipFileName:= AppDirectory + 'system files.zip';
FileCount:= (High(RequiredDlls) + High(RegisteredFiles) + 2);
ProgressStep:= 33 / FileCount;
for i:= 0 to High(RequiredDlls) do
begin
AddSplashItem('
checking system files ...<
');
//AddSplashItem(Format('
checking %s...<
', [RequiredDlls[i]]));
DestFile:= SystemPath + RequiredDlls[i];
if ProgramUninstall then
begin
if FileExists(DestFile) then
begin
AddSplashItem(Format('
deleting %s ...<
', [RequiredDlls[i]]));
DeleteFile(PChar(DestFile));
end;
end else if Not ProgramInstalled then
begin
AddSplashItem(Format('
checking %s ...<
', [RequiredDlls[i]]));
if Not FileExists(DestFile) or ZipFileCompare(ZipMaster1, RequiredDlls[i], DestFile) then
begin
AddSplashItem(Format('
copying %s ...<
', [RequiredDlls[i]]));
ZipStreamToFile(ZipMaster1, RequiredDlls[i], DestFile);
end;
end;
UpdateProgress(ProgressStep);
end;
for i:= 0 to High(RegisteredFiles) do
begin
DestFile:= SystemPath + RegisteredFiles[i];
AddSplashItem('
checking registered files ...<
');
if ProgramUninstall then
begin
if CheckRegisteredFile(DestFile) then
begin
AddSplashItem(Format('
unregistering %s ...<
', [RegisteredFiles[i]]));
RegisterOCX(RegisteredFiles[i], ProgramUninstall);
end;
AddSplashItem(Format('
deleting %s ...<
', [RegisteredFiles[i]]));
DeleteFile(PChar(DestFile));
end else if Not ProgramInstalled then
begin
if Not FileExists(DestFile) or ZipFileCompare(ZipMaster1, RegisteredFiles[i], DestFile) then
begin
AddSplashItem(Format('
copying %s ...<
', [RegisteredFiles[i]]));
ZipStreamToFile(ZipMaster1, RegisteredFiles[i], DestFile);
end;
if Not CheckRegisteredFile(DestFile) then
begin
AddSplashItem(Format('
registering %s ...<
', [RegisteredFiles[i]]));
RegisterOCX(RegisteredFiles[i]);
end;
end;
UpdateProgress(ProgressStep);
end;
FileCount:= 0;
AdvSmoothSplashScreen1.ProgressBar.Position:= 33;
if ProgramUninstall then
begin
GetFileCount(FileCount, DirCount, ProgramSetupPath, True);
ProgressStep:= 33 / (FileCount + DirCount);
RemoveProgramFiles(ProgramSetupPath)
end else if DirectoryExists(SetupFilePath) or Not ProgramInstalled then
begin
if FileExists(AppDirectory + 'setup files.zip') then
begin
ZipMaster1.ZipFileName:= AppDirectory + 'setup files.zip';
ProgressStep:= 33 / (ZipMaster1.Count + 1);
CopyProgramFiles(ProgramSetupPath);
end;
if FileExists(AppDirectory + 'SysSetup.exe') then
begin
AddSplashItem('
Registering TOEIC Speaking CD Program group ...<
');
ExecAndWait(AppDirectory + 'SysSetup.exe', '/sp- /silent /norestart /' + ExtractFileName(Application.ExeName));
end;
UpdateProgress(ProgressStep);
end;
end;
FinishSplashScreen;
end;
procedure TForm1.FinishSplashScreen;
begin
AdvSmoothSplashScreen1.ProgressBar.Position:= 66;
ProgressStep:= 2;
if ProgramUninstall then
AddSplashItem('
TOEIC Speaking CD Program uninstall finishied ...<
')
else
AddSplashItem('
Launching TOEIC Speaking CD Program ...<
');
while AdvSmoothSplashScreen1.ProgressBar.Position <= 100 do
begin
if not ProgramUninstall then
Sleep(5);
UpdateProgress(ProgressStep);
end;
LaunchFalshFile;
Timer1.Enabled:= True;
end;
end.