Delphi – Le formulaire principal de l’application se focalise incorrectement

Dans deux parties de ma demande, le formulaire principal se concentre au mauvais moment:

Bug 1. En cliquant sur ‘OK’ à partir d’un formulaire d’imprimante spécifique.

  1. J’ouvre un aperçu PDF FastReports – c’est le premier popup. Ce popup n’est pas affiché séparément dans la barre des tâches. Cette forme est modale.
  2. Puis je clique sur print,
  3. Cela ouvre une autre fenêtre avec des options d’impression standard.
  4. Ensuite, je clique sur les propriétés – cela ouvre la forme spécifique du pilote. Je change le paramètre de double impression.
  5. Lorsque je clique sur «OK», le formulaire de prévisualisation (1) doit être focalisé, mais le formulaire principal est mis au premier plan . Comme le formulaire de prévisualisation est toujours modal, il est difficile de revenir au formulaire de prévisualisation. Seulement avec des clics aléatoires, le formulaire de prévisualisation se concentre à nouveau.

en cliquant à travers


Bug 2. En cliquant ou en faisant glisser cette scrollbox spécifique, vous focalisez le formulaire principal

  1. Cette fenêtre est active. Ceci est une fenêtre séparée dans la barre des tâches Windows et n’est pas modale. Il y a un lecteur de pdf gnostice sur ce formulaire.
  2. Lorsque je clique sur la barre de défilement pour commencer à glisser, le formulaire principal est mis au premier plan. Lorsque je continue à glisser, le défilement au format pdf continue. De plus, une infobulle près de la souris indique quelle page est actuellement affichée.

Bug 2

Je veux résoudre ce comportement étrange. Donc, ma question est:


Qu’est-ce qui peut causer ces bugs de focalisation?


A propos de l’application:

  • J’ai déjà remarqué: les formulaires contextuels semblent un peu trop gros, comme vous pouvez le voir ici: la forme semble grande
  • voir modifier
  • Certaines formes sont des enfants MDI.
  • J’ai recherché dans le code tous les événements de souris et y ai placé des points d’arrêt. Mais ce code n’a pas été exécuté au moment des deux bogues.
  • VCLskin est utilisé.
  • Le bogue 1 se produit avec les rapports rapides version 5.6.1 et 5.6.8.
  • Windows 10.
  • Delphi XE 10.2.

modifier

  • Le formulaire principal de l’application est défini correctement. Au démarrage, un formulaire de connexion s’affiche d’abord. Après votre connexion, les modules de données sont créés, certains formulaires sont créés sans propriétaire (ils sont libérés à la fin de l’application).

Tous les autres formulaires, y compris le formulaire principal, appartiennent à Application et non au formulaire de connexion. Et en effet pas en tant que parent, mais en tant que propriétaire, comme l’a dit @ uwe-raabe.

Ensuite, le formulaire principal est créé. Ceci est créé via le formulaire de connexion:

Frm_DatabaseLogin.CreateForm(TFrm_MainMenu, Frm_MainMenu); 

Qui appelle:

 procedure TFrm_DataBaseLogin.CreateForm(InstanceClass: TComponentClass; var Reference); begin Updateprogress(InstanceClass.ClassName); Application.CreateForm(InstanceClass,Reference); end; 

Dans UpdateProgress, rien de spécial ne se produit.

Après cela, les autres formulaires sont également créés, appartenant à l’application. A la fin, le formulaire de connexion se cache et par conséquent le formulaire principal est affiché.

Je fais quelques hypothèses ici sur votre code de démarrage.

“Formulaire principal” peut être un terme déroutant. Du sharepoint vue TApplication, Application.MainForm est toujours le premier formulaire créé à l’aide d’Application.CreateForm.

Étant donné que votre formulaire de connexion crée le formulaire principal de votre application puis se cache, le formulaire de connexion rest le formulaire “principal”.

Votre capture d’écran contient deux icons affichées dans la barre des tâches. Je suppose que vous êtes soit sur CreateParams, soit en appelant SetWindowLong pour y arriver.

J’ai une configuration similaire avec un formulaire de connexion “principal” qui est ensuite masqué.

Dans mon application, je remplace les CreateParams pour les formulaires qui doivent être autonomes et avoir une icône de barre des tâches:

 procedure TMgrMain.CreateParams(var Params: TCreateParams); begin inherited CreateParams(Params); Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW; Params.WndParent := 0; end; 

Ensuite, lorsque vous affichez des popups, je crée le formulaire avec un propriétaire (probablement pas nécessaire), puis configurez PopupMode et PopupParent. Depuis que j’ai commencé, je n’ai plus de formulaires qui apparaissent derrière.

 procedure ShowAbout(Owner: TForm); var LocalForm: TAbout; begin LocalForm := TAbout.Create(Owner); try LocalForm.PopupMode := pmExplicit; LocalForm.PopupParent := Owner; LocalForm.ShowModal; finally FreeAndNil(LocalForm); end; end; 

De l’ aide de PopupParent :

Si la propriété PopupMode est définie sur pmExplicit et que PopupParent est nulle, l’application.MainForm est implicitement utilisée en tant que PopupParent. Si aucun Application.MainForm n’est assigné, Application.Handle est utilisé comme PopupParent.

Si la propriété PopupMode est définie sur pmAuto, Screen.ActiveForm est utilisé comme propriété PopupParent.

Une partie de l’endroit où je suis passé par un ancien groupe de discussion de Peter Below. C’est aussi un très vieux conseil maintenant et avant l’ajout de PopupParent / PopupMode

Groupes de discussion: borland.public.delphi.winapi
De: “Peter Below (TeamB)” <100113.1 ... @ compuXXserve.com>
Date: 2000/11/30
Objet: Re: La fenêtre sans modalité agit comme .exe

.. Couper ..
Notez que cela peut causer des problèmes avec les formulaires modaux affichés dans les formulaires secondaires. Si l’utilisateur s’éloigne de l’application alors qu’un formulaire modal est affiché, puis revient au formulaire qui l’a montré, le formulaire modal peut se cacher sous le formulaire. Il est possible de traiter cela en s’assurant que le formulaire modal est associé au formulaire qui l’a montré (en utilisant params.WndParent comme ci-dessus) mais ce n’est pas possible avec les boîtes de dialog standard de l’unité Dialogs et les exceptions nécessitant plus d’efforts pour faites-les fonctionner correctement (en manipulant essentiellement Application.OnActivate, en recherchant les formulaires modaux associés à l’application via GetLastActivepopup et en les plaçant en tête de l’ordre Z via SetWindowPos).
.. Couper ..

Enfin, voici un article de blog qui explique pourquoi les modifications apscopes à PopupMode et PopupParent ont été effectuées.