TreeNode : disparition des scrollsBars [Résolu]

Utilisateur anonyme - 25 août 2006 à 19:52 - Dernière réponse :  Utilisateur anonyme
- 27 août 2006 à 17:28
Salut à tous,

Suite au source http://www.delphifr.com/codes/VIDEOCREATOR-ANIMATION-IMAGES_39259.aspx, il est apparu dans ce projet un probleme au niveau des scrollbars d'un treeview. Quand on parcoure les TreeNode avec le curseur via la procedure OnChange, la scrollbar disparait puis réapparait parfois. 

J'ai donc gelé le code de la procedure OnChange : autrement dit plus rien du tout. Manque de chance, le probleme est toujours présent.

Pour résumé quand on navigue rapidement avec le clavier au sein d'un treeview, la scrollbar disparait. Est ce un beug de ce composant ??


 


@+ et merci ;).
Afficher la suite 

Votre réponse

5 réponses

Meilleure réponse
cs_Forman 663 Messages postés samedi 8 juin 2002Date d'inscription 6 avril 2010 Dernière intervention - 27 août 2006 à 17:15
3
Merci
Le problème est dans Delphi, et provient de l'utilisation (en général) de la propriété BevelKind (par exemple avec bkFlat) pour pas mal de composants, ou dans le cas du TreeView/ListView de la propriété FlatScrollBars=True. Le bug est dans la gestion du message WM_NCPAINT, je l'ai corrigé pour un de mes compo (TVirtualScrollingWinControl):

procedure TVirtualScrollingWinControl.WMNCPaint(var Message: TWMNCPaint);  //another fix of Delphi VCL...
const
  InnerStyles: array[TBevelCut] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER, 0);
  OuterStyles: array[TBevelCut] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER, 0);
  EdgeStyles: array[TBevelKind] of Integer = (0, 0, BF_SOFT, BF_FLAT);
  Ctl3DStyles: array[Boolean] of Integer = (BF_MONO, 0);
var
  DC: HDC;
  RC, RW, RWH, RWV, SaveRW: TRect;
  EdgeSize: Integer;
  WinStyle: Longint;
begin
  { Get window DC that is clipped to the non-client area }
  inherited;
  if (BevelKind <> bkNone) or (BorderWidth > 0) then
  begin                     
    DC := GetWindowDC(Handle);
    try
      Windows.GetClientRect(Handle, RC);
      GetWindowRect(Handle, RW);
      MapWindowPoints(0, Handle, RW, 2);
      OffsetRect(RC, -RW.Left, -RW.Top);
      ExcludeClipRect(DC, RC.Left, RC.Top, RC.Right, RC.Bottom);
      { Draw borders in non-client area }
      SaveRW := RW;
      InflateRect(RC, BorderWidth, BorderWidth);
      RW := RC;
      WinStyle := GetWindowLong(Handle, GWL_STYLE);
      if BevelKind <> bkNone then
      begin
        EdgeSize := 0;
        if BevelInner <> bvNone then Inc(EdgeSize, BevelWidth);
        if BevelOuter <> bvNone then Inc(EdgeSize, BevelWidth);
        with RW do
        begin
          if beLeft in BevelEdges then Dec(Left, EdgeSize);
          if beTop in BevelEdges then Dec(Top, EdgeSize);
          if beRight in BevelEdges then Inc(Right, EdgeSize);
          if (WinStyle and WS_VSCROLL) <> 0 then Inc(Right, GetSystemMetrics(SM_CYVSCROLL));
          if beBottom in BevelEdges then Inc(Bottom, EdgeSize);
          if (WinStyle and WS_HSCROLL) <> 0 then Inc(Bottom, GetSystemMetrics(SM_CXHSCROLL));
          DrawEdge(DC, RW, InnerStyles[BevelInner] or OuterStyles[BevelOuter],
            Byte(BevelEdges) or EdgeStyles[BevelKind] or Ctl3DStyles[Ctl3D] or BF_ADJUST);
        end;
        IntersectClipRect(DC, RW.Left, RW.Top, RW.Right, RW.Bottom);
        RW := SaveRW;
      end;
      RWH:=Rect(2*BevelWidth+BorderWidth,RW.Bottom,RW.Right,RW.Bottom);
      RWV:=Rect(RW.Right,2*BevelWidth+BorderWidth,RW.Right,RW.Bottom);
      if (WinStyle and WS_VSCROLL) <> 0 then begin
        Dec(RWH.Right, GetSystemMetrics(SM_CXVSCROLL));
        Dec(RWV.Left, GetSystemMetrics(SM_CXVSCROLL));
      end;
      if (WinStyle and WS_HSCROLL) <> 0 then begin
        Dec(RWH.Top, GetSystemMetrics(SM_CYHSCROLL));
        Dec(RWV.Bottom, GetSystemMetrics(SM_CYHSCROLL));
      end;
      with RWH do
        ExcludeClipRect(DC,Left,Top,Right,Bottom);
      with RWV do
        ExcludeClipRect(DC,Left,Top,Right,Bottom);
      { Erase parts not drawn }
      OffsetRect(RW, -RW.Left, -RW.Top);
      Windows.FillRect(DC, RW, Brush.Handle);
    finally
      ReleaseDC(Handle, DC);
    end;
  end;

  if ThemeServices.ThemesEnabled and (csNeedsBorderPaint in ControlStyle) then
    ThemeServices.PaintBorder(Self, False);
