2008-10-08 5 views
2

J'utilise le contrôle de liste MFC dans la vue de rapport avec des lignes de quadrillage pour afficher les données de façon vaguement chiffrée.Le défilement du contrôle de liste MFC affiche des lignes de quadrillage supplémentaires

Parfois, lorsque l'utilisateur fait défiler verticalement le contrôle, des lignes de grille supplémentaires sont dessinées, ce qui semble terrible.

Cela ne se produit pas lorsque le curseur ou la roulette de la souris est utilisée pour faire défiler, uniquement lorsque la petite touche fléchée vers le bas située en bas de la commande de défilement est utilisée.

Il semble que cela se produise lorsque la taille de la fenêtre de contrôle de liste n'est pas un nombre pair exact de lignes, de sorte qu'une ligne partielle est visible en bas.

Si j'ajuste la taille du contrôle de liste afin qu'il n'y ait aucune ligne partielle visible, le problème est résolu. Cependant, il apparaîtra lorsque le programme est exécuté sur un autre ordinateur, vraisemblablement parce que le nombre de pixels occupés par une ligne change. Je suppose qu'il s'agit d'une interaction entre la résolution de l'écran, la taille de la police et les "unités de dialogue".

Je suppose que je dois forcer par programme la taille du contrôle quand il est créé. Mais quelle taille?

J'ai essayé d'utiliser la méthode ApproximateViewRect() mais je n'arrive pas à l'obtenir. Peut-être que cette méthode ne connaît pas la vue de rapport?

L'autre méthode, je suppose, serait de créer ma propre spécialisation de CListCtrl et de surcharger n'importe quelle méthode faisant défiler. Cela semble être beaucoup de travail.

Cette capture d'écran montre un problème étroitement lié, où les lignes de la grille disparaissent

alt text http://ravenspoint.com/list_scroll_missing_grids.jpg

et voici une avec les lignes de grille supplémentaires

alt text http://ravenspoint.com/list_scroll_extra_grids.jpg

La seule différence entre ces deux et entre eux et celui qui défile parfaitement est quelques pixels différents dans la taille verticale du contrôle.

Répondre

-1

Pour corriger ce bogue dans le MFC Liste de contrôle dont vous avez besoin de se spécialiser le contrôle, surpassement la méthode Wich répond pour le défiler, et le forcer à redessiner la liste complètement après avoir fait le défilement.

tête d'interface

class cSmoothListControl : public CListCtrl 
{ 
public: 
    DECLARE_MESSAGE_MAP() 
    afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); 
}; 

mise en œuvre:

BEGIN_MESSAGE_MAP(cSmoothListControl, CListCtrl) 
ON_WM_VSCROLL() 
END_MESSAGE_MAP() 

void cSmoothListControl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{ 
    // call base class method to do scroll 
    CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar); 

    // force redraw to cover any mess that may be created 
    Invalidate(); 
    UpdateWindow(); 
} 
+3

Cette réponse ajoute simplement la carte de message périphérique à ma réponse déjà suffisante. –

+0

Ajryan, je n'ai pas trouvé votre réponse suffisante. Quand je l'ai implémenté, il a échoué. Il a fallu environ une heure pour trouver le code nécessaire que vous aviez omis. J'ai pensé sauver les autres ce chagrin. – ravenspoint

+1

Complètement ridicule. C'est comme demander comment ajouter deux nombres et dire que la réponse n'était pas suffisante parce qu'elle n'a pas indiqué comment imprimer le résultat. –

0

Est-ce que cela se produit avec la liste de stock, ou est-ce un tirage personnalisé? Je n'ai jamais vu redessiner les problèmes avec les contrôles Windows standard.

Peut-être pourriez-vous poster une capture d'écran pour illustrer le problème? Je présume que vous préférez résoudre le problème de redessiner et ne pas dimensionner le contrôle exactement?

+0

stock complètement. Le problème est difficile à reproduire, et je ne suis pas clair sur la façon de poster une image ici. – ravenspoint

+0

Ajouté screenshots – ravenspoint

+0

Ok je vois. Ce contrôle est-il créé avec l'éditeur de ressources, ou le créez-vous dynamiquement (dans OnInitDialog() avec m_ListCtrl.Create (...) par exemple?) Si vous faites le dernier, avez-vous essayé de jouer avec WS_CLIPCHILDREN et WM_CLIPSIBLINGS? Cela a corrigé des problèmes similaires de redraw pour moi dans le passé. – Roel

1

Je me souviens que c'était un bug dans le ListView (pas seulement à travers MFC, mais le contrôle commun en général) lui-même. Un google rapide à ce sujet semble frapper beaucoup de gens à la même conclusion. Je suppose que Windows Explorer n'a pas de grille, ils ne sentent pas le besoin de résoudre ce problème? Je me souviens de ça à la fin des années 90.

Je suppose que l'astuce serait d'invalider la fenêtre après un défilement - peut-être en réponse à un message VSCROLL? Juste une supposition.

+0

Quels termes de recherche avez-vous utilisés dans google? Je n'ai rien trouvé. Est-ce que "ListView" est le même que "List Control", ce qui est ce que j'utilise> – ravenspoint

6

Ceci est en effet un bug lié à « un défilement fluide, » est ici une solution de contournement:

void CMyListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{ 
    __super::OnVScroll(nSBCode, nPos, pScrollBar); 
    Invalidate(); 
    UpdateWindow(); 
} 
+0

Pour que l'appel du framework appelle l'overide, il est nécessaire de l'ajouter à la carte des messages. – ravenspoint

+0

Détails du codage de mappage de message dans ma réponse – ravenspoint

+1

La carte de message est quelque chose que tout le monde travaillant dans MFC devrait comprendre, pas spécifiquement pertinent à cette réponse. –

Questions connexes