2011-09-23 3 views
8

Pour notre dbgrid, nous voulons que les barres de défilement soient constamment cachées. Depuis TDBGrid ne dispose pas d'une propriété « » scrollbars, nous utilisons:Gardez les barres de défilement cachées dans un dbgrid Delphi (même lors du redimensionnement)

ShowScrollBar(DBGrid1.Handle, SB_VERT, False); 
ShowScrollBar(DBGrid1.Handle, SB_HORZ, False); 

Cependant, lorsque nous redimensionnez la fenêtre (et le panneau contenant le DBGrid), pour une deuxième apparaissent les barres de défilement et becom cachés à nouveau seulement après avoir rappelé les deux méthodes ci-dessus.

Une solution consiste à appeler ces méthodes dans DrawColumnCell, mais cela provoque le scintillement du dbgrid, même si DoubleBuffered est défini sur true.

Est-il possible de masquer les barres de défilement de façon permanente?

Merci d'avance!

+0

Veuillez noter que 'DoubleBuffered 'dans Delphi VCL et, dans une certaine partie, dans Windows lui-même n'est pas une véritable technique DoubleBuffered. –

+0

S'il vous plaît ne dites pas Delphi dans le titre si vous voulez un exemple de C++ Builder. –

+0

Idée de piratage ridicule: placez DBGrid dans un panneau et dimensionnez le panneau de façon à ce qu'il soit suffisamment grand pour ne jamais afficher les barres de défilement. Au lieu de cela, vous obtiendrez du contenu tronqué. –

Répondre

6

Le masquage de la barre de défilement du TDBGrid dans CreateParams a un effet de temps très court. Il y a la procédure UpdateScrollBar qui fait que la barre de défilement est visible. Cela arrive parce que la visibilité de la barre de défilement est contrôlée en fonction des données affichées, ainsi cette procédure est appelée chaque fois que les données sont modifiées.

Et puisque cette procédure est appelée chaque fois que la barre de défilement doit être mise à jour et parce qu'elle est virtuelle, il est temps de la remplacer.
L'exemple de code suivant utilise la classe interposés, de sorte que tous TDBGrid composants sur la forme qui appartient à cette unité se comportera de la même:

unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs; 

type 
    TDBGrid = class(DBGrids.TDBGrid) 
    private 
    procedure UpdateScrollBar; override; 
    end; 

type 
    TForm1 = class(TForm) 
    DBGrid1: TDBGrid; 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TDBGrid.UpdateScrollBar; 
begin 
    // in this procedure the scroll bar is being shown or hidden 
    // depending on data fetched; and since we never want to see 
    // it, do just nothing at all here 
end; 

end. 
+0

Pas très familier avec la syntaxe Delphi.Cela peut-il être fait sans dériver une nouvelle classe et installer un nouveau composant sur la boîte à outils dans l'environnement de développement? – truthseeker

+2

Ceci est ce que l'on appelle la classe insérée et il suffit si vous mettez-le dans votre unité (voir la mise à jour), il remplacera * la classe d'origine dans l'espace de noms où vous l'avez placé (donc tous les composants TDBGrid sur le formulaire qui appartient à l'unité seront * sous-classés *) – TLama

+0

Tout va bien mais j'aurais besoin que cet exemple soit réécrit en C++ Toutes les sources web que je pourrais trouver ont des exemples en langage Delphi Votre exemple pourrait rester tel quel et ajouter un exemple C++ ou au moins un lien vers une source faisant autorité à ce sujet mécanisme – truthseeker

0

Peut-être en remplaçant CreateParams() méthode et en supprimant WS_HSCROLL et WS_VSCROLL bits forment Params.Style fait la différence. Vous pouvez essayer de le faire avec class helper si vous ne voulez pas écrire de descendant personnalisé.

Vous pouvez également utiliser l'API avec SetWindowLongPtrGWL_STYLE changer le style de la fenêtre mais les modifications sont perdues lorsque la fenêtre de grille est recréée pour une raison quelconque (donc il est pas aussi fiable que remplaçant CreateParams).

+0

Merci! Je n'ai pas réussi à implémenter une version de travail d'une de vos suggestions. Je viens maintenant de désactiver les barres de défilement avec le même appel que j'ai mentionné, lorsque le panneau que dbgrid fait partie des redimensionnements. – user729103

+0

SetWindowLongPtr ne fonctionne pas pour moi :-(. – truthseeker

1

La barre de défilement est mis à jour en TDBGrid.UpdateScrollBar. Malheureusement, cette routine n'est pas virtuelle (en D7 au moins). Dans cette routine, SetScrollInfo est appelée, une fonction Windows qui n'envoie aucun message susceptible d'être intercepté. Pas de chance là-bas.

La gauche seule possibilité est de remplacer le gestionnaire de messages pour le message qui est envoyé chaque fois que la commande de taille a changé:

type 
    TDBGrid = class(DBGrids.TDBGrid) 
    private 
    procedure WMWindowPosChanged(var Message: TWMWindowPosChanged); 
     message WM_WINDOWPOSCHANGED; 
    end; 

procedure TDBGrid.WMWindowPosChanged(var Message: TWMWindowPosChanged); 
begin 
    inherited; 
    Windows.ShowScrollBar(Handle, SB_VERT, False); 
end; 

Bien que UpdateScrollBar est également appelé lorsque les données sont modifiées ou lorsque Active changements de propriété de l'ensemble de données , cela semble fonctionner ici sans scintillement.

+5

Dans Delphi 2007, UpdateScrollbar * est * virtual, donc le besoin de ce hack dépend de votre version de Delphi. – GolezTrol

+0

J'ai un problème avec la barre de défilement horizontale - la zone cliente où la barre de défilement n'était pas cliquable -> ne peut pas sélectionner la ligne du bas –

Questions connexes