Il arrive parfois que l'on veut empêcher le déplacement de la première colonnes d'un TListView et autoriser les autres à se déplacer en mettant la propriété FullDrag à true.

Par exemple dans Microsoft Office Outlook la dernière colonne, Statut, ne peut se déplacer. Je n'ai pas trouver d'exemple avec la première colonne, mais on n'a qu'à penser à une liste avec des cases à cocher que l'on veut garder en toute circonstance en première position.

Pour arriver à ce résultat on doit d'abord déclarer les éléments suivants:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
    Classes::TWndMethod OldWindowProc;
    void __fastcall ListViewWndProc(Messages::TMessage &Message);
    bool PreventDrag;
Dans le constructeur on ajoute ceci:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
    OldWindowProc = ListView1->WindowProc;
    ListView1->WindowProc = ListViewWndProc;
    PreventDrag = false;
    ListView1->FullDrag = true; // Permet à toutes les colonnes de bouger
Finalement, on capte quelques messages envoyés à la list view:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void __fastcall TForm1::ListViewWndProc(Messages::TMessage &Message)
{
    if(Message.Msg == WM_NOTIFY)
    {
        NMHEADER* pNMHeader = (NMHEADER*) Message.LParam;
        switch(pNMHeader->hdr.code)
        {
            case HDN_BEGINDRAG:
                if(PreventDrag || pNMHeader->iItem == 0)
                {   // La première colonne ne doit pas bouger
                    Message.Result = true;
                    PreventDrag = true;
                    return;
                }
                break;
            case HDN_ENDDRAG:
                if(pNMHeader->pitem && pNMHeader->pitem->iOrder == 0)
                {   // Aucune colonne doit prendre la place de la première
                    Message.Result = true;
                    return;
                }
                break;
            case NM_RELEASEDCAPTURE:
                PreventDrag = false;
                break;
        }
    }
    OldWindowProc(Message);
}
Comment faire, si au lieu d'interdire le déplacement de la première colonne, je veut que se soit la dernière?

Premièrement on prend le numéro de la colonne en note avec:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
int LastCol = ListView1->Columns->Count - 1;
Et dans le code plus haut on change les deux "== 0" pour "== LastCol ".

J'espère que ce code vous sera utile.