AGB  ·  Datenschutz  ·  Impressum  







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

Mausrad, ScrollBox und PageControl

Ein Thema von Dalai · begonnen am 7. Nov 2012 · letzter Beitrag vom 8. Nov 2012
Antwort Antwort
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#1

Mausrad, ScrollBox und PageControl

  Alt 7. Nov 2012, 11:07
Hey Leute,

da ich gestern auf dem PC meines Vaters ein Problem mit der Verwendung des Mausrads in einem meiner Programme hatte (reagierte nicht mehr und musste abgeschossen werden), wollte ich die Behandlung des Events umbauen. Dazu gab es vor kurzem bereits ein ähnliches Thema in der DP, aber da mein Problem etwas anders gelagert ist, eröffne ich besser ein neues Thema.

Ich beziehe mich mit dem Code für die Ereignisbehandlung auf diesen Post von Uwe Raabe, den ich 1:1 übernommen habe (nachdem ich die im Delphi 5 fehlende Funktion Sign() nachgebaut habe). Das Problem ist nun folgendes: Befindet sich auf der Form eine ScrollBox, funktioniert der Code sauber. Sobald ich auf der Form ein PageControl und darin (auf einem TabSheet) eine ScrollBox habe, ermittelt die Funktion ControlAtPos() das PageControl und nicht die ScrollBox.

Nochmal kurz als Übersicht:
Code:
Funktioniert:       TForm > TScrollBox
Funktioniert nicht: TForm > TPageControl > TTabSheet > TScrollBox
Das führt natürlich in der Folge dazu, dass die jeweils ermittelten Parents nur noch die Form und dann nil sind, wodurch das Scrollen natürlich nicht funktioniert. Eigentlich bleibt mir ja nichts anderes übrig, als die Childs des von ControlAtPos() ermittelten PageControls durchzugehen (z.B. mit dem property Components), aber dann könnte ich auch gleich auf die ScrollBox gehen, da ich ja weiß, dass auf jeder Seite des PageControl eine ScrollBox ist.

Wie würdet ihr das Problem angehen?

MfG Dalai
  Mit Zitat antworten Zitat
Pitschki1801

Registriert seit: 9. Feb 2012
14 Beiträge
 
Delphi XE Professional
 
#2

AW: Mausrad, ScrollBox und PageControl

  Alt 7. Nov 2012, 13:11
Hallo Dalai,

Ich habe in meinen Programmen bereits beide Strukturen verwendet und bis jetzt keine Probleme gehabt. Die Ereignisbehandlung von Uwe Raabe habe ich gerade bei mir getestet und sie klappt, wie in deinem Fall, wirklich nicht.
Jetzt frage mich allerdings warum du dies im Form OnMouseWheel behandelt willst und nicht im Ereignis der ScrollBox?
Ich habe in meinem Programm der ScrollBox im OnMouseWheel lediglich diese Zeile hinzugefügt:

Delphi-Quellcode:
procedure TForm.ScrollBoxMouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
    ScrollBox.VertScrollBar.Position := ScrollBox.VertScrollBar.Position - WheelDelta;
end;
Das funktioniert soweit ohne Probleme und vllt. löst es bereis dein Problem.

Gruß Pitschki
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#3

AW: Mausrad, ScrollBox und PageControl

  Alt 7. Nov 2012, 13:55
Jetzt frage mich allerdings warum du dies im Form OnMouseWheel behandelt willst und nicht im Ereignis der ScrollBox?
Das ist recht einfach zu beantworten und hat 2 Gründe:
  • die ScrollBoxen sind allesamt dynamisch erzeugt. Wenn ich die Ereignisbehandlung also in der Form mache, spare ich mir die (dynamische) Zuweisung des Eventhandlers komplett und damit potentielle Fehlerquellen.
  • Viel schwerwiegender ist aber, dass ich ein Scrollen auch dann ermöglichen will, wenn ein völlig anderes Steuerelement den Fokus hat (ein Button außerhalb des PageControls oder die Tabs des PageControls), der Mauszeiger aber trotzdem über der ScrollBox ist. Ich habe es gerade nochmal getestet und kann bestätigen, dass die Ereignisbehandlung der ScrollBox selbst nur dann ausgelöst wird, wenn ein Objekt innerhalb der ScrollBox (oder die ScrollBox selbst bei TabStop=True) den Fokus hat.

MfG Dalai
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#4

AW: Mausrad, ScrollBox und PageControl

  Alt 7. Nov 2012, 18:54
Ich hab nun "ein wenig" (eher stundenlang, weil mir mein eigener Code im Weg stand ) rumprobiert und bin zu der Erkenntnis gelangt, dass das harte Setzen der Position keine gute Idee ist, weil es bescheiden aussieht. Daher habe ich mich dazu entschieden, bei meiner Methode zu bleiben, nur mit dem Unterschied, dass ich nun
ScrollBox.Perform(WM_VSCROLL, msg, 0); // msg ist entweder SB_LINEDOWN oder SB_LINEUP verwende statt wie bisher
SendMessage(ScrollBox.Handle, WM_VSCROLL, msg, 0);

