IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

ShellExecute dans un SplashScreen


Sujet :

Langage Delphi

  1. #1
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut ShellExecute dans un SplashScreen
    Bonjour,

    Comment exécuter un ShellExecute avant que l'application soit Application.Run ?

    Dans mon dpr, je lance un téléchargement, une fois terminé, je lance un shellexecute dans l'evenement OnWorkEnd, et je ferme le SplashScreen, mais celui-ci ne s'execute pas.

    Voilà mon Dpr :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    begin
      FSplashScreen := TFSplashScreen.Create(Application); // On crée la fenetre de Splash
     
      FSplashScreen.Show; // affichage de cette fenetre
     
      FSplashScreen.Update; // On force l'affichage de la fenetre (sinon elle n'apparait que partiellement)
     
      Application.Initialize;
      if Not FSplashScreen.Version then
      Begin
        Application.Title := 'Planning';
     
    // ...
        Application.Run;
      end
      else
        FSplashScreen.Download('xxxxxxx.exe'); // On télécharge et on execute dans la foulé
    Voilà l'évenement OnWorkEnd de mon splashscreen :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure TFSplashScreen.IdFTP1WorkEnd(ASender: TObject; AWorkMode: TWorkMode);
    begin
      sGaugeDownload.Progress := sGaugeDownload.MaxValue;
      sLabelDownload.Caption := 'Téléchargement terminé.';
      Application.ProcessMessages;
      ShellExecute(Handle, 'open', PWideChar(SaveDialog1.FileName), '', '',  SW_SHOWNORMAL);
      Application.Terminate;
    end;
    J'ai essayé en mettant,
    - Close; à la place de Application.Terminate;
    - Application.Handle à la place de Handle dans mon shellexecute
    - j'ai mis une pause avant le Application.terminate;
    mais rien n'est concluant.

    Comment procéderiez-vous ?

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Regarde ce code qui récupère un fichier depuis le réseau local (tu peux le remplace par le FTP, il faut que ce processus soit bloquant) qui relance l'exe après téléchargement ...

    sinon le Application.ProcessMessages avant même d'avoir lancé le Run, euh, très mauvaise idée !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    @ShailLeTroll,

    Je vais regardé ce topic.

    Précision, ce que je télécharge c'est un setup qui n'est donc pas le même executable que l'application en cours.


    Cela change quelquechose ?

  4. #4
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 685
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 685
    Points : 13 102
    Points
    13 102
    Par défaut
    De toute façon, le contrôle d'une nouvelle version devrait être faite dans une tâche indépendante (asynchrone) une fois que l'application est lancée.

    Si pour une raison xy ton site n'est pas accessible ou que la connexion internet pose problème, l'utilisateur va rester bloqué plusieurs secondes (voir dizaines jusqu'au timeout) sur ton splash à chaque démarrage et va vite perdre patience .

  5. #5
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Bien,

    J'ai retiré mon ShellExecute de l'evenement OnWorkEnd, pour le placer juste après le idftp.Get();
    Et cela fonctionne trés bien.

    @AndNotOr,
    J'ai lu ta remarque, Il y a-t-il un exemple de thread asynchrone lié à un téléchargement ? Je t'avoue être totalament largé avec les Threads.
    Peut-être pourrais-tu montrer un début de code ?

    @ShailLeTroll,
    Merci pour ton aide et ton lien.

  6. #6
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 685
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 685
    Points : 13 102
    Points
    13 102
    Par défaut
    Voilà une démo complète.

    2 tâches: Une qui contrôle la version et une qui la télécharge.

    Principe:
    1. La 1er tâche est démarrée depuis OnCreate (mais pourrait être ailleurs)
    2. Si une nouvelle version est disponible, un message WM_NEWVERSION est envoyé à la fiche principale.
    3. Si l'utilisateur confirme le téléchargement, démarrage de la 2ème tâche.
    4. A la fin du téléchargement, le message WM_DOWNLOADCOMPLETE est envoyé à la fiche principale (y compris en cas d'erreur) et la tâche se met en pause.
    5. Si l'utilisateur confirme l'installation -> ShellExecute.


    CheckVersion.pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    unit CheckVersion;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Classes, URLMon, ShellAPI, Forms;
     
    const
      WM_NEWVERSION       = WM_USER;       //Message Nouvelle version disponible
      WM_DOWNLOADCOMPLETE = WM_USER +1;    //Téléchargement terminé (ou erreur)
     
    type
      //Tâche contrôle de version
      TCheckVersionThread = class(TThread)
      private
        Wnd            :hWnd;    //Fenêtre qui reçoit les notifications
        RemoteFile     :string;  //HTTP://... fichier distant contenant le numéro de version
        CurrentVersion :string;  //Version actuellement installée
      protected
        function  CompareVersion(aFileName :TFileName) :boolean;
        procedure Execute; override;
      public
        constructor Create(const aWnd :hWnd; const aRemoteFile, aCurrentVersion :string);
      end;
     
      //Tâche téléchargement
      TDownloadNewVersionThread = class(TThread)
      private
        Wnd        :hWnd;        //Fenêtre qui reçoit les notifications
        RemoteFile :string;      //HTTP://... fichier nouvelle version
      protected
        procedure Execute; override;
      public
        constructor Create(const aWnd :hWnd; const aRemoteFile :string);
      end;
     
    implementation
     
    { TCheckVersionThread }
     
    function TCheckVersionThread.CompareVersion(aFileName: TFileName): boolean;
    begin
      //A toi d'implémenter ton contrôle de version :-)
      //Pour la demo, renvoi toujours vrai !
      Result := TRUE;
    end;
     
    constructor TCheckVersionThread.Create(const aWnd :hWnd; const aRemoteFile, aCurrentVersion: string);
    begin
      inherited Create(FALSE);
     
      Wnd            := aWnd;
      RemoteFile     := aRemoteFile;
      CurrentVersion := aCurrentVersion;
     
      //Libération automatique à la fin du thread
      FreeOnTerminate := TRUE;
    end;
     
    procedure TCheckVersionThread.Execute;
    var
      TempFileName :array[0..MAX_PATH] of Char;
     
    begin
      //Télécharge dans le cache internet.
      //On aurait aussi pu récupérer directement une chaîne
      //avec un idHttp sans passer par un fichier
      if URLDownloadToCacheFile(nil, PChar(RemoteFile), TempFileName, MAX_PATH, 0, nil) = S_OK then
     
        //Comparaison...
        if CompareVersion(TempFileName) then
     
          //...et le cas échéant, notifie la fiche principale
          PostMessage(Wnd, WM_NEWVERSION, 0, 0);
    end;
     
    { TDownloadNewVersionThread }
     
    constructor TDownloadNewVersionThread.Create(const aWnd: hWnd; const aRemoteFile: string);
    begin
      inherited Create(FALSE);
     
      Wnd        := aWnd;
      RemoteFile := aRemoteFile;
     
      //Libération automatique à la fin du thread
      FreeOnTerminate := TRUE;
    end;
     
    procedure TDownloadNewVersionThread.Execute;
    var
      TempFileName :array[0..MAX_PATH] of Char;
      Result       :integer;
     
    begin
      //Télécharge dans le cache internet...
      Result := URLDownloadToCacheFile(nil, PChar(RemoteFile), TempFileName, MAX_PATH, 0, nil);
     
      //...et notifie la fiche principale, même en cas d'erreur !
      //Attend la décision de la tâche principale (installation (ID_YES) ou non)
      if SendMessage(Wnd, WM_DOWNLOADCOMPLETE, Result, integer(@TempFileName)) = ID_YES then
      begin
        ShellExecute(0, 'open', TempFileName, nil, nil, SW_SHOWNORMAL);
        PostMessage(Application.MainForm.Handle, WM_CLOSE, 0, 0);
      end;
    end;
     
    end.
    Form1:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, CheckVersion;
     
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        procedure WMNewVersion(var Message :TMessage); message WM_NEWVERSION;
        procedure WMDownloadComplete(var Message :TMessage); message WM_DOWNLOADCOMPLETE;
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    { TForm5 }
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      //Lance la tâche de contrôle
      TCheckVersionThread.Create(Handle, 'http://TonSite.com/appname.txt', '1.22');
    end;
     
    procedure TForm1.WMNewVersion(var Message: TMessage);
    begin
      //Nouvelle version disponible
      if MessageDlg('Une nouvelle version est disponible.'#13
                   +'Voulez-vous la télécharger et l''installer maintenant ?',
                   mtConfirmation, [mbYes, mbNo], 0) = mrYes then
        TDownloadNewVersionThread.Create(Handle, 'http://TonSite.com/appname.exe');
    end;
     
    procedure TForm1.WMDownloadComplete(var Message: TMessage);
    begin
      //Ne fait rien par défaut
      Message.Result := mrAbort;
     
      case Message.WParam of
        S_OK          : //Téléchargement terminé
                        Message.Result := MessageDlg('Téléchargement terminé !'#13
                                                    +'Installer maintenant ?',
                                                    mtConfirmation, [mbYes, mbNo], 0);
     
        E_FAIL        : //Erreur
                        MessageDlg('Erreur de téléchargement !', mtError, [mbOk], 0);
     
        E_OUTOFMEMORY : //Erreur
                        MessageDlg('Mémoire insuffisante !', mtError, [mbOk], 0);
      end;
    end;
     
    end.
    Je suis passé par le cache internet, mais tu peux aussi figer les noms de fichiers et utiliser URLDownloadToFile.
    J'ai testé en http, mais ça doit aussi fonctionner en ftp .

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. ProgressBar dans un SplashScreen
    Par adelneo dans le forum Composants VCL
    Réponses: 6
    Dernier message: 20/11/2011, 14h24
  2. Réponses: 7
    Dernier message: 12/12/2007, 18h52
  3. Probleme d'ajout d'un image dans un splashscreen
    Par laurentdb dans le forum Windows Forms
    Réponses: 1
    Dernier message: 30/03/2007, 21h39
  4. Réponses: 8
    Dernier message: 16/11/2006, 10h15
  5. ShellExecute dans une application console?
    Par balu dans le forum Delphi
    Réponses: 5
    Dernier message: 24/06/2006, 21h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo