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 :

Accès "avancé" au presse-papier sous Wine


Sujet :

Delphi

  1. #1
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut Accès "avancé" au presse-papier sous Wine
    Bonjour,

    J'ai écrit une application qui, à un moment donné, utilise le contenu du presse-papier comme ceci:
    - s'il contient du HTML
    - et si la source est reconnue (SourceURL)
    -> alors fait diverses manips sur le texte (brut)

    Ça fonctionne comme prévu sous Windows, mais pas sous Wine (Linux).

    Comment faire pour récupérer le HTML sous Wine ?

    Extrait du code...

    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
    uses
    // (...)
    ClipBrd;
     
    var
      CF_HTML: UINT;
     
    function ClipboardHtmlToString: string;
    var
      Data: THandle;
      Ptr: PChar;
    begin
      Result := '';
      with Clipboard do begin
        Open;
        try
          Data := GetAsHandle(CF_HTML);
          if Data <> 0 then begin
            Ptr := GlobalLock(Data);
            if Ptr <> nil then begin
              try
                Result := string(Ptr);
              finally
                GlobalUnlock(Data);
              end;
            end;
          end;
        finally
          Close;
        end;
      end;
    end;
     
    procedure TForm1.btnCollerClick(Sender: TObject);
    var
      slItems, slClipBoard: TStringList;
      s, sItem, sTmp: string;
      i1, iCount: Integer;
    begin
      slClipBoard := TStringList.Create;
      try
        slClipBoard.Text := Clipboard.AsText;
     
        iCount := 0;
        s := ClipboardHtmlToString; // \\ // \\ Sous Wine, retourne "<" au lieu du contenu complet !? // \\ // \\
        // ShowMessage(s);
        if Pos('monsite1.com', s) > 0 then begin
          slItems := TStringList.Create;
          try
            repeat
              Split(slClipBoard[iCount], #9, slItems);  // #9 = TAB
              sItem := Trim(slItems[1]);
              i1 := Pos(' -', sItem) + 1;
              if Length(sItem) = i1 then
                SetLength(sItem, i1 - 1);
              edt[iCount, 0].Text := sItem;
              edt[iCount, 1].Text := Trim(slItems[2]);
              Inc(iCount);
            until (iCount >= slClipBoard.Count) or (iCount >= speNbItems.IntValue);
          finally
            slItems.Free;
          end;
        end
        else if Pos('monsite2.com', s) > 0 then begin
          repeat
            sTmp := Trim(slClipBoard[5 * iCount]);
            i1 := Pos(' ', sTmp);
            sItem := Copy(sTmp, i1, Length(sTmp));
            edt[iCount, 0].Text := Trim(sItem);
            edt[iCount, 1].Text := slClipBoard[5 * iCount + 4];
     
            Inc(iCount);
          until ((5 * iCount) >= slClipBoard.Count) or (iCount >= speNbItems.IntValue);
        end
        else if Pos('monsite3.com', s) > 0 then begin
          slClipBoard.Delete(0);  // Supprime la première ligne, vide
          repeat
            edt[iCount, 0].Text := Trim(slClipBoard[8 * iCount + 1]);
            edt[iCount, 1].Text := Trim(slClipBoard[8 * iCount + 5]);
     
            Inc(iCount);
          until ((8 * iCount) >= slClipBoard.Count) or (iCount >= speNbItems.IntValue);
        end;
      finally
        slClipBoard.Free;
      end;
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      CF_HTML := RegisterClipboardFormat('HTML Format');
    end;
    PS: tout le reste de l'application fonctionne parfaitement sous Wine, il y a juste ce problème avec le presse-papier qui m'empêche de passer complètement sous Linux ;-)

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut
    Hum, j'ai l'impression que ce problème n'inspire pas grand monde :-\

    Par acquis de conscience j'ai également essayé avec:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      CF_HTML := RegisterClipboardFormat('text/html');
    end;
    Mais ça ne passe pas non plus.

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 988
    Par défaut
    CF_HTML devrait être de l'ASCII et tu as là manifestement de l'Unicode.
    Un problème avec la source ?

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut
    Peux-tu préciser ta pensée ?
    CF_HTML est un UINT (type d'entier), où est-ce que tu vois du ascii/unicode ?
    (j'ai aussi essayé avec Ptr défini comme PAnsiChar au lieu de PChar, même résultat)

    PS: le HTML provient d'une sélection "copiée" (ctrl+c) depuis le navigateur (Firefox chez moi).

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut
    Pour simplifier les choses, j'ai écrit un petit programme qui copie juste le contenu HTML du presse-papier dans un TMemo.

    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
    procedure TForm1.btnClipboardClick(Sender: TObject);
    var
      MyHandle: THandle;
    begin
      if Clipboard.HasFormat(CF_HTML) then begin
        MyHandle := Clipboard.GetAsHandle(CF_HTML);
        Memo1.Lines.Add(StrPas(GlobalLock(MyHandle)));
        GlobalUnlock(MyHandle);
      end;
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
        CF_HTML := RegisterClipboardFormat('HTML Format');
    end;
    Dans Firefox je copie ta réponse ci-dessus et voici le résultat quand je clique sur le bouton...

    Sous Windows:
    Nom : Capture_Windows.PNG
Affichages : 314
Taille : 16,6 Ko

    Sous Wine:
    Nom : Capture_Wine.PNG
Affichages : 370
Taille : 104,7 Ko

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 988
    Par défaut
    Commence par contrôler qu'il y a bien une donnée CF_HTML dans le presse-papiers par HasFormat et si oui, tu peux ensuite déterminer sa taille par GlobalSize.

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if Clipboard.HasFormat(CF_HTML) then begin
    Si cette première condition n'était pas respectée, le Memo ne serait pas modifié !
    Je ne sais pas si le problème vient de Wine ou si c'est à cause d'une gestion différente du presse-papier sous Linux :-\ Je penche plutôt pour la première hypothèse...

  8. #8
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 188
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 188
    Par défaut
    Salut,

    mon grain de sel parce que ça fait 3 ans que j'ai basculé sous Linux (Debian 32 bits / LXDE)

    Citation Envoyé par GoustiFruit Voir le message
    Je ne sais pas si le problème vient de Wine ou si c'est à cause d'une gestion différente du presse-papier sous Linux :-\ Je penche plutôt pour la première hypothèse...
    Mon point de vue d'utilisateur (je n'ai encore rien eu à coder [avec Lazarus] touchant au presse-papier) : sous Linux c'est le foutoir !
    Le nombre de fois que je hurle parce que je me fais avoir avec un truc complètement idiot : il faut que la source (de la copie) soit encore ouverte pour pouvoir coller dans la cible.
    Et je n'ai pas encore trouvé pourquoi des fois il faut cette condition et des fois ça n'est pas nécessaire.

    Alors ça n'a sans doute pas de rapport avec ton souci précis, mais blinde ton code de tests divers et variés sur le contenu du presse-papiers.

    Quelque chose d'intéressant à lire : ça...
    En fait, ton histoire avec CF_HTML n'a pas l'air aussi simple que ça...

    Courage !

  9. #9
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Salut,

    mon grain de sel parce que ça fait 3 ans que j'ai basculé sous Linux (Debian 32 bits / LXDE)

    Mon point de vue d'utilisateur (je n'ai encore rien eu à coder [avec Lazarus] touchant au presse-papier) : sous Linux c'est le foutoir !
    Le nombre de fois que je hurle parce que je me fais avoir avec un truc complètement idiot : il faut que la source (de la copie) soit encore ouverte pour pouvoir coller dans la cible.
    Et je n'ai pas encore trouvé pourquoi des fois il faut cette condition et des fois ça n'est pas nécessaire.
    Oui la gestion du presse-papier est différente sous linux, et parfois "bizarre". C'est dû je crois à un accent mis sur la sécurité (éviter que des données sensibles restent quelque part en mémoire) et au fait que les applications peuvent gérer leur propre presse-papier au lieu d'avoir un presse-papier partagé global.

    Mais dans mon cas, ce n'est pas le problème parce que j'ai un accès normal au format *texte* du presse-papier.

    Quelque chose d'intéressant à lire, chez les voisins
    Oui il est bien possible que le format soit différent sous Linux, sous Windows il faut enregistrer le format "HTML Format" en passant par les API Windows, sous Linux je n'ai entendu parler que de "text/html". Mais comme mon application tourne sous Wine, j'espérais que ces API étaient implémentées pour faire la conversion si nécessaire. Elles sont implémentées puisque je n'ai pas de plantage ou erreur, mais ça ne donne pas le résultat escompté.

    En passant, j'ai accès au contenu "text/html" du presse-papier avec xclip, donc le presse-papier contient bien ce que je cherche à récupérer dans mon programme Delphi/Wine.

  10. #10
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut
    PS: je viens de faire un test avec Notepad++ tournant sous Wine. Même problème ! J'ai accès au format texte, mais si je choisis "Collage spécial" -> "Coller du contenu HTML", j'ai juste quelques caractères "spéciaux" :-\ Ça sent le pâté !
    Nom : Capture_Texte.PNG
