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

EDI Delphi Discussion :

[D2010] Problème de clic sur bouton dans une DLL


Sujet :

EDI Delphi

  1. #1
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 961
    Points
    6 961
    Par défaut [D2010] Problème de clic sur bouton dans une DLL
    Depuis que mes DLL ont été migrées de Delphi 6 à Delphi 2010, le clic sur les boutons (TBitBtn) fonctionnent mal. En fait, il faut cliquer deux fois (pas un double-clic).
    Le premier clic donne le focus, et le deuxième clic fait réellement le clic sur le bouton (il s'enfonce).

    J'ai remarqué que les boutons de la barre d'outils de la fenêtre de prévisualisation de QuickReport avaient désormais le même problème.

    Par contre, aucun problème avec un exe normal (seulement dans les DLL).
    Ce problème est très génant pour les utilisateurs qui utilise très fréquement certains boutons : ca leur fait perdre du temps (et c'est agaçant).

    Quelqu'un aurait l'ombre d'une idée (parce que là, je ne vois pas ce que je peux y faire) ?
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Joue avec MainFormOnTaskBar, au lieu que TApplication soit l'objet de la Barre des Taches, c'est ton MainForm

    Est-ce des fenêtres ancrées ?
    via Windows.SetParent, j'ai constaté des problèmes de Focus aussi
    via TControl.Parent, nettement mieux mais nécessite BPL avec RTL Dynamique en C++Builder ou FastShareMem\Brlndmm.dll en Delphi
    via Dock ?

    Est-ce des fenêtres NON ancrées ?

    Tu peux tenter ceci, la fenêtre ainsi créée aura son propre bouton dans la barre des taches
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //---------------------------------------------------------------------------
    void __fastcall T***Form::CreateParams(Controls::TCreateParams &Params)
    {
      inherited::CreateParams(Params);
      Params.WndParent = GetDesktopWindow();
    }

    Tu as l'inverse en affectant un Handle genre HInstance au TApplication.Handle DANS la DLL, j'ai plus l'astuce exacte en tête
    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

  3. #3
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 961
    Points
    6 961
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Joue avec MainFormOnTaskBar, au lieu que TApplication soit l'objet de la Barre des Taches, c'est ton MainForm
    Je ne vois pas le rapport avec mon problème.
    J'ai essayé quand même, mais ça ne change rien.


    Citation Envoyé par ShaiLeTroll Voir le message
    Est-ce des fenêtres ancrées ?
    Je ne comprend pas la question.
    Si tu demandes comment mes fenêtres sont affichées, j'en ai une qui est maximisée avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SendMessage(Handle, WM_SYSCOMMAND, SC_MAXIMIZE, 0);

    Citation Envoyé par ShaiLeTroll Voir le message
    Tu peux tenter ceci, la fenêtre ainsi créée aura son propre bouton dans la barre des taches
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //---------------------------------------------------------------------------
    void __fastcall T***Form::CreateParams(Controls::TCreateParams &Params)
    {
      inherited::CreateParams(Params);
      Params.WndParent = GetDesktopWindow();
    }
    J'ai essayé, mais ça ne change rien.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure TFormColisage.CreateParams(Params: TCreateParams);
    begin
       inherited CreateParams(Params);
       Params.WndParent := GetDesktopWindow;
    end;

    Citation Envoyé par ShaiLeTroll Voir le message
    Tu as l'inverse en affectant un Handle genre HInstance au TApplication.Handle DANS la DLL, j'ai plus l'astuce exacte en tête
    Je ne comprend pas bien non plus.
    Au début de mes DLL, je leur fournis le Handle de l'exe appelant, pour qu'elles partagent le même élément dans la barre Windows (c'est plus propre).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       Application.Handle := HandleApp;
    Cà a pas de rapport avec mon problème, si ?
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Citation Envoyé par Lung Voir le message
    Je ne vois pas le rapport avec mon problème. ?
    Cela change la gestion de la prise de Focus par la MainForm, fait une application en D6 et la même en D2010
    une MainForm et un form secondaire créée et affiché à la volée, regarde la différence de prise de focus !
    D6 : la MainForm passe par dessus les autres fenêtres
    D210 : La MainForm reste toujours en dessous

    Citation Envoyé par Lung Voir le message
    J'ai essayé quand même, mais ça ne change rien.
    Dommage

    Citation Envoyé par Lung Voir le message
    Je ne comprend pas la question.
    Si tu demandes comment mes fenêtres sont affichées, j'en ai une qui est maximisée .
    Donc j'en déduiis que tes fenêtres sont affichées par Show ou ShowModal sans ancrage !

    Ta fenêtre s'appelle TFormColisage, j'avais créée une TFrmColisage en 2001 lorsque j'étais apprenti le monde est petit


    Citation Envoyé par Lung Voir le message
    Je ne comprend pas bien non plus.
    ... partagent le même élément dans la barre Windows
    Eh bien tu comprends plus que tu ne le crois, as-tu essayé de retirer cette ligne ?
    Cela change la gestion de prise de focus des fenêtres, et comme en D2010 la gestion de la barre windows a justement changé (voir MainFormOnTaskBar)

    Avec CreateParams, tu peux cacher l'icone de la fenêtre sans jouer avec le Handle

    Dans le projet dont je m'occupe, on a beaucoup de fenêtre contenu dans des DLL, l'EXE appel des fonctions qui se chargent de l'instanciation, ShowModal et libération, on a presque exclusivement des BitBtn, pas de problème de Focus
    Et pourtant, je ne trouve pas le fameeux Application->Handle = ...Je ne sais pas comment mon responsable a masquer cela
    Le plus proche serait la ligne dans le constructeur ancêtre de TOUTES les fenêtres de nos applications :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DefaultMonitor = dmDesktop;

    Seules les fenêtres ancrées avec l'API SetParent lors du passage de BCB2007 à BCBXE2 provoquait un problème de focus, le OnExit d'un TDBEdit par exemple n'était pas provoqué par le clic sur un BitBtn (lui directement dans le Parent) du coup pas de modification du DataLink->DataField ...

    J'ai aussi eu un phénomène de prise de focus pénible comme le tien mais avec des TComboBox, il fallait cliquer deux fois pour l'ouvrir
    En passant par la propriété Parent impliquant l'échange d'un TWinControl entre EXE et DLL au lieu d'un Handle, le problème était résolu
    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
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 961
    Points
    6 961
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Donc j'en déduiis que tes fenêtres sont affichées par Show ou ShowModal sans ancrage !
    Oui, je les affiche avec un ShowModal.
    (A part Show ou ShowModal, il existe quoi d'autre ? )

    Citation Envoyé par ShaiLeTroll Voir le message
    Eh bien tu comprends plus que tu ne le crois, as-tu essayé de retirer cette ligne ?
    Si tu parles du Application.Handle := HandleApp; situé dans la DLL, j'ai essayé de l'enlever, mais ça ne change rien.

    Citation Envoyé par ShaiLeTroll Voir le message
    Dans le projet dont je m'occupe, on a beaucoup de fenêtre contenu dans des DLL, l'EXE appel des fonctions qui se chargent de l'instanciation, ShowModal et libération, on a presque exclusivement des BitBtn, pas de problème de Focus
    J'ai ça aussi : c'est une fonction de ma DLL (appelée par l'exe), qui se charge de créer, afficher (par un ShowModal), et détruire la fenêtre.

    Citation Envoyé par ShaiLeTroll Voir le message
    J'ai aussi eu un phénomène de prise de focus pénible comme le tien mais avec des TComboBox, il fallait cliquer deux fois pour l'ouvrir
    En passant par la propriété Parent impliquant l'échange d'un TWinControl entre EXE et DLL au lieu d'un Handle, le problème était résolu
    J'ai pas compris : tu passais un TComboBox en paramètre à ta DLL ?
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Citation Envoyé par Lung Voir le message
    Oui, je les affiche avec un ShowModal.
    (A part Show ou ShowModal, il existe quoi d'autre ? )
    Show\Hide n'est qu'un raccourci pour l'affectation de Visible à true\false
    l'important n'était pas Show ou ShowModal mais le terme "sans ancrage"

    Citation Envoyé par Lung Voir le message
    J'ai pas compris : tu passais un TComboBox en paramètre à ta DLL ?
    Non
    Suis-je aussi peu clair des mes propos ?

    L'échange d'objet entre EXE et DLL a l'air de te choquer, pour les BPL ont été justement conçus pour cela !
    Je vais t'expliquer mon propre contexte, mais je previens, cela va te paraître comme osé !

    Ma DLL contient plusieurs fenêtres,
    Ces fenêtres contiennent diverses contrôles comme TDBEdit, TDBCheckBox, TDBRadioGroup et TComboBox ainsi que des TBitBtn d'ailleurs

    J'évoquais un problème de focus similaire au tient, sur les ComboBox pour les déployer (Drop Down), il fallait cliquer dedans puis sur le bouton

    Cette fenêtre TForm (la fenêtre contenant la combo)utilisée comme une Frame (d'où le terme fenêtre avec ancrage),
    en lui spécifiant un Parent une TForm se comporte comme une Frame, c'est visuellement indétectable.
    Cela me permet de "choisir" l'écran adaptée à la situation, c'est dans le cadre d'une gestion de périphérique
    Chaque marque\modèle ayant ses particularités, un seul écran dans l'EXE pour configurer par exemples les Caméras, depuis l'exe, on défini les valeurs de base comme un nom, la marque et le modèle
    la marque indiquera la Dll associé, le modèle une classe (interface) dans la DLL
    chaque modèle a un écran de configuration différent que j'intègre dans la fenêtre de l'Exe comme une Frame

    Ma fenêtre est mappée par une interface c++ (équivalent d'une classe abstraite en delphi, interface au sens POO) que la DLL fourni à l'EXE, l'interface expose différentes méthodes, il y a évidemment une séparation IHM\Métier, il y a une interface pour l'écran relié à une interface métier, tous ces objets étant créés par la DLL est utilisée par l'EXE
    En plus, j'utilise aussi des DelphiInterface, le GUID, le Support en parallèle des pseudo-interface C++ mais je m'écarte !

    Ce bug de focus n'apparaissait qu'avec unz TForm (la fenêtre contenant la combo) ancrée par l'API SetParent encapsulé par ma méthode SetParentHandle en lui passant un Handle d'un TScrollBox
    Echanger un Handle me semblait moins violent que d'échanger un TWinControl
    Mais en XE2, le comportement de l'ancrage était moins bon par Windows.SetParent(Handle) que par TControl.SetParent(TWinControl).


    J'ai donc renommé SetParentHandle en SetParentVCL avec comme paramètre un TWinControl (souvent un ScrollBox ou un Panel), ce control est affecté à la propriété Parent de ma fenêtre, cela l'intègre comme une Frame (nécessite un BorderStyle à bsNone)

    Eh oui, j'échange un TWinControl entre EXE et DLL ce qui est tout à fait possible avec les BPL d'execution et la RTL Dynamique (ShareMem pour les Delphiste)
    A savoir que l'affectation dans la DLL de la propriété Parent de la TForm avec ce TWinControl modifie la propriété Controls[] de ce dernier, donc allocation mémoire et tout le tralala mais comme ce code est contenu dans les BPL, il n'y a pas de problème de mémoire

    Pour les fenêtres non ancrées, je n'ai jamais vu ce problème de focus, désolé, je suis à cours d'idée !
    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

  7. #7
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 961
    Points
    6 961
    Par défaut
    Je comprend mieux.

    Citation Envoyé par ShaiLeTroll Voir le message
    Cette fenêtre TForm (la fenêtre contenant la combo)utilisée comme une Frame (d'où le terme fenêtre avec ancrage),
    en lui spécifiant un Parent une TForm se comporte comme une Frame, c'est visuellement indétectable.
    J'ai déjà fait ça aussi.

    Citation Envoyé par ShaiLeTroll Voir le message
    Mais en XE2, le comportement de l'ancrage était moins bon par Windows.SetParent(Handle) que par TControl.SetParent(TWinControl).
    Bon à savoir.

    Citation Envoyé par ShaiLeTroll Voir le message
    Pour les fenêtres non ancrées, je n'ai jamais vu ce problème de focus, désolé, je suis à cours d'idée !
    Je vais envoyer un message à Embarcadero (un de plus). On verra ce que ça donnera ...
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

Discussions similaires

  1. Réponses: 2
    Dernier message: 23/03/2013, 02h08
  2. [WD16] Zone Répété Et clic sur bouton dans rupture
    Par predalpha dans le forum WinDev
    Réponses: 0
    Dernier message: 08/10/2012, 17h34
  3. Problème d'affichage de boutons dans une Frame ayant une image en background
    Par felxio dans le forum Interfaces Graphiques en Java
    Réponses: 0
    Dernier message: 13/08/2012, 14h35
  4. Réponses: 15
    Dernier message: 13/03/2007, 17h25
  5. [CSS]problème centrage texte de bouton dans une boîte
    Par Aurelius dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 06/09/2005, 16h01

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