AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TComboBox - MouseMove

Ein Thema von Amateurprofi · begonnen am 8. Aug 2018 · letzter Beitrag vom 12. Aug 2018
Antwort Antwort
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.097 Beiträge
 
Delphi XE2 Professional
 
#1

TComboBox - MouseMove

  Alt 8. Aug 2018, 01:58
Ich habe in der Main-Form eine TComboBox und möchte auf MouseMove-Events reagieren, wenn sich der Maus-Zeiger in der ComboBox oder in der aufgeklappten Liste befindet.

Meine bisherige Lösung:

1) In einer Unit, die in der Uses-Liste der Main-Form aufgeführt ist habe ich deklariert
Delphi-Quellcode:
   TComboBox = class(Vcl.StdCtrls.TComboBox)
   public
      property OnMouseMove;
   end;
2) Im FormCreate der Main-Form habe ich

Delphi-Quellcode:
procedure TMain.FormCreate(Sender: TObject);
begin
   …
   ComboBox.OnMouseMove := ComboBoxMouseMove;
   …
end;
und

Delphi-Quellcode:
procedure TMain.ComboBoxMouseMove(Sender:TObject; Shift:TShiftState; X,Y:Integer);
begin
   …
   …
end;
wo ich auf das MouseMove reagiere.

Das funktioniert gut, allerdings nur, wenn sich der Maus-Zeiger im Textfeld der ComboBox befindet.
Ist die Liste aufgeklappt und ich bewege die Maus im aufgeklappten Teil, wird kein MouseMove-Event ausgelöst (jeenfalls kommt es nicht im ComboBoxMouseMove an).

Frage:
Wie erreiche ich, dass ich auch auf Mausbewegungen im aufgeklappten Bereich der ComboBox reagieren kann.



Ein weiteres Problem:
Wen die Liste aufgeklappt wird, reicht diese bis an den unteren Rand der Form.
Ich möchte aber die Höhe begrenzen.

Ich habe es bereits mit DropDownCount versucht, aber das funktioniert nicht, auch dann nicht, wenn ich DropDownCount zur Laufzeit setze.
Ich vermute, dass das an Style = csOwnerDrawFixed liegt.

Frage:
Wie kann ich die Höhe der Liste begrenzen.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von ConnorMcLeod
ConnorMcLeod

Registriert seit: 13. Okt 2010
Ort: Bayern
490 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: TComboBox - MouseMove

  Alt 8. Aug 2018, 06:33
AFAIR ist die DropDownList ein eigenes Fenster. Das müsstest Du dann extra behandeln / overriden.
Nr.1 Delphi-Tool: [F7]
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: TComboBox - MouseMove

  Alt 8. Aug 2018, 10:18
Dort -> TComboBox - how to adjust drop down list height while it is dropped down? gefunden.
Delphi-Quellcode:
procedure TCustomCombo.SetDropDownCount(const Value: Integer);
begin
  if Value <> FDropDownCount then
  begin
    FDropDownCount := Value;
    if HandleAllocated and CheckWin32Version(5, 1) and ThemeServices.ThemesEnabled then
      SendMessage(Handle, CB_SETMINVISIBLE, WPARAM(FDropDownCount), 0);
  end;
end;
Auf gleichem Server auch eine Antwort für Mouse Events, les mal ob Dir das reicht, über das Hint-Ereignis.How to make the note of ComBoBox in Delphi
Gruß vom KodeZwerg

Geändert von KodeZwerg ( 8. Aug 2018 um 10:23 Uhr)
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.097 Beiträge
 
Delphi XE2 Professional
 
#4

AW: TComboBox - MouseMove

  Alt 9. Aug 2018, 01:06
Dort -> TComboBox - how to adjust drop down list height while it is dropped down? gefunden.
Delphi-Quellcode:
procedure TCustomCombo.SetDropDownCount(const Value: Integer);
begin
  if Value <> FDropDownCount then
  begin
    FDropDownCount := Value;
    if HandleAllocated and CheckWin32Version(5, 1) and ThemeServices.ThemesEnabled then
      SendMessage(Handle, CB_SETMINVISIBLE, WPARAM(FDropDownCount), 0);
  end;
