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

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.

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.

How do I create a checkbox on Ready page

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;

Inno Setup: Combo box closing immediately on drop-down (which starts an application)

I am getting a list of Application Pools and then populating the combo box with the names of app pools. The problem is that when when the OnDropDown event is called the combo box opens for a fraction of a second and then closes straight away. It does not remain "dropped down". I do see all the app pools in the combo box. Here is my code:
function GetApplicationPoolList() : TArrayOfString;
var
i, nExitCode: Integer;
sFileLines: TArrayOfString;
sTempFileName, sListAppPoolCmd: String;
begin
sListAppPoolCmd := ExpandConstant('{sys}') + '\inetsrv\appcmd list apppool /text:name';
sTempFileName := ExpandConstant('{tmp}') + '\appPoolList.txt';
if not ExecAppCmd(Format('%s > %s',[sListAppPoolCmd, sTempFileName]), nExitCode) then begin
MsgBox('Could not get app pools', mbError, MB_OK);
end else begin
LoadStringsFromFile(sTempFileName, sFileLines);
end
Result := sFileLines;
end;
// ==============================================
procedure OnAppPoolComboBoxDropDown(Sender: TObject);
var
sAppPoolList: TArrayOfString;
i: Integer;
begin
// Clear existing
appPoolComboBox.Items.Clear;
// Populate the combo box with the application pools
sAppPoolList := GetApplicationPoolList;
For i := 0 to GetArrayLength (sAppPoolList) - 1 do
begin
// ComboBox with Application Pool Names
appPoolComboBox.Items.Add(sAppPoolList[i]);
end;
appPoolComboBox.ItemIndex := 0;
end;
function ExecAppCmd(params :String; nExitCode: Integer) :Boolean;
var
execSuccessfully :Boolean;
resultCode :Integer;
begin
execSuccessfully := Exec('cmd.exe', '/c ' + '' + ' ' + params, '', SW_HIDE, ewWaitUntilTerminated, resultCode);
nExitCode := resultCode;
Result := execSuccessfully and (resultCode = 0);
end;
I am not sure what is happening here. Any advice is appreciated.
EDIT: ExecAppCmd seems to be the issue, commenting it out makes the combo box behave normally... Though not sure why
The drop-down closes probably because the combo box loses focus momentarily as the application is starting.
I'd say it's a bad practice to call an application on drop-down, as it takes time and it ruins a user experience. Populate the combo box earlier, like from CurPageChanged.

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