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

 Delphi Discussion :

[D7] Problème de Drag And Drop dans la FAQ


Sujet :

Delphi

  1. #1
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 339
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 339
    Points : 3 107
    Points
    3 107
    Par défaut [D7] Problème de Drag And Drop dans la FAQ
    Bonjour,

    j'ai essayé de tester le Drag and drop de la FAQ

    Comment récupérer le nom d'un fichier de l'explorateur Windows dans un TListBox avec un drag & drop ?

    La fenêtre accepte le Drag and drop d'un fichier depuis l'explorateur, mais le nom du fichier ne s'affiche pas dans la ListBox ?

    Savez vous pourquoi ? (on ne passe pas dans la fonction WM_DropFiles)

    A+
    Charly

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 671
    Points : 13 065
    Points
    13 065
    Par défaut
    Essaye ceci.

  3. #3
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 339
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 339
    Points : 3 107
    Points
    3 107
    Par défaut
    Merci Andornot,

    j'ai ajouté

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      ChangeWindowMessageFilterEx(AImage.Handle, WM_COPYGLOBALDATA, MSGFLT_ADD, nil);
      ChangeWindowMessageFilterEx(AImage.Handle, WM_DROPFILES, MSGFLT_ADD, nil);
    dans le create de ma form, mais comme d'habitude je ne trouve pas le uses à ajouter ... (le F1 de D7 ne me donne rien !) je cherche ...

    A+
    Charly

  4. #4
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 844
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 844
    Points : 11 274
    Points
    11 274
    Billets dans le blog
    6
    Par défaut
    Si jamais D7 ne le connaît pas (c'est arrivé avec W7), il suffit de l'importer de User32.dll ; le prototype est : sur le msdn.
    Delphi 5 Pro - Delphi 10.4 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  5. #5
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 339
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 339
    Points : 3 107
    Points
    3 107
    Par défaut
    Merci Tourlourou,

    j'ai essayé, mais je n'arrive pas à grand chose ! j'ai ajouté :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      function ChangeWindowMessageFilterEx(hWnd: HWND; Message : Integer ; Action : DWord): Boolean; stdcall; external 'User32.dll';
    et dans le Create de la Form :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    procedure TForm2.FormCreate(Sender: TObject);
    begin
      //la fenêtre accepte le glissement d'objets
      ChangeWindowMessageFilterEx(Handle, WM_COPYGLOBALDATA, MSGFLT_ADD, nil);
      ChangeWindowMessageFilterEx(Handle, WM_DROPFILES, MSGFLT_ADD, nil);
      DragAcceptFiles(Handle, True);
    end;
    WM_COPYGLOBALDATA et MSGFLT_ADD ne sont pas trouvés (et le nil est en trop)

    A+
    Charly

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 671
    Points : 13 065
    Points
    13 065
    Par défaut
    Il manque un paramètre dans ton prototype "Ex".

    Pour ChangeWindowMessageFilter : function(Msg: uint; dwFlag : dword):BOOL; stdcall;.

    MSGFLT_ADD = 1
    WM_COPYGLOBALDATA = $49

    ps: ce n'est pas une bonne solution de déclarer statiquement cette fonction si ton app doit encore supporter XP.

  7. #7
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 339
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 339
    Points : 3 107
    Points
    3 107
    Par défaut
    Toujours en pleine panade ...

    je fais :

    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
    unit Unit2;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Grids, StdCtrls, ShellApi  ;
     
    Const
         WM_COPYGLOBALDATA = $49  ;
         MSGFLT_ADD = 1  ;
     
     
    type
      TForm2 = class(TForm)
        Label1: TLabel;
        ...
        ListBox1: TListBox;
        procedure FormCreate(Sender: TObject);
        procedure ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
          State: TDragState; var Accept: Boolean);
        ...
      private
        { Déclarations privées }
      protected
         procedure WM_DropFiles(var Msg: TMessage); message WM_DROPFILES;
      public
        { Déclarations publiques }
      end;
    var
      Form2: TForm2;
      ...
      ChangeWindowMessageFilter : function(Msg: uint; dwFlag : dword):BOOL; stdcall;
    implementation
     
    {$R *.dfm}
     
    { =========================================================== }
    procedure TForm2.FormCreate(Sender: TObject);
    begin
      //la fenêtre accepte le glissement d'objets
      ChangeWindowMessageFilter(WM_DROPFILES,1);
    //  ChangeWindowMessageFilterEx(Handle, WM_COPYGLOBALDATA, MSGFLT_ADD);
    //  ChangeWindowMessageFilterEx(Handle, WM_DROPFILES, MSGFLT_ADD);
      DragAcceptFiles(Handle, True);
    end;
     { =========================================================== }
    procedure TForm2.WM_DropFiles(var Msg: TMessage);  
    // d'après le FAQ
     
    var hDeposer: THandle;  
        countFiles, i: integer;  
        FileName: Array[0..255]Of Char;  
    begin  
      //Récupérer dans hDeposer le handle envoyé par le message WM_DROPFILES  
      hDeposer := THandle(Msg.wParam);
      //Compter le nombre de fichiers déposés.  
      countFiles := DragQueryFile(hDeposer, UINT(-1), nil, 0);  
      for i := 0 to pred(countFiles) do  
      begin  
        //Déterminer le nom du ième fichier déposé  
        DragQueryFile(hDeposer, i, FileName, 255);  
        //Ajouter le nom du fichier dans le listbox 
        ListBox1.Items.Add(FileName);  
      end;  
      //Indiquer à Windows la fin du déposer  
      DragFinish(hDeposer);  
    end;
     { =========================================================== }
     
    ...
     
    end.
    j'ai un message pas assez de paramètres originaux sur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      ChangeWindowMessageFilter(WM_DROPFILES,1);
    de plus, avec ChangeWindowMessageFilter MSGFLT_ADD et WM_COPYGLOBALDATA ne servent pas ? (sinon il faut utiliser ChangeWindowMessageFilterEx ?)


    pour éviter la déclaration statique, comment faire autrement ?

    A+
    Charly

  8. #8
    Membre éprouvé
    Avatar de Cirec
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 467
    Points : 1 072
    Points
    1 072
    Par défaut
    Bonjour,

    peut être comme ceci:
    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
    var
      ChangeWindowMessageFilter : function(Msg: uint; dwFlag : dword):BOOL; stdcall;
    const
      MSGFLT_ADD = 1;
      WM_COPYGLOBALDATA = $49;
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      lbrHandle: THandle;
    begin
      lbrHandle := SafeLoadLibrary('User32.dll');
     if lbrHandle <> 0 then
     try
       ChangeWindowMessageFilter := GetProcAddress(lbrHandle, 'ChangeWindowMessageFilter');
       if Assigned(ChangeWindowMessageFilter) then begin
         ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD);
         ChangeWindowMessageFilter(WM_COPYGLOBALDATA, MSGFLT_ADD);
       end;
     finally
       FreeLibrary(lbrHandle);
     end;
    end;
    Cordialement,
    @+

  9. #9
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 339
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 339
    Points : 3 107
    Points
    3 107
    Par défaut
    Bonjour Cirec,

    j'ai mis ton code dans mon Create, mais à la compil, j'ai toujours 'pas assez de paramètres originaux' sur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD);
    juste après WM_DROPFILES,

    il doit y avoir un Pb dans la déclaration de la fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      ChangeWindowMessageFilter : function(Msg: uint; dwFlag : dword):BOOL; stdcall;
    A+
    Charly

  10. #10
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 339
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 339
    Points : 3 107
    Points
    3 107
    Par défaut
    C'est curieux car si je fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    //     ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD);
         ChangeWindowMessageFilter(WM_COPYGLOBALDATA, MSGFLT_ADD);
    ça compile. C'est le WM_DropFiles qui ne lui plait pas ?

  11. #11
    Membre éprouvé
    Avatar de Cirec
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 467
    Points : 1 072
    Points
    1 072
    Par défaut
    j'ai testé le code avec D7 et W7 et il fonctionne
    ce qui me fait penser à ...

    as tu retiré toutes les anciennes déclarations du type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     function ChangeWindowMessageFilterEx(hWnd: HWND; Message : Integer ; Action : DWord): Boolean; stdcall; external 'User32.dll';
    de ton code qui pourraient parasiter et peut être mener à ce genre d'erreur !!

    sinon je vois pas!

    EDIT:
    ah ben là encore plus curieux. Toujours est il que chez moi ça fonctionne !
    essayes peut être dans un nouveau projet pour voir si ça passe ou pas

    Cordialement,
    @+

  12. #12
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 844
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 844
    Points : 11 274
    Points
    11 274
    Billets dans le blog
    6
    Par défaut
    Le problème doit venir de la FAQ : le compilo n'aime pas que le même nom soit utilisé 2 fois :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    procedure WM_DropFiles(var Msg: TMessage); message WM_DROPFILES;
    Delphi 5 Pro - Delphi 10.4 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  13. #13
    Membre éprouvé
    Avatar de Cirec
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 467
    Points : 1 072
    Points
    1 072
    Par défaut
    Citation Envoyé par tourlourou Voir le message
    Le problème doit venir de la FAQ : le compilo n'aime pas que le même nom soit utilisé 2 fois :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    procedure WM_DropFiles(var Msg: TMessage); message WM_DROPFILES;
    Effectivement bien vu

    il suffit donc de modifier en:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    procedure WMDropFiles(var Msg: TMessage); message WM_DROPFILES;
    Cordialement,
    @+

  14. #14
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 339
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 339
    Points : 3 107
    Points
    3 107
    Par défaut
    Super,
    ça marche

    je pense qu'il faudrait modifier la FAQ (le WMDropFiles) et aussi pour ceux qui ont W10 ou W8 ajouter le code de Cirec ?

    Reste ce que dit Andnotor sur XP ?

    Merci à tous les 3

    A+
    Charly

  15. #15
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 844
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 844
    Points : 11 274
    Points
    11 274
    Billets dans le blog
    6
    Par défaut
    Oui, la modification de la FAQ a été demandée, enrichie de toutes ces remarques.
    Delphi 5 Pro - Delphi 10.4 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  16. #16
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 339
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 339
    Points : 3 107
    Points
    3 107
    Par défaut
    Sinon,

    une fonction autonome qui marche bien à appeler dans le Create de la fenêtre :

    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
     { =========================================================== }
     procedure  TForm2.SetDragAndDropOnSystemsWIthUAC(Wnd : HWND; IsEnabled : boolean);
    type
      TChangeWindowMessageFilter = function(Msg : Cardinal; Action : Word) : Bool; stdcall;
    const
      Msg_Add = 1;
      WM_COPYGLOBALDATA = $49;
    var
      DllHandle : THandle;
      ChangeWindowMessageFilter : TChangeWindowMessageFilter;
    begin
      DllHandle := LoadLibrary('user32.dll');
      if DllHandle > 0 then
      begin
        ChangeWindowMessageFilter := GetProcAddress(DllHandle, 'ChangeWindowMessageFilter');
        if Assigned(ChangeWindowMessageFilter) then
        begin
          DragAcceptFiles(Wnd, IsEnabled);
          ChangeWindowMessageFilter(WM_DROPFILES, Msg_Add);
          ChangeWindowMessageFilter(WM_COPYGLOBALDATA, Msg_Add);
        end;
      end;
    end;
     { =========================================================== }
    appel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    { =========================================================== }
    procedure TForm2.FormCreate(Sender: TObject);
    begin
      SetDragAndDropOnSystemsWIthUAC(Handle, True);
      DragAcceptFiles(Handle, True);
    end;
    { =========================================================== }
    Merci à tous

    A+
    Charly

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 671
    Points : 13 065
    Points
    13 065
    Par défaut
    Il faut tout de même rappeler que ce problème survient à cause d'une différence de privilèges entre l'application cible et la source.
    En gros, ton application est lancée en mode admin (il y a eu élévation de privilèges) ou tu débogues depuis Delphi qui a été lancé en mode admin.
    UIAccess=TRUE dans un manifest alloue aussi des privilèges supplémentaires (même s'il n'y a pas de fenêtre de confirmation). Les messages qui lui sont adressés sont également filtrés.

    Et pour être plus généraliste, ça concerne une partie des messages en dessous de WM_USER et tous ceux en dessus.

  18. #18
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 339
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 339
    Points : 3 107
    Points
    3 107
    Par défaut
    Ok, merci Andnotor, je pense qu'il faudra expliquer tout cela dans la FAQ (de façon la plus simple possible, car pour moi ce n'est pas évident !!)

    J'ai vu pas mal d'articles sur le net à ce sujet et je ne suis donc pas seul à avoir eu ce Pb.

    Je marque résolu, car chez moi tout marche bien maintenant.

    A+
    Charly

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 16/05/2010, 21h42
  2. Drag and drop dans un input
    Par kriekbellevue dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 25/12/2006, 21h55
  3. [VB.net] Drag and drop dans une Treeview
    Par gégécap dans le forum Windows Forms
    Réponses: 2
    Dernier message: 19/10/2006, 11h05
  4. [VB.NET]Drag and Drop dans une Listview
    Par gégécap dans le forum Windows Forms
    Réponses: 5
    Dernier message: 23/08/2006, 19h41
  5. Drag and drop dans un TTreeView
    Par BigBenQ dans le forum C++Builder
    Réponses: 3
    Dernier message: 07/10/2005, 15h57

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