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/)
-   -   Prüfen ob Scrollbar aktiviert (https://www.delphipraxis.net/161367-pruefen-ob-scrollbar-aktiviert.html)

EWeiss 30. Jun 2011 10:34


Prüfen ob Scrollbar aktiviert
 
Wie kann ich beim Memo gegenprüfen ob eine Scrollbar aktiviert wurde?
Grundsätzlich verfügt ein memo ja über beide Scrollbars Horiz/Vert

Ich prüfe nun mit meinem Code ob diese zur verfügung stehen.
Das problem ist nur Sie werden auch erkannt wenn sie nicht unter Eigenschaften aktiviert wurden (Sichtbar sind).

Wie kann ich also gegenprüfen ob sie aktiviert wurden unabhängig vom Eigenschaftsdialog.

Zur besseren Verständigung hier noch was Code!

Delphi-Quellcode:
function THookedScrollbar.StoreVertical(WinHandle: HWND): Boolean;
var
  State: Boolean;

begin

  Result := False;

  VScrInfo.cbSize := SizeOf(VScrInfo);
  VScrInfo.fMask := SIF_ALL;

  // ScrollBar vorhanden?
  State := GetScrollInfo(WinHandle, Windows.SB_VERT, VScrInfo);
 
  // keine ScrollBar vorhanden
  if not State then
    exit;

  // Lese aktuelle Bar Parameter
  VScrBar.cbSize := Sizeof(VScrBar);
  GetScrollBarInfo(WinHandle, integer(OBJID_VSCROLL), VScrBar);

  // kopiere den aktuellen Rect zur späteren bearbeitung
  CopyRect(VertRect, VScrBar.rcScrollBar);
  Result := True;
end;

State liefert immer True zurück egal ob unter Eigenschaften die Bars eingeschaltet wurden oder nicht!

gruss

Thom 30. Jun 2011 11:54

AW: Prüfen ob Scrollbar aktiviert
 
GetScrollInfo:
Zitat:

Return Value
Type: BOOL
If the function retrieved any values, the return value is nonzero.
Dadurch erhälst Du immer True, sobald eine Scrollbar zum Fenster gehört - unabhängig davon, ob sie eingeblendet ist oder nicht.

Das Problem hatte ich vor x Jahren auch einmal. Ich habe aber keine Möglichkeit im Win-API gefunden, die es ermöglicht, eindeutige festzustellen, ob eine integrierte Scrollbar sichtbar ist oder nicht.
Ich hatte mir dann damit beholfen, Client- und Fenstergröße miteinander zu vergleichen. Ist also zum Beispiel die Clientbreite gleich der Fensterbreite minus Scrollbarbreite (evtl. noch den Rahmen berücksichtigen), ist die vertikale Leiste eingeblendet. Diese Lösung ist zwar nicht schön - funktioniert aber in den meisten Fällen.

EWeiss 30. Jun 2011 12:12

AW: Prüfen ob Scrollbar aktiviert
 
Zitat:

Dadurch erhälst Du immer True, sobald eine Scrollbar zum Fenster gehört - unabhängig davon, ob sie eingeblendet ist oder nicht.
Das ist hart weil mir dann ein Teil im unteren bereich fehlt bzw. als Scrollbar gezeichnet wird obwohl nicht vorhanden.

Zitat:

Ich hatte mir dann damit beholfen, Client- und Fenstergröße miteinander zu vergleichen.
Wäre eine alternative.

Muss mir das mal näher anschauen.

PS:
Leider gibt es ja sowas nicht in Delphi ScrollBars eines Fensters den eigenen Bedürfnissen anzupassen ( Kostenlos ohne Komponente)
daher baue ich mir eine eigene LIB bzw.. Units die das ermöglichen sollen.

Danke!

gruss

Thom 30. Jun 2011 12:29

AW: Prüfen ob Scrollbar aktiviert
 
Zitat:

Zitat von EWeiss (Beitrag 1109190)
Leider gibt es ja sowas nicht in Delphi ScrollBars eines Fensters den eigenen Bedürfnissen anzupassen ( Kostenlos ohne Komponente)
daher baue ich mir eine eigene LIB bzw.. Units die das ermöglichen sollen.

Ja, das ist leider wahr (zumindest kenne ich keine derartige Lösung)... Da wünsche ich Dir viel Erfolg!

Viele Grüße

alfold 30. Jun 2011 12:31

AW: Prüfen ob Scrollbar aktiviert
 
Da ich ja immer noch daran arbeite:wink: kleiner Tip
Wenn hsi.nMax oder vsi.nMax<=0, wird die jeweilige Scrollbar nicht angeszeigt!
Automatisch passt sich, in diesem Beispiel Dein Grid in der Grösse an und die zu zeichnnde Fläsche wird um die jweilige Scroolbar grösser
Zitat:

Das ist hart weil mir dann ein Teil im unteren bereich fehlt bzw. als Scrollbar gezeichnet wird obwohl nicht vorhanden
stimmt also so nicht:wink:
GRuss alfold

EWeiss 30. Jun 2011 12:56

AW: Prüfen ob Scrollbar aktiviert
 
Zitat:

Zitat von alfold (Beitrag 1109203)
Da ich ja immer noch daran arbeite:wink: kleiner Tip
Wenn hsi.nMax oder vsi.nMax<=0, wird die jeweilige Scrollbar nicht angeszeigt!
Automatisch passt sich, in diesem Beispiel Dein Grid in der Grösse an und die zu zeichnnde Fläsche wird um die jweilige Scroolbar grösser
Zitat:

Das ist hart weil mir dann ein Teil im unteren bereich fehlt bzw. als Scrollbar gezeichnet wird obwohl nicht vorhanden
stimmt also so nicht:wink:
GRuss alfold

Ahhh das muss ich mal testen..
In wie weit das jetzt mit einem Memo funktioniert muss ich wiederum erst testen.

Jo ich mach das auch für meine SK_AERO LIB denke das ist einfacher zu händeln als
wenn ich zwei ScrollBars einzeln anfertigen (Programmieren muss).

gruss

EWeiss 30. Jun 2011 12:57

AW: Prüfen ob Scrollbar aktiviert
 
Zitat:

Zitat von Thom (Beitrag 1109201)
Zitat:

Zitat von EWeiss (Beitrag 1109190)
Leider gibt es ja sowas nicht in Delphi ScrollBars eines Fensters den eigenen Bedürfnissen anzupassen ( Kostenlos ohne Komponente)
daher baue ich mir eine eigene LIB bzw.. Units die das ermöglichen sollen.

Ja, das ist leider wahr (zumindest kenne ich keine derartige Lösung)... Da wünsche ich Dir viel Erfolg!

Viele Grüße

Funktioniert ja soweit schon abgesehen vom zeichnen der Bitmaps ;)
Schau mal unter meinen Projekten.

