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

API, COM et SDKs Delphi Discussion :

L'évènement OnChange ne se déclenche pas pour les contrôles TNT (Unicode)


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre éclairé

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    361
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 361
    Billets dans le blog
    1
    Par défaut L'évènement OnChange ne se déclenche pas pour les contrôles TNT (Unicode)
    Bonjour,

    Je suis sous W10 et utilise Delphi 6 PE.

    Je suis en train d'explorer ceci:
    { Tnt Delphi Unicode Controls }
    { http://www.tntware.com/delphicontrols/unicode/ }
    { Version: 2.3.0
    J'arrive à créer et configurer les différents controles, utiliser les classes etc sans problèmes.
    J'arrive a configurer des évènements sur les controles (OnClicl, OnClose, ...). Tout cela fonctionne.

    Mais je n'arrive pas à activer l'évènement OnChange, sur les contrôles suivants;
    TTntEdit, TTntMemo, TTntComboBox.

    A la compilation, aucune erreur. C'est juste que l'évènement n'est jamais déclenché.
    C'est pourtant un TNotifyEvent banal, tout comme le OnClick qui, lui, se déclenche correctement.

    Sur des contrôles VCL normaux (ceux de Delphi 6 PE, je peux déclencher cet évènement sans problème.
    Je pense qu'il y a un problème spécifique aux contrôles TTnt... pour cet évènement particulier.

    Est-ce que vous auriez une idée ?

  2. #2
    Membre éclairé

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    361
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 361
    Billets dans le blog
    1
    Par défaut
    Désolé, le problème se situait entre la chaise et le clavier...
    L'ereur venait de mon code, et maintenant, tout fonctionne bien.
    Voici, à tout hasard, ce que je fais, dans un fichier ZIP contenant le projet complet...
    Fichiers attachés Fichiers attachés

  3. #3
    Membre éclairé

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    361
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 361
    Billets dans le blog
    1
    Par défaut
    Fausse joie... Il y a bien un problème.

    L'évènement OnChange ne se déclenche pas si l'objet Unicode est créé dans une DLL, mais il se déclenche pas s'il est créé dans le code principal du programme.
    Et ceci est vrai que le programme soit écrit en Delphi ou dans un autre langage (comme Panoramic dans mon cas). Je joins un ZIP avec les codes et exécutables complets pour mettre le problème en évidence, ainsi qu'un fichier ReadMe.rtf donnant des explications détaillées. La DLL nécessaire (KGF.dll) peut être tééchargée partir du lien suivant: http://klauspanoramic.infinityfreeapp.com/KGF.zip. Ce fichier était trop gros pour l'intégrer dans le premier ZIP - le upload se terminait toujours en erreur.

    Voici ce que contient ReadMe.rtf:
    Problème de l'évènement ON_CHANGE
    =================================

    Ce dossier contient une copie de ma DLL en Delphi 6 PE.
    Cette DLL contient des centaines de fonctions, dont une seule esy utilisée ici:
    function TestEditChangeNew(hnd: THandle): integer; stdcall;

    Ce dossier comprend deux programmes de démonstration:
    test_UnicodeEdit programme en Panoramic (Basic)
    UnicodeEdit programme écrit en Delphi 6 PE

    test_UnicodeEdit
    Le programme en Panoramic affiche un bouton qui appelle une fonction de KGF.dll qui crée un TTntEdit ainsi qu'un TMemo. Cette fonction affecte un évènement OnClick et un évènement OnChange à l'objet TTntEdit créé par elle. Les procédures évènement ne font rien d'autre que de déposer une ligne identifiante de l'évènement dans le TMemo.

    Or, on voit clairement que l'évènement OnClick est bien pris en compte, mais l'évènement OnChange ne se déclenche jamais.

    UnicodeEdit
    Le programme écrit en Delphi 6 PE affiche deux boutons:
    Via DLL
    Sans DLL

    Le premier bouton effecture exactement le même traitementque celui du programme Panoramic: appel de la fonction TestEditChangeNew de KGF.dll.
    Résultat: identique !

    Le second bouton effecture exactement le même traitement, mais sans DLL, le code étant copié à l'intérieur du code de traitement du clic sur le bouton.
    Résultat: Là, tout marche bien !

    J'en tire un conclusion qui me laisse perplexe:
    1. L'évènement OnClick fonctionne qu'il soit traité dans le code ou dans la DLL
    2. L'évènement OnChange ne fonctionne que s'il est traité dans le code. Il ne se déclenche pas s'il est traité dans la DLL.

    Pourquoi ? Qu'est-ce que j'ai raté ou mal compris ?
    Fichiers attachés Fichiers attachés

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 999
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 999
    Par défaut
    Avec un TEdit classique, on suppose que le OnChange fonctionne correctement ?
    En y réfléchissant un peu, on pourrait en douter aussi !

    Cela serait une mauvaise transmission du message WM_COMMAND via DoControlMsg en CN_COMMAND avec EN_CHANGE

    C'est parfois tordu, je crois que c'est fenêtre Parent qui reçoit le message et fait le dispatch sur des fenêtres enfants (un TCustomEdit, TEdit ou TTntEdit sont des enfants) et tu as l'inverse aussi, comme pour la capture du KeyPreview, l'enfant envoie à son parent le Message pour un traitement global avant le traitement local.

    When the VCL processes certain WM notifications from the Win32 API, like WM_COMMAND and WM_NOTIFY, which are sent from a child control to its parent window, the VCL reflects them as CN messages (CN_COMMAND and CN_NOTIFY) back to the child that sent them. This allows VCL controls to handle their own notifications.
    C'est différent du OnClick qui correspond à WM_LBUTTONUP qui est envoyé à la fenêtre ayant le focus.


    On peut penser que la propriété Parent du TTntEdit qui permet qu'il soit présent dans Controls[] qui permet le Dispatch
    Je n'ai pas lu le code mais tu dois utiliser le SetParent via Handle donc tu perds toutes la logique de la VCL revenant au plus strict comportement de l'API Windows.

    J'ai eu pas mal de problème d'un SetParent Handle, plein de composant réagisse mal dans ce cas, j'utilisais beaucoup de forme imbriquée, je ne créé pas de Controles mais une TForm utilisé comme des Frames pouvant être Exe Form + DLL Form + 2eme DLL Form + 3eme DLL Form, chaque Form ayant un Panel ou un GroupBox, éventuellement un ScrollBox comme container de la fenêtre en dessous.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre éclairé

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    361
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 361
    Billets dans le blog
    1
    Par défaut
    C'est une piste intéressante ! Je vais faire des tests...

  6. #6
    Membre éclairé

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    361
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 361
    Billets dans le blog
    1
    Par défaut
    Tu avais raison !

    Même avec un TEdit "normal", ça fait le même problème !

    J'ai donc créé un TPanel normal dont le parent est un TForm défini dans une unité de données globales (donc toujours visible)?
    J'ai ensuite créé mon TTntEdit avec ce TForm comme parent et le handle de ce TForm comme ParentWindow.
    Je n'ai rien changé d'autre, et [B]ça marche[/B]

    Voici la fonction de ma DLL, avec ces changements;
    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
    function TestEditChangeNew(hnd: THandle): integer; stdcall; export;
    begin
      if not assigned(Memo1) then begin
        Memo1 := TMemo.Create(nil);
        Memo1.ParentWindow := hnd;
        Memo1.Top := 50;
        Memo1.Width := 300;
        Memo1.Height := 400;
        Memo1.ScrollBars := ssBoth;
      end;
     
      MyPanel := TPanel.Create(frmDllForm);
      MyPanel.ParentWindow := hnd;
      MyEdit := TTntEdit.Create(MyPanel);
      MyEdit.ParentWindow := MyPanel.Handle;
      MyEdit.Top := 0;
      MyEdit.Left := 0;
      MyPanel.Top := 10;
      MyPanel.Left := 10;
      MyPanel.Width := MyEdit.Width;
      MyPanel.Height := MyEdit.Height;
      MyEdit.OnClick := TUnicodeObject.Click;
      MyEdit.OnChange := TUnicodeObject.Change;
    end;
    exports TestEditChangeNew;
    Je suis content - ça marche ! MERCI !
    C'est tout de même intrigant...

  7. #7
    Membre éclairé

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    361
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 361
    Billets dans le blog
    1
    Par défaut
    Juste pour le plaisir:

    J'arrive à générer dynamiquement, dans ma DLL, les cntrôles visuels TNTetc.
    Je peux les placer dans la destination de mon choix, gérer leur contenu, leurs dimensions et attributs, y compris graphiques.
    Je peux gérer maintenant les évènements OnVlci, OnChange et OnClose.

    Je vais maintenant avancer lentement pour m'approprier les autres fonctionnalités de ce produit TNT.
    J'arrive déjà à gérer les WideFindFilefirst et sonsorts pour parcourir une arborescence de dossiers avec des noms en Unicode,
    faire des recherches et sélections dans ces dossiers etc.

    Jje sais gérer les WideString, , TntWideStrings etc, les écrire sur disque et les récupérer.
    Je sais même les passer à un programme écrit dans un langage non-Unicode et ne supportant pas WideString (come Panoramic) et retour.
    Ces dernières opérations se font par des arrays de type integer, avec 2 WideChar par élément.
    Je commence à réaliser un ensemble de fonctions travaillant ue ces données, donnant ainsi accès à Panoramic (et à d'autres programmes non-unicode) à cet univers multi-culturel qui est de plus en plus présent. Tout cela à partir de Delphi 6 PE.

    Un très grand MERCI à tous ceux qui m'ont apporté leur aide !

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 25/04/2008, 21h21
  2. Réponses: 6
    Dernier message: 06/12/2007, 09h33
  3. FileGetAttr ne marche pas pour les dossiers ?
    Par WebPac dans le forum Delphi
    Réponses: 13
    Dernier message: 06/07/2006, 14h36
  4. [Performance] - Blob ou pas pour les images d'un site ?
    Par ShinJava dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 04/07/2005, 17h32

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