Affichages : 353
Taille : 140,4 Ko

    Nom : Capture_HTML.PNG
Affichages : 308
Taille : 138,4 Ko

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 988
    Par défaut
    Citation Envoyé par GoustiFruit Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if Clipboard.HasFormat(CF_HTML) then begin
    Si cette première condition n'était pas respectée, le Memo ne serait pas modifié !
    Je n'avais pas fait attention que tu l'avais rajouté depuis le premier message

    Mais je le répète, le contenu du presse-papier est Unicode (FFFE est le BOM) alors qu'il devrait être en ASCII d'après ce que je lis ici. StrPas, c'est pour l'ANSI. Tu ne retrouves donc que la première lettre puisque le premier #0 est considéré comme la fin de chaîne.

    Si ton Delphi n'est pas Unicode, passe par un PWideChar pour remplir une WideString.

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 988
    Par défaut
    Bien sûr, ce n'est qu'un emplâtre puisque le formatage ne semble pas être conservé...

  13. #13
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut
    Ah ok, je crois comprendre ce que tu veux dire: sous Windows le contenu du presse-papier est en ASCII alors qu'il serait en Unicode sous Linux ? Je vais tester ça... avec Delphi 7 pour info.

    EDIT: il y a du mieux... mais du coup ça ne passe plus sous Windows. Je ne souhaite pas écrire de code qui détecte l'environnement pour s'y adapter, je cherche une solution "universelle" (sinon, autant appeler un outil externe sous Linux - comme xclip - pour faire le travail !)
    Nom : Capture.PNG