end;

A noter: le bug se produit aussi pour d'autres composants lors du réaffichage de la fenêtre (par exemple TMemo) lorsque BevelKind=bkFlat par exemple. Ce bout de code (à utiliser à la place du TWinControl.WMNCPaint original de Delphi) devrait corriger le problème, avec ou sans le thème. En tout cas, ça fonctionnait avec mon compo.

Merci cs_Forman 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 92 internautes ce mois-ci

Commenter la réponse de cs_Forman
Utilisateur anonyme - 25 août 2006 à 20:08
0
Merci
J'ai trouvé la raison :

*Ajouter un XPManifest, compiler et ouvrer : vous constatez quoi ?

*Supprimer l'image principale "video Creator" :
-recommencer alors ??
-Tester le TreeView : Alors ??

Le TImage : autre beug que Le DoubleBuffered ?? A vons de conclure

@+
Commenter la réponse de Utilisateur anonyme
Utilisateur anonyme - 25 août 2006 à 21:27
0
Merci
J'ai fais une bourde : Hihihihi. Enfin presque

*XPMan : Probleme reglé si on supprime le TImage. Donc un probleme peut etre ?

*Le TreeView : indépendant du TImage. La preuve :

Pour aller plus loin dans l'analyse voila ce que j'ai fais :

Utiliser un TreeView, un bouton et un OpenDialog.

Source :

Procedure AddFileInTreeView(AListFile : TStrings);
Var
CNode:TTreeNode;
NmFile : LongInt;
Begin
With Form1.ImageFiles_TreeView do
Begin
{On définir le TreeNode en cas de TreeView vide, sinon si pas vide}
IF selected=nil then CNode:=selected Else
Begin
{Si la sélection n'est pas un fichier on sort}
If Selected.ImageIndex<>0 then Exit
{Sinon le TreeNode est le prochain TreeNode "frère"}
Else CNode:=selected.getNextSibling;
End;
{On fait une boucle avec tout les fichiers sélectionnés (rappel on est en multisélection)}
For NmFile:=0 to(AListFile.Count-1) do
Begin
{On définit l'icone}
{On insert le nom du fichier dans le TreeNode}
Items.insert(CNode, AListFile[NmFile]);
End;
End;
End;

procedure TForm1.ImageFilesAdd_BtClick(Sender: TObject);
begin
{On vide l'Edit}
{Avec l'OpenDialog}
With OpenDialog1 do
Begin
{On définit les filtres}
Filter:='Fichier images|*.bmp;*.jpg;*.jpeg';
{On se met en multisélection}
Options:=[OfAllowMultiSelect];
If Execute then
{S'il executé on place le nom des fichiers images dans le TreeView}
AddFileInTreeView(OpenDialog1.Files);
End;
end;

Bingo : On se ballade encore dans le TreeView, et bien dans le mille on perd encore le ScrollBar et les TreeNodes scintillent.

Conclusion : La propriété OnChange semble capoter dans le TreeNode, non ?
Commenter la réponse de Utilisateur anonyme
Utilisateur anonyme - 25 août 2006 à 21:39
0
Merci
Par rapport au XPManifest, je confirme :

Il y a un beug entre le TImage et ce composant : avec juste les boutons, Timages et autres.
Commenter la réponse de Utilisateur anonyme
Commenter la réponse de Utilisateur anonyme

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.