Уважаемые гости и пользователи форума.
Администрация настоятельно рекомендует не регистрировать несколько аккаунтов для одного пользователя. При выявлении наличия мультиаккаунтов будут заблокированы все учетные записи данного пользователя.
Аккаунты, зарегистрированные на временную почту, будут также заблокированы.
Помогите кто нибудь.
Как сделать таймер перед перезагрузкой компьютера на последней странице или в отдельном сообщении? Подробнее: это нужно для атоматической установки .NET Framework и других системных компонентов. Выглядит это примерно так: чтобы в конце установки, на странице "Завершения" или в отдельном сообщении - показало таймер, а по истечении таймера происходила автоматическая перезагрузка компьютера.
Таймер можно или на кнопке или на форме, если на форме, то кнопку скрыть. В качестве кода перезагрузки, можно просто добавить код запуска файла по истечении таймера.
А как сделать, чтобы после установки игры, инсталлятор закрывался сам по таймеру, допустим через 10 секунд и выдавал сообщение что все установлено нажмите ок?
ты такой пришел увидел. нажал ок и сел играть)
А типа ты такой пришёл, увидел финиш пэйдж и на ней всё ок, нажал на "Завершить", или как у нас "Начать игру" и сел играть) Не? К чему лишний геммор? Хотя всё это реализуемо.
Мужики, выручайте... Второй день голову ломаю. Пытаюсь сделать следующее...
То есть закрытие формы по обнулению таймера. Сначала пытался прикрутить таймер к MsgBox но, как потом выяснилось, это не возможно. Создал форму и все прочее, но выявилась проблемка. Таймер отсчитывает время с очень коротким интервалом. Варианты со сторонними библиотеками у меня есть, но хочется без них обойтись. Как решить задачу нормального отсчета?
[Setup]
AppName=Custom Form
AppVersion=1.0
DefaultDirName={pf}\Custom Form
DisableFinishedPage=yes
procedure MyOnTimer(Sender: TObject);
begin
i:=i-1; // отнимаем по одной сек.
OkButton.Caption := 'Ок' + #32 + #40+IntToStr(i)+ #99 +#41;
if i=0 then
begin
Timer1.Enabled:=false;
Form.Close;
end;
end;
function CreateTimer(): Boolean;
begin
i:=10; // отсчет начинать с 10 сек.
Timer1 := TTimer.Create(Form)
Timer1.Interval := 1000; // интервал 1 сек.
Timer1.OnTimer := @MyOnTimer;
Timer1.Enabled := true;
end;
procedure FormButtonClick(Sender: TObject);
begin
case TNewButton(Sender) of
OkButton: FormClose := True;
end;
Form.Close;
end;
function ShowCancelMessage(): Boolean;
begin
Form := CreateCustomForm();
with Form do
begin
ClientWidth := ScaleX(300);
ClientHeight := ScaleY(100);
Caption := SetupMessage(msgStatusRunProgram);
CenterInsideControl(WizardForm, False);
end;
FormLabel := TLabel.Create(Form);
with FormLabel do
begin
Parent := Form;
SetBounds(ScaleX(60), ScaleY(15), ScaleX(280), ScaleY(80));
Caption := ' Программа установлена.';
Font.Height := -12;
end;
OkButton := TNewButton.Create(Form);
with OkButton do
begin
Parent := Form;
SetBounds(ScaleX(110), ScaleY(70), ScaleX(75), ScaleY(23));
OnClick := @FormButtonClick;
Caption := 'Ок' + #32 + #40+IntToStr(i)+ #99 +#41;
end;
IconImg := TNewIconImage.Create(Form);
with IconImg do
begin
Parent := Form;
SetBounds(ScaleX(5), ScaleY(12), ScaleX(32), ScaleY(32));
ExtractTemporaryFile('InnoSetup.ico');
Icon.LoadFromFile(ExpandConstant('{tmp}\InnoSetup.ico'));
end;
Form.ShowModal;
Result := FormClose;
Form.Free;
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if (CurStep = ssDone) then
if not wizardsilent then
ShowCancelMessage;
CreateTimer;
end;
Как что-то сделать параллельно, как я понимаю есть главный поток, это наша программа и можно вызывать параллельный поток в которым можно будет что-то делать, типа функцию в параллельном потоке? Не подскажите как будет выглядеть такая функция, функция которая будет выполнятся параллельно не тормозящая сановной поток?
К примеру изменять текст один на другой каждую 0.1 секунду.
MISHAWIN, не знаю какая версия Inno есть, вот пример на Inno EE. Таймер - повторяющаяся функция по времени (типа цикла), а callback функция для перехвата тех самых сообщений к окнам Windows\процессам с последующей их обработкой в коде.
Думаю, уместно использовать Timer, можно сделать вызов WinApi функций и на оригинальный Inno, используйте в место CallbackAddr - CreateCallBack, удачи. надеюсь понятно, а то я уставший сегодня... может отжег чушь, как обычно
Код:
[Setup]
AppName=My Program
AppVerName=My Program
DefaultDirName=My Program
[Code]
var
TimerID: LongWord;
function SetTimer(hWnd: LongWord; nIDEvent, uElapse: LongWord; lpTimerFunc: LongWord): LongWord; external 'SetTimer@user32.dll stdcall';
function KillTimer(hWnd: LongWord; nIDEvent: LongWord): LongWord; external 'KillTimer@user32.dll stdcall';
procedure OnTimer(HandleW, msg, idEvent, TimeSys: LongWord);
begin
with WizardForm do begin
Caption:= Copy(Caption, Length(Caption), 1) + Copy(Caption, 1, Length(Caption)-1);
end;
end;
procedure InitializeWizard;
begin
WizardForm.Caption:= '> - - - - - - - - - - - - - - -';
TimerID:= SetTimer(0, 0, 100, CallbackAddr('OnTimer'));
end;
procedure DeinitializeSetup;
begin
KillTimer(0, TimerID)
end;
MISHAWIN, не знаю какая версия Inno есть, вот пример на Inno EE. Таймер - повторяющаяся функция по времени (типа цикла), а callback функция для перехвата тех самых сообщений к окнам Windows\процессам с последующей их обработкой в коде.
Думаю, уместно использовать Timer, можно сделать вызов WinApi функций и на оригинальный Inno, используйте в место CallbackAddr - CreateCallBack, удачи. надеюсь понятно, а то я уставший сегодня... может отжег чушь, как обычно
Код:
[Setup]
AppName=My Program
AppVerName=My Program
DefaultDirName=My Program
[Code]
var
TimerID: LongWord;
function SetTimer(hWnd: LongWord; nIDEvent, uElapse: LongWord; lpTimerFunc: LongWord): LongWord; external 'SetTimer@user32.dll stdcall';
function KillTimer(hWnd: LongWord; nIDEvent: LongWord): LongWord; external 'KillTimer@user32.dll stdcall';
procedure OnTimer(HandleW, msg, idEvent, TimeSys: LongWord);
begin
with WizardForm do begin
Caption:= Copy(Caption, Length(Caption), 1) + Copy(Caption, 1, Length(Caption)-1);
end;
end;
procedure InitializeWizard;
begin
WizardForm.Caption:= '> - - - - - - - - - - - - - - -';
TimerID:= SetTimer(0, 0, 100, CallbackAddr('OnTimer'));
end;
procedure DeinitializeSetup;
begin
KillTimer(0, TimerID)
end;
Как что-то сделать параллельно, как я понимаю есть главный поток, это наша программа и можно вызывать параллельный поток в которым можно будет что-то делать, типа функцию в параллельном потоке? Не подскажите как будет выглядеть такая функция, функция которая будет выполнятся параллельно не тормозящая сановной поток?
К примеру изменять текст один на другой каждую 0.1 секунду.
Если вы пользуетесь сборкой от ResTools, то смотрите пример в файле Example_Application.iss, где показано использование этого метода.
Официальная версия Inno не поддерживает метод Application.ProcessMessage. В этом случае его можно заменить функциями WinAPI.
Код замещения взят с ресурса stackoverflow.
Вот пример на базе Example_Application.iss, но для официальной версии Inno Setup.
Код:
[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={autopf}\My Application
PrivilegesRequired=none
OutputDir=userdocs:Inno Setup Examples Output
DisableWelcomePage=no
[Languages]
Name: ru; MessagesFile: "compiler:Languages\Russian.isl"
[Code]
// --- Замещение метода "Application.ProcessMessage"
{
Официальная версия InnoSetup не предоставляет метод Application.ProcessMessage().
Код, представленный ниже, выполняет замещение метода "Application.ProcessMessages"
путём использования WinAPI функций PeekMessage(), TranslateMessage() и DispatchMessage().
}
type
TMsg = record
hwnd: HWND;
message: UINT;
wParam: Longint;
lParam: Longint;
time: DWORD;
pt: TPoint;
end;
const
PM_REMOVE = 1;
function PeekMessage(var lpMsg: TMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax, wRemoveMsg: UINT): BOOL;
external 'PeekMessageA@user32.dll stdcall';
function TranslateMessage(const lpMsg: TMsg): BOOL;
external 'TranslateMessage@user32.dll stdcall';
function DispatchMessage(const lpMsg: TMsg): Longint;
external 'DispatchMessageA@user32.dll stdcall';
procedure AppProcessMessage;
var
Msg: TMsg;
begin
while PeekMessage(Msg, WizardForm.Handle, 0, 0, PM_REMOVE) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
// --- Конец замещения "Application.ProcessMessage"
{ Процедура обработки нажатия на кнопку }
procedure BtnOnClick(Sender: TObject);
var
i: Integer;
begin
For i := 0 to 50000 do
begin
WizardForm.Caption := 'Счетчик: ' + IntToStr(i);
{ Использование функции "AppProcessMessage" позволяет продолжить
выполнение программы установки несмотря на запущенную работу счетчика.
Иначе, пока не будет завершён текущий цикл, ничего нельзя будет сделать
(приложение будет выглядеть "зависшим").}
AppProcessMessage;
end;
end;
{ Функция инициализации GUI программы установки }
procedure InitializeWizard();
begin
{ Добавляем на форму кнопку }
with TButton.Create(WizardForm) do
begin
Caption := 'Запустить счетчик';
Anchors := [akLeft, akBottom];
Left := WizardForm.ClientWidth - WizardForm.CancelButton.Left - WizardForm.CancelButton.Width;
Top := WizardForm.CancelButton.Top;
Width := ScaleX(130);
Height := WizardForm.CancelButton.Height;
Parent := WizardForm;
OnClick := @BtnOnClick;
end;
end;
Если вы пользуетесь сборкой от ResTools, то смотрите пример в файле Example_Application.iss, где показано использование этого метода.
Официальная версия Inno не поддерживает метод Application.ProcessMessage. В этом случае его можно заменить функциями WinAPI.
Код замещения взят с ресурса stackoverflow.
Вот пример на базе Example_Application.iss, но для официальной версии Inno Setup.
Код:
[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={autopf}\My Application
PrivilegesRequired=none
OutputDir=userdocs:Inno Setup Examples Output
DisableWelcomePage=no
[Languages]
Name: ru; MessagesFile: "compiler:Languages\Russian.isl"
[Code]
// --- Замещение метода "Application.ProcessMessage"
{
Официальная версия InnoSetup не предоставляет метод Application.ProcessMessage().
Код, представленный ниже, выполняет замещение метода "Application.ProcessMessages"
путём использования WinAPI функций PeekMessage(), TranslateMessage() и DispatchMessage().
}
type
TMsg = record
hwnd: HWND;
message: UINT;
wParam: Longint;
lParam: Longint;
time: DWORD;
pt: TPoint;
end;
const
PM_REMOVE = 1;
function PeekMessage(var lpMsg: TMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax, wRemoveMsg: UINT): BOOL;
external 'PeekMessageA@user32.dll stdcall';
function TranslateMessage(const lpMsg: TMsg): BOOL;
external 'TranslateMessage@user32.dll stdcall';
function DispatchMessage(const lpMsg: TMsg): Longint;
external 'DispatchMessageA@user32.dll stdcall';
procedure AppProcessMessage;
var
Msg: TMsg;
begin
while PeekMessage(Msg, WizardForm.Handle, 0, 0, PM_REMOVE) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
// --- Конец замещения "Application.ProcessMessage"
{ Процедура обработки нажатия на кнопку }
procedure BtnOnClick(Sender: TObject);
var
i: Integer;
begin
For i := 0 to 50000 do
begin
WizardForm.Caption := 'Счетчик: ' + IntToStr(i);
{ Использование функции "AppProcessMessage" позволяет продолжить
выполнение программы установки несмотря на запущенную работу счетчика.
Иначе, пока не будет завершён текущий цикл, ничего нельзя будет сделать
(приложение будет выглядеть "зависшим").}
AppProcessMessage;
end;
end;
{ Функция инициализации GUI программы установки }
procedure InitializeWizard();
begin
{ Добавляем на форму кнопку }
with TButton.Create(WizardForm) do
begin
Caption := 'Запустить счетчик';
Anchors := [akLeft, akBottom];
Left := WizardForm.ClientWidth - WizardForm.CancelButton.Left - WizardForm.CancelButton.Width;
Top := WizardForm.CancelButton.Top;
Width := ScaleX(130);
Height := WizardForm.CancelButton.Height;
Parent := WizardForm;
OnClick := @BtnOnClick;
end;
end;
Помогите разобраться, не понимаю почему код не работает, Page10 это страница перед wpInstalling по идеи после нажатия кнопки далее, должен запускается таймер, проверять условия, как только загрузка будет >10, вывести сообщение 1-н раз и всё, но оно спамит сообщениями, что делаю не так?
Код:
procedure MyOnTimer(Sender: TObject);
var
curValue: Integer;
Blok1: Boolean;
begin
with WizardForm.ProgressGauge do begin
curValue:= (Position-Min)/((Max - Min)/100);
end;
if (curValue > 10) and (curValue < 19) and Blok1=false then begin
Blok1:= true;
MsgBox('Cообщение', mbError, mb_Ok);
end;
end;
Код:
function NextButtonClick(CurPageID: Integer): Boolean;
begin
if CurPageID = Page10.ID then begin
with TTimer.Create(WizardForm) do
begin
Interval := 10;
OnTimer := @MyOnTimer;
end;
end;
end;
MISHAWIN, переменную типа Boolean (Blok1) нужно сделать глобальной, а не локальной. Проще говоря, объявить ее вне тела процедуры\функции, например в самом начале секции Code.
На данном сайте используются файлы cookie, чтобы персонализировать контент и сохранить Ваш вход в систему, если Вы зарегистрируетесь.
Продолжая использовать этот сайт, Вы соглашаетесь на использование наших файлов cookie.