Search code examples
cursorinno-setup

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.


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.


Solution

  • 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.