TLIstBox scrolling mit Mausrad festlegen
-
Hallo.
Ich habe eine Listebox und möchte gern diese mit dem Mausrad scrollen, aber nicht alle 3 Zeilen pro drehen, sondern nur 1 Zeile.
Das Problem das hier sicherlich zwischen funkt wird sein, dass diese 3 Zeilen vom Maustreiber kommen, denn wie ich nachgeschaut habe steht dort "Folgende Anzahl Zeilen: 3" für das Mausrad.
Ich möchte aber dies nicht global ändern, sondern nur für meine Anwendung für diese eine Komponente. Ich zeichne den Inhalt selbst und die Zeilen sind sehr groß. Wenn ich nun scrolle schaut das furchtbar aus. Wenn ich mit den Scrollbalkenpfeilen durchscrolle sieht es Top aus! Kann da wer helfen?
-
Hallo,
ich vermute dein Problem ist per WinAPI zu lösen, indem man Botschaften von der Maus abfängt / manipuliert. Mehr als diesen Ansatz habe ich im Moment nicht parat, aber vielleicht kommst du damit schon weiter
MfG
-
Ich gehe mal davon aus das man in die Header
void __fastcall wmMessage(TMessage &Msg); BEGIN_MESSAGE_MAP MESSAGE_HANDLER(WM_MOUSEWHEEL, TMessage, wmMessage); END_MESSAGE_MAP(TForm);
und in die Unit
void __fastcall TForm1::wmMessage(TMessage &Msg) { // ? }
setzen muss.
Allerdings weiss ich nicht wie ich jetzt eine TListBox zum scrollen bewegen soll. Eine public Scrollbar Eigenschaft besitzt diese ja nicht.
-
Kann jetzt erfolgreich das scrollen faken mit ListBox1->TopIndex.
Das einzige Problem das ich nun noch habe ist, dass ich ja nur die ListBox1 so scrollen möchte, aber mein MESSAGE_HANDLER systemweit ist.
Jetzt habe ich simple probiert
void __fastcall TForm1::wmMessage(TMessage &Msg) { if (ListBox1->Focused()) { } }
Aber damit geht er in die if gar nicht mehr rein. Wie kann ich den MESSAGE_HANDLER auf diese eine ListBox fixieren?
-
Hi,
du musst die Message zerlegen um Sender der ListBox zu erhalten.
mfg
kpeter
-
Danke für den Hinweis, damit kann ich diesmal leider nichts anfangen.
Du meinst sicher sowas in der Art
if (Message.LParam==ListBox1->Handle)
Aber wie man das korrekt abfragt und auf was ist jetzt für mich leider nicht klar und die Doku hilft mir da auch leider nicht weiter.
-
Kann irgendwer helfen und mir bitte sagen wie man es schafft das das WM_MOUSEWHEEL nur für ListBox1 ausgeführt wird? Hab es nämlich immer noch nicht hinbekommen.
-
Gibt es eigentlich eine Möglichkeit richtig zu scrollen und nicht das über TopIndex zu faken?
Ich habe gestern SendMessage(Handle, WM_MOUSEWHEEL, 20, 0); ausprobiert, aber dann bekomme ich einen Stack-Überlauf.
-
Shala schrieb:
..wie man es schafft das das WM_MOUSEWHEEL nur für ListBox1 ausgeführt wird?
Hi,
erstelle im Formularheader eine abgeleitete TListBox und überschreibe die geschützte
Methode WndProc. Etwa so:*.h-Datei
class TWheelListBox : public TListBox { private: protected: virtual void __fastcall WndProc(Messages::TMessage &Message); public: __fastcall TWheelListBox(TComponent* Owner); __fastcall ~TWheelListBox(void); // Eigenschaften etc. ergänzen }; // Hier dein Form: class TForm1 : public TForm { public: int wheelpos; TWheelListBox* WListBox; __fastcall TForm1(TComponent* Owner); __fastcall ~TForm1(void); // Destruktor einfügen, falls nicht schon da };
in der *.cpp:
// in den Konstruktor des Forms einfügen //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { wheelpos = 0; // Mausradposition WListBox = new TWheelListBox(this); WListBox->Parent = Form1; WListBox->Top = 20; WListBox->Left = 20; WListBox->Width = 150; WListBox->Height = 250; // etwas beleben for (int i = 0; i <=30; i++) { WListBox->Items->Add("Zeile : " + IntToStr(i)); } } //--------------------------------------------------------------------------- // Destruktor des Forms __fastcall TForm1::~TForm1(void) { delete WListBox; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- __fastcall TWheelListBox::TWheelListBox(TComponent* AOwner):TListBox(AOwner){} __fastcall TWheelListBox::~TWheelListBox(void) {} //--------------------------------------------------------------------------- void __fastcall TWheelListBox::WndProc(Messages::TMessage &Message) { switch(Message.Msg) { case WM_MOUSEWHEEL : { // hier kannst du nun ansetzen WORD fwKeys = Message.WParamLo; WORD zDelta = Message.WParamHi; WORD xPos = Message.LParamLo; WORD yPos = Message.LParamHi; if (zDelta < 0 ) Form1->wheelpos -= yPos; // Mausrad runter if (zDelta > 0 ) Form1->wheelpos += yPos; // Mausrad hoch break; } //case WM_LBUTTONDOWN : { ShowMessage("Test auf WM_LBUTTONDOWN"); break; } case WM_MOUSEMOVE : { this->SetFocus(); break; } } TListBox::WndProc(Message); } //---------------------------------------------------------------------------
Probiers mal aus und halt uns auf dem Laufenden ;).
mfg
kpeter
-
Guten Morgen. Danke für dein tolles Bemühen! Jetzt hat man die ListBox mit einem eigenen Verhalten. Kann man so auch irgendwie auf Scrollbars Position zugreifen um darüber den Scrollbalken zu bewegen?
Alternativ ist es doch bestimmt möglich ein "Pfeilklick" anzustossen, oder? Also eine Message zu senden, die sagt, dass man bei der ListBox den Scrollbuttonpfeil für hoch bzw runter gedruckt haben will.
-
Also, wenn ich das WM_MOUSEWHEEL global mit MESSAGE_HANDLER abfange und der Komponente nicht den Focus gebe. Dann klappt folgender Code:
if (zDelta>0) SendMessage(ListBox1->Handle, WM_VSCROLL, SB_LINEUP, 0); else SendMessage(ListBox1->Handle, WM_VSCROLL, SB_LINEDOWN, 0);
Klicke ich aber in die Komponente TLIstBox1 oder setze SetFocus(), dann funktioniert obiges SendMessage() nicht mehr.
Idee woran das liegen kann und was man dagegen tun kann?
@kpeter
Das mit this in deiner WndProc bewirkt leider auch nichts.
Btw der Scrollbalken bewegt sich sehr sonderbar falsch in TWheelListBox.
-
Klappt jetzt alles .. großes Dankeschön für die tolle Hilfe