gruss

alfold 30. Jun 2011 13:07

AW: Prüfen ob Scrollbar aktiviert
 
Allerdings, ist ganz wichtig!!!! Vermische nicht Daten mit Graphic:evil:
OT// muss Dein Miditracker, was die GraphicRoutinen betreffen neu machen, leider wenig Zeit//OT

Gruss alfold

EWeiss 30. Jun 2011 13:14

AW: Prüfen ob Scrollbar aktiviert
 
Zitat:

Zitat von alfold (Beitrag 1109224)
Allerdings, ist ganz wichtig!!!! Vermische nicht Daten mit Graphic:evil:
OT// muss Dein Miditracker, was die GraphicRoutinen betreffen neu machen, leider wenig Zeit//OT

Gruss alfold

Hää ?
Keine Ahnung was du meinst.
Bei mir funktioniert das alles :)

PS:
Im Memo kann man die Scrollbar nicht auf Max = 0 stellen.
Die scheint virtuell erstellt zu werden.

gruss

alfold 30. Jun 2011 14:00

AW: Prüfen ob Scrollbar aktiviert
 
Ich weiss ja nicht was Du da machst aber in Deinem Grid funct es
Delphi-Quellcode:
        hsi.cbSize := Sizeof(SCROLLINFO);
        hsi.nMin  := XSizeMid;
        hsi.nMax  := (rc.Right) - (XSize - XSizeMid); //<--ist hier der wert <= 0 wird keine Scrollbar angezeigt
        hsi.nPos  := StartX + XSizeMid;
        hsi.fMask := SIF_POS or SIF_RANGE;
        SetScrollInfo(FHGrid, SB_HORZ, hsi, True);
Bei einem VCL Memo gibt es ja noch (ssHorizontal, ssVertical, ssNone, ssBoth)
Wenn ssHorizontal nicht aktiv ist passt sich xsize vom Memo auch an.

Wie Du das bei Dir umgesetzt hast :gruebel: weiss ich ja nicht.
EDIT:
wenn also hsi.nMax = 0 dann darf ssHorizontal nicht aktiv sein!

Gruss alfold

Thom 30. Jun 2011 14:17

AW: Prüfen ob Scrollbar aktiviert
 
Zitat:

Zitat von EWeiss (Beitrag 1109218)
Schau mal unter meinen Projekten.

