2011-09-05 14 views
5

Ho due controlli TEdit. Quando esco da edit1, edit2 riceve lo stato attivo. Sul mio evento Su uscita di Edit1 Ho il seguente codice:TEdit focus & caret

procedure TForm1.Edit1Exit(Sender: TObject); 
begin 
    edit2.Enabled := false; 
    edit2.Enabled := true; 
    edit2.setfocus; 
end; 

Edit2 ha il focus. Tuttavia, non c'è caret in esso. Posso iniziare a digitare, ma è confuso perché non lo so quale controllo ha lo stato attivo.

Io sono più interessato a ciò che è il capovolgimento della proprietà Enabled che sta causando alcuni messaggi di essere non sparare correttamente? Ad esempio, l'evento OnEnter di edit2 non viene attivato.

Questo è su D2006 se è importante.

Grazie per la risposta.

+1

Perché vuoi farlo? –

+0

c'è un sacco di codici tra disabilitare e abilitare edit2. non è necessariamente edit2, ma qualunque sia l'activecontrol. quindi, dopo aver riattivato l'activecontrol, vorrei reimpostare il focus su di esso. beh, è ​​sicuramente l'activecontrol, ma non c'è caret. – Rick

risposta

8

non capisco il motivo per cui disabilitare e abilitare edit2, ma si esegue questa operazione:

procedure TForm1.Edit1Exit(Sender: TObject); 
begin 
    edit2.Enabled := false; 
    edit2.Enabled := true; 
    edit2.setfocus; 
    PostMessage(edit2.Handle, WM_SETFOCUS, 0, 0); 
end; 

BTW, sono d'accordo con Andreas Rejbrand.

+1

Personalmente preferisco questo approccio se assegnato (ActiveControl) quindi PostMessage (ActiveControl.Handle, WM_SETFOCUS, 0,0); dopo aver impostato la messa a fuoco su un altro controllo. Dopo determinate operazioni, Windows API sembra non riconoscere il controllo attivo e pertanto gli eventi OnExit/OnEnter non vengono attivati ​​correttamente. Questa riga lo corregge. – ertx

+0

Sono d'accordo ma non so se può mettere a fuoco un altro componente ... – Whiler

+0

Funziona, grazie! Ho provato a rintracciare la catena di eventi per capire perché non ridisegna l'attenzione e il punto di riferimento. Colpisci il muro su WndProc e si limita a questo punto e ho perso la traccia di quale messaggio sta elaborando. – Rick

8

Sospetto seriamente che tu stia facendo qualcosa in modo negativo, e la soluzione migliore è molto probabilmente una riprogettazione. Non si dovrebbe disabilitare e quindi abilitare un controllo mentre sta ricevendo lo stato attivo.

+0

Sono d'accordo, non è l'ideale. E certo ci sono soluzioni alternative. Ma sono solo curioso di sapere cosa serve per il punto di vista e l'attenzione per mostrare. Qualcosa sulla disabilitazione di activecontrol w/nell'evento OnExit che interrompe la catena di messaggi di windows. – Rick

0

C'è un sacco di codici tra disabilitare e abilitare edit2.

Avere un sacco di codice nel gestore di eventi Su uscita del precedente controllo attivo non non richiedono di disattivare il controllo successivo attiva. Il codice eseguirà prima che il successivo controllo attivo mostri il cursore e sarà in grado di ricevere l'input dell'utente. Assicurati solo che non passi l'esecuzione con qualcosa come iniziare una nuova discussione o usare Application.ProcessMessages.

Impostare Screen.Cursor a crHourGlass per rendere chiaro all'utente che il prossimo controllo attivo non è ancora pronto.

0

Trovato un problema quando OnActive per MainForm attiva un altro modulo.

TMainForm.OnActivate; 
begin 
ChildForm.ShowModal; 
end; 

Il fuoco di controllo è impostato ma non funziona. Il lavoro che ho trovato è stato l'invio di PostMessage (Handle, WM_SETFOCUS, 0, 0); al manico del modulo.

procedure TChildForm.FocusControl(AWinControl: TWinControl); 
begin 
    try 
    // http://stackoverflow.com/questions/7305296/tedit-focus-caret 
    PostMessage(Handle, WM_SETFOCUS, 0, 0); 
    PostMessage(AWinControl.Handle, WM_SETFOCUS, 0, 0); 
    if AWinControl.CanFocus then 
     AWinControl.SetFocus; 
    except 
    on E: Exception do 
    begin 
     Error(Self, E); 
    end; 
    end; 
end;