Domanda

Ho un'applicazione Delphi che ha un browser documenti come modulo principale. Quando l'utente apre un documento, apriamo una finestra dell'editor. Vogliamo avere ciascun editor con un pulsante sulla barra delle attività, nonché il modulo principale. Ho applicato il codice normale per farlo (sotto), ma quando faccio clic sul modulo principale dopo aver utilizzato la finestra dell'editor, l'editor viene lasciato in primo piano, mentre lo stato attivo è sul modulo principale. Non riesco a capire cosa sta causando questo comportamento.

Impostazioni fase: apro il modulo principale e un modulo documento.

  1. Fai clic su un'altra app, fai clic sul modulo principale, il modulo principale rimane focalizzato. (Comportarsi come previsto.)

  2. Fai clic sul modulo del documento, fai clic sul modulo principale, viene visualizzato il modulo del documento da dietro a sinistra, ma mostrato inattivo. (L'immagine mostra il risultato)

alt text http://www.matthew-jones.com/temp_xfer/titlebarfailure .jpg

Primo passo, questo è Delphi 2007 e ho nel progetto:

Application.MainFormOnTaskBar := True;

Per il modulo principale, non ho un codice aggiuntivo.

Per il modulo del documento, ho

procedure TCommonEditForm.CreateParams(var params: TCreateParams);
begin
  inherited;
  params.WndParent := 0; // GetDeskTopWindow; no diff
end;

Ho provato a capire se c'è un messaggio che lo sta facendo accadere, ma non riesco a trovare qualcosa di appropriato. Ho cercato nel codice qualsiasi cosa abbia a che fare con & Quot; attiva & Quot ;. Indizi benvenuti!

È stato utile?

Soluzione

La mia applicazione funziona come descritto. Ecco l'approccio che ho seguito. Mi sarebbe piaciuto trovare un approccio più semplice ma non l'ho mai fatto.

Ho iniziato leggendo questi articoli. Questo primo è un ottimo scritto di Peter Below:

http: // gruppi -beta.google.com/group/borland.public.delphi.winapi/msg/e9f75ff48ce960eb?hl=en

Altre informazioni sono state trovate anche qui, tuttavia questa non si è rivelata una soluzione valida: per il mio uso:    http://blogs.teamb.com/DeepakShenoy/archive/ 2005/04/26 / 4050.aspx

Alla fine ecco cosa ho finito con.

La mia schermata iniziale funge anche da modulo principale dell'applicazione. Il modulo principale ha un legame speciale con l'oggetto applicazione. L'uso di tutti i moduli secondari mi dà il comportamento che stavo cercando.

In ogni modulo che desidero sulla barra delle applicazioni sostituisco CreateParams. Lo faccio sui miei moduli di modifica e su ciò che gli utenti vedono come & Quot; modulo principale & Quot;

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

Il mio " Principale " forma per quanto riguarda Delphi carica la vera forma principale nella sua funzione Activitate. Uso una variabile membro per tenere traccia della prima attivazione. Quindi alla fine della funzione nascondo la schermata iniziale, ma non la chiudo. Questo è stato importante per me perché se l'utente stava modificando un documento e ha chiuso il modulo principale, non volevo che le schermate di modifica fossero forzate contemporaneamente. In questo modo tutte le forme visibili vengono trattate allo stesso modo.

    if FFirstActivate = false then
      exit;

    FFristActivate := false;

    /* 
       Main Load code here 
       Update Splash label, repaint
       Application.CreateForm
       etc.
    */


    // I can't change visible here but I can change the size of the window
    Self.Height := 0;
    Self.Width := 0;
    Self.Enabled := false;

    //  It is tempting to set Self.Visible := false here but that is not
    // possible because you can't change the Visible status inside this
    // function.  So we need to send a message instead.
    ShowWindow(Self.Handle, SW_HIDE);

  end;

Ma c'è ancora un problema. È necessario chiudere la finestra principale / splash quando tutti gli altri moduli sono chiusi. Ho un controllo extra nelle mie routine di chiusura per Parent & Lt; & Gt; nullo perché utilizzo i moduli come plugin (i miei scopi funzionano meglio dei frame).

Non mi è piaciuto molto usare l'evento Idle, ma non noto che si tratta di un trascinamento sulla CPU.

{
  TApplicationManager.ApplicationEventsIdle
  ---------------------------------------------------------------------------
}
procedure TApplicationManager.ApplicationEventsIdle(Sender: TObject;
  var Done: Boolean);
begin

  if Screen.FormCount < 2 then
    Close;
end;

{
  TApplicationManager.FormCloseQuery
  ---------------------------------------------------------------------------
}
procedure TApplicationManager.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
var
  i: integer;
begin

  for i := 0 to Screen.FormCount - 1 do
  begin
    if Screen.Forms[i] <> self then
    begin
      // Forms that have a parent will be cleaned up by that parent so
      // ignore them here and only attempt to close the parent forms
      if Screen.Forms[i].Parent = nil then
      begin
        if Screen.Forms[i].CloseQuery = false then
        begin
          CanClose := false;
          break;
        end;
      end;
    end;
  end;

end;

{
  TApplicationManager.FormClose
  ---------------------------------------------------------------------------
}
procedure TApplicationManager.FormClose(Sender: TObject;
  var Action: TCloseAction);
var
  i: integer;
begin

  for i := Screen.FormCount - 1 downto 0 do
  begin
    if Screen.Forms[i] <> self then
    begin
      // Forms that have a parent will be cleaned up by that parent so
      // ignore them here and only attempt to close the parent forms
      if Screen.Forms[i].Parent = nil then
      begin
        Screen.Forms[i].Close;
      end;
    end;
  end;

end;

Questo mi ha servito bene finora. Ho apportato una piccola modifica a Vista perché l'icona per il mio & Quot; Main / Splash & Quot; lo schermo stava ancora mostrando. Non ricordo di cosa si trattasse. Probabilmente non ho bisogno di impostare larghezza, altezza, abilitazione e inviare il messaggio Nascondi nella schermata iniziale. Volevo solo assicurarmi che non comparisse :-).

Era necessario affrontare gli eventi vicini. Se ricordo bene che era necessario per quando Windows ha inviato un messaggio di spegnimento. Penso che solo il modulo principale riceva quel messaggio.

Altri suggerimenti

Mi dispiace se questo è davvero stupido, ma non hai lo stile del form impostato su fsStayOnTop, vero? Questo spiegherebbe questo comportamento.

forse aggiungilo nei createparam

Params.ExStyle := Params.ExStyle OR WS_EX_APPWINDOW;

o prova questo ovunque nel codice. Lo uso presonalmente sui moduli .OnCreate event.

SetWindowLong(Wnd, GWL_EXSTYLE, 
  GetWindowLong(Wnd, GWL_EXSTYLE) or WS_EX_APPWINDOW) ;

il rovescio della medaglia di questo è che se il modulo principale è ridotto a icona anche gli altri moduli si nascondono, ma ripristinano quando lo fa il modulo principale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top