end;
Auf gleichem Server auch eine Antwort für Mouse Events, les mal ob Dir das reicht, über das Hint-Ereignis.How to make the note of ComBoBox in Delphi
Danke, KodeZwerg.

SetDropDownCount wird ja aufgerufen, wenn ich zur Laufzeit den DropDownCount setze, aber wie in #1 erwähnt, bringt das nichts.
Ich hab dann mal spaßeshalber im Form.Create ein SendMessage(ComboBox.Handle, CB_SetMinVisible, 10, 0); eingefügt und siehe da, das funktioniert.
Ist wohl nicht so sehr sauber, aber "sieht ja niemand".

Und zum Thema MouseMove hab ich mir mal angeschaut was unter dem von dir gezeigten Link zu finden ist.
Im Moment verstehe ich das alles nicht - muss ich mich wohl durchbeißen...
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: TComboBox - MouseMove

  Alt 9. Aug 2018, 06:38
Hallo Amateurprofi,

Ich hab dann mal spaßeshalber im Form.Create ein SendMessage(ComboBox.Handle, CB_SetMinVisible, 10, 0); eingefügt und siehe da, das funktioniert.
Ist ja nicht weiter schlimm, Du hast meinen Vorschlag halt nicht korrekt umgesetzt, als Methode der Klasse. Ja auf das SendMessage() läuft es hinaus, Hauptsache Du rufst es an geeigneter Stelle auf, Form.Create mag ich pers. nicht für so etwas, aber nach einer Listenfüllung um es dynamisch anzupassen.
Und zum Thema MouseMove hab ich mir mal angeschaut was unter dem von dir gezeigten Link zu finden ist.
Ja mit den Mouse Events würde ich halt über das Hint-Event gehen, darüber kannst Du Dir ausrechnen lassen wo die Maus gerade steckt, ich habe in Post #1 nicht so ganz verstanden worauf Du da genau aus bist, das Hint-Ereignis ermöglicht Dir halt ein Item aus der ComboBox nur anhand der Mausposition zu bestimmen.
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.097 Beiträge
 
Delphi XE2 Professional
 
#6

AW: TComboBox - MouseMove

  Alt 9. Aug 2018, 16:59
Hallo Amateurprofi,

Ich hab dann mal spaßeshalber im Form.Create ein SendMessage(ComboBox.Handle, CB_SetMinVisible, 10, 0); eingefügt und siehe da, das funktioniert.
Ist ja nicht weiter schlimm, Du hast meinen Vorschlag halt nicht korrekt umgesetzt, als Methode der Klasse. Ja auf das SendMessage() läuft es hinaus, Hauptsache Du rufst es an geeigneter Stelle auf, Form.Create mag ich pers. nicht für so etwas, aber nach einer Listenfüllung um es dynamisch anzupassen.
Und zum Thema MouseMove hab ich mir mal angeschaut was unter dem von dir gezeigten Link zu finden ist.
Ja mit den Mouse Events würde ich halt über das Hint-Event gehen, darüber kannst Du Dir ausrechnen lassen wo die Maus gerade steckt, ich habe in Post #1 nicht so ganz verstanden worauf Du da genau aus bist, das Hint-Ereignis ermöglicht Dir halt ein Item aus der ComboBox nur anhand der Mausposition zu bestimmen.
Nee, deinen Vorschlag habe ich nicht umgesetzt, weil es mir nicht zielführend erschien.
Dir von dir gezeigte Methode "TCustomCombo.SetDropDownCount(const Value: Integer);" ist bereits Bestandteil von TCustomCombo und TComboBox ist ein Nachfahre von TCustomCombo.
Was also soll das bringen?
Ich hab mittlerweile auch geprüft, ob TCustomCombo.SetDropDownCount auch aufgerufen wird, wenn DropDownCount gesetzt wird.
Wird sie, aber das "SendMessage" wird nicht ausgeführt (wg. StyleServices).

