2012-04-12 15 views
6

Przygotowałem prosty skrypt wyświetlający obraz pod numerem ProgressGauge na stronie wpInstalling.Ustawienia Inno - wyświetlanie wielu obrazów (pokaz slajdów) na wpInstworzenie strony pod paskiem paska postępu

Ale ... potrzebuję bardziej złożonej funkcjonalności.

Potrzebuję wielu obrazów, każdy po X (np. 7) sekund (z pętlą, gdy instalacja trwa dłużej niż Xs * liczba obrazów) lub po X (na przykład 10) procent instalacji. Próbowałem osadzić obrazy wyświetlane w ProgressGauge.Position, ale mi się nie udało.

Oto co mam:

procedure CurPageChanged(CurPageID: Integer); 
var 
    BmpFile: TBitmapImage; 
begin 
    ExtractTemporaryFile('01.bmp'); 
    ExtractTemporaryFile('02.bmp'); 
    ExtractTemporaryFile('03.bmp'); 

    if CurPageID = wpInstalling then 
    begin 
    BmpFile:= TBitmapImage.Create(WizardForm); 
    BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}\01.bmp')); 
    BmpFile.Width:= ScaleX(420); 
    BmpFile.Height:= ScaleY(180); 
    BmpFile.Left := WizardForm.ProgressGauge.Left + ScaleX(0); 
    BmpFile.Top := WizardForm.ProgressGauge.Top + ScaleY(35); 

    // BmpFile.Parent:= WizardForm.InstallingPage; 
    // BmpFile:= TBitmapImage.Create(WizardForm); 
    // BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}\03.bmp')); 
    // BmpFile.Width:= ScaleX(420); 
    // BmpFile.Height:= ScaleY(400); 
    // BmpFile.Left := WizardForm.ProgressGauge.Left + ScaleX(0); 
    // BmpFile.Top := WizardForm.ProgressGauge.Top + ScaleY(35); 
    // BmpFile.Parent:= WizardForm.InstallingPage; 

    // BmpFile:= TBitmapImage.Create(WizardForm); 
    // BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}\03.bmp')); 
    // BmpFile.Width:= ScaleX(420); 
    // BmpFile.Height:= ScaleY(400); 
    // BmpFile.Left := WizardForm.ProgressGauge.Left + ScaleX(0); 
    // BmpFile.Top := WizardForm.ProgressGauge.Top + ScaleY(35); 
    // BmpFile.Parent:= WizardForm.InstallingPage; 
    end; 
end; 

Celem jest:
Na wpInstalling nie powinno być wyświetlane obrazy X, każda następna za X sekund lub po X procent instalacji.

Odpowiedz

7

Ponieważ ProgressGauge nie ma żadnych zdarzeń zmiany przebiegu i nie ma sposobu na przetworzenie komunikatów aplikacji instalacyjnej, konieczne będzie użycie timera interfejsu Windows API. Ten timer potrzebuje funkcji wywołania zwrotnego, której nie możesz zdefiniować w skryptach Inno Setup, więc będziesz potrzebował zewnętrznej biblioteki do wykonania tej pracy. Istnieje jednak biblioteka InnoCallback, która może zrobić dokładnie to.

Na poniższym kodzie skopiować bibliotekę InnoCallback.dll do katalogu instalacyjnego, łączenia tego kodu ze skryptu Inno Setup i realizować jakąś obracania widoku pokazu slajdów w przypadku OnSlideTimer które będą okresowo nazwie (przy aktualnych ustawieniach każdej sekundy).

[Files] 
Source: "InnoCallback.dll"; DestDir: "{tmp}"; Flags: dontcopy 

[code] 
var 
    TimerID: Integer; 

type 
    TTimerProc = procedure(Wnd: HWND; Msg: UINT; TimerID: UINT_PTR; 
    SysTime: DWORD); 

function WrapTimerProc(Callback: TTimerProc; ParamCount: Integer): LongWord; 
    external '[email protected]:InnoCallback.dll stdcall';  
function SetTimer(hWnd: HWND; nIDEvent, uElapse: UINT; 
    lpTimerFunc: UINT): UINT; external '[email protected] stdcall'; 
function KillTimer(hWnd: HWND; uIDEvent: UINT): BOOL; 
    external '[email protected] stdcall'; 

procedure OnSlideTimer(Wnd: HWND; Msg: UINT; TimerID: UINT_PTR; 
    SysTime: DWORD); 
begin 
    { here you can turn your slideshow pages; use some variable to store the } 
    { current index of the slide you are on, note that this procedure is called } 
    { periodically each 1000 ms (see below why), so here you can also check the } 
    { progress value, if you want to } 
end; 

procedure StartSlideTimer; 
var 
    TimerCallback: LongWord; 
begin 
    TimerCallback := WrapTimerProc(@OnSlideTimer, 4); 
    { third parameter here is the timer's timeout value in milliseconds } 
    TimerID := SetTimer(0, 0, 1000, TimerCallback); 
end; 

procedure KillSlideTimer; 
begin 
    if TimerID <> 0 then 
    begin 
    if KillTimer(0, TimerID) then 
     TimerID := 0; 
    end; 
end; 

function InitializeSetup: Boolean; 
begin 
    Result := True; 
    TimerID := 0; 
end; 

procedure DeinitializeSetup; 
begin 
    KillSlideTimer; 
end; 

procedure CurPageChanged(CurPageID: Integer); 
begin 
    if CurPageID = wpInstalling then 
    StartSlideTimer 
    else 
    KillSlideTimer; 
end; 
+0

To rozwiązało mój problem! Dodałem globalny Indeks Var: Integer; i nieznacznie zmodyfikowany kod dla obrazów (IntToStr) – RobeN

+1

Tak, możesz mieć licznik czasu lub dostęp do wskaźnika postępu, jeśli potrzebujesz. Dlatego pokazałem tylko, jak wdrożyć zdarzenie licznika czasu dla ciebie ;-) Ale może powinieneś również sprawdzić stan wskaźnika postępu, ponieważ nie będzie tak dobrze, jeśli wystąpi błąd i nadal będzie obracać pokaz slajdów. Myślę, że powinieneś przesuwać swoje obrazy tylko wtedy, gdy 'WizardForm.ProgressGauge.State = npbsNormal', ale to także na ciebie. Zobacz ['here'] (http://www.jrsoftware.org/ishelp/topic_scriptclasses.htm#TNewProgressBarState) dla dostępnych stanów postępu. – TLama

+1

Zrobiłem. Specjalna funkcja dla 'Paused', dla' Error' oraz dla 'Position = Max' (podczas instalowania aplikacji innych producentów). Dzięki za pomoc i wsparcie! – RobeN

2

Dlaczego nie stosować AfterInstall do każdej pozycji pliku, aby zmienić obraz?

+0

To nie jest to, czego potrzebuję. Rozwiązanie TLamy jest zdecydowanie lepsze (przynajmniej dla mnie). – RobeN

+0

Dobrze będzie zobaczyć przykład Twojej pracy ... nadal mam problem z prawidłowym działaniem tego skryptu. – Dielo

Powiązane problemy