Werde ich machen!

Aber mir ist gerade etwas anderes aufgefallen:
In einem TMemo werden bei ScrollBars:=ssBoth immer beide Leisten angezeigt, auch wenn sie nicht notwendig sind (dann eben nur deaktiviert). TMemo kennt ja irgendwie kein automatisches Ein- und Ausblenden der Scrollbars.

Insofern ist mein Vorschlag, die Clientgröße des Fensters zu testen, völliger Unsinn, da die Leisten immer da sind... :pale:

Was ich aber jetzt gefunden habe:
SCROLLBARINFO
Aus dem Parameter rgstate lassen sich Rückschlüsse darauf ziehen, ob ein Element (oder die gesamte Scrollbar) zum Beispiel unsichtbar (STATE_SYSTEM_INVISIBLE) oder deaktiviert (STATE_SYSTEM_UNAVAILABLE) ist.

Ist wenig Text im Memo enthalten und die vertikale Scrollbar überflüssig, sieht der Status so aus:
Delphi-Quellcode:
ScrollBarInfo.rgstate[0]=STATE_SYSTEM_UNAVAILABLE; //gesamte Scrollbar deaktiviert
ScrollBarInfo.rgstate[1]=STATE_SYSTEM_UNAVAILABLE; //oberer Button deaktiviert
ScrollBarInfo.rgstate[2]=STATE_SYSTEM_UNAVAILABLE; //Page up-Bereich deaktiviert
ScrollBarInfo.rgstate[3]=STATE_SYSTEM_STATE_SYSTEM_INVISIBLE; //verschiebbarer Button unsichtbar
ScrollBarInfo.rgstate[4]=STATE_SYSTEM_UNAVAILABLE; //Page down-Bereich deaktiviert
ScrollBarInfo.rgstate[5]=STATE_SYSTEM_UNAVAILABLE; //unterer Button deaktiviert
Wird die vertikale Scrollbar benötigt, ändert sich das so:
Delphi-Quellcode:
ScrollBarInfo.rgstate[0]=0; //gesamte Scrollbar ist aktiviert
//...
Vielleicht hilft Dir das weiter...

EWeiss 30. Jun 2011 14:18

AW: Prüfen ob Scrollbar aktiviert
 
Zitat:

Ich weiss ja nicht was Du da machst aber in Deinem Grid funct es
Siehe erster Eintrag!

Bei meinem grid ist das normal weil die Scrollbar über CreateWindow erstellt wurde
und ich zu jederzeit Einfluss auf die Value nehmen kann.

Beim Memo geht das aber nicht oder aber du kannst mir sagen wo ich dort die Max Value einstellen kann.

gruss

EWeiss 30. Jun 2011 14:30

AW: Prüfen ob Scrollbar aktiviert
 
Zitat:

Vielleicht hilft Dir das weiter...
Leider nein habe alle möglichen parameter geprüft.
Ich teste das mal mit der ListView oder anderer Komponente.

Edit:
ListView und TreeView funktionieren.

gruss

alfold 30. Jun 2011 15:15

AW: Prüfen ob Scrollbar aktiviert
 
ListView, auch wenn es auf vsList steht?
Gruss

EWeiss 30. Jun 2011 15:19

AW: Prüfen ob Scrollbar aktiviert
 
Zitat:

Zitat von alfold (Beitrag 1109266)
ListView, auch wenn es auf vsList steht?
Gruss

auf list, report und icon

gruss

Thom 30. Jun 2011 15:26

AW: Prüfen ob Scrollbar aktiviert
 
Hmm... Das verstehe ich jetzt nicht.
Deine Frage bezog sich doch darauf, ob eine Scrollbar eines TMemo's aktiv ist, oder nicht (sichtbar ist sie ja leider permanent)!?
Und das kann man doch sehr gut mit ScrollBarInfo.rgstate[0] überprüfen?
Das funktioniert bei mir (Delphi XE, XP) ganz hervorragend:
Delphi-Quellcode:
function ScrollBarEnabled(Wnd: HWnd; Vert: Boolean): Boolean;
var
  ScrollBarInfo: TScrollBarInfo;
  IdObject: Integer;
begin
  ScrollBarInfo.cbSize:=Sizeof(TScrollBarInfo);
  if Vert
    then IdObject:=OBJID_VSCROLL
    else IdObject:=OBJID_HSCROLL;
  Result:=GetScrollBarInfo(Wnd,IdObject,ScrollBarInfo) and
          (ScrollBarInfo.rgstate[0] and STATE_SYSTEM_UNAVAILABLE=0);
end;