Und was ich genau will?
In meinen Programmen ist es Standard, dass am unteren Rand der Form eine Statusbar ist und darüber ist ein freier Bereich, in dem ich zur Laufzeit Hinweise ausgebe. (Schau mal hier https://www.delphipraxis.net/134885-rechenprogramm.html).

Die Combobox, listet einige Musik-Titel auf und zeigt nicht nur die Titel sondern auch diverse Informationen zu dem jeweiligen Titel (siehe Anhang "Combobox aufgeklappt").
Ich möchte, wenn ich die Maus über die aufgeklappte Liste bewege, im oben erwähnten Hinweis-Feld ausgeben, wofür der Wert steht, auf den die Maus zeigt (siehe Anhang "Combobox zugeklappt").
Das ist aber vergebliche Mühe, wenn die Liste bis zum unteren Rand der Form reicht.
Deshalb will ich die Höhe der aufgeklappten Liste begrenzen, so dass das Hinweis-Feld frei bleibt.
Klar könnte ich den Hinweis auch direkt beim Cursor einblenden - ich will aber bei meinem Standard-Verfahren bleiben.
Angehängte Grafiken
Dateityp: jpg ComboBox aufgeklappt.jpg (202,8 KB, 23x aufgerufen)
Dateityp: jpg ComboBox zugeklappt.jpg (226,0 KB, 30x aufgerufen)
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.097 Beiträge
 
Delphi XE2 Professional
 
#7

AW: TComboBox - MouseMove

  Alt 11. Aug 2018, 17:02
Ja mit den Mouse Events würde ich halt über das Hint-Event gehen, darüber kannst Du Dir ausrechnen lassen wo die Maus gerade steckt, ich habe in Post #1 nicht so ganz verstanden worauf Du da genau aus bist, das Hint-Ereignis ermöglicht Dir halt ein Item aus der ComboBox nur anhand der Mausposition zu bestimmen.
Hallo KodeZwerg,
ich habe mir angeschaut, was unter den Links, die Du netterweise zur Verfügung gestellt hast, zu lesen ist.
Wenn ich das richtig verstehe, dann funktioniert Dein Vorschlag über das Hint-Event zu gehen, in meinem Fall nicht (Style ist csOwnerDrawFixed, nicht csSimple).

Zitat:
If the TComboBox.Style property is not set to csSimple, the ListBox is only visible when it is dropped down.
The OnShowHint/CM_HINTSHOW trick will not work in this situation.
However, you can use the TComboBox.OnDropDown event to manually subclass the ListBox directly (and the OnCloseUp event to remove the subclass), using SetWindowLongPtr() or SetWindowSubclass().
That will allow you to intercept WM_MOUSEMOVE messages that are sent directly to the ListBox, and then you can send LB_ITEMFROMPOINT to the ListBox with the provided mouse coordinates.
However, to actually display a hint, it is not enough to just set the TComboBox.Hint property in this Situation (it won't be displayed, as the dropped-down list is basically acting as a modal window and is blocking the normal hint mechanism).
You will have to display your own hint window manually, such as by using the THintWindow class directly.
Was mir vielversprechend erscheint, ist der in obigem Text erwähnte Hinweis auf TComboBox.OnDropDown / SetWindowSubclass() / OnCloseUp / (RemoveWindowSubclass()).
Problem ist, dass ich nicht einmal ansatzweise verstehe, wie ich das realisieren kann.
Kannst Du mir kurz skizzieren wie ich das machen kann.
Was ich mir vorstelle ist:
Wenn die Liste aufgeklappt ist, und die Maus in der List bewegt wird, wird ein MouseMove ausgelöst und eine "eigene" MouseMove Methode ausgerufen, in der ich die die Position der Maus auswerten kann.
Vielen Dank.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:00 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz