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 :

chm déchargement fichier locké


Sujet :

Langage Delphi

  1. #1
    Membre expérimenté
    Avatar de ouiouioui
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2006
    Messages
    984
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 984
    Points : 1 419
    Points
    1 419
    Par défaut chm déchargement fichier locké
    Bonjour, j'ai ajouté un fichier d'aide à mon application au format chm
    tout fonctionne à part un petit truc que je ne comprends pas

    lorsque l'utilisateur appuie sur f1 l'aide s'affiche

    si l'utilisateur quitte l'application sans fermer l'aide, alors l'aide se ferme et le fichier s'efface

    si l'utilisateur ferme l'aide puis quitte l'application alors le fichier ne s'efface pas.

    Ce que je ne comprends pas car dans les deux cas avant de tenter d'effacer le fichier je décharge HHCTRL.OCX
    et dans le debugger je voir clairement déchargement de... avant l'étape d'effacement.
    Mais rien n'y fait si le fichier a été fermé avant l'application il reste protégé et je ne peux pas l'effacer même à la main tans que l'application fonctionne.

    Je vous montre mon code:
    j'ai une unité utils que j'inclus dans le programme:
    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
    Unit Utils;
     
    Interface
     
    Uses
      Windows, Messages, SysUtils, Classes, TLHelp32;
     
    Const
      // constante utilisée pour afficher l'aide selon divers paramètres
      HH_DISPLAY_TOPIC     = $0000;
      HH_DISPLAY_TOC       = $0001;
      HH_CLOSE_ALL         = $0012;
     
    Type
      // type utilisé pour récupérer la fonction contenue dans le OCX chargé par la fonction HtmlHelp
      TFNHtmlHelpA = Function(hwndCaller: HWND; pszFile: PAnsiChar; uCommand: UINT; dwData: DWORD): HWND; Stdcall;
     
    Var
      HelpModule: HModule;
      FHtmlHelp:  TFNHtmlHelpA;
     
    Procedure HtmlHelp(hwndCaller: HWND; pszFile: PChar; uCommand: UINT; dwData: DWORD; HelpFileName: String = ''; Language: String = '');
    Function ExtractOfRes(ResName, FileName: String): Boolean;
     
    Implementation
     
    Procedure HtmlHelp(hwndCaller: HWND; pszFile: PChar; uCommand: UINT; dwData: DWORD; HelpFileName: String = ''; Language: String = '');
    Begin
      If Not FileExists(HelpFileName) Then // si le fichier d'aide n'existe pas
        ExtractOfRes('help' + Language, HelpFileName); // alors on essaie de l'extraire selon la langue du programme actuel
      If HelpModule = 0 Then // on vérifie que le module n'est pas déjà chargé et on le charge
      Begin
        HelpModule := LoadLibrary('HHCTRL.OCX'); // on charge le fichier OCX pour gérer le fichier d'aide
        @FHtmlHelp := GetProcAddress(HelpModule, 'HtmlHelpA'); // on récupère l'adresse de la fonction qui permet d'afficher un fichier d'aide
      End;
      If (HelpModule <> 0) And (@FHtmlHelp <> nil) Then // le module est déjà chargé et on connaît l'adresse de la fonction
        FHtmlHelp(hwndCaller, pszFile, uCommand, dwData); // on lance la commande qui permet d'afficher le fichier spécifié à la page demandée
    End;
     
    Function ExtractOfRes(ResName, FileName: String): Boolean;
    Var
      ResourceStream: TResourceStream;
      FichierStream:  TFileStream;
    Begin
      If FileExists(FileName) Then // on vérifie que le fichier à extraire n'existe pas déjà
        DeleteFile(FileName); // sinon on le supprime
      If Not FileExists(FileName) Then // si le fichier n'existe pas alors on l'extrait
      Begin
        ResourceStream := TResourceStream.Create(hInstance, ResName, RT_RCDATA); // création d'un flux mémoire donnant accès à la ressource compilé
        Try
          FichierStream := TFileStream.Create(FileName, fmCreate); // FileStream permet aux applications de lire et écrire dans un fichier disque.
          Try
            FichierStream.CopyFrom(ResourceStream, 0); // copie du flux donnant accès aux ressources vers le flux fichier
          Finally
            FichierStream.Free; //libération mémoire du stream fichier
          End;
        Finally
          ResourceStream.Free; //libération mémoire du flux mémoire
        End;
      End;
      Result := True;
    End;
     
    initialization
      HelpModule := 0;
      FHtmlHelp := nil;
     
    End.
    et dans mon programme j'ai lorsque j'appuie sur la touche f1 Sa lance la procédure ci-dessous:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Procedure TMain.ShowHelp;
    Begin
    //  j'appelle la  fonction contenue dans mon unité ci-dessus avec en paramètre:
    //- le handle de mon applications
    //- le nom de mon fichier d'aide suivi de la page a afficher
    //- la constante qui permet d'afficher une page
    //- 0 par ce que je n'utilise pas TOC
    //- le nom de mon fichier d'aide
    //- la langue de mon programme afin de connaître le fichier d'aide à utiliser
      HtmlHelp(Application.Handle, PChar(HelpFileName + '::/main.html'), HH_DISPLAY_TOPIC, 0, HelpFileName, Conf.Language);
    End;
    puis dans mon closequery:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Procedure TMain.FormCloseQuery(Sender: TObject; Var CanClose: Boolean);
    Begin
      If FileExists(HelpFileName) Then // si le fichier d'aide existe 
        HtmlHelp(Application.Handle, nil, HH_CLOSE_ALL, 0, HelpFileName, Conf.Language); // j'envoie un message afin de fermer l'aide
    End;
    et enfin dans mon destroy:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Procedure TMain.FormDestroy(Sender: TObject);
    Begin
      If FileExists(HelpFileName) Then // si le fichier d'aide existe
      Begin
        If HelpModule <> 0 Then //  si le module d'aide est chargé
          FreeLibrary(HelpModule);// on décharge le module
        DeleteFile(HelpFileName);// on efface le fichier d'aide
      End;
    End;
    est-ce que quelqu'un aurait une idée? merci d'avance
    Il existe 3 sortes de gens: ceux qui savent compter et ceux qui ne savent pas.

  2. #2
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    je n'est pas bien compris mais ta fonction FHtmlHelp renvoie un handle essaie de le fermer

  3. #3
    Membre expérimenté
    Avatar de ouiouioui
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2006
    Messages
    984
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 984
    Points : 1 419
    Points
    1 419
    Par défaut
    merci pour ton aide, j'ai essayé mais sa n'a rien changé

    j'ai suivi point par point l'exemple donné dans l'aide de Delphi 2007 sur comment charger dynamiquement, utiliser une fonction puis libérer.

    D'ailleurs dans l'exemple il libère la ressource sans rien faire au préalable
    ms-help://borland.bds5/devcommon/librariesandpackagesov_xml.html
    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
    uses Windows, ...; 
     
    type
      TTimeRec = record
        Second: Integer;
        Minute: Integer;
        Hour: Integer;
      end;
     
      TGetTime = procedure(var Time: TTimeRec);
      THandle = Integer;
     
      var
        Time: TTimeRec;
        Handle: THandle;
        GetTime: TGetTime;
                    .
                    .
                    .
      begin
        Handle := LoadLibrary('libraryname');
        if Handle <> 0 then
        begin
         @GetTime := GetProcAddress(Handle, 'GetTime');
         if @GetTime <> nil then
          begin
          GetTime(Time);
                 with Time do
                    WriteLn('Il est ', Hour, ':', Minute, ':', Second);
         end;
         FreeLibrary(Handle);
        end;
      end;
    c'est énervant tout fonctionne correctement sauf si l'utilisateur ferme l'aide d'abord, j'ai réfléchi je ne vois pas comment je pourrai l'empêcher de fermer l'aide avant le programme ou résoudre cette erreur
    L'utilisateur ne voit rien mais ce n'est pas une raison pour polluer son dossier temporaire, même si au démarrage de l'application j'efface le fichier si je le trouve dans le dossier temporaire.

    Ou alors créé un petit batch qui attendra une seconde ou qui attendra que le programme se ferme avant d'essayer d'effacer le fichier d'aide, et je n'aurais qu'à lancer ce petit fichier batch en mode caché à la fermeture.

    Je ne vois pas d'autre solution, ou alors je dis aux personnes de trouver toute seule qu'elles n'ont pas besoin d'aide lol

    j'ai changé dans mon premier message, j'ai rajouté des commentaires.
    Il existe 3 sortes de gens: ceux qui savent compter et ceux qui ne savent pas.

  4. #4
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    si tu veux effacer le fichier help dans les deux cas citées voici ma demarche
    ajoute un variable globale dans l'unite Utils
    sHandle:integer;
    change
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     sHandle:=FHtmlHelp(hwndCaller, pszFile, uCommand, dwData);
    et change
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Procedure TMain.FormDestroy(Sender: TObject);
    Begin
      If FileExists(HelpFileName) Then // si le fichier d'aide existe
      Begin
        If HelpModule <> 0 Then //  si le module d'aide est chargé
          FreeLibrary(HelpModule);// on décharge le module
     
       If sHandle <> 0 Then //  si le module d'aide est chargé
          CloseHandle(sHandle);
     
        DeleteFile(HelpFileName);// on efface le fichier d'aide
      End;
    End;

  5. #5
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    si je mets le code de FormDestroy dans FormCloseQuery ne plante pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    procedure TMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
     
    begin
        If FileExists(HelpFileName) Then // si le fichier d'aide existe
        HtmlHelp(Application.Handle, nil, HH_CLOSE_ALL, 0, HelpFileName); // j'envoie un message afin de fermer l'aide
     
      If FileExists(HelpFileName) Then // si le fichier d'aide existe
      Begin
        If HelpModule <> 0 Then //  si le module d'aide est chargé
          FreeLibrary(HelpModule);// on décharge le module
          DeleteFile(HelpFileName);// on efface le fichier d'aide
      End;
    end;

  6. #6
    Membre expérimenté
    Avatar de ouiouioui
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2006
    Messages
    984
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 984
    Points : 1 419
    Points
    1 419
    Par défaut
    J'essaye, je l'avais lus quelque part pour envoyer HH_CLOSE_ALL il faut être dans le onclosequery je l'est bien respecté mais j'ai pas pensé à sa pour le reste.
    Il existe 3 sortes de gens: ceux qui savent compter et ceux qui ne savent pas.

  7. #7
    Membre expérimenté
    Avatar de ouiouioui
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2006
    Messages
    984
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 984
    Points : 1 419
    Points
    1 419
    Par défaut
    voila mon onclosequery:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Procedure TMain.FormCloseQuery(Sender: TObject; Var CanClose: Boolean);
    Begin
      CanClose := ReadyToClose; // on vérifie si l'utilisateur à le droit de fermer le logiciel
      If ReadyToClose And FileExists(HelpFileName) Then // si le logiciel se ferme et le fichier d'aide existe
      Begin
        If HelpModule <> 0 Then // si le module permettant de piloter les fichiers d'aide est chargé
        Begin
          HtmlHelp(Application.Handle, nil, HH_CLOSE_ALL, 0, HelpFileName, Conf.Language); // on envoie un message pour fermer le fichier d'aide
          FreeLibrary(HelpModule); // on le libère
        End;
        DeleteFile(HelpFileName); // on efface le fichier d'aide
      End;
    End;
    et bien que je ferme l'aide avant le programme ou pas le fichier reste!

    vu que chez toi c'est bon j'en conclu que c'est mon pc (sur mes deux pc même résultat) je lance une machine virtuelle avec Windows XP SP3 à jour (mais sans les logiciels de développement et autres que j'ai sur les deux ordinateurs) et la ça fonctionne correctement!

    j'ai vérifié la version de hhctrl.ocx c'est la même sur mes ordinateurs et sur la machine virtuelle.

    Alors la je ne sais plus quoi penser, je ne pense pas que ça impact les utilisateurs, mais je préférerai trouver pourquoi cela ne fonctionne pas chez moi

    Et j'ai essayé aussi ta méthode en déclarant une variable global de type integer
    qui reçoit le handle de FHtmlHelp
    et j'utilise CloseHandle après chaque affectation de cette variable
    Mais cela n'a rien changé

    Je vais y laisser comme ça, et je demanderai à plusieurs utilisateurs si ils ont le même problème que moi d'effacement du fichier d'aide à la fermeture de l'application.

    Merci beaucoup pour ton aide précieuse.
    Il existe 3 sortes de gens: ceux qui savent compter et ceux qui ne savent pas.

  8. #8
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    Le code dans FormDestroy d'un mainform rarement qu'il s'execute correctement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Procedure TMain.FormDestroy(Sender: TObject);
    Begin
     sleep(10000)
    End;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Procedure TMain.FormDestroy(Sender: TObject);
    Begin
     showmessage('Destroy');
    End;
    il est imopossible pour effacer un fichier en lecture seule

    tu peux remplacer deletefile par CreateFile le fichier sera supprimer automatiquement apres la fermeture de l'applis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CreateFile(PChar(HelpFileName),0,0,nil,OPEN_EXISTING,FILE_FLAG_DELETE_ON_CLOSE,0);

  9. #9
    Membre expérimenté
    Avatar de ouiouioui
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2006
    Messages
    984
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 984
    Points : 1 419
    Points
    1 419
    Par défaut
    tout dépens ce que l'on met dedans, moi j'ai sa et aucun problème:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Procedure TMain.FormDestroy(Sender: TObject);
    Begin
      LoadDllZipNow(ZipMaster, False); // on vйrifie si le fichier dll zip est extrait est chargй et si oui ont le dйcharge puis on l'efface
      If PResLanguage <> 0 Then // on vйrifie si un fichier de traduction est chargй
      Begin
        FreeLibrary(PResLanguage); // libиre le fichier de traduction de la mйmoire
        DeleteFile(LanguageResFile); // puis on l'efface du disque dur
      End;
    End;
    sauf pour ce fichu chm! qui déconne même dans onclosequery
    Il existe 3 sortes de gens: ceux qui savent compter et ceux qui ne savent pas.

Discussions similaires

  1. [Eclipse] fichier locké impossible de le délocker
    Par bucheron007 dans le forum Subversion
    Réponses: 0
    Dernier message: 28/08/2008, 11h23
  2. Fichier Lock du service POP3
    Par undercrash dans le forum Windows Serveur
    Réponses: 1
    Dernier message: 04/06/2008, 16h50
  3. Synchronisation grace à un fichier .lock
    Par AliJava dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 21/01/2008, 12h06
  4. Fichier locké par explorer.exe
    Par Glob dans le forum Windows XP
    Réponses: 6
    Dernier message: 31/08/2006, 09h05

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