OnMouseWheel im DBGrid (Code) Hilfe



  • Hallo Leute,

    ich suche mich bisher fast perfekt durch die Hilfen des BCB, dieser Faq und einigen Beiträgen. Hat bisher auch recht gut geklappt, allerdings dachte ich bei meinem letzten Problem, dass die Suche hier nicht funktioniert, da andauernd, egal was für Kombinationen ich zu meinem Problem eingegeben hatte folgende Zeile zu lesen war:

    „Keine Beiträge entsprechen Ihren Kriterien.”

    Das Scrollen mit der Maus beim DBGrid ist von Natur aus eine Katastrophe, weil immer der "gdSelected" verspringt, nachdem man anschließend in das DBGrid klickt. Ok, das Thema wurde im Forum „meiner Meinung” nach noch nicht abgehandelt (Ich wurde nicht annähernd fündig!).

    Habe dann gegooglet und wurde zum Teil belohnt, allerdings ist es Delphi-Code. Die simplen Sachen, wie Variablen-Zuweisung und so kenne ich auch bei Delphi, nur einiges daraus macht mir Kopfschmerzen (im Code durch Kommentare angedeutet!). Vielleicht kann mir ja jemand beim Umsetzen im Builder dabei behilflich sein?

    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Grids, DBGrids, DB, DBTables;
    
    type
      TForm1 = class(TForm)
        DataSource1: TDataSource;
        Table1: TTable;
        DBGrid1: TDBGrid;
        procedure FormCreate(Sender: TObject);
        procedure DBGridMouseWheel(Sender: TObject; Shift: TShiftState;
          WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    /* 
    Problem!
    -----------------------------------
      TWheelDBGrid = class(TDBGrid)
      public
        property OnMouseWheel;
      end;
    -----------------------------------
    */
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm1.FormCreate(Sender: TObject);
    /*
    Problem!
    -----------------------------------
    begin
      TWheelDBGrid(DBGrid1).OnMouseWheel := DBGridMouseWheel;
    end;
    -----------------------------------
    
    Kann ich diese Funktion auch einfach auf die Form setzen oder vorher irgendwo deklarieren? Und wofür steht das @-Zeichen?
    -----------------------------------
    function GetNumScrollLines: Integer;
    begin
      SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, @Result, 0);
    end;
    -----------------------------------
    */
    procedure TForm1.DBGridMouseWheel(Sender: TObject; Shift: TShiftState;
      WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
    var
      Direction: Shortint;
    begin
      Direction := 1;
      if WheelDelta = 0 then
        Exit
      else if WheelDelta > 0 then
        Direction := -1;
    /*
    Problem wegen Assigned und Invalidate
    -----------------------------------
      with TDBGrid(Sender) do
      begin
        if Assigned(DataSource) and Assigned(DataSource.DataSet) then
          DataSource.DataSet.MoveBy(Direction * GetNumScrollLines);
        Invalidate;
      end;
    -----------------------------------
    */
    end;
    
    end.
    

    Wäre super, wenn mir jemand hilft! 🙂


  • Mod

    Hallo

    am besten du leitest dir eine neue Komponente ab

    oder (als kleiner Einstieg)

    in FormCreate
    // für TDBGrid und die Wheelmaus
    OldWndProcDBGrid = DBGridProd->WindowProc;
    DBGridProd->WindowProc = NewWndProcDBGrid;
    // für TDBGrid und die Wheelmaus

    sowie

    //-------------------------------------------------------
    void __fastcall TForm1::NewWndProcDBGrid(TMessage &AMsg)
    {
    switch (AMsg.Msg)
        {
        case WM_MOUSEWHEEL :
                if (DBGridProd->DataSource && DBGridProd->DataSource->DataSet &&
                            !DBGridProd->DataSource->DataSet->IsEmpty())
                    {
                    if (AMsg.WParam < 0)
                        DBGridProd->DataSource->DataSet->Next();
                    else
                        DBGridProd->DataSource->DataSet->Prior();
                    }
        break;
               default : OldWndProcDBGrid(AMsg);
        }
    }
    //----------------------------------------------------------------------------------
    

    MfG
    Klaus



  • Hallo

    am besten ist es, wenn du ein neues Control von DBGrid ableitest (mit den Assistenten ist das leicht) und einfach diese Funktion überschreibst :

    // Funktion nach MouseWheelUp
    bool __fastcall TDBGridEx::DoMouseWheelUp(Classes::TShiftState Shift, const Windows::TPoint &MousePos)
    {
      if (DataSource == NULL) return(false);
      DataSource->DataSet->Prior(); // vorhergehenden Datensatz auswählen
      return(true);
      }
    
    // Funktion nach MouseWheelDown
    bool __fastcall TDBGridEx::DoMouseWheelDown(Classes::TShiftState Shift, const Windows::TPoint &MousePos)
    {
      if (DataSource == NULL) return(false);
      DataSource->DataSet->Next(); // nächsten Datensatz auswählen
      return(true);
      }
    

    bis bald
    akari



  • Danke ertsmal für die schnelle Hilfe.

    @klausb:

    Ich glaube ich verstehe die Logik. Du schiebst erstmal deine Nachrichtenabfang routine für´s DBGrid dazwischen, und lässt danach die ursprüngliche Nachrichtenverarbeitung durchlaufen, richtig?

    Also laut Hilfe initialisere ich eine neue WindowsProcedure mit WndProc, aber irgendwie haut das nicht hin. Ich bekomme keine Struktur-Deklaration von "OldWndProcDBGrid" hin, vielleicht zu unwissend, kannste mir da mal ne kleine Hilfestellung zu geben, da mir diese Lösung auch recht komfortabel und einfach erscheint.

    @akari:

    ich habe es noch nie gemacht, wie geht so etwas (komponente ableiten und methoden überschreiben? Kannste mir da ne kurze Step by Step Anleitung geben?

    Vielen Dank im voraus! 🙂

    gruß gerd



  • @klausb

    habe es jetzt so versucht, klappt allerdings nichts. wahrscheinlich kapier ich es nicht.

    Im FromCreate:

    MSG msg;
    WndProc(msg.message) OldWndProcDBGrid;
    WndProc(msg.message) NewWndProcDBGrid;
    
    OldWndProcDBGrid = DBGridProd->WindowProc;
    DBGridProd->WindowProc = NewWndProcDBGrid;
    

    Gruß Gerd


  • Mod

    Hallo

    mach nur das was ich dir gepostet habe
    zusaetzlich in def .h

    // für TDBGrid und die Wheelmaus
    TWndMethod OldWndProcDBGrid;
    void __fastcall NewWndProcDBGrid(TMessage &AMsg);
    // für TDBGrid und die Wheelmaus

    aber eine eigene Komponente ist eigentlich besser
    aber zum allgemeinen Verstaendnis naja ...

    MSG msg;
    WndProc(msg.message) OldWndProcDBGrid;
    WndProc(msg.message) NewWndProcDBGrid;

    brauchst du nicht

    Mfg
    Klaus



  • @akari:

    ich habe es noch nie gemacht, wie geht so etwas (komponente ableiten und methoden überschreiben? Kannste mir da ne kurze Step by Step Anleitung geben?

    Also :
    - Menü Komponente/NeueKomponente
    im Dialog Werte eintragen/auswählen :
    Vorfahrtyp : DBGrid
    Klassenname : TDBGridEx
    Palettenseite : Beispiel lassen oder Datensteuerung
    Name der Unit : <Pfad>\DBGridEx.cpp
    ->Ok
    - Es wird ein Projekt mit der neuen Klasse erzeugt, in die du den oben
    genannten Code einfügst. Die Deklaration der Funktionen in der Headerdatei
    nicht vergessen
    - Menü Ansicht/Projektverwaltung, im Fenster den Installieren-Button drücken
    Projekt wird kompiliert und Control wird registriert.
    - Die Datei DBGridEx.h in ein Pfad kopieren, der immer included ist, z.B. <BCB-Pfad>/Include

    Dann kannst du alle DBGrids durch DBGridEx ersetzten

    bis bald
    akari



  • hi akari und klausb,

    als erstes, sieht der thread bei euch auch so komisch aus, vielleicht nen tag falsch verschachtelt?

    also erstmal besten dank, zweite variante hatte ich auch versucht, nur irgendwie hatte es noch nicht ganz hingehauen, aber ich denke jetzt bin ich in der lage dazu.

    eine frage noch, die methoden unter __published, oder unter public: wo liegt da eigentlich ganz genau der unterschied?

    das mit dem Nachrichten auffangen klappt jetzt übrigends auch wunderbar, aber ich denke es ist wirklich von vorteil sich dafür gleich ne klasse abzuleiten und für die zukunft parat zu halten.

    und wo wir gerade beim thema sind, ist es möglich bei abgeleiteten klassen weitere eigenschaften im objektinspektor anzeigen zu lassen? und kann man aus abgeleiteten klassen auch ein ocx genrieren, oder auf anderen weg?

    vielen dank im voraus!

    gruß gerd



  • hi akari,

    habe es laut deiner Version versucht, wie schon gesagt, meines hatte nen klaren Fehler. Deines aber ebenfalls:

    Antwort des Builders:

    [C++ Fehler] DBGridEx.h(19): E2113 Virtuelle Funktion '_fastcall TDBGridEx::DoMouseWheelUp(TShiftState,const TPoint &)' verursacht Konflikte mit der Basisklasse 'TCustomGrid'

    Was mach ich nun?

    Mit der Hoffnung auf Hilfe 🙂

    Gruß Gerd



  • Hallo

    die seite wird auch mir zerhackt, es liegt wohl an KlausB's letztem Post

    Wegen dem Fehler : hast du vielleicht das bool vergessen
    [cpp]bool __fastcall TDBGridEx::DoMouseWheelUp(Classes::TShiftState Shift, const Windows::TPoint &MousePos)[/cpp]

    bis bald
    akari



  • hi,

    nein, alles so eingefügt, trotzdem geht es nicht!

    Headerdatei:

    //---------------------------------------------------------------------------
    
    #ifndef DBGridExH
    #define DBGridExH
    //---------------------------------------------------------------------------
    #include <SysUtils.hpp>
    #include <Controls.hpp>
    #include <Classes.hpp>
    #include <Forms.hpp>
    #include <DBGrids.hpp>
    #include <Grids.hpp>
    //---------------------------------------------------------------------------
    class PACKAGE TDBGridEx : public TDBGrid
    {
    private:
    protected:
    public:
        __fastcall TDBGridEx(TComponent* Owner);
        // Funktion nach MouseWheelUp
        bool __fastcall DoMouseWheelUp(Classes::TShiftState Shift, const Windows::TPoint &MousePos);
        // Funktion nach MouseWheelDown
        bool __fastcall DoMouseWheelDown(Classes::TShiftState Shift, const Windows::TPoint &MousePos);
    __published:
    };
    //---------------------------------------------------------------------------
    #endif
    

    Quelldatei:

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "DBGridEx.h"
    #pragma package(smart_init)
    //---------------------------------------------------------------------------
    // ValidCtrCheck wird benutzt, um sicherzustellen, daß die erzeugten Komponenten
    // keine rein virtuellen Funktionen besitzen.
    //
    
    static inline void ValidCtrCheck(TDBGridEx *)
    {
        new TDBGridEx(NULL);
    }
    //---------------------------------------------------------------------------
    __fastcall TDBGridEx::TDBGridEx(TComponent* Owner)
        : TDBGrid(Owner)
    {
    }
    //---------------------------------------------------------------------------
    namespace Dbgridex
    {
        void __fastcall PACKAGE Register()
        {
             TComponentClass classes[1] = {__classid(TDBGridEx)};
             RegisterComponents("Datensteuerung", classes, 0);
        }
    }
    //---------------------------------------------------------------------------
    

    Gruß Gerd



  • Hallo

    sorry, hatte vergessen, DYNAMIC zun erwähnen
    das muß also in die Headerdatei:

    protected:
    
        // Funktion nach MouseWheelUp
        DYNAMIC bool __fastcall DoMouseWheelUp(Classes::TShiftState Shift, const Windows::TPoint &MousePos);
    
        // Funktion nach MouseWheelDown
        DYNAMIC bool __fastcall DoMouseWheelDown(Classes::TShiftState Shift, const Windows::TPoint &MousePos);
    

    und das in die Quellcode-Datei

    // Funktion nach MouseWheelUp
    bool __fastcall TDBGridEx::DoMouseWheelUp(Classes::TShiftState Shift, const Windows::TPoint &MousePos)
    {
      if (DataSource == NULL) return(false);
      DataSource->DataSet->Prior(); // vorhergehenden Datensatz auswählen
      return(true);
      }
    //---------------------------------------------------------------------------
    
    // Funktion nach MouseWheelDown
    bool __fastcall TDBGridEx::DoMouseWheelDown(Classes::TShiftState Shift, const Windows::TPoint &MousePos)
    {
      if (DataSource == NULL) return(false);            
      DataSource->DataSet->Next(); // nächsten Datensatz auswählen
      return(true);
      }
    //---------------------------------------------------------------------------
    

    Dann kompiliert das auch.

    bis bald
    akari



  • hi akari,

    funzt prima, danke dir für deine müheund natürlich auch klausb! 🙂

    gruß gerd



  • Hallo, Akari,

    habe alles so gemacht wie von dir beschrieben, aber es geht nicht. Bekomme einige Fehlermeldungen:

    [C++ Error] DBGridMy.h(17): E2316 'TPoint' is not a member of 'Windows'
    [C++ Error] DBGridMy.h(17): E2293 ) expected
    [C++ Error] DBGridMy.h(20): E2316 'TPoint' is not a member of 'Windows'
    [C++ Error] DBGridMy.h(20): E2293 ) expected
    [C++ Error] DBGridMy.cpp(34): E2316 'TPoint' is not a member of 'Windows'
    [C++ Error] DBGridMy.cpp(34): E2316 'DoMouseWheelUp' is not a member of 'TDBGridMy'
    [Linker Fatal Error] Fatal: Unable to open file 'DBGRIDMY.OBJ'

    Kannst du mir weiter helfen?

    MfG Denis



  • Problem geloest...

    Windows musste durch Types ersetzt werden

    Denis


Anmelden zum Antworten