Blöd ist, dass das Problem trotz dieser Änderung auf dem Problem-PC bestehen bleibt . Immerhin habe ich rausgefunden, dass das am Property ScrollBox.VertScrollBar.Smooth liegt. Schalte ich das ab, läuft das Programm normal weiter. Verstehen tue ich das nicht, denn das ist im Moment der einzige PC, auf dem das auftritt. Ich hatte das Problem schonmal auf meinem Laptop, allerdings war es nach einem Update der Synaptic-Treiber verschwunden.

Nur der Vollständigkeit halber hier noch die komplette Methode zur Ereignisbehandlung:
Delphi-Quellcode:
procedure TMainForm.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
var
  rect: TRect;
  msg: LongInt;
begin
    if MainPageControl.ActivePageIndex < 0 then
        Exit;
    rect.Top:= 0;
    rect.Left:= 0;
    rect.TopLeft:= MainPageControl.ClientToScreen(rect.TopLeft);
    rect.Bottom:= MainPageControl.Height;
    rect.Right:= MainPageControl.Width;
    rect.BottomRight:= MainPageControl.ClientToScreen(rect.BottomRight);
    msg:= SB_LINEDOWN;
    if WheelDelta > 0 then
        msg:= SB_LINEUP;
    if PtInRect(rect, MousePos) then
    begin
        arPages[MainPageControl.ActivePageIndex].scroll.Perform(WM_VSCROLL, msg, 0);
        Handled:= True;
    end;
end;
// arPages ist ein dynamisches Array of record, in dem sich unter anderem eine ScrollBox und ein TabSheet befinden
// ja, ich weiß, dass man die Datenspeicherung noch optimieren kann :)
MfG Dalai
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Mausrad, ScrollBox und PageControl

  Alt 7. Nov 2012, 19:50
Ich habe jetzt nicht ganz genau verstanden welches Problem aktuell noch besteht, vielleicht gibt das Beispiel ggf. eine Anregung...

Delphi-Quellcode:
procedure TFormTest.MessageEvent(var Msg: TMsg; var Handled: Boolean);
var
  H: HWND;
  C: TControl;
  WC: TWinControl;
  I: Integer;

  function GetParentScrollBox(WC: TWinControl): TWinControl;
  begin
    Result := WC;
    if (not(WC is TScrollBox)) and (WC.Parent <> nil) then
      Result := GetParentScrollBox(WC.Parent);
  end;

begin
  if ((Msg.Message = WM_MOUSEWHEEL) or (Msg.Message = WM_MOUSEHWHEEL)) and (Msg.wParam and MK_CONTROL = 0) then
    begin
      H := WindowFromPoint(Msg.Pt);
      C := FindControl(H);
      if C is TWinControl then
        begin
          WC := GetParentScrollBox(C as TWinControl);
          if WC <> nil then
            begin
              for I := 1 to Mouse.WheelScrollLines do
                WC.Perform(CM_MOUSEWHEEL, Msg.wParam, Msg.lParam); // Msg.Message funktioniert nicht
              H := 0;
            end;
        end;
      if (H = 0) or ((Msg.HWND <> H) and (GetWindowThreadProcessId(H, nil) <> GetCurrentThreadId)) then
        begin
          Msg.HWND := 0;
          Msg.Message := WM_NULL;
          Handled := True;
        end
      else
        Msg.HWND := H;
    end
end;
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#6

AW: Mausrad, ScrollBox und PageControl

  Alt 8. Nov 2012, 08:00
Ich habe jetzt nicht ganz genau verstanden welches Problem aktuell noch besteht [...]
Das Problem ist, dass sich eines meiner Programme beim Betätigen des Mausrads über einer ScrollBox aufhängt, aber nur auf diesem einen PC. Allerdings scheint das überhaupt nichts mit meiner Ereignisbehandlung zu tun zu haben, denn das passiert auch dann, wenn man auf einen der beiden Pfeile des Scrollbalkens klickt, und somit die Ereignisbehandlung des Mausrads überhaupt nicht ausgelöst wird.

Interessanterweise passiert das nicht, wenn man den Balken selbst anfasst und hin- und herschiebt. Sobald das Smooth-Scrolling der ScrollBox(ScrollBar) ausgeschaltet ist, tritt es ebenfalls nicht mehr auf. Es passiert auch nicht bei einem ListView im selben Programm; allerdings hat die dieses ListView beinhaltende Form auch keinen MouseWheel-Handler...

Ich habe die Vermutung, dass das an diesem einen PC hängt, der schon eine Uptime von mehr als 30 Tagen hat und vermutlich ist das Problem nach einem Neustart verschwunden, denn wie immer gilt: "Reboot tut gut" (vor allem bei Windows ).

MfG Dalai
  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 04:48 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