Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Library: Windows API / MS.NET Framework API (https://www.delphipraxis.net/20-library-windows-api-ms-net-framework-api/)
-   -   Delphi Text in der Titelzeile zentrieren (https://www.delphipraxis.net/11193-text-der-titelzeile-zentrieren.html)

Luckie 1. Nov 2003 18:46


Text in der Titelzeile zentrieren
 
Delphi-Quellcode:
procedure TForm1.WMNCPAINT(var Msg: TMessage);
var
  rect: TRect;
  dc: HDC;
  MyCaption: String;
begin
  Inherited;
  if Msg.Msg = WM_NCPAINT then
  begin
    dc := GetWindowDC(Handle);
    rect.Left := GetSystemmetrics(SM_CXEDGE);
    rect.Top := GetSystemmetrics(SM_CYEDGE)+2;
    rect.Right := Form1.Width-GetSystemmetrics(SM_CXEDGE);
    rect.Bottom := GetSystemmetrics(SM_CYCAPTION)+GetSystemmetrics(SM_CYEDGE);
    SetBkMode(dc, TRANSPARENT);
    SetTextColor(dc, RGB(255,255,255));
    MyCaption := 'Meine zentrirte Fenster-Caption';
    DrawText(dc, @MyCaption[1], lstrlen(@MyCaption[1]), rect, DT_CENTER or DT_VCENTER);
    ReleaseDc(Handle, dc);
  end;
end;

negaH 3. Nov 2003 10:33

Re: Text in der Titelzeile zentrieren
 
Zitat:

rect.Right := Form1.Width-GetSystemmetrics(SM_CXEDGE);
Der Zugriff auf Form1.Width ist hier unangebracht:
1.) Zugriff auf globale Variable statt auf Self.Width
2.) .Width kann im wm_NCPaint noch undefiniert sein, d.h. stimmt nicht mit den tatsächlichen Größenverhältnissen des Fensterhandles überein. GetWindowRect() wäre richtiger.

Generell sollte man sich bei solchen Messages nicht auf die VCL verlassen sondern nur auf's Windows-API.

Gruß Hagen

Luckie 4. Nov 2003 00:40

Re: Text in der Titelzeile zentrieren
 
Hier die verbesserte Version:
Delphi-Quellcode:
type
  TForm1 = class(TForm)
  private
    { Private-Deklarationen }
    procedure WMNCPAINT(var Msg: TMessage); Message WM_NCPAINT;
    procedure WMNCACTIVATE(var msg: TMessage); Message WM_NCACTIVATE;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

const
  MYCAPTION = 'Meine zentrierte Fenster-Caption';

procedure PaintCaption(hWnd: THandle; WndCaption: String);
var
  dc : HDC;
  CaptRect, WndRect: TRect;
begin
  dc := GetWindowDC(hWnd);
  GetWindowRect(hWnd, WndRect);
  CaptRect.Left := GetSystemMetrics(SM_CXEDGE);
  CaptRect.Top := GetSystemMetrics(SM_CYEDGE)+2;
  CaptRect.Right := WndRect.right-WndRect.Left-GetSystemMetrics(SM_CYEDGE);
  CaptRect.Bottom := GetSystemMetrics(SM_CYCAPTION)+GetSystemMetrics(SM_CYEDGE);
  SetBkMode(dc, TRANSPARENT);
  SetTextColor(dc, RGB(255, 255, 255));
  DrawText(dc, @WndCaption[1], lstrlen(@WndCaption[1]), CaptRect, DT_CENTER or DT_VCENTER);
  ReleaseDC(hWnd, dc);
end;

procedure TForm1.WMNCPAINT(var Msg: TMessage);
begin
  Inherited;
  if msg.Msg = WM_NCPAINT then
  begin
    PaintCaption(Self.Handle, MyCaption);
  end;
end;

procedure TForm1.WMNCACTIVATE(var msg: TMessage);
begin
  Inherited;
  if msg.Msg = WM_NCACTIVATE then
    PaintCaption(Self.Handle, MyCaption);
end;

negaH 4. Nov 2003 13:03

Re: Text in der Titelzeile zentrieren
 
Nochwas, ich weis ich nerve:
Delphi-Quellcode:
DrawText(dc, @WndCaption[1], lstrlen(@WndCaption[1]), CaptRect, DT_CENTER or DT_VCENTER);
Die Flags sollten DT_CENTER or DT_VCENTER or DT_SINGLELINE sein, da der User ja aus versehen ein <CR> in der Caption haben könnte. Dies sähe dann ohne DT_SINGLELINE unschön aus. Es sein denn es ist erwünscht :)

Wichtig wäre auch noch den Font korrekt auszuwählen, denn bei ToolWindows ist dieser kleiner. Oder bei aktiviertem Fenster kann ein anderer Font eingestellt sein als bei deaktiviertem Fenster. Aber es ging ja auch nur ums Prinzip ;)

Gruß hagen

Motzi 4. Nov 2003 14:18

Re: Text in der Titelzeile zentrieren
 
Zitat:

Zitat von negaH
Die Flags sollten DT_CENTER or DT_VCENTER or DT_SINGLELINE sein, da der User ja aus versehen ein <CR> in der Caption haben könnte. Dies sähe dann ohne DT_SINGLELINE unschön aus. Es sein denn es ist erwünscht :)

Abgesehn davon zeigt DT_VCENTER nur bei DT_SINGLELINE Wirkung...! ;)

OLLI_T 4. Nov 2003 15:41

Re: Text in der Titelzeile zentrieren
 
HY Luckie!

Irgendwie lässt Du die gute alte Property Caption des Forms völlig ausser acht.
Schau Dir mal GetWindowText, WM_NCCalcSize, WM_NCHitTest, WM_NCMouse... an und CM_TEXTCHANGED an. Dann noch ein paar nette Bildchen als Ressourcen einbinden und die BorderIcons ins Nirwana verdammen und Du hast die volle Macht über die Titelleiste. So ist es nur ein nettes Demo.

Liebe Grüsse

OLLI

Luckie 4. Nov 2003 16:01

Re: Text in der Titelzeile zentrieren
 
War auch nur mal schnell hingecoded, weil jemand wissen wollte wie er den Text in der Titelzeile anders ausrichten könnte. Sollte also auch nur ein nettes Demo sein. :zwinker:

negaH 4. Nov 2003 17:54

Re: Text in der Titelzeile zentrieren
 
@Olli_T:

er muß das sogar, da ansonsten inherited WMCNPaint() diese Caption zeichnen würde. Seine eigene Caption Routine müsste nun exakt diese schon gezeichnete Caption wieder überzeichnen, was bekanntlich auf Grund der vielen verschiedenen Gimmecks der einzelnen Windows Versionen sehr schwierig wird. Das große Problem mit dem Non Client Bereich ist das die internen Windows Message Handler sich NICHT an logische Standards halten. Wird z.B. der Schließen Button gedrückt, verzweigt Windows intern in eine eigene Schleife und zeichnet direkt in den Non Client hinein. Dies hat aber den großen Nachteil das eine eigene Zeichenroutine nun aussen vor ist. Man müsste also demzufolge das KOMPLETTE Non Client Verhalten selber nachprogrammieren. Dies enthält alle Mausereignisse, Zeichenroutinen, Client bereich Berechnungs Routinen, MDI Child Routinen, Menu Routinen usw. usw. Denn in jeder dieser Message haben die Windows Entwickler ihre Schleifen und direkte NC Zeichenroutinen drinnen.

Gruß Hagen


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