Affichages : 309
Taille : 139,2 Ko

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 988
    Par défaut
    Je doute qu'il y ait une solution universelle.

    En cherchant un peu, il semblerait qu'il faille lire le presse-papier sous différents formats pour retrouver plus ou moins un équivalent au "HTML format" Windows : text/x-moz-url-priv pour SourceURL et text/_moz_htmlcontext pour le corps du message incluant les balises <HTML><BODY>.

    Ca a l'air assez complexe sous Linux. Comme le mentionnait Jipété, il y a une communication mise en place entre l'app source et celle de destination.

  15. #15
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut
    Ah merci pour ce lien, à partir de là j'ai fait des recherches sur text/x-moz-url-priv et trouvé un outil (InsideClipboard.exe sur Nirsoft.net) qui liste les formats disponibles et leur contenu sous Windows; il semblerait que je puisse récupérer la source avec text/x-moz-url-priv sous Windows et Linux, ce qui ensuite me permettrait de faire le traitement adéquat sur le format texte du presse-papier. Je reviendrai quand j'aurai testé...

  16. #16
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut
    Et ça... marche !

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

Discussions similaires

  1. gestion du presse-papier sous Python
    Par jpb974 dans le forum Général Python
    Réponses: 2
    Dernier message: 15/02/2014, 13h09
  2. [XL-2000] coller tout le presse-papier sous Excel 2000
    Par juju05 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 21/01/2010, 19h32
  3. Réponses: 12
    Dernier message: 10/06/2006, 20h07

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