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 :

Pb conversion de caractères après reception de WM_COPYDATA [Débutant]


Sujet :

C#

  1. #1
    Membre régulier
    Homme Profil pro
    retraité
    Inscrit en
    Mars 2023
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Mars 2023
    Messages : 89
    Points : 75
    Points
    75
    Par défaut Pb conversion de caractères après reception de WM_COPYDATA
    Bonjour

    Je passe des valeurs d une application Delphi à une application C#.
    Lors de la reception dans l appli C#, le texte affiché ne correspond pas vraiment à celui envoyé :
    Affichage C#:
    l'id de l'expediteurr¾p
    ¸°
    —é|Ë?ý‚ R¸6É
    ÿ%hüv¤$
    7.76876924197368E-317
    0
    Attendu :
    l''id de l''expediteur
    Une info
    Un commentaire
    123.456
    789.123;
    J'ai cherché du côté de [MarshalAs(UnmanagedType.LPStr)] mais l'affichage ne correspond toujours pas...
    Côté 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
    public struct COPYDATASTRUCT
            {
                public IntPtr dwData;
                public int cbData;
                [MarshalAs(UnmanagedType.LPStr)]
                public string Expediteur;
                [MarshalAs(UnmanagedType.LPStr)]
                public string Information;
                [MarshalAs(UnmanagedType.LPStr)]
                public string Commentaire;
                public double Valeur1;
                public double Valeur2;
     
            }
     
     
    mystr = new COPYDATASTRUCT();
                        Type mytype = mystr.GetType();
                        mystr = (COPYDATASTRUCT)m.GetLParam(mytype);
                        Trace(mystr.Expediteur);
                        Trace(mystr.Information);
                        Trace(mystr.Commentaire);
                        Trace(mystr.Valeur1.ToString());
                        Trace(mystr.Valeur2.ToString());
    Mon code côté Delphi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    type
      PEnvoiMSG = ^TEnvoiMSG;
     
      TEnvoiMSG = packed record
        Expediteur: string[255];
        Information: string[255];
        Commentaire: string[255];
        Valeur1: double;
        Valeur2: double;
      end;
    Le fait que le string soit limité en taille à 255 caractères a t il une influence ?

    Je débute et ne comprends absolument pas pourquoi un tel résultats étant donné que les déclarations ont le bon type et que je n ai aucun message d'erreur./avertissement

    Merci pour votre aide

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    1 322
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 1 322
    Points : 1 928
    Points
    1 928
    Par défaut
    Les données sont envoyés et reçues de quelle façon? fichier, flux, encodage, ...
    Retire le mot clé packed coté Delphi pour voir si c'est mieux.

  3. #3
    Membre régulier
    Homme Profil pro
    retraité
    Inscrit en
    Mars 2023
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Mars 2023
    Messages : 89
    Points : 75
    Points
    75
    Par défaut
    merci de te pencher sur mon problème.
    j ai essayé en retirant le packed mais idem.
    pour l envoi je procède ainsi :
    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
     
    var
      h: THandle;
      CopyDataStruct: TCopyDataStruct;
      Envoi: TEnvoiMSG;
    begin
     
    ...
     
     with Envoi do
        begin
          Expediteur := 'l''id de l''expediteur';
          Information := 'Une info';
          Commentaire := 'Un commentaire';
          Valeur1 := 123.456;
          Valeur2 := 789.123;
        end;
        with CopyDataStruct do
        begin
          dwData := 1;
          cbData := sizeof(Envoi);
          lpData := @Envoi;
        end;
        SendMessage(h, WM_COPYDATA, Form1.Handle, LongInt(@CopyDataStruct));

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    1 322
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 1 322
    Points : 1 928
    Points
    1 928
    Par défaut
    Je pense que le problème est dans la réception si je regarde différents forums, dont celui-ci surtout https://stackoverflow.com/a/1638559
    Je cite la réponse:

    After a long time searching for the answer to this question, I realized that I was missing a VERY important step. I feel like an idiot, but here's the answer to my own question.

    The C# struct should look like this:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
    public unsafe struct DataStruct
    {
        public int x;
        public int y;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=40)]
        public string s;
        public double d;
        public char c;
    };
    And another struct must be defined to receive the WM_COPYDATA info. It looks like this:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
    public unsafe struct CopyDataStruct
    {
        public IntPtr dwData;
        public int cbData;
        public IntPtr lpData;
    }
    And the WndProc method should be changed to look like this:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        if (msg == 0x4A)
        {
            CopyDataStruct cps = (CopyDataStruct)Marshal.PtrToStructure(lParam, typeof(CopyDataStruct));
            DataStruct data = (DataStruct)Marshal.PtrToStructure(cps.lpData, typeof(DataStruct));
            updateText(data);
            handled = true;
        }
     
        return (IntPtr)0;
    }
    I was using the CopyDataStruct in my previous working solution, and I just forgot to use it in the newer version.

  5. #5
    Membre régulier
    Homme Profil pro
    retraité
    Inscrit en
    Mars 2023
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Mars 2023
    Messages : 89
    Points : 75
    Points
    75
    Par défaut
    Merci pour le lien
    J ai donc créé une nouvelle application pour tester. en reprenant la structure du code du post cité
    Depuis mon appli delphi j'envois 3 fois le message suivant :
    x := 777;
    y := 444;
    s := 'Un String';
    d := 123.456;
    c := 'z';
    Résultat :
    un entier 777
    un autre entier 444

    un string Un StringD
    Taille string 11

    un double 3.60923473990647E-308
    Le double < 1

    un char entre chevrons >>>*<<<
    ---------------------------------------
    un entier 777
    un autre entier 444

    un string Un Stringt“ÿÿÿÿÿ„1
    Taille string 22

    un double 6.55158051300956E-311
    Le double < 1

    un char entre chevrons >>><<<
    ---------------------------------------
    un entier 777
    un autre entier 444

    un string Un String¡”ÿÿÿÿÿ„1
    Taille string 22

    un double 7.31125500617512E-311
    Le double < 1

    un char entre chevrons >>><<<
    ---------------------------------------
    Pour la réception du message en C# j'utilise ce 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
    protected override void WndProc(ref Message m)
            {
                switch (m.Msg)
                {
                    case WM_USER:
                        MessageBox.Show("Message recieved: " + m.WParam + " - " + m.LParam);
                        break;
                    case WM_COPYDATA:
                        CopyDataStruct cps = (CopyDataStruct)Marshal.PtrToStructure(m.LParam, typeof(CopyDataStruct));
                        DataStruct data = (DataStruct)Marshal.PtrToStructure(cps.lpData, typeof(DataStruct));
                        memo1.Text +="un entier " +data.x.ToString() + "\r\n";
                        memo1.Text += "un autre entier "+data.y.ToString() + "\r\n";
     
                        memo1.Text += "\r\n";
                        memo1.Text += "un string " + data.s + "\r\n";                   
                        memo1.Text += "Taille string " + data.s.Length.ToString() + "\r\n";
     
                        memo1.Text += "\r\n";
                        memo1.Text += "un double " + data.d.ToString() + "\r\n";
                        if (data.d < 1)
                        {
                            memo1.Text += "Le double < 1" + "\r\n";
                        }
     
                        memo1.Text += "\r\n";
                        memo1.Text += "un char entre chevrons >>>" + data.c.ToString() + "<<<\r\n";
                        memo1.Text += "---------------------------------------\r\n";
                        break;
                }
                base.WndProc(ref m);
     
            }
    Donc je suis totalement perdu parce que j'imagine mon app delphi envoi tout ou rien et qu en l occurrence elle envoi ...
    Donc tous les conseils sont les bienvenus.

    Dernière chose. Comment tester la longueur d un char. Si je tente .length VS me dit que impossible car integer et si je teste is null, impossible car type non nullable ?

    Merci pour votre aide

  6. #6
    Membre régulier
    Homme Profil pro
    retraité
    Inscrit en
    Mars 2023
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Mars 2023
    Messages : 89
    Points : 75
    Points
    75
    Par défaut
    bon etant donné que je ne suis parvenu à rien, j ai traité la chaine reçue avec une Regex pour parvenir à avoir un affichage conforme

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

Discussions similaires

  1. Conversion de caractére après TMap
    Par Bugatti dans le forum Développement de jobs
    Réponses: 6
    Dernier message: 28/07/2011, 10h38
  2. [VB.NET] Conversion de caractères
    Par WriteLN dans le forum Windows Forms
    Réponses: 8
    Dernier message: 17/03/2005, 08h45
  3. [DOS] batch et conversion de caractères
    Par lujayne dans le forum Scripts/Batch
    Réponses: 2
    Dernier message: 14/12/2004, 16h05
  4. [DB2][Access]Conversion de caractères
    Par BAYRAL dans le forum DB2
    Réponses: 2
    Dernier message: 12/10/2004, 10h00
  5. Conversion et re-conversion des caractères reservé à MySQL
    Par Didier100 dans le forum Bases de données
    Réponses: 4
    Dernier message: 30/06/2004, 14h23

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