How do I create a checkbox on Ready page - checkbox

I created a code which plays a slideshow or plays a background video when installing my program using Inno Setup.
But I want to add a checkbox to the Background Option selection wizard page (CurPageID=wpReady) that can disable the background video/slideshow from playing.
When the Checkbox I prefer to add is checked, I want it to stop playing background slideshow or video and only to show the installing progress page (CurPageID=wpInstalling).
I wrote this but the compiler keeps saying
Line 1053, Column 3, Identifier Expected
The script I wrote:
var
NoBackgroundCheckBox: TNewCheckBox;
procedure NoBackgroundCheckBoxClick(Sender: TObject);
begin
if NoBackgroundCheckBox.Checked then
begin
with WizardForm do
begin
FWAdd:=False
end else begin
with WizardForm do
begin
FWAdd:=True
end;
end;
with NoBackgroundCheckBox do
begin
Name := 'NoBackgroundCheckBox';
Parent := WizardForm;
Left := ScaleX(560);
Top := ScaleY(115);
Width := ScaleX(90);
Height := ScaleY(14);
Alignment := taLeftJustify;
Caption := 'No Background Option';
OnClick := #NoBackgroundCheckBoxClick;
end;
NoBackgroundCheckBox.TabOrder := 3;
end;
Thanks in advance.

Create the checkbox in the InitializeWizard. And test its state in the NextButtonClick(wpReady), to decide if to start the playback or not. Alternatively you can also use CurStepChanged(ssInstall).
var
NoBackgroundCheckBox: TNewCheckBox;
procedure InitializeWizard();
begin
{ shrink the "Ready" memo to make room for the checkbox }
WizardForm.ReadyMemo.Height := WizardForm.ReadyMemo.Height - ScaleY(24);
{ create the checkbox }
NoBackgroundCheckBox := TNewCheckBox.Create(WizardForm);
with NoBackgroundCheckBox do
begin
Parent := WizardForm.ReadyMemo.Parent;
Left := WizardForm.ReadyMemo.Left;
Top := WizardForm.ReadyMemo.Top + WizardForm.ReadyMemo.Height + ScaleY(8);
Height := ScaleY(Height);
Width := WizardForm.ReadyMemo.Width;
Caption := 'No Background Option';
end;
end;
function NextButtonClick(CurPageID: Integer): Boolean;
begin
{ Next button was just clicked on the "Ready" page }
if CurPageID = wpReady then
begin
{ is the checkbox checked? }
if NoBackgroundCheckBox.Checked then
begin
Log('NoBackgroundCheckBox is checked, won''t play anything');
end
else
begin
{ the checkbox is not checked, here call your function to start the playback }
Log('NoBackgroundCheckBox is not checked, will play');
end;
end;
Result := True;
end;

Related

Inno Setup : Automatically check a checkbox after a specified time in seconds

