Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Listbox: Wie kann ich auf Änderung des TopIndex' reagieren? (https://www.delphipraxis.net/39022-listbox-wie-kann-ich-auf-aenderung-des-topindex-reagieren.html)

Nogge 27. Jan 2005 16:01


Listbox: Wie kann ich auf Änderung des TopIndex' reagieren?
 
Hallo Community,
Ich würde gern auf eine Änderung des Listbox.TopIndex reagieren können, nur weiß ich nicht wie ich das machen soll. Ich habe schon im OI und im Forum nachgeschaut, aber bisher nichts gefunden ;_;
Helft mir plz^^

mfg
Nogge

Stevie 28. Jan 2005 08:20

Re: Listbox: Wie kann ich auf Änderung des TopIndex' reagier
 
Hi Nogge,

wenn es dir nur in einer Unit darum geht, auf die Änderung des TopIndex zu reagieren,
würde ich dir empfehlen, die Klasse TListBox zu hacken:
Delphi-Quellcode:
interface
  TListBox = class(StdCtrls.TListBox)
  private
    function GetTopIndex: Integer;
    procedure SetTopIndex(Value: Integer);
  public
     property TopIndex: Integer read GetTopIndex write SetTopIndex;
  end;

  //hier kommt deine TForm-Klasse...

implementation

function TListBox.GetTopIndex: Integer;
begin
  Result := SendMessage(Handle, LB_GETTOPINDEX, 0, 0);
end;

procedure TListBox.SetTopIndex(Value: Integer);
begin
  if GetTopIndex <> Value then
    SendMessage(Handle, LB_SETTOPINDEX, Value, 0);
  // hier dein OnTopIndex-Event
end;
Dann werden in dieser Unit die von dir implementierten Methoden ausgeführt.

Wenn du allerdings generell diese Funktionalität benutzen willst,
dann wäre es besser, wenn du eine neue Komponente erstellen würdest.

MfG
Stevie

Nogge 28. Jan 2005 12:01

Re: Listbox: Wie kann ich auf Änderung des TopIndex' reagier
 
mmh, nicht so schön...ich möchte bei Änderung des TopIndex' informiert werden, so wie bei einem Stringgrid zB das Event "OnTopLeftChanged" dafür verantwortlich ist. Deine Methode würde nur mit einem Timer funktionieren (wenn ich den code richtig verstanden habe), was ich vermeiden möchte.
Ich habe leider noch nie eigene Kompontente erstellt, d.h. ich kann deinen Tipp leider nicht alleine ausführen. Trotzdem habe ich noch eine Frage speziell an dich: wozu hast du in public eine property deklariert bzw. was ist eine property?

Stevie 28. Jan 2005 12:14

Re: Listbox: Wie kann ich auf Änderung des TopIndex' reagier
 
Zitat:

Zitat von Nogge
mmh, nicht so schön...ich möchte bei Änderung des TopIndex' informiert werden, so wie bei einem Stringgrid zB das Event "OnTopLeftChanged" dafür verantwortlich ist. Deine Methode würde nur mit einem Timer funktionieren (wenn ich den code richtig verstanden habe), was ich vermeiden möchte.
Ich habe leider noch nie eigene Kompontente erstellt, d.h. ich kann deinen Tipp leider nicht alleine ausführen. Trotzdem habe ich noch eine Frage speziell an dich: wozu hast du in public eine property deklariert bzw. was ist eine property?

Ein Timer??? Nö!
Ich hab eigentlich nix anderes gemacht, als nicht schon in TListBox drin ist. Das Problem dabei ist, dass die Set-Methode private ist, und ich nicht da ran komme. Deshalb hab ich die Set- und Get-Methoden überschrieben und die Eigenschaft gleich mit, denn dieser sind ja die Methoden zugeordnet. An dieser Stelle muss ich darauf hinweisen, dass man sich hier schon in einem Bereich aufhält, der von einigen als nicht saubere OOP bezeichnet wird! Für deinen Fall ist es aber IMHO genau der richtige Weg.
Wenn du dich mit der OOP noch nicht so genau auskennst, empfehle ich dir, dich damit erstmal zu beschäftigen.

Eine Frage noch: Willst du nur informiert werden, wenn direkt über die Eigenschaft (property ;-)) TopIndex die ListBox gescrollt wird, oder auch bei einem generellen Scrollen? Denn dann müsstest du das ganze etwas anders lösen...

Nogge 29. Jan 2005 07:39

Re: Listbox: Wie kann ich auf Änderung des TopIndex' reagier
 
Ich möchte aufs Scrollen allgemein in der Listbox reagieren können, d.h. mit der Maus und mit den Tasten. Deshalb dachte ich auch daran, auf die Änderung des TopIndex' zu reagieren, denn dann wird ja immer gescrollt.
Ich verstehe deine Property aber immer noch nicht (sry^^). Also wenn ich jetzt in die SetTopIndex-Procedure meinen Code hineinschreibe, wird dieser immer ausgeführt, wenn sich der TopIndex ändert (habs noch nicht ausprobiert^^)?

Stevie 31. Jan 2005 08:16

Re: Listbox: Wie kann ich auf Änderung des TopIndex' reagier
 
Zitat:

Zitat von Nogge
Ich möchte aufs Scrollen allgemein in der Listbox reagieren können, d.h. mit der Maus und mit den Tasten. Deshalb dachte ich auch daran, auf die Änderung des TopIndex' zu reagieren, denn dann wird ja immer gescrollt.

Ok, jetzt versteh ich... Dann musst du die Windows-Message für das Scrollen abfangen und ein Event dafür schreiben (so wie OnClick usw.)
Zitat:

Zitat von Nogge
Ich verstehe deine Property aber immer noch nicht (sry^^). Also wenn ich jetzt in die SetTopIndex-Procedure meinen Code hineinschreibe, wird dieser immer ausgeführt, wenn sich der TopIndex ändert (habs noch nicht ausprobiert^^)?

Der Code würde eben nur dann ausgeführt werden, wenn du über die Eigenschaft TopIndex direkt setzt (ListBox.TopIndex := x) und nicht, wenn du per Tastatur oder Maus scrollst...

Also schreiben wir ein OnScroll-Event für die ListBox:
Delphi-Quellcode:
unit ListBoxEx;

interface

uses
  Messages, Classes, StdCtrls;

type
  TListBoxEx = class(TListBox)
  private
    FOnScroll: TScrollEvent;
    procedure WMScroll(var Message: TWMScroll); message WM_VSCROLL;
  published
    property OnScroll: TScrollEvent read FOnSCroll write FOnScroll;
  end;

  procedure Register;

implementation

procedure TListBoxEx.WMScroll(var Message: TWMScroll);
var
  ScrollPos: Integer;
begin
  inherited;
  ScrollPos := Message.Pos;
  if Assigned(FOnScroll) then
    if TScrollCode(Message.ScrollCode) in [scLineUp, scLineDown,
     scPageUp, scPageDown, scPosition, scTop, scBottom] then
      FOnScroll(Self, TScrollCode(Message.ScrollCode), ScrollPos);
end;

procedure Register;
begin
  RegisterComponents('Beispiele', [TListBoxEx]);
end;

end.
Im Menü unter Komponente/Komponente installieren wählst du diese Unit aus und installierst sie.
Dann hast du in der Komponentenleiste auf dem Reiter Beispiele eine neue Komponente (ListBoxEx).

MfG
Stevie

P.S. Hier im Forum findest du genug zum Thema Komponenten-Entwicklung, wenn du dich damit näher befassen willst.

Nogge 31. Jan 2005 13:30

Re: Listbox: Wie kann ich auf Änderung des TopIndex' reagier
 
Die Message "WM_VSCROLL" (TWMScroll) wird aber leider nur beim Scrollen mit der Maus ausgelöst (das hatte ich selbst ja auch schon ausprobiert). Wenn ich die Pfeiltaste nach unten oder oben drücke, geschieht gar nichts.

Stevie 31. Jan 2005 17:34

Re: Listbox: Wie kann ich auf Änderung des TopIndex' reagier
 
Ok, hier ein kleiner Denkanstoß, wie man das mit den Tasten regeln könnte:
Delphi-Quellcode:
procedure TListBoxEx.WMKeyDown(var Message: TWMKey);
var
  ItemCount: Integer;
  ScrollPos: Integer;
begin
  ScrollPos := 0;
  ItemCount := ClientHeight div ItemHeight;
  if Assigned(FOnScroll) then
    case Message.CharCode of
    VK_DOWN: if Succ(ItemIndex - TopIndex) = ItemCount then
      FOnScroll(Self, scLineDown, ScrollPos);
    VK_UP: if ItemIndex = TopIndex then
      FOnScroll(Self, scLineUP, ScrollPos);
    VK_HOME: if TopIndex > 0 then
      FOnScroll(Self, scTop, ScrollPos);
    VK_END: if (Count - TopIndex) > ItemCount then
      FOnScroll(Self, scBottom, ScrollPos);
  end;
  inherited;
end;
Diese Methode ist noch nicht vollständig (Page-Up, Page-Down) und
feuert auch noch nicht richtig, aber das dürfte dir schonmal helfen.

MfG
Stevie

Jippie, mein 1000. Beitrag!!! *g*

Nogge 1. Feb 2005 07:56

Re: Listbox: Wie kann ich auf Änderung des TopIndex' reagier
 
Jo, Danke...genau das wollte ich haben (Hätte ich auch eigentlich selber drauf kommen müssen o_O)! Allerdings habe ich mir keine Komponente erstellt, da ich die Listbox wohl nur für dieses eine Projekt benötigen werde. Habe stattdessen einen eigenen "Type" deklariert (nur für die, die das selbe Problem haben, wie ich es hatte^^):
Delphi-Quellcode:
type
  TListboxEx = class(TListBox)
  private
    procedure WMNCCalcSize(var Msg: TWMNCCalcSize); // keine ScrollBar
      message WM_NCCALCSIZE;
    procedure WMMouseWheel(var Msg: TWMMouseWheel); // Scrollen trotzdem aktivieren
      message WM_MOUSEWHEEL;
    procedure WMVSCROLL(var Msg: TWMScroll);        // aufs Scrollen mit der Maus reagieren
      message WM_VSCROLL;
    procedure WMKeyDown(var Msg:TWMKey);            // aufs Scrollen mit den Tasten reagieren
      message WM_KEYDOWN;
  end;
Vielen Dank Stevie für die Hilfe und Inspiration!


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:02 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz