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

C Discussion :

Contenu texte du presse papier


Sujet :

C

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 58
    Points : 76
    Points
    76
    Par défaut Contenu texte du presse papier
    Bonjour,

    Quelqu'un pourrait-il me proposer une fonction C qui renvoie avec le type char* le contenu texte du presse papier système (Clipboard). J'aimerai disposer des versions de cette fonction tant pour Windows que pour Linux.

    De même j'aimerai bien avoir les fonctions sous Windows et Linux qui fassent l'opération inverse, à savoir mettre le contenu d'un char* sous la forme d'un texte dans le presse papier système.

    Merci d'avance.

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Sous Windows, regarde du côté de OpenClipboard() et ses fonctions sœurs. Mais c'est compliqué et basé sur des vieux mécanismes, tu ferais donc mieux d'utiliser une bibliothèque portable qui le ferait pour toi.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 58
    Points : 76
    Points
    76
    Par défaut Une solution qui a l'air de fonctionner pour Windows - Miracle ?
    Merci pour le pointeur. La petite bibliothèque suivante permet bien de lire le presse papier et d'y écrire à partir d'une console sous Windows. Par contre je ne sais pas si elle est écrire dans les règles de l'art concernant la gestion des erreurs (sans doute pas...). Je ne sais pas ce qu'elle peut donner sous Linux.

    Le fichier Interface de la bibliothèque : Presse_Papier.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    const char* Lire_du_PressePapier();
     
    void Ecrire_dans_PressePapier(const char* w);
    et le corps de la bibliothèque : Presse_Papier.c
    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
    #include <windows.h>
    #include <stdio.h>
    #include "Presse_Papier.h"
     
    void BailOut(char *msg)
    {
      fprintf(stderr, "Exiting: %s\n", msg);
      exit(1);
    }
     
    const char* Lire_du_PressePapier()
    {
      HANDLE h;   
      if (!OpenClipboard(NULL)) BailOut("Presse-Papier impossible à ouvrir");   
      h = GetClipboardData(CF_TEXT); 
      CloseClipboard();
      return (char *) h; 
    }
     
     
      void Ecrire_dans_PressePapier(const char* w)
      {
        const size_t len = strlen(w) + 1;
        HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
        memcpy(GlobalLock(hMem), w, len);
        GlobalUnlock(hMem);
        OpenClipboard(0);
        EmptyClipboard();
        SetClipboardData(CF_TEXT, hMem);
        CloseClipboard();
      }

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 58
    Points : 76
    Points
    76
    Par défaut La lecture et l'écriture du Pressse-Papier
    Après génération par compilation du fichier objet Presse_Papier.o, le binding vers Ada de cette petite bibliothèque marche bien :

    Fichier interface Ada :
    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
    pragma Ada_2012;
    pragma Style_Checks (Off);
     
    with Interfaces.C; use Interfaces.C;
    with Interfaces.C.Strings;
     
    package Presse_Papier_h is
     
       function Lire_du_PressePapier return Interfaces.C.Strings.chars_ptr;  -- Presse_Papier.h:2
       pragma Import (C, Lire_du_PressePapier, "Lire_du_PressePapier");
     
       procedure Ecrire_dans_PressePapier (w : Interfaces.C.Strings.chars_ptr);  -- Presse_Papier.h:4
       pragma Import (C, Ecrire_dans_PressePapier, "Ecrire_dans_PressePapier");
     
    end Presse_Papier_h;
    Programme de test en Ada :
    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
    pragma Ada_2012;
    pragma Style_Checks (Off);
     
    with presse_papier_h;
    use presse_papier_h;
    with Interfaces.C; use Interfaces.C;
    with Interfaces.C.Strings; use Interfaces.C.Strings;
    with Ada.Text_IO; use Ada.Text_IO;
     
     
    procedure Main_Ada is
    PRAGMA Linker_Options("d:\PROGRAMMATION\C\Clipboard\Presse_Papier.o") ; 
     
    Function Lire return string is
    K : constant Chars_Ptr := Lire_du_PressePapier;
     
    begin
      return Value(K);
     
    end;
     
    begin
      Put_Line(Value(Lire_du_PressePapier));
      Ecrire_dans_PressePapier(New_String("Emile8 vous salue bien !"));
     
    end Main_Ada;

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je ne vois rien là-dedans qui dit comment la string retournée par la fonction C est censée être libérée... En d'autres termes, grosse fuite de mémoire.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 58
    Points : 76
    Points
    76
    Par défaut Fuite ... Quelle fuite ?
    À la lecture, on ne touche pas au contenu du Clipboard (Presse papier). On se contente de manipuler un pointeur vers ce contenu. Je ne pense pas qu'il puisse y avoir de fuite au niveau de la place mémoire occupée par ce pointeur si les retours fonctions se font bien par copie.

    À l'écriture dans le Clipboard, au niveau de la fonction C, on fait bien attention d'appeler une fonction spécifique qui vide ce Clipboard de son contenu, ce qui doit correctement restituer la mémoire si cette fonction est bien conçue. Si le souci est du coté Ada, c'est la fonction New_String qui construit un Char* avec la zone mémoire qu'il permet de contrôler à partir de son paramètre String Ada. Ce Char* est transmit par copie à la fonction C qui copie la mémoire qu'il contrôle dans le Clipboard. Ada par la suite, à la sortie de son bloc, libèrera le Char* et l'empreinte mémoire qui lui avait été initialement associée.

    À priori si je ne me trompe pas, je ne pense pas qu'il y ait de mécanisme de fuite mémoire si mes hypothèses sont bonnes.

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ah tu as raison, le handle est contrôlé par le presse-papier, je croyais que GetClipboardData() en allouait un nouveau.
    Par contre:
    The application must not use the handle after the EmptyClipboard or CloseClipboard function is called,
    Tu as ici une race condition, car un autre processus pourrait manipuler le presse-papier, rendant invalide le handle.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 58
    Points : 76
    Points
    76
    Par défaut
    Je pense que les instructions OpenClipboard(0) et CloseClipboard() sont là pour garantir un seul accès à la fois au Clipboard en écriture de la part de processus concurrents (idem objets protégés d'Ada). Ton warning est respecté car la fonction qui écrit dans le Clipboard n'y touche plus après sa dernière instruction CloseClipboard().

    Quant à l' installation préalable en mémoire C de la chaine de caractères destinée au Clipboard, elle est aussi protégée entre un GlobalLock et un GlobalUnlock. De plus cette zône mémoire étant nouvelle, elle ne devrait pas être connue des autres processus car le Clipboard ne pointe pas encore vers elle.

    Je n'ai pas le détail de ces fonctions, mais leur présences et le sens de leurs noms font penser qu'elles veillent bien au grain des "Race conditions".

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ce n'est pas protégé par le GlobalLock() parce que le code Ada accède à la zone mémoire après le GlobalUnlock()! Et pareil pour le coup du CloseClipboard().

    Pour éviter cela, il faudrait convertir la chaîne C en chaîne Ada directement dans le code C, et la retourner ainsi; mais en cherchant sur Internet, je n'ai vu aucun moyen simple de créer une chaîne Ada depuis un code C.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 58
    Points : 76
    Points
    76
    Par défaut Une analyse plus détaillée
    Ada peut bien sur accéder aux données pointées par w car celui-ci est le char* qu'il a passé lors de l'appel de la fonction C d'écriture dans le Clipboard.
    Mais une fois ces données copiées dans hMem par l'instruction memcpy(GlobalLock(hMem), w, len);, Ada ne pourra pas les modifier dans leur nouvelle localisation car il ne connait pas l'adresse de cette zône mémoire hMem qui a été affectée dynamiquement au C par le système et ce dernier de toute façon interdirait à Ada d'aller écrire en dehors de son territoire (erreur de segmentation ?). C'est cette nouvelle zône qui va devenir le lieu de stockage du Clipboard via l'instruction SetClipboardData(CF_TEXT, hMem); et ce après restitution au système de son lieu de stockage précédent via l'instruction EmptyClipboard();.

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je parlais de la fonction de lecture. Celle d'écriture m'a l'air pas trop mal.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 58
    Points : 76
    Points
    76
    Par défaut
    Je n'ai vu aucun moyen simple de créer une chaîne Ada depuis un code C
    .
    En fait il suffirait que le code C crée une chaine char* temporaire, copie du contenu du Clipboard et la renvoie à Ada qui est capable de la lire et éventuellement de la transformer en String Ada avec sa fonction Value. Charge à C de recycler ce char* après avoir laissé le temps à Ada d'y travailler.

    Ceci dit, j'ai un peu essayé de "corrompre" le Clipboard à partir d'Ada en utilisant le retour de la fonction C de lecture telle que je l'ai écrite, mais je n'y suis pas encore arrivé . Si vous avez une idée pour réaliser cette opération ...

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par Emile8 Voir le message
    Charge à C de recycler ce char* après avoir laissé le temps à Ada d'y travailler.
    Et pour ça, il faut qu'Ada fasse un appel de fonction vers le C.

    Un truc du genre:
    Code C : 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
    char* Lire_du_PressePapier()
    {
    	HGLOBAL h;
    	char const *p;
    	char* ret;
    	if (!OpenClipboard(NULL)) BailOut("Presse-Papier impossible à ouvrir");   
    	h = GetClipboardData(CF_TEXT); 
    	if(h == NULL) { CloseClipboard(); return NULL; }
    	p = GlobalLock(h);
    	ret = CoTaskMemAlloc(strlen(p)+1);
    	if(ret == NULL) BailOut("Plus de mémoire!");
    	strcpy(ret, p);
    	GlobalUnlock(h);
    	CloseClipboard();
    	return ret; 
    }
     
    void Liberer_Chaine_PressePapier(char *p)
    {
    	CoTaskMemFree(p);
    }

    Ceci dit, j'ai un peu essayé de "corrompre" le Clipboard à partir d'Ada en utilisant le retour de la fonction C de lecture telle que je l'ai écrite, mais je n'y suis pas encore arrivé . Si vous avez une idée pour réaliser cette opération ...
    En lecture, le risque n'est pas de corrompre le presse-papier: Le risque est que le code Ada accède à un pointeur non-valide et (si tu as du bol) crashe sur le coup.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 58
    Points : 76
    Points
    76
    Par défaut
    J'ai fait l'essai avec la nouvelle fonction lecture proposée que j'ai un peu modifiée au niveau des instructions d'allocation et de libération de la mémoire (la compilation ne se faisait pas avec celles proposées. Sans doute un Pb de bibliothèque C ...).

    Le résultat est que la nouvelle lecture à partir d'Ada marche lorsque le texte mis dans le presse-papier n'est pas trop important, mais qu'elle plante (raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION) lorsqu'il est de taille conséquente.

    Avec ma fonction de lecture initiale la lecture d'un gros texte dans le presse-papier se fait par contre sans encombre.

    CODE C :
    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
    #include <windows.h>
    #include <stdio.h>
    #include <Objbase.h>
    #include "Presse_Papier.h"
     
    void BailOut(char *msg)
    {
      fprintf(stderr, "Exiting: %s\n", msg);
      exit(1);
    }
     
    const char* Lire_du_PressePapier()
    {
      HANDLE h;   
      if (!OpenClipboard(NULL)) BailOut("Presse-Papier impossible à ouvrir");   
      h = GetClipboardData(CF_TEXT); 
      CloseClipboard();
      return (char *) h; 
    }
     
    char* Lire2_du_PressePapier()
    {
    	HGLOBAL h;
    	char const *p;
    	char* ret;
    	if (!OpenClipboard(NULL)) BailOut("Presse-Papier impossible à ouvrir");   
    	h = GetClipboardData(CF_TEXT); 
    	if(h == NULL) { CloseClipboard(); return NULL; }
    	p = GlobalLock(h);
    	//ret = CoTaskMemAlloc(strlen(p)+1);
    	ret = GlobalAlloc(GMEM_MOVEABLE, strlen(p)+1);
    	if(ret == NULL) BailOut("Plus de mémoire pour Buffer de lecture du Press-papier!");
    	strcpy(ret, p);
    	GlobalUnlock(h);
    	CloseClipboard();
    	return ret; 
    }
     
    void Liberer_Chaine_PressePapier(char *p)
    {
    	//CoTaskMemFree(p);
    	GlobalFree(p);
    }
     
     
     
      void Ecrire_dans_PressePapier(const char* w)
      {
        const size_t len = strlen(w) + 1;
        HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
        memcpy(GlobalLock(hMem), w, len);
        GlobalUnlock(hMem);
        OpenClipboard(0);
        EmptyClipboard();
        SetClipboardData(CF_TEXT, hMem);
        CloseClipboard();
    }
    CODE ADA :
    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
    pragma Ada_2012;
    pragma Style_Checks (Off);
     
    with presse_papier_h;
    use presse_papier_h;
    with Interfaces.C; use Interfaces.C;
    with Interfaces.C.Strings; use Interfaces.C.Strings;
    with Ada.Text_IO; use Ada.Text_IO;
     
    procedure Main_Ada is
    PRAGMA Linker_Options("d:\PROGRAMMATION\C\Clipboard\Presse_Papier.o") ;
     
    Function Lire_clipboard return string is
     K :  Chars_Ptr := Lire_du_PressePapier;
     S : String := Value(K);
    begin
      return S;
    end;
     
    Function Lire2_clipboard return string is
     K :  Chars_Ptr := Lire2_du_PressePapier;
     S : String := Value(K);
    begin
      Liberer_Chaine_PressePapier(K);  
      return S;
    end;
     
    begin
      Put_Line("MAIN_ADA Run");
      Put_Line(Lire2_Clipboard);
      Ecrire_dans_PressePapier(New_String("Emile8 vous salue bien !"));
     
    end Main_Ada;
    INTERFACE ADA POUR LE BINDING :
    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
    pragma Ada_2005;
    pragma Style_Checks (Off);
     
    with Interfaces.C; use Interfaces.C;
    with Interfaces.C.Strings;
     
    package Presse_Papier_h is
     
       function Lire_du_PressePapier return Interfaces.C.Strings.chars_ptr;  -- Presse_Papier.h:2
       pragma Import (C, Lire_du_PressePapier, "Lire_du_PressePapier");
     
       function Lire2_du_PressePapier return Interfaces.C.Strings.chars_ptr;  -- Presse_Papier.h:4
       pragma Import (C, Lire2_du_PressePapier, "Lire2_du_PressePapier");
     
       procedure Liberer_Chaine_PressePapier (p : Interfaces.C.Strings.chars_ptr);  -- Presse_Papier.h:6
       pragma Import (C, Liberer_Chaine_PressePapier, "Liberer_Chaine_PressePapier");
     
       procedure Ecrire_dans_PressePapier (w : Interfaces.C.Strings.chars_ptr);  -- Presse_Papier.h:8
       pragma Import (C, Ecrire_dans_PressePapier, "Ecrire_dans_PressePapier");
     
    end Presse_Papier_h;

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Utilise GPTR au lieu de GMEM_MOVEABLE pour l'allocation de ret.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #16
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 58
    Points : 76
    Points
    76
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Utilise GPTR au lieu de GMEM_MOVEABLE pour l'allocation de ret.
    Effectivement tout s'arrange avec GPTR et je retrouve la capacité avec la nouvelle fonction de lecture à traiter les gros volumes de données dans le Presse-papier. Je ne connaissais pas cette différence avec GMEM_MOVEABLE.

    Finalement il y a bien symétrie entre les deux fonctions d'écriture et de lecture qui doivent réserver de la mémoire tampon pour effectuer leurs opérations.

    Merci.

    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
    #include <windows.h>
    #include <stdio.h>
    //#include <Objbase.h>
    #include "Presse_Papier.h"
     
    void BailOut(char *msg)
    {
      fprintf(stderr, "Exiting: %s\n", msg);
      exit(1);
    }
     
    const char* Lire_du_PressePapier()
    {
      HANDLE h;   
      if (!OpenClipboard(NULL)) BailOut("Presse-Papier impossible à ouvrir");   
      h = GetClipboardData(CF_TEXT); 
      CloseClipboard();
      return (char *) h; 
    }
     
    char* Lire2_du_PressePapier()
    {
    	//HGLOBAL h;
    	HANDLE h; 
    	char const *p;
    	char* ret;
    	if (!OpenClipboard(NULL)) BailOut("Presse-Papier impossible à ouvrir");   
    	h = GetClipboardData(CF_TEXT); 
    	if(h == NULL) { CloseClipboard(); return NULL; }
    	p = GlobalLock(h);
    	//ret = CoTaskMemAlloc(strlen(p)+1);
    	ret = GlobalAlloc(GPTR, strlen(p)+1);
    	if(ret == NULL) BailOut("Plus de mémoire pour Buffer de lecture du Press-papier!");
    	strcpy(ret, p);
    	GlobalUnlock(h);
    	CloseClipboard();
    	return ret; 
    }
     
    void Liberer_Chaine_PressePapier(char *p)
    {
    	//CoTaskMemFree(p);
    	GlobalFree(p);
    }
     
     
     
      void Ecrire_dans_PressePapier(const char* w)
      {
        const size_t len = strlen(w) + 1;
        HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
        memcpy(GlobalLock(hMem), w, len);
        GlobalUnlock(hMem);
        OpenClipboard(0);
        EmptyClipboard();
        SetClipboardData(CF_TEXT, hMem);
        CloseClipboard();
    }

Discussions similaires

  1. Coller une image contenu dans le Presse papier dans un contrôle Image VBA
    Par Fredooooo dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 10/01/2016, 21h59
  2. [XL-2010] Rechercher et remplacer un texte contenu dans le presse papier
    Par fate1 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 11/06/2015, 14h25
  3. [Toutes versions] Copier contenu Textbox dans presse papier
    Par zouille dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 09/02/2014, 10h43
  4. Réponses: 13
    Dernier message: 15/09/2010, 14h18
  5. Selection Text et presse papier
    Par Mozofeuk dans le forum Silverlight
    Réponses: 3
    Dernier message: 20/05/2010, 10h00

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