windows - Delphi - Programmets hovedformular bliver fokuseret forkert

Indlæg af Hanne Mølgaard Plasc

Problem



I to dele af min ansøgning bliver hovedformularen fokuseret på det forkerte tidspunkt:


Fejl 1. Når du klikker på 'OK' fra en bestemt printerformular.



  1. Jeg åbner en FastReports PDF preview - det er den første popup. Denne popup vises ikke separat i proceslinjen. Denne formular er modal.

  2. Så klikker jeg på print

  3. Der åbnes et andet vindue med standard udskriftsindstillinger.

  4. Så klikker jeg på egenskaber - der åbner driverens specifikke form. Jeg ændrer indstillingen for dobbelt udskrivning.

  5. Når jeg klikker på 'OK', skal preview-formularen (1) fokuseres, men hovedformularen er bragt til front . Da forhåndsformularen stadig er modal, er det svært at komme tilbage til preview-formularen. Kun med tilfældige klik, vises formen på formen igen.



klikke igennem [5]





Bug 2. Ved at klikke på eller trække denne specifikke scrollboks fokuserer hovedformularen



  1. Dette vindue er aktivt. Dette er et separat vindue i proceslinjen i Windows og er ikke modal. Der er en gnostice pdf viewer på denne formular.

  2. Når jeg klikker på rulleboksen for at begynde at trække, kommer hovedformularen til fronten. Når jeg fortsætter med at trække, fortsætter scrollningen på pdf-formularen stadig. Et værktøjstip nær musen angiver også, hvilken side der aktuelt vises.



Bug 2 [6] [7]


Jeg vil gerne løse denne underlige opførsel. Så mit spørgsmål er:






   Hvad kan forårsage disse fokuserer fejl?






Om ansøgningen:



  • Jeg har allerede bemærket: popup-formularerne synes lidt for store, som du kan se her:
    formular synes at være stort

  • se redigering

  • Nogle former er MDI-barn.

  • Jeg søgte i koden for alle museventilføjelser og satte pausepunkter. Men den kode blev ikke udført i øjeblikket af de to fejl.

  • VCLskin bruges.

  • Fejl 1 opstår med Hurtige rapporter version 5.6.1 og 5.6.8.

  • Windows 10.

  • Delphi XE 10.2.



Rediger [8] [9]



  • Programmets hovedformular er indstillet korrekt. Ved opstart vises først et login-formular. Efter dit login oprettes datamodulerne, nogle former oprettes uden en ejer (de frigives på ansøgningsenden).



Alle andre former, også hovedformularen er ejet efter ansøgning og ikke ved login-formularen. Og faktisk ikke som forælder, men som ejer, som @ uwe-raabe sagde.


Derefter oprettes hovedformularen. Dette oprettes via login-formularen:


Frm\_DatabaseLogin.CreateForm(TFrm\_MainMenu, Frm\_MainMenu);


Det kalder:


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


I UpdateProgress sker der ikke noget særligt.


Derefter oprettes de andre former også, der ejes af ansøgningen. I slutningen skjuler login-skjemaet og derfor vises hovedformularen.

Bedste reference


Jeg gør nogle antagelser her på din startkode.


'Main Form' kan være et forvirrende udtryk. Fra TApplication synspunkt Application.MainForm er altid den første formular, der oprettes ved hjælp af Application.CreateForm.


Da din login formular skaber din applikations primære form og derefter skjuler sig selv, er login-formularen stadig den 'vigtigste' formular.


Dit skærmbillede har to ikoner vist på proceslinjen. Jeg antager, at du enten er tilrettelæggende CreateParams eller ringer SetWindowLong for at få det til at ske.


Jeg har en lignende opsætning med en 'main' login formular, der så er skjult.


I min ansøgning tilsidesætter jeg CreateParams for formularer, der skal være frittstående og have et proceslinjeikon:


procedure TMgrMain.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.ExStyle := Params.ExStyle or WS\_EX\_APPWINDOW;
  Params.WndParent := 0;
end;


Så når jeg viser popups, opretter jeg formularen med en ejer (sandsynligvis ikke nødvendigt), og derefter indstiller PopupMode og PopupParent. Siden jeg startede dette har jeg ikke længere formularer, der pop-behind.


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;


Fra PopupParent-hjælpen: [10]



  Hvis PopupMode-egenskaben er indstillet til pmExplicit og PopupParent er nul,
  så er Application.MainForm implicit anvendt som PopupParent.
  Hvis ingen Application.MainForm er tildelt, så Application.Handle er
  bruges som PopupParent.

  
  Hvis PopupMode-egenskaben er indstillet til pmAuto, bruges Screen.ActiveForm
  som PopupParent-ejendommen.



En del af hvor jeg tog mine skridt fra var fra en gammel Peter Under nyhedsgruppe post. Også dette er virkelig gamle råd nu og var før tilføjelsen af ​​PopupParent/PopupMode [11]



  Nyhedsgrupper: borland.public.delphi.winapi

    Fra: 'Peter Below (TeamB)' < 100113.1 ... @ compuXXserve.com>

    Dato: 2000/11/30

    Emne: Re: Modeless window act like .exe

  
   .. cut ..

  Bemærk at dette kan medføre
  nogle problemer med modale former vist fra sekundære former. Hvis brugeren
  skifter væk fra appen, mens en modal form er op og derefter tilbage til
  formularen, der viste den modale formularen, kan skjule under formularen. Det
  Det er muligt at håndtere dette ved at sørge for modalformen
  parented til formularen, der viste det (ved brug af params.WndParent som ovenfor)
  men det er ikke muligt med standarddialogerne fra dialogerne
  enhed og undtagelser, som har brug for mere indsats for at få dem til at arbejde rigtigt
  (grundlæggende håndtering Application.OnActivate, leder efter modalformer
  parented til Application via GetLastActivepopup og bringe dem til
  toppen af ​​Z-ordren via SetWindowPos).

    .. cut ..



Endelig er her et blogindlæg, der snakker om, hvorfor ændringerne til PopupMode og PopupParent blev lavet. [12]