Hello I want My Inno Setup Script to automatically check a CheckBox in one of my wizard pages after a specified time (e.g. 5 seconds).
Here's Why:
I created a checkbox which can change WizardForm's ClientWidth and ClientHeight when toggled.
If I don't click on it, the width and height of the WizardForm stays same. That's how it behaves.
The code I written to do that:
var
MinimizerCheckBox: TNewCheckBox;
procedure InitializeWizard();
begin
MinimizerCheckBox := TNewCheckBox.Create(WizardForm);
with MinimizerCheckBox do
begin
Name := 'MinimizerCheckBox';
Parent := WizardForm;
Left := ScaleX(560);
Top := ScaleY(315);
Width := ScaleX(90);
Height := ScaleY(14);
Alignment := taLeftJustify;
Caption := 'Compact Mode';
OnClick := #MinimizerCheckBoxClick;
TabOrder := 3;
end;
end;
procedure MinimizerCheckBoxClick(Sender: TObject);
begin
if MinimixerCheckBox.Checked then
begin
with WizardForm do
begin
WizardForm.ClientWidth:=420;
WizardForm.ClientHeight:=175;
end;
end else begin
with WizardForm do
begin
WizardForm.ClientWidth:=654;
WizardForm.ClientHeight:=407;
end;
end;
end;
I want to check that checkbox automatically after a specified time.
Any example code to do this?
Thanks in advance.
You can schedule a timer to check the checkbox like this:
[Code]
var
MinimizerCheckBox: TCheckBox;
...
function SetTimer(
hWnd: longword; nIDEvent, uElapse: longword; lpTimerFunc: longword): longword;
external 'SetTimer#user32.dll stdcall';
function KillTimer(hWnd: HWND; uIDEvent: UINT): BOOL;
external 'KillTimer#user32.dll stdcall';
var
CheckTimerID: Integer;
procedure StopCheckTimer;
begin
Log('Killing timer');
KillTimer(0, CheckTimerID);
CheckTimerID := 0;
end;
procedure CheckProc(h: LongWord; msg: LongWord; idevent: LongWord; dwTime: LongWord);
begin
Log('Timer elapsed');
StopCheckTimer;
MinimizerCheckBox.Checked := True;
end;
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpXXX then { your page id }
begin
Log('Starting 5s timer');
CheckTimerID := SetTimer(0, 0, 5000, CreateCallback(#CheckProc));
end
else
if CheckTimerID <> 0 then
begin
StopCheckTimer;
end;
end;
For CreateCallback function, you need Inno Setup 6. If you are stuck with Inno Setup 5, you can use WrapCallback function from InnoTools InnoCallback library.

Hide mouse pointer / cursor when playing video / slideshow in Inno Setup

I created an Inno Setup script that plays a slideShow or a video during program installation depending on what I choose to play.
When I bring mouse to the area which the playback is doing during the slideshow / video playback, a cursor (crArrow) is appearing on video / slideshow.
I want to prevent the mouse cursor from being displayed on video / slideshow while the slideshow / video is playing.
When using crNone property for the handling form window (BackgroundForm) the cursor is hiding only from it and not from slideshow / video. Isn't there anyway I can hide the cursor from slideshow/video? How can I apply crNone for that? I mean like SlideShow.crNone or Video.crNone.
I attached two images showing how the cursor appearing.
The Cursor appearing when playing SlideShow.
The Cursor appearing when playing Video.
How I handle video on the BackgroundForm using Inno Media Player:
procedure PlayMPEGVideo();
begin
if VBRadio2.Checked then begin
if FileExists(ExpandConstant('{tmp}\Video.mp4')) then
begin
if DSInitializeVideoFile(ExpandConstant('{tmp}\Video.mp4'), BackgroundForm.Handle, Width, Height, #BackgroundVideoPlay) then
begin
BackgroundForm.Width := GetSystemMetrics(0);
BackgroundForm.Height := GetSystemMetrics(1);
BASS_Pause;
SoundCtrlButton.Enabled := False;
DSSetVolume(-0);
DSPlayMediaFile;
WizardForm.BringToFront;
PauseBT.Show;
PlayBT1.hide;
PlayBT.hide;
with WizardForm do begin
WizardForm.NextButton.Caption := 'Install';
end;
end;
end;
end else begin
with WizardForm do begin
if CurPageID = wpInstalling then begin
PauseBT.hide;
CompactCheckBox.Visible := False;
WizardForm.WizardSmallBitmapImage.Show;
WizardForm.Bevel1.Show;
with WizardForm do begin
WizardForm.ProgressGauge.show;
end;
end;
end;
end;
end;
How I handle slideshow on the BackgroundForm using isSlideShow:
procedure MakeSlideShow();
var
i :integer;
begin
if NoBackgroundCheckBox.Checked = True then begin
with WizardForm do begin
if CurPageID=wpInstalling then begin
PauseBT.hide;
CompactCheckBox.Visible := False;
WizardForm.WizardSmallBitmapImage.Show;
WizardForm.Bevel1.Show;
with WizardForm do begin
WizardForm.ProgressGauge.show;
end;
end;
end;
end else begin
BackgroundForm:= TForm.Create(nil);
BackgroundForm.BorderStyle:= bsNone;
BackgroundForm.Color:=clBlack;
BackgroundForm.SetBounds(0, 0, GetSystemMetrics(0), GetSystemMetrics(1))
BackgroundForm.Visible:=True;
BackgroundForm.enabled:= False;
PicList:=tstringlist.Create;
#ifexist "Slides\1.jpg"
#sub ExtractFile
ExtractTemporaryFile('{#i}.jpg');
#endsub
#for {i = 1; FileExists(StringChange("Slides\FileName.jpg", "FileName", Str(i))) != 0; i++} ExtractFile
#endif
i:=1;
repeat
piclist.add(ExpandConstant('{tmp}\'+IntToStr(i)+'.jpg'));
i:=i+1;
until FileExists(ExpandConstant('{tmp}\'+IntToStr(i)+'.jpg')) = False;
BackgroundForm.Show;
InitializeSlideShow(BackgroundForm.Handle, 0, 0, GetSystemMetrics(0), GetSystemMetrics(1), true, 1);
ShowImage(ExpandConstant('{tmp}') + '\1.jpg', 1);
PlayBT1 := PlayBT;
end;
end;
Thanks in advance.
In general, to hide a mouse cursor, set the .Cursor property of a control to crNone.
For Inno Media Player: There's no "video" control exposed by its API. You would have to modify its source code and recompile. Particularly, you need to call the IVideoWindow::HideCursor method on the FVideoWindow in the TDirectShowPlayer.InitializeVideoWindow.
const
OATRUE = -1;
procedure TDirectShowPlayer.InitializeVideoWindow(WindowHandle: HWND; var Width,
Height: Integer);
begin
ErrorCheck(FGraphBuilder.QueryInterface(IVideoWindow, FVideoWindow));
ErrorCheck(FVideoWindow.HideCursor(OATRUE));
...
end;
Note that it does not work, when the parent window (the BackgroundForm) is disabled. So you cannot set the BackgroundForm.Enabled := False.
To prevent the background/video window from getting activated, handle the TForm.OnActive by returning focus back to the wizard form:
procedure BackgroundFormActivated(Sender: TObject);
begin
WizardForm.BringToFront;
end;
...
begin
...
BackgroundForm:= TForm.Create(nil);
...
BackgroundForm.OnActivate := #BackgroundFormActivated;
end;
This is a complete code that works for me - hides the cursor over the background video - when using the recompiled MediaPlayer.dll with the HideCursor call, provided by you - tested on Windows 10.
var
BackgroundForm: TForm;
procedure OnMediaPlayerEvent(EventCode, Param1, Param2: Integer);
begin
{ noop }
end;
procedure BackgroundFormActivated(Sender: TObject);
begin
WizardForm.BringToFront;
end;
procedure PlayMPEGVideo();
var
Width, Height: Integer;
begin
BackgroundForm := TForm.Create(nil);
BackgroundForm.BorderStyle := bsNone;
BackgroundForm.Color := clBlack;
BackgroundForm.Visible := True;
BackgroundForm.Cursor := crNone;
BackgroundForm.OnActivate := #BackgroundFormActivated;
Width := GetSystemMetrics(0);
Height := GetSystemMetrics(1);
BackgroundForm.SetBounds(0, 0, Width, Height)
if DSInitializeVideoFile(
'...\video.avi', BackgroundForm.Handle, Width, Height, #OnMediaPlayerEvent) then
begin
DSPlayMediaFile;
WizardForm.BringToFront;
end;
end;
For isSlideShow: I didn't find any documentation or source code for this.

Index out of range (-1) when I click on any item in the TListBox

The TListBox called lboMtrlList is populated with records from the database. The data displays properly when I run the application. When I click on any item in the list, shows the error:
Index out of range (-1)
despite the list not being empty.
Here's the code for populating the lboMtrlList:
procedure TfrmMakeQuote.FormCreate(Sender: TObject);
begin
con := TFDConnection.Create(nil);
query := TFDQuery.Create(con);
con.LoginPrompt := false;
con.Open('DriverID=SQLite;Database=C:\Users\katiee\Documents\Embarcadero\Studio\Projects\ProgramDatabase;');
query.Connection := con;
performQuery;
query.SQL.Text :=
'SELECT [Material Description] FROM MtrlDatabase ORDER BY MtrlID';
try
query.Open;
lboMtrlList.Items.Clear;
while not query.EOF do
begin
lboMtrlList.Items.Add(query.Fields[0].AsString);
query.Next;
end;
finally
query.Close;
end;
//ledtDesc.Height := 81;
//ledtNotes.Height := 51;
end;
I want to be able to double click on an item in the lboMtrlList and move it to another TListBox called lboSelectedMtrl. Here's the code:
procedure TfrmMakeQuote.lboMtrlListDblClick(Sender: TObject);
begin
lboMtrlList.Items.Add(lboSelectedMtrl.Items.Strings[lboSelectedMtrl.ItemIndex]);
end;
I want to be able to double click on an item in the lboMtrlList and move it to another TListBox called lboSelectedMtrl.
Your code is doing the opposite of that. It is trying to move an item from lboSelectedMtrl to lboMtrlList. You are getting the bounds error because there is no item selected in lboSelectedMtrl (lboSelectedMtrl.ItemIndex is -1).
Swap the ListBox variables, and add some error checking:
procedure TfrmMakeQuote.lboMtrlListDblClick(Sender: TObject);
var
Idx: Integer;
begin
Idx := lboMtrlList.ItemIndex;
if Idx <> -1 then
lboSelectedMtrl.Items.Add(lboMtrlList.Items.Strings[Idx]);
end;

How to change DBLookupComboBox value in Delphi?

I'm trying to change the visible text (value) of a DBLookupComboBox, using :
DBLookupComboBox1.KeyValue:=S;
and
DBLookupComboBox2.KeyValue:=X;
If the KeyValue and S are strings, then everything works fine, and I can set the value.
But when the KeyValue is an integer/Int64 (UID in the DB), and X is an Int64 variable - it doesn't work, and nothing changes.
So for an example, i need to set "Amsterdam" in DBLookupComboBox1, and 1500 in DBLookupComboBox2.
"Amsterdam" from the "City" field of the users, and 1500 as the UID.
What am I doing wrong please?
Thanks
This code is Important for you:
lkcbbArzSource.KeyValue:=2;//c(or another number);
lkcbbArzSource is a dbLookupComboBox object and you can insert only a number in this!why? because is numeric and another side of that there is a field that show a text or String of that numeric in combo.
in below sample code you can see a dbLookupComboBox how to menage and fill with Data-set and add in a grid :
rzSource.Enabled:= True;
lkcbbArzSource.Font.Size:=8;
lkcbbArzSource.Tag := V_Counter;
lkcbbArzSource.Visible:= True;
lkcbbArzSource.Enabled:= True;
lkcbbArzSource.Font.Name:='tahoma';
lkcbbArzSource.ListSource := myDsrSource;
lkcbbArzSource.KeyField := 'Code';
lkcbbArzSource.ListField := 'Des';
lkcbbArzSource.KeyValue:= IntToStr(FieldByName('P_ARZSOURCE').AsInteger);
lkcbbArzSource.OnChange := myBicLookUpChange;
SGrid2.Objects[look_col,lkcbbArzSource.Tag]:= lkcbbArzSource;
SGRID2.Objects[look_col,V_Counter] := nil;
Setting the KeyValue calls the SetKeyValue of the TDBLookupControl which in Delphi 7 appears as:
procedure TDBLookupControl.SetKeyValue(const Value: Variant);
begin
if not VarEquals(FKeyValue, Value) then
begin
FKeyValue := Value;
KeyValueChanged;
end;
end;
procedure TDBLookupComboBox.KeyValueChanged;
begin
if FLookupMode then
begin
FText := FDataField.DisplayText;
FAlignment := FDataField.Alignment;
end else
if ListActive and LocateKey then
begin
FText := FListField.DisplayText;
FAlignment := FListField.Alignment;
end else
begin
FText := '';
FAlignment := taLeftJustify;
end;
Invalidate;
end;
As you can see, your variable x is used as part of a LocateKey.
function TDBLookupControl.LocateKey: Boolean;
var
KeySave: Variant;
begin
Result := False;
try
KeySave := FKeyValue;
if not VarIsNull(FKeyValue) and FListLink.DataSet.Active and
FListLink.DataSet.Locate(FKeyFieldName, FKeyValue, []) then // << ---here
begin
Result := True;
FKeyValue := KeySave;
end;
except
end;
end;
Stepping into these procedures and functions should help you to debug your issue. All are located in the DbCtrls unit..
I have used this and solved my problem.
Use this lines of code at Form1.OnShow :
DBLookupComboBox1.ListSource.DataSet.Locate('City', 'Amsterdam', []);
DBLookupComboBox1.ListSource.DataSet.FieldByName(DBLookupComboBox1.KeyField).Value;
DBLookupComboBox2.ListSource.DataSet.Locate('UID', '1500', []);
DBLookupComboBox2.ListSource.DataSet.FieldByName(DBLookupComboBox2.KeyField).Value;

Delete and refresh a record in DBgrid where u maintain the same position

I have a small database I'm using dbgo, I have a DBgrid displaying my records, I need to know how to delete a record and refresh the database where the index arrow stays in the same position or at least go to the next? but currently my index arrow jump to start form the beginning each time I refresh !
Just keep and reset Recno
var
I:Integer;
.......
I := Ads.Recno;
Ads.Delete;
Ads.Recno := I;
an example implementation for usage with DBNavigator could be
Procedure DeleteAndKeepRecno(Ads: TCustomAdoDataset);
var
rn: Integer;
begin
rn := Ads.RecNo;
Ads.Delete;
Ads.RecNo := rn;
end;
procedure TForm4.DBNavigator1Click(Sender: TObject; Button: TNavigateBtn);
begin
if Button = nbDelete then
begin
DeleteAndKeepRecno (TCustomAdoDataset(TDBNavigator(Sender).DataSource.DataSet));
Abort;
end;
end;

Resources