2009-03-31 15 views
19

Mi sforzo di mostrare un secondo modulo sopra il modulo principale senza perdere la concentrazione.Delphi: Mostra finestra senza attivazione

Ho provato ShowWindow(second.handle, SW_SHOWNOACTIVATE), ma il modulo principale perde lo stato attivo. Se ho impostato Visible := false sulla seconda finestra, la chiamata a ShowWindow non attivare il secondo modulo, ma le finestre è vuoto quando mostrato ...

Qualcuno ha una buona ricetta per questo?

AGGIORNAMENTO: Quello che sto cercando di fare è mostrare una finestra di notifica in un dato evento. È fondamentale che la forma principale non perda la concentrazione in qualsiasi momento.

+0

Hum ... Una delle mie modifiche è andato ... immagino di sì avuto qualche problema in precedenza ...? – Vegar

risposta

24

Ci deve essere qualcosa di sbagliato nel codice.

ho provato questo codice, funziona:

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    ShowWindow(Form2.Handle, SW_SHOWNOACTIVATE); 
    Form2.Visible := True; 
end; 

fare attenzione ad utilizzare Visible, non Show! Altrimenti sostituirà lo SW_SHOWNOACTIVATE.

+0

Mi spiace, ma è ancora attivato :-( – Vegar

+0

Ho modificato la mia risposta e l'ho provata :) –

+0

Wow, è incredibile :-) I trucchi sembrano essere lasciati essere falsi in fase di progettazione e impostarli su true dopo la chiamata a showwindow(). Grazie! – Vegar

2

È possibile visualizzare la finestra (non modale) e reimpostare lo stato attivo sulla finestra principale.

procedure TMainForm.ButtonClick(Sender: TObject); 
begin 
    OtherForm.Show; 
    SetFocus; 
end; 

provata su 2006.

Questo non mostra l'altra forma sopra. Ma è molto controintuitivo avere una finestra in primo piano che non ha il focus.

+0

Ma questo sarebbe sufficiente per innescare eventi e datastorage ecc, e non voglio che ... – Vegar

+0

questo non funziona in varie circostanze, ad esempio se si sta lavorando (ad esempio la modifica del testo) in un modulo figlio del modulo principale e il modulo principale deve far apparire una notifica. perdi tutti i personaggi in corso di digitazione e l'impostazione della messa a fuoco sul modulo principale non riporta la messa a fuoco al modulo figlio originale in cui stavi modificando. Questo problema mi ha ossessionato per un lungo periodo di tempo fino a quando non ho trovato i DR semplici (Avrei dovuto pensarci) correzione. – DeveloperChris

1

ho usato questo in passato

SetWindowPos(WindowHandle, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOMOVE); 

Non ho provato questo con le recenti versioni di Delphi però ...

1

Se possibile, si dovrebbe considerare utilizzando una sorta di punta dell'utensile finestra per visualizzare le informazioni di notifica. Un suggerimento non ruberà lo stato attivo dalla finestra principale quando viene visualizzato o quando un utente fa clic su di esso. Un modulo normale avrà un bordo per impostazione predefinita e se l'utente fa clic su quel bordo il modulo principale perderà il focus.

Ecco un codice di base per eseguire questa operazione. La punta scompare quando viene chiamato gratis; tuttavia, sarebbe meglio impostare un timer rispetto all'utilizzo del sonno.

with THintWindow.Create(nil) do 
    try 
    ActivateHint(MyRect, 'My Notification'); 
    Sleep(DisplayTime); 
    finally 
    Free; 
    end 
+0

Forse questa è la via più facile da percorrere, ma dovrei personalizzare la finestra di suggerimento per mostrare più di un semplice testo ... – Vegar

1

Qui sono:

// you have set your 2nd form as non resizable, without border nor title etc... 
    Form2.Enabled := False; // prevent the 2nd form to grab focus even when clicked 
    SetWindowPos(Form2.Handle, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW or SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOMOVE); 
    // be sure to hide it automatically when done as it is disabled... 
+0

Questo lo rende effettivamente visibile senza impostare il modulo Visibile? –

1

Ho fatto questo in passato, ma non ho il codice perché era proprietarie in ultimo lavoro (mi dispiace).

Se ricordo bene, quello che ho fatto è stato:

  1. dalla classe cliente una chiamata di una procedura (o funzione) che non appartiene a nessuna classe (un metodo tradizionale Pascal).
  2. Da tale metodo, chiamare un metodo in una classe B che non eredita da TForm
  3. Dal metodo in B, creare un'istanza del modulo popup P, ma senza genitore o proprietario; e chiama un metodo nell'istanza.
  4. Dal metodo chiamato nell'istanza, mostra se stesso.

Il codice (di fase 3) potrebbe andare qualcosa come questo:

var p: TPopupForm; 
begin 
    p := TPopupForm.Create(nil); 
    p.ShowWindow; 
    p.Release; 
end; 

Mi dispiace se questo non funziona, non ho Delphi troppo.

0

codice Daniels funziona fino ...

ShowWindow(Form2.Handle, SW_SHOWNOACTIVATE); 
Form2.Visible := True; 

Fino a quando il secondo modulo viene creato in modo dinamico . Quindi il tuo secondo modulo si trova nella posizione 0,0 con larghezza e altezza predefinite.

Per un breve momento in cui viene eseguito ShowWindow, sullo schermo verrà visualizzato il secondo modulo, che scomparirà quando viene eseguita la riga successiva.

Sto usando il codice per un modulo di overlay trasparente che viene creato dinamicamente. Il seguente codice è una combinazione delle risposte date e inserisce il secondo modulo senza attivazione sul modulo padre.

SetWindowPos(Form2.Handle, HWND_TOP, Left, Top, Width, Height, SWP_NOACTIVATE); 
Form2.Visible := True;