2016-02-04 1 views
4

Le list-view control a le message LVM_GETTOPINDEX qui permet d'obtenir l'index de l'élément visible le plus haut.Contrôle de liste LVM_SETTOPINDEX requis

Maintenant, j'ai besoin de définir l'élément le plus visible, mais étonnamment, il n'y a pas de message LVM_SETTOPINDEX qui serait naturel.

Existe-t-il un moyen facile de régler l'élément le plus haut?

Mon contrôle de liste est toujours en mode rapport.

+0

Le message 'LVM_ENSUREVISIBLE' est un début. Définissez 'lParam' sur' FALSE' pour vous assurer que l'élément est * entièrement * visible. Mais cela fait juste en sorte qu'il soit visible, il ne le fait pas nécessairement en haut de la liste. Ce sera plutôt difficile à faire, bien sûr, en fonction de la taille du contrôle de liste et du nombre d'éléments qu'il contient. –

+0

@CodyGray lorsque vous écrivez 'LVM_ENSUREVISIBLE' est un début, mais cela garantit simplement qu'il effectue un défilement minimal pour que l'élément sélectionné soit visible, il sera soit à la première ligne de la dernière ligne selon si l'élément sélectionné était au dessus ou en dessous de la vue. 'LVM_SETTOPINDEX' est de nouveau quelque chose que Microsoft a oublié. –

+0

Considérez si vous avez un très grand contrôle de vue liste, et seulement quelques éléments. Les éléments ne remplissent pas la boîte, et il n'y a aucune raison pour qu'une barre de défilement apparaisse. Maintenant, comment allez-vous les faire défiler pour que l'objet n ° 5 soit en haut? Tu ne peux pas. Vous ne pouvez pas le faire de manière interactive, et vous ne pouvez pas le faire par programmation. Certes, il y a des moments où cela fonctionnerait, mais il y a des moments où ce ne serait pas le cas, donc vous ne pouvez pas avoir un message générique qui le fait. –

Répondre

2
  1. Utilisez LVM_GETITEMPOSITION ou LVM_GETITEMRECT pour obtenir la position des éléments. Utilisez LVM_SCROLL pour faire défiler la liste afin que votre article soit le premier article.
+0

C'est ce dont j'avais besoin, voir ma propre réponse ci-dessous. –

+0

Je pense que ma réponse a tout ce qu'il faut, non? Le concept est ce qui compte sûrement. Je ne suis pas sûr de ce que vous avez contre cette réponse. –

+0

Votre réponse est bonne, je viens de fournir la mise en œuvre dans ma propre réponse. –

2

D'abord, cela peut ne pas être possible. Par exemple, si la liste n'a pas assez d'éléments après votre index supérieur pour remplir la page.

Comme il n'y a pas de manière directe, vous pouvez compter le nombre d'éléments sur la page, ajouter ce nombre à votre index et appeler EnsureVisible(). Cela vous assurera que votre dessus est au-dessus de la page visible. Le prochain EnsureVisible() pour votre article l'amènera dans la vue, en haut de la page. Bien sûr, vous devrez bloquer les mises à jour pour éviter les saccades de l'écran.

Exemple (mis à jour par Vlad):

void CDlg::SetTopIndex(int top) 
{ 
    int bottom = min(top + m_List.GetCountPerPage(), m_List.GetItemCount() - 1); 
    m_List.SetRedraw(FALSE); 
    m_List.EnsureVisible(bottom, TRUE); 
    m_List.EnsureVisible(top, FALSE); 
    m_List.SetRedraw(TRUE); 
} 
+0

J'ai ajouté un exemple si cela ne vous dérange pas –

+0

Cela ne me dérange pas, mais je viens de mettre à jour votre exemple pour refléter ma proposition. –

0

Cette fonction fait le travail:

void SetTopIndex(CListCtrl & listctrl, int topindex) 
{ 
    int actualtopindex = listctrl.GetTopIndex(); 
    int horspacing; 
    int lineheight; 
    listctrl.GetItemSpacing(TRUE, &horspacing, &lineheight); 

    CSize scrollsize(0, (topindex - actualtopindex) * lineheight); 
    listctrl.Scroll(scrollsize); 
} 

Pas d'assainissement des paramètres se fait ici.

Merci à David Heffernan et Remy Lebeau pour m'avoir donné l'idée.