Newsgroup: it.comp.lang.delphi
Titolo: disabilitare una CheckListBox

In una form ho una CheckListBox in cui mostro delle informazioni, che
l'utente non può modificare. Ho quindi provato a disabilitare l'oggetto
oppure i singoli elementi con ItemEnabled ma in entrambi i casi mi disegna
gli elementi in grigio. C'è un modo più o meno veloce e semplice per rendere
l'oggetto non modificabile dall'utente ma che appaia con i colori normali?
-- 
Lis
ICQ@Home #7317603sette     ICQ@Work #16285702tre
Mercatino: 
http://lis77.bravepages.com
 (aggiornato *con foto*: 16/06/03)


    Via De Gasperi, 14 - 42019
    Scandiano (Reggio Emilia)

 ha scritto nel messaggio
news:1xt4nuzyqhxci$.12jv62so2ovp7.dlg@40tude.net...


 non avendo il focus non è modificabile dall'utente.
Ignoranza massima: come faccio ad intercettare un messaggio su un
componente? Per il momento ho solo provato a intercettare i messaggi che
arrivano ad una finestra (
p.es
. con 'procedure WMWindowsChildCount(var Msg:
TMessage); message WM_WINDOWSCHILDCOUNT;').
Sto provando con
procedure WMKillFocus(var Msg: TMessage); message WM_KILLFOCUS;
procedure TFrm.WMKillFocus(var Msg: TMessage);
var
  Handle: HWND;
begin
  Handle := Msg.wParam;
  if Handle = myCheckBox.Handle then
    Frm.SetFocus;
end;
ma non entra mai nella procedura. Preciso che la form è modale. Sto
commettendo qualche grossolano errore?


 OwnerDrawState.
Ci ho provato, ho guarato un pò il codice della vcl e cambiare il colore del
testo è semplice mentre per gestire anche la checkbox dovrei portarmi dietro
un pò troppo codice... grazie comunque per l'idea


 l'oggetto non modificabile dall'utente ma che appaia con i colori normali?
Visto che la checkbox contiene al massimo 10 elementi ho creato un array in
cui memorizzo il valore iniziale del check. Quindi nll'evento ClickCheck
(che però non ritorna quale elemento è stato cliccato, giusto?) reimposto
ogni volta i valori delle checkbox.
So che è una bestialità, ma alla fine ottengo velocemente quello che mi
serve e l'utente non vede nulla di strano.
In ogni caso, se avete qualche consiglio per continuare con le altre
soluzioni proposte, proverei ad implementare anche quelle, se non altro per
il gusto di capire e sperimentare


 altro per il gusto di capire e sperimentare
Potresti metterla in un container (group box, panel) che disabiliti, ma
in tal caso non hai piu' le scroll bar funzionanti.
Saluti
Paolo Arosio

 in tal caso non hai piu' le scroll bar funzionanti.
Esatto, ci avevo pensato anche io...



Prova ad intercettare il WM_MOUSEDOWN e il WM_KEYDOWN, bloccando nel primo
caso ogni click e nel secondo i tasti che consentono la modifica dei check
Ciao,
Stefano

 (che però non ritorna quale elemento è stato cliccato, giusto?)
In parte...
quando un item viene cliccato l'indice si sposta su di esso. Quindi, dato
che lo stato viene modificato, basta mettere quest'unica linea nella
procedura attaccata all'evento:
CheckListBox1.Checked[CheckListBox1.ItemIndex]:= not
CheckListBox1.Checked[CheckLIstBox1.Itemindex];
Ciao.
Giuseppe

 componente?
Ogni controllo ha una property windowproc. Prendi il valore di tale
proprietà lo salvi in una tua variabile e lo sovrascrivi con la tua
procedura di controllo.
tipo:
oldproc: procedure(var message:tmessage) of object;
nel constructor, o dove ti pare più giusto, subclassi la Windowproc della
checklistbox...
oldproc:= checklistbox.windowproc;
checklistbox.windowproc:= miawindowproc;
Poi nella tua windowproc controlli tutti i messaggi che arrivano a quella
finestra:
procedure tform1.miawindowproc(var message:tmessage);
begin
if message.msg = wm_setfocus then
begin
...
end
else oldproc(message);
end;
E' indispensabile che se la tua windowproc non processa i messaggi li invii
alla vecchia e originaria procedura.
Prova a vedere un po' se il cambio di stato di un elemento sia preceduto da
un messaggio... messaggio che ovviamente bloccherai.
Ciao.
Giuseppe.

 CheckListBox1.Checked[CheckLIstBox1.Itemindex];
Azz...ancora meglio. grazie
