Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - TPageControl - Cursor für einzelne Tabs ändern


trm - So 18.05.14 22:04
Titel: TPageControl - Cursor für einzelne Tabs ändern
Hi.

Gibt es denn eigentlich für Das TPageControl auch eine Möglichkeit z.B. dem aktiven Tab einen anderen Cursor zuzuweisen?

Den einzelnen TabSheets ja, hat aber keine Auswirkung auf die Tabs vom PageControl.


trm - Mo 19.05.14 00:05

Eine halbwegs funktionierende Lösunghabe ich inzwischen gemacht.

Jedoch klappt das nur, wenn alle Tabs auch sichtbar sind, also keines versteckt ist. Die Lösung an sich ist zwar nicht schön, aber funktionell. Eine Lösung, um versteckte Tabs mit zu finden werde ich noch finden, denke ich. Nur die Lösung an sich gefällt mir nicht.



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TForm1.PageControl1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin

  case TPageControl(Sender).ActivePageIndex = TPageControl(Sender).IndexOfTabAt(X, Y) of
    True:
      TPageControl(Sender).Cursor := crDefault;
    False:
      TPageControl(Sender).Cursor := crHandPoint;
  end;

end;


rushifell - Mo 19.05.14 19:42

Ja, das ist blöd, dass Delphi nicht den "wahren" Index zurückgibt. Versuch mal folgendes (PageControl mit 3 TabSheets):


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
procedure TForm1.PageControl1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
Var  i,
     VisIndex,          //Index der sichtbaren Tabsheets
     TrueIndex:Integer; //der "wahre" Index
begin
VisIndex:=PageControl1.IndexOfTabAt(X,Y);

IF PageControl1.PageCount>0 then //Braucht man eigentlich nicht, aber zur Sicherheit
   BEGIN
     TrueIndex:=-1;
     i:=0;

     Repeat
       IF i<=VisIndex then
          BEGIN
           inc(TrueIndex);
           IF PageControl1.Pages[TrueIndex].TabVisible then
              inc(i);
          END;
     Until i>VisIndex;
   END ELSE
   TrueIndex:=-1;

IF TrueIndex=0 then PageControl1.Cursor:=crCross else //TabSheet1
IF TrueIndex=1 then PageControl1.Cursor:=crDrag else  //TabSheet2
IF TrueIndex=2 then PageControl1.Cursor:=crHandPoint else //TabSheet3
   PageControl1.Cursor:=crDefault;

end;


Edit: Hab den Quellcode nochmal leicht korrigiert.

Viele Grüße


trm - Mo 19.05.14 22:58

Huhu.

Ganz herzlichen Dank, rushifell. Deine Idee habe ich generisch angepasst, das folgende ist für jedes TPageControl somit nutzbar, ohne dass man wissen muss, wieviel TabSheets vorhanden sind.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
var
  i, VisIndex, // Index der sichtbaren Tabsheets
  TrueIndex: Integer; // der "wahre" Index
begin

  VisIndex := TPageControl(Sender).IndexOfTabAt(X, Y);
  TrueIndex := 0;
  i := 0;

  repeat
    if TPageControl(Sender).Pages[TrueIndex].TabVisible then
      inc(i);
    if i <= VisIndex then
      inc(TrueIndex);
  until i >= VisIndex;

  if TrueIndex <> TPageControl(Sender).ActivePageIndex then
    TPageControl(Sender).Cursor := crHandPoint
  else
    TPageControl(Sender).Cursor := crDefault;



Eine schöne Woche, falls noch jemand eine einfachere Lösung mit der Standardkomponente hat - immer her damit. :)


rushifell - Mo 19.05.14 23:22

Hallo,

habe den Code in meinem Beitrag nochmal leicht korrigiert, für den Fall, dass VisIndex den Wert -1 erhält (Keine Ahnung, ob das wirklich jemals eintritt). Der vorherige Code hat auch funktioniert, und soweit ich das richtig sehe, spielt es bei Deinem angepassten Code keine Rolle, ob Du TrueIndex anfangs auf 0 oder auf -1 setzt.

Wobei, wenn Du nur crHandPoint nutzt, reicht doch auch folgendes:

Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.PageControl1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
PageControl1.Cursor:=crHandPoint;
end;

... oder noch einfacher, den Cursor vom PageControl auf crHandPoint setzen!?

Viele Grüße


trm - Mo 19.05.14 23:33

In meinem Code ist es wichtig, dass Trueindex nicht mit -1 intialisiert wird, weil es sonst einen Fehler out of Index gibt ;)

Somit passt es mit :=0 ganz gut.


trm - Mo 19.05.14 23:36

user profile iconrushifell hat folgendes geschrieben Zum zitierten Posting springen:
Hallo,
Wobei, wenn Du nur crHandPoint nutzt, reicht doch auch folgendes:

... oder noch einfacher, den Cursor vom PageControl auf crHandPoint setzen!?

Viele Grüße


Nein. Ich möchte nur für inaktive, sichtbare TabSheets den Cursor als Hand haben. Der aktive Tab, der nciht anklickbar ist, weil er ja schon sichtbar im Vordergrund ist, soll mit einem anderen Cursor behandelt werden. :)


Edit:

Mir ist gerade ein weiterer Weg eingefallen. Entweder über den Tag definieren, welcher Tab gerade aktiv ist und bei onmousemove kann der Tag abgefragt werden. Oder per Boolean-Array.

Aber Deine Lösung reicht vollkommen aus, mit meiner kleinen Modifizierung reicht es mir auch. :)