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/)
-   -   Delphi WM_NCPAINT - Rahmen selber Zeichnen klappt nicht so recht... (https://www.delphipraxis.net/72564-wm_ncpaint-rahmen-selber-zeichnen-klappt-nicht-so-recht.html)

turboPASCAL 3. Jul 2006 07:35


WM_NCPAINT - Rahmen selber Zeichnen klappt nicht so recht...
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi,

ich mochte um eine Form einen eigenen Rahmen mit WM_PAINT zeichnen. Ich dachte mir dass das
eigentlich eine einfache Sache ist, aber ne...

Folgenden Code verwende ich z.Z.:

Delphi-Quellcode:
procedure TForm1.WMNCPaint(var _Message: TWMNCPaint);
var
  aCanvas: TCanvas;
  r, r2: trect;
  rn, rn2: hrgn;
begin
  inherited;

  aCanvas := TCanvas.Create;
  try
    aCanvas.Handle := GetWindowDC(Handle);

    getwindowrect(handle, r);
    rn := CreateRectRgnIndirect(r);

    r2 := clientrect;
    r2.top := 5;

    rn2 := CreateRectRgnIndirect(r2);

    CombineRgn(rn, rn, rn2, RGN_XOR);

    aCanvas.Pen.Color := clLime;
    aCanvas.Brush.Style := bsFDiagonal {bsSolid};
    aCanvas.Brush.Color := clBlack;

    if not FillRGN(aCanvas.Handle, rn, aCanvas.Brush.Handle) then
      windows.Beep(880,20);

    deleteobject(rn);
    deleteobject(rn2);

    aCanvas.Brush.Style := bsClear;
    aCanvas.Pen.Style := psSolid;
    aCanvas.Rectangle(0, 0, Width, Height);
  finally
    ReleaseDC(Handle, aCanvas.Handle);
    aCanvas.Free;
  end;
end;
Das Problem ist das der Rahmen nicht richtig gezeichnet wird bzw. verschwindet
beim dem Verändern der Grösse des Fensters.

Wer kann helfen ?

dataspider 3. Jul 2006 08:08

Re: WM_NCPAINT - Rahmen selber Zeichnen klappt nicht so rech
 
Hi turbopascal,

mit fällt erst mal auf, dass du ein neues Canvas - Object erzeugst.
TForm hat doch ein Canvas, auf welches du zeichnen kannst.
Und dann überschreibe ich immer die Methode Paint.
Ausserdem muss du noch GetClientRect anpassen, damit ein Control den Rahmen nicht verdecken kann.

Cu, Frank

turboPASCAL 3. Jul 2006 08:49

Re: WM_NCPAINT - Rahmen selber Zeichnen klappt nicht so rech
 
Liste der Anhänge anzeigen (Anzahl: 1)
Du kanst mit {FormX.}Canvas nur auf das ClientRect eines Fensters zugreifen.
Mir geht es aber um den Rahmen (NonClientArray).

Delphi-Quellcode:
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.Style := Params.Style or WS_SIZEBOX {WS_BORDER};
end;
Im Ergebnis soll das dann so aussehen:

xaromz 3. Jul 2006 11:20

Re: WM_NCPAINT - Rahmen selber Zeichnen klappt nicht so rech
 
Hallo,

ich hab mir eine Funktion geschrieben, die mir den DC gleich richtig anpasst:
Delphi-Quellcode:
function TMyForm.GetWindowDC: HDC;
var
  DC: HDC;
  RC, RW: TRect;
begin
  DC := Windows.GetWindowDC(Handle);
  Windows.GetClientRect(Handle, RC);
  GetWindowRect(Handle, RW);
  MapWindowPoints(0, Handle, RW, 2);
  OffsetRect(RC, -RW.Left, -RW.Top);
  ExcludeClipRect(DC, RC.Left, RC.Top, RC.Right, RC.Bottom);
  Result := DC;
end;
Vielleicht klappt's ja damit.

Gruß
xaromz

SirThornberry 3. Jul 2006 12:14

Re: WM_NCPAINT - Rahmen selber Zeichnen klappt nicht so rech
 
@turboPASCAL: Wenn das ganze wie in deinem Bild aussehen soll wäre es doch das einfachste den BorderStyle auf bsNone zu setzen. Anschließend kannst du im OnPaint des Forms den Rahmen zeischnen.

turboPASCAL 3. Jul 2006 12:21

Re: WM_NCPAINT - Rahmen selber Zeichnen klappt nicht so rech
 
Jupp, dachte ich auch erst. Als ich dann aber ein Control auf alClient setzen wollte musste
ich die Idee wieder verwerfen.
Eine Eigene Kompon. zu basteln die einen Border zeichnet, ala Panel, möchte ich nicht.
Das währe zu einfach. :mrgreen:

turboPASCAL 4. Jul 2006 22:03

Re: WM_NCPAINT - Rahmen selber Zeichnen klappt nicht so rech
 
Gestatten ? Ein "Push", "pop", "blupp" or "fsStayOnTop". :stupid:

igel457 5. Jul 2006 12:33

Re: WM_NCPAINT - Rahmen selber Zeichnen klappt nicht so rech
 
Zitat:

Jupp, dachte ich auch erst. Als ich dann aber ein Control auf alClient setzen wollte musste
ich die Idee wieder verwerfen.
Dafür gibt es bei TForm die eigenschaft BorderWidth oder so ähnlich.

turboPASCAL 6. Jul 2006 00:35

Re: WM_NCPAINT - Rahmen selber Zeichnen klappt nicht so rech
 
Zitat:

Zitat von igel457
Dafür gibt es bei TForm die eigenschaft BorderWidth oder so ähnlich.

Schon, aber in der nonVCL gibt es die dann nischt mehr. :stupid:

Christian Seehase 6. Jul 2006 10:50

Re: WM_NCPAINT - Rahmen selber Zeichnen klappt nicht so rech
 
Moin Matti,

schau Dir doch mal die Funktion MSDN-Library durchsuchenGetDCEx an.
Bei mir bringt die im WMNCPAINT-Event zwar immer 0 zurück (obwohl die übergebenen Werte eigentlich stimmen sollten), aber vielleicht funktioniert es ja bei Dir.
(GetLastError meldet mir auch "Der Vorgang wurde erfolgreich durchgeführt" :gruebel:)

Mein Aufruf:
Delphi-Quellcode:
hdc := GetDCEx(self.Handle,msg.RGN,DCX_WINDOW or DCX_INTERSECTRGN);

turboPASCAL 6. Jul 2006 12:12

Re: WM_NCPAINT - Rahmen selber Zeichnen klappt nicht so rech
 
Zitat:

Zitat von Christian Seehase
Moin Matti,

schau Dir doch mal die Funktion MSDN-Library durchsuchenGetDCEx an.
Bei mir bringt die im WMNCPAINT-Event zwar immer 0 zurück (obwohl die übergebenen Werte eigentlich stimmen sollten), aber vielleicht funktioniert es ja bei Dir.
(GetLastError meldet mir auch "Der Vorgang wurde erfolgreich durchgeführt" :gruebel:)

Mein Aufruf:
Delphi-Quellcode:
hdc := GetDCEx(self.Handle,msg.RGN,DCX_WINDOW or DCX_INTERSECTRGN);

Jupp, hab ich schon. Du bekommst ein gültigen DCdurch das hinzufügen des Flags DCX_USERSTYLE.

Delphi-Quellcode:
DCX_USERSTYLE = $10000; // oder war es $100000 *grübel*

//...
hdc := GetDCEx(Handle, msg.RGN, DCX_WINDOW or DCX_INTERSECTRGN or USERSTYLE);
// zur sicherheit mach ich dann noch:
if hdc = 0 then hdc := GetWindowDC(Handle);
Das Problem ist das der Rahmen zwar gezeichnet wird aber beim ändern der Grösse des Fensters nicht exakt gezeichnet wird.

Vjay 7. Jul 2006 10:46

Re: WM_NCPAINT - Rahmen selber Zeichnen klappt nicht so rech
 
Also ich habe mir mal dein Beispiel aus dem ersten Post geladen und gestartet.
Man hat doch garnicht die Möglichkeit die Grösse zu ändern, oder meinst du per width:= etc. ?
Ansonsten schaue dir nochmal die WM_NCCALCSIZE, vermute auf den ersten Gedanken, dass dort das Progblem liegt.

Christian Seehase 7. Jul 2006 12:07

Re: WM_NCPAINT - Rahmen selber Zeichnen klappt nicht so rech
 
Moin Matti,

ein Stück weiter gekommen bin ich ja.
Schau's Dir doch mal an, ob es weiterhilft.

Delphi-Quellcode:
procedure TForm1.WMNCPAINT(var Msg: TWMNCPaint);

const
  DCX_USESTYLE = $10000;

var
  aCanvas: TCanvas;

begin
  inherited;
  aCanvas := TCanvas.Create;
  try
    aCanvas.Handle     := GetDCEx(self.Handle,Msg.RGN,DCX_WINDOW or DCX_INTERSECTRGN or DCX_USESTYLE);
    aCanvas.Pen.Color  := clLime;
    aCanvas.Brush.Style := bsFDiagonal {bsSolid};
    aCanvas.Brush.Color := clBlack;
    aCanvas.Rectangle(0, 0, Width, Height);
    Msg.Result := 0;
  finally
    ReleaseDC(Handle, aCanvas.Handle);
    aCanvas.Free;
  end;
end;

procedure TForm1.WMPAINT(var Msg: TWMPaint);

var
  aCanvas : TCanvas;

begin
  inherited;
  aCanvas := TCanvas.Create;
  try
    aCanvas.Handle     := Msg.DC;
    aCanvas.Pen.Color  := clBtnFace;
    self.DoubleBuffered := true;
  finally
    aCanvas.Free;
  end;
  Msg.Result := 1;
end;

TAC 7. Jul 2006 12:24

Re: WM_NCPAINT - Rahmen selber Zeichnen klappt nicht so rech
 
Moin zusammen,

ich habe, glaube ich zumindest, so etwas mal mit dem Real-Player gesehen. Und irgendwie auch mal über Titelleist und real-player gegooglet und auch was gefunden, weiß jeodch leider nicht mehr, wie es hieß. Vielleicht hilfst ja weiter.
Was ist sonst mit dem BoundsRect, könnte das vielleicht weiterhelfen, um den CLientbereich einzugrenzen?


LG
Der TAC


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