Newsgroup: it.comp.programmare.win32
Titolo: [MFC] ListView: disabilitazione tasti

Ciao a tutti,
come da oggetto ho una listview, in modalità report, su una dialog.
Ho bisogno che vengano ablilitati certi bottoni e funzionalità a seconda
dell'elemento selezionato.
Intercettando i click del mouse con una ON_NOTIFY(NM_CLICK,...) riesco
nell'intento.
Però è sempre possibile muoversi sulla lista attraverso i tasti arrow key e
i tasti PgUp, PgDn, Home, End.
Per le arrow key ho usato una ON_NOTIFY(LV_KEYDOWN, ...).
Il problema sorge con i gli altri, che mi fanno "saltare posizioni" e
perdere le proprietà dei vari item della
lista.
Mi chiedevo se era possibile in qualche modo disabilitare questi tasti (in
generale un sottoinsieme di tasti).
Forse attraverso un WM_KEYDOWN, o attraverso una CWnd::OnKeydown(), ma il
meccanismo non
mi è molto chiaro...
Grazie,
Davide.

 mi è molto chiaro...
Quel meccanismo (della tastiera) e' una vera lacuna dei
trattati/guide/MSDN che non
riescono a dare una porzione esauriente di codice utile.
Unica eccezione, forse, Prosaise nel caso MFC che utilizza Acceleratori
e messaggi WM_COMMAND in una funzione "PreTranslateMessage()".
Il caso e' quello di una calcolatrice "Dialog Based".
Riporto:
To circumvent these problems, I decided to use accelerators to process
keyboard input.
I first created an accelerator resource by selecting the Resource
command from Visual C++'s
Insert menu and double-clicking "Accelerator." Then I added accelerators
for all the keys
on the face of the calculator—"1" for the IDC_1 button, "2" for the
IDC_2 button, and so on.
Next I added an HACCEL member variable to CDlgCalcDlg and inserted the
following
statement into CDlgCalcDlg's constructor to load the accelerators: 
m_hAccel = ::LoadAccelerators (AfxGetInstanceHandle (),
    MAKEINTRESOURCE (IDR_ACCELL));
Finally, I overrode PreTranslateMessage and replaced it with a version
that calls ::TranslateAccelerator on each message that the dialog
receives:
BOOL CCalcDialog::PreTranslateMessage (MSG* pMsg)
{
    if (m_hAccel != NULL)
        if (::TranslateAccelerator (m_hWnd, m_hAccel, pMsg))
            return TRUE;
 
    return CDialog::PreTranslateMessage (pMsg);
}
This way, ::TranslateAccelerator sees keyboard messages even before
 ::IsDialogMessage does, and messages corresponding to accelerator
 keys are magically transformed into WM_COMMAND messages. Because the
 accelerator keys are assigned the same command IDs as the
 calculator's push buttons, the same ON_BN_CLICKED handlers process 
button clicks and keypresses.
A questo punto deve essere processato WM_COMMAND
L'intero trattato e' lungo, ma si tratta a questo punto di processare
OnCommand()
in cui vi e' 
int nID = (int) LOWORD (wParam);
if (m_bErrorFlag && (nID != IDC_QUELLOCHEMIINTERESSA))
 {
    ::MessageBeep (MB_ICONASTERISK);
    return TRUE;
}
La mia soluzione Win32 non MFC e' stata quella di replicare in parte
l'idea
del "PreTranslateMessage" dell'MFC.
In pratica catturo i messaggi WM_KEYDOWN nel ciclo principale dei
messaggi
e spedisco un messaggio WM_TUTTOMIOKEYDOWN con gli stessi param alla
Dialog proprietaria
del controllo listview, poi, ovviamente, e' tutto sotto controllo.
Ma per una soluzione MFC mi viene in mente
1) cattura dei messaggi in PreTranslateMessage (vedi Prosaise)
2) Sub/Superclassing
3) hic sunt leones...
Saluti
JJ
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG