Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Eigenes TPageControl - APIs zum zeichnen? (https://www.delphipraxis.net/161415-eigenes-tpagecontrol-apis-zum-zeichnen.html)

wicht 2. Jul 2011 20:54

Eigenes TPageControl - APIs zum zeichnen?
 
Hi Forum!

Ich bin seit längerem dabei, ein eigenes Tab-Control zu bauen (abgeleitet von TWinControl). Der Header (das Teil, wo die Tabs drauf gemalt werden) soll genau so aussehen, wie das normale Windows-Control (In Delphi TPageControl). Wenn Themes aktiv sind funktioniert das auch, weil man sich ja mit den ThemeServices in Delphi das Aussehen jedes Elements ganz einfach holen kann. Allerdings weiß ich nicht, wie ich das Zeichnen ordentlich machen soll, wenn Themes abgeschaltet sind. Gibt es dafür irgendeine Funktion von Windows? Falls nicht muss ich wohl alles per Hand zeichnen, oder mir ein Tab-Control im Hintergrund erstellen, das in eine Bitmap kopieren und dann mit der TabRect()-Methode die Abmessungen eines Tabs holen, um es aus der Bitmap zu kopieren und selber benutzen zu können.. aber das sind beides keine besonders schönen Lösungen, wie ich finde.

Hat jemand da einen Tipp? Das wäre spitze... Ich wäre auch über ein "Dafür gibt es definitiv keine API" erfreut, weil ich dann wüsste, dass ich den "unschönen" Weg gehen muss.


Liebe Grüße, noch ein schönes Restwochenende und TIA,

Alexander

himitsu 2. Jul 2011 21:07

AW: Eigenes TPageControl - APIs zum zeichnen?
 
Bau och einfach ein TTabControl oben in deine Komponente?
Das nutze ich auch immer sehr erfolgreich, wenn ich sowas wie ein PageControl brauche, mich aber selber um die untere Darstellung kümmern möchte.
Bzw. schau dir an, was sich in dieser Komponente versteckt.

Luckie 2. Jul 2011 21:08

AW: Eigenes TPageControl - APIs zum zeichnen?
 
Warum leitest du nicht von TTabControl ab?

wicht 2. Jul 2011 21:38

AW: Eigenes TPageControl - APIs zum zeichnen?
 
Hi, danke für eure Antworten.

Dass es auf "Benutz doch TTabControl oder TPageControl" hinausläuft, dachte ich mir irgendwie schon. Dann hole ich mal noch etwas mehr aus. Bis jetzt habe ich das auch ungefähr so gemacht, wie von euch vorgeschlagen (nur dass ich TPageControl genutzt habe). Auf meinen Tabs ist allerdings ein Knopf zum Schließen drauf. Und völlig egal wie ich Tabs schließe - es tritt immer das hier beschriebene Problem auf. Und mittlerweile nervt mich das so extrem, dass ich mein eigenes Tab bauen möchte (Dort funktioniert es nämlich wie gewünscht - aber eben nur mit Themes z.Z.). Die Unit, in der das genannte Problem auftritt, ist übrigens auf streamwriter.org in den Quellen mit drin, Datei common\MControls.pas.
Dort ist auf jedem Tab oben ein Knopf drauf. Wird dieser geklickt, wird das Tab per PostMessage() benachrichtigt, dass ein Tab zu schließen ist. Wenn die Message ankommt, ruft das PageControl die Methode "RemoveTab" auf, die ich hier mal poste:

Delphi-Quellcode:
procedure TMPageControl.RemoveTab(Tab: TTabSheet);
var
  Idx: Integer;
begin
  SendMessage(Handle, WM_SETREDRAW, 0, 0);
  try
    if Assigned(TMTabSheet(Tab).FOnClosed) then
      TMTabSheet(Tab).FOnClosed(Tab);

    if Tab = ActivePage then
    begin
      if PageCount - 1 > ActivePageIndex then
        Idx := ActivePageIndex
      else
        Idx := ActivePageIndex - 1;
    end else
    begin
      if Tab.PageIndex <= ActivePageIndex then
        Idx := ActivePageIndex - 1
      else
        Idx := ActivePageIndex;
    end;

    if Idx < 0 then
      Idx := 0;
    if PageCount = 0 then
      Idx := -1;

    Tab.Parent := nil;
    TabClosed(TMTabSheet(Tab));
    Tab.Free;

    ActivePageIndex := Idx;
  finally
    SendMessage(Handle, WM_SETREDRAW, 1, 0);
  end;
end;
Ja, WM_SETREDRAW ist über, bitte nicht hauen. Auch wenn die Berechnung von Idx nicht perfekt sein sollte, der Variable kann ich auch fest eine "1" zuweisen, das Problem mit dem Springen im Link von oben tritt *immer* auf. Ich habe da schon wochenlang experimentiert (auch den Vorschlag aus dem verlinkten Post von Union getestet) - nichts funktioniert. So aus Langeweile würde ich ja auch nicht versuchen, so ein Control selber zu implementieren.. :|

wicht 2. Jul 2011 22:25

AW: Eigenes TPageControl - APIs zum zeichnen?
 
Toll. Jetzt klicke ich ein bisschen hier im Forum rum und lese den letzten Post von EWeiss in seinem "Virtual Piano"-Thread. Dort schreibt der liebe Emil was von LockWindowUpdate(). Das unterdrückt den unerwünschten Effekt mit dem "Springteufel" am Tab scheinbar! Im MSDN steht aber, dass man das nicht machen soll, weil das eine "global state"-Operation ist - und hier geht es ja nur um mein eigenes Tab, ohne dass irgendetwas anderes vom Desktop beteiligt ist. WM_SETREDRAW soll dafür gut sein. Allerdings bewirkt es bei mir am TPageControl nichts... Vielleicht hat da ja noch jemand einen Hinweis - sonst bleibe ich einfach bei LockWindowUpdate(). Mir ist zur Zeit eine nicht ganz saubere Lösung lieber, als die nächsten Wochen am eigenen Tab weiter zu arbeiten, was dann noch ganz andere Probleme hat.. Blöde Einstellung, ich weiß :? ...


Nocheinmal Danke und liebe Grüße,

Alex

EWeiss 2. Jul 2011 22:52

AW: Eigenes TPageControl - APIs zum zeichnen?
 
jo WM_SETREDRAW führt nicht immer zum gewünschten erfolg deshalb habe ich auch LockWindowUpdate
zusätzlich verwendet .. MSN hin und her für mich zählt letztendlich das was funktioniert ;)
Und auf keinen Fall mit PostMessage die wartet nämlich nicht auf die Abarbeitung.

PS:
Du könntest ja nochmal ein invalidate nach WM_SETREDRAW hinterherschicken oder UpdateWindow
Dann gibt es auch noch RedrawWindowAny

' RedrawWindow zeichnet ein Fenster neu, RedrawWindowAny
' erlaubt in diesem Fall das Auslassen der RECT-Angabe
' (spart hier die Verwendung der Funktion GetClientRect).

gruss

wicht 2. Jul 2011 23:10

AW: Eigenes TPageControl - APIs zum zeichnen?
 
Ich bin ja eigentlich kein Freund davon, Dinge zu machen, wozu z.B. das MSDN sagt "nicht so machen". Aber hier muss ich das dann wohl. Ausserdem dauert das Schließen so eines Tabs ja nicht lange und währenddessen wird sehr sicher von keinem anderen Programm irgendein Drag&Drop durch den Benutzer gemacht werden. Und selbst wenn es mal fehlschlägt ist das kein Beinbruch, es sieht nur minimal unschön für den Benutzer aus.
Deshalb nocheinmal Danke für deinen Post, den ich da entdeckt habe :P ...

Ups: Das PS teste ich gleich noch. Oder morgen ;)

EWeiss 2. Jul 2011 23:39

AW: Eigenes TPageControl - APIs zum zeichnen?
 
MSN!

Zitat:

Leider ist es damit noch nicht ganz getan: Im Gegensatz zu LockWindowUpdate nämlich wird alleine durch das Aufheben der Sperrung noch kein Neuzeichnen ausgelöst.
Ein Neuzeichnen der betroffenen Fläche ist zwar nicht zwingend notwendig, jedoch der Regelfall:
Schließlich werden Sie wollen, dass die diversen "im Versteckten" vorgenommenen Änderungen letztlich auch sichtbar werden.
Du mußt selber dafür sorgen das dein Window aktualisiert wird.
Nach WM_SETREDRAW ;)


gruss

wicht 2. Jul 2011 23:50

AW: Eigenes TPageControl - APIs zum zeichnen?
 
Bei den Versuchen von vorhin hat das leider nicht geklappt. Das blöde PageControl macht trotzdem den Springteufel zwischen meinen WM_SETREDRAW Aufrufen.. es scheint, als hätte WM_SETREDRAW gar keinen Einfluss auf das Verhalten - im Gegensatz zu LockWindowUpdate(). Darum ist das "danach aktualisieren" auch nicht wirklich wichtig... :|

EWeiss 2. Jul 2011 23:55

AW: Eigenes TPageControl - APIs zum zeichnen?
 
Zitat:

Zitat von wicht (Beitrag 1109713)
Bei den Versuchen von vorhin hat das leider nicht geklappt. Das blöde PageControl macht trotzdem den Springteufel zwischen meinen WM_SETREDRAW Aufrufen.. es scheint, als hätte WM_SETREDRAW gar keinen Einfluss auf das Verhalten - im Gegensatz zu LockWindowUpdate(). Darum ist das "danach aktualisieren" auch nicht wirklich wichtig... :|

Ok! Hauptsache du kommst damit klar.
Und du führst keinen Springteufel auf die dahinter liegenden Fenster aus.
Das mußt halt testen. ;)

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:54 Uhr.
Seite 1 von 2  1 2      

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