EWeiss 30. Jun 2011 16:19

AW: Prüfen ob Scrollbar aktiviert
 
Zitat:

Zitat von Thom (Beitrag 1109272)
Hmm... Das verstehe ich jetzt nicht.
Deine Frage bezog sich doch darauf, ob eine Scrollbar eines TMemo's aktiv ist, oder nicht (sichtbar ist sie ja leider permanent)!?
Und das kann man doch sehr gut mit ScrollBarInfo.rgstate[0] überprüfen?
Das funktioniert bei mir (Delphi XE, XP) ganz hervorragend:
Delphi-Quellcode:
function ScrollBarEnabled(Wnd: HWnd; Vert: Boolean): Boolean;
var
  ScrollBarInfo: TScrollBarInfo;
  IdObject: Integer;
begin
  ScrollBarInfo.cbSize:=Sizeof(TScrollBarInfo);
  if Vert
    then IdObject:=OBJID_VSCROLL
    else IdObject:=OBJID_HSCROLL;
  Result:=GetScrollBarInfo(Wnd,IdObject,ScrollBarInfo) and
          (ScrollBarInfo.rgstate[0] and STATE_SYSTEM_UNAVAILABLE=0);
end;

Hmm...
Ich kann unter Eigenschaften die Scrollbar welche sichtbar sein soll auswählen.
Bsp. ssVertikal

Alle anderen sind dann im Designer auch nicht sichtbar das ist Fakt.
Aber!
Trotzdem bekomme ich bei der Abfrage siehe erster Beitrag bei State immer einen Positiven wert zurückgeliefert
deshalb wird meine Virtuelle ScrollBar bei ssHorizontal trotzdem gezeichnet.

Habe neue Version unter Projekte hochgeladen.
Bilder werden jetzt gerendert.

gruss

alfold 30. Jun 2011 17:38

AW: Prüfen ob Scrollbar aktiviert
 
nimm mal um zu testen STATE_SYSTEM_INVISIBLE.
STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)
STATE_SYSTEM_UNAVAILABLE – if disabled

Wenn man dies abfragen kann, muss man es ja auch setzten können.

//OT: aber mit Img sowas zu machen ist aber nicht der Renner oder? OT//

gruss alfold

EWeiss 30. Jun 2011 18:07

AW: Prüfen ob Scrollbar aktiviert
 
Zitat:

//OT: aber mit Img sowas zu machen ist aber nicht der Renner oder? OT//
In wie fern ?
Es wird ja niemand zu seinem Glück gezwungen! :)
Wenn ich eine Skinned komponente habe nonvcl oder auch nicht..
dann sieht es besch.. aus wenn ausgerechnet die ScrollBar nicht dazu passt.

Deine Vorschläge habe ich alle schon durch. ;)

gruss

alfold 30. Jun 2011 18:34

AW: Prüfen ob Scrollbar aktiviert
 
Ich würde es mir nie wagen, Dich in Deinem Eifer zu Bremsen:-D

Zitat:

Das Projekt soll ermöglichen XBeliebe ScrollBars von Komponenten die über eine ScrollBar verfügen den eigenen bedürfnissen anzupassen.
Währe es nicht besser, Du stellst die Propertis zu verfügung und jeder kann sich sein Hintegrund, Farverlauf, Rahmen, Transparenz selber setzten, die er haben möchte, als das mit img zu machen? Das währe doch Top!:wink:

Wer hat schon Zeit sich dafür evtl erst noch img zu zeichnen/testen usw.

Egal, wie Du schon sagst: "Es wird ja niemand zu seinem Glück gezwungen!":P

Gruss alfold

EWeiss 30. Jun 2011 18:50

AW: Prüfen ob Scrollbar aktiviert
 
Zitat:

Zitat von alfold (Beitrag 1109316)
Ich würde es mir nie wagen, Dich in Deinem Eifer zu Bremsen:-D

Zitat:

Das Projekt soll ermöglichen XBeliebe ScrollBars von Komponenten die über eine ScrollBar verfügen den eigenen bedürfnissen anzupassen.
Währe es nicht besser, Du stellst die Propertis zu verfügung und jeder kann sich sein Hintegrund, Farverlauf, Rahmen, Transparenz selber setzten, die er haben möchte, als das mit img zu machen? Das währe doch Top!:wink:

Wer hat schon Zeit sich dafür evtl erst noch img zu zeichnen/testen usw.

Egal, wie Du schon sagst: "Es wird ja niemand zu seinem Glück gezwungen!":P

Gruss alfold

Nope dann müßte ich das Teil als Komponente auslegen die dann erst noch Installiert/Registriert werden muss.
Das tue ich mir nicht an :)


gruss

Thom 30. Jun 2011 20:43

AW: Prüfen ob Scrollbar aktiviert
 
Entschuldigung, wenn ich noch einmal nerve, aber mir hat die ganze Sache keine Ruhe gelassen und ich habe es noch einmal gestest:
Delphi-Quellcode:
function ScrollBarEnabled(Wnd: HWnd; Vert: Boolean): Boolean;
var
  ScrollBarInfo: TScrollBarInfo;
  IdObject: Integer;
begin
  ScrollBarInfo.cbSize:=Sizeof(TScrollBarInfo);
  if Vert
    then IdObject:=OBJID_VSCROLL
    else IdObject:=OBJID_HSCROLL;
  Result:=GetScrollBarInfo(Wnd,IdObject,ScrollBarInfo) and
          (ScrollBarInfo.rgstate[0] and STATE_SYSTEM_UNAVAILABLE=0);
end;

function ScrollBarVisible(Wnd: HWnd; Vert: Boolean): Boolean;
var
  ScrollBarInfo: TScrollBarInfo;
  IdObject: Integer;
begin
  ScrollBarInfo.cbSize:=Sizeof(TScrollBarInfo);
  if Vert
    then IdObject:=OBJID_VSCROLL
    else IdObject:=OBJID_HSCROLL;
  Result:=GetScrollBarInfo(Wnd,IdObject,ScrollBarInfo) and
          (ScrollBarInfo.rgstate[0] and STATE_SYSTEM_INVISIBLE=0);
end;
Das funktioniert bei mir ohne Probleme mit einem TMemo.

EWeiss 30. Jun 2011 20:51

AW: Prüfen ob Scrollbar aktiviert
 
Zitat:

Entschuldigung, wenn ich noch einmal nerve, aber mir hat die ganze Sache keine Ruhe gelassen und ich habe es noch einmal gestest:
Du nervst nicht! :)

Habe das Projekt funktionstüchtig.. bis auf das hier genannte problem.
Ich habe deine erste Version geprüft und die schlägt immer fehl (ScrollBarEnabled).

Dann habe ich diese mit
Delphi-Quellcode:
ScrollBarInfo.rgstate[3] and STATE_SYSTEM_INVISIBLE=0

geprüft.. schlug auch fehl.

Wenn du interesse an dem Projekt hast schikce ich dir gerne den Quelltext zu.
Dann kannst du vor ort testen.

Ist in D2009 geschrieben sollte also auch in XE ohne probleme laufen.

EDIT:
Du solltest aber das hier
ScrollBarVisible..
Delphi-Quellcode:
ScrollBarInfo.rgstate[0] and STATE_SYSTEM_INVISIBLE=0

den Index 0 mit 3 ersetzen Oder?


gruss

Thom 30. Jun 2011 21:02

AW: Prüfen ob Scrollbar aktiviert
 
Kannst Du mir gern zuschicken! Die Email-Adresse bekommst Du aus meiner VCard.

Index 0 betrifft die komplette Scrollbar, Index 3 nur den verschiebbaren Teil. Siehe MSDN.

In meinem Test prüfe ich zuerst auf Sichtbarkeit und erst danach auf Enabled:
Delphi-Quellcode:
  if ScrollBarVisible(Memo1.Handle,false) then
  begin
    if ScrollBarEnabled(Memo1.Handle,false)
      then Label1.Caption:='enabled'
      else Label1.Caption:='disabled';
  end else Label1.Caption:='not visible';

EWeiss 30. Jun 2011 21:14

AW: Prüfen ob Scrollbar aktiviert
 
Zitat:

Zitat von Thom (Beitrag 1109343)
Kannst Du mir gern zuschicken! Die Email-Adresse bekommst Du aus meiner VCard.

Index 0 betrifft die komplette Scrollbar, Index 3 nur den verschiebbaren Teil. Siehe MSDN.

In meinem Test prüfe ich zuerst auf Sichtbarkeit und erst danach auf Enabled:
Delphi-Quellcode:
  if ScrollBarVisible(Memo1.Handle,false) then
  begin
    if ScrollBarEnabled(Memo1.Handle,false)
      then Label1.Caption:='enabled'
      else Label1.Caption:='disabled';
  end else Label1.Caption:='not visible';

Projekt ist Unterwegs ;)
EDIT:
Nur nochmal zur Info wenn die Horizontale Bar ausgeschaltet ist darf die Maske nicht gezeichnet werden.
Suche einfach im Quelltext nach dem im ersten Thread erstellen Code.

gruss Emil


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:22 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