Delphi-PRAXiS
Seite 1 von 2  1 2      

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 Zeichnen auf MDI-Form... (https://www.delphipraxis.net/100859-zeichnen-auf-mdi-form.html)

bingo72 4. Okt 2007 19:13


Zeichnen auf MDI-Form...
 
Hallo Kollegen!!

Ich bräuchte wiedermal eure Hilfe:

Ich habe eine MDI-Form auf der links ein MenüTree ist, der in seiner Breite verschiebbar ist. Auf der verbleibenden Fläche der Applikation, soll ein Hintergrundlogo mittig zentriert plaziert werden und die Fläche selbst eine Hintergrundfarbe bekommen.
Die Applikation selbst ist in seiner Größe ebenfalls veränderbar.

Das Hintergrundlogo (jpeg) hab ich mal als erstes in eine TImage-Komponente verpackt und diese auf der Form platziert. Als nächstes habe ich eine Canvas-Komponente erzeugt und lasse das in ein Bitmap umgewandelte Hintergrundlogo, zeichnen (mittels Draw).
Dies funktioniert soweit auch schon.

Das Problem ist, daß wenn ich entweder beim Verändern der MenüTree-Breite oder beim Verändern der Größe des Applikationsfensters, ein massives 'Neuzeichnen'-Problem bekomme. Soll heissen, das Logo plaziert sich nicht neu in die neue Mitte bzw. wird das Logo beim Verkleinern des Fensters einfach mit der Hintergrundfarbe 'übermalt'. Nur wenn ich das Fenster minimiere oder ein anderes Fenster anklicke (zufällig geöffnete Datei) scheint es sich neu zu zeichnen....nicht aber eben beim Ändern der Applikations-Fenstergröße!!

Wem mit Code geholfen ist, kann ich morgen in der Früh Code-Stücke beifügen...

Ich hoffe es kennst sich wer damit aus... :gruebel:

LG
Thomas

peschai 5. Okt 2007 07:09

Re: Zeichnen auf MDI-Form...
 
Hallo
Zitat:

habe ich eine Canvas-Komponente erzeugt
Wie hast du das gemacht ?
Warum verwendest du nicht den Canvas der Form selber ?
Benutzt du OnPaint und eventuell auch Invalidate? :roteyes:

bingo72 5. Okt 2007 07:27

Re: Zeichnen auf MDI-Form...
 
Hey!!

Bin jetzt schon ein gutes Stück weitergekommen und hab im Netz doch noch wertvolle Tipps gefunden:

Vielleicht mal ein wenig Code:

Im Create mach ich das:
Delphi-Quellcode:
fLogo := imLogo.Picture.Graphic;

  fBkBrush := CreateSolidBrush(GetColor);
  fClientInstance := MakeObjectInstance(MainClientWndProc);
  fPrevClientProc := Pointer (GetWindowLong(ClientHandle, GWL_WNDPROC));
  SetWindowLong(ClientHandle, GWL_WNDPROC, Longint(fClientInstance));
 
  fCanvas := TCanvas.Create;
  fCanvas.Handle := GetDC(ClientHandle);
und im Destroy das...
Delphi-Quellcode:
DeleteObject(fBkBrush);
  ReleaseDC(ClientHandle, fCanvas.Handle);

  fCanvas.Free;
im ClientWindowProc(var Message: TMessage) das:

Delphi-Quellcode:
var
  lDC             : HDC;
  lBrushOld       : HBRUSH;
begin
  with Message do begin
    case Msg of WM_ERASEBKGND:
      begin
        lDC := TWMEraseBkGnd(Message).DC;
        lBrushOld := SelectObject(lDC, fBkBrush);
        FillRect(lDC, ClientRect, fBkBrush);
        SelectObject(lDC, lBrushOld);
        Result := 1;
      end else begin
        Result := CallWindowProc (fPrevClientProc, ClientHandle, Msg, wParam, lParam);
      end;
    end;
  end;
end;
und zu guter Letzt die DrawBackground-Methode:
Delphi-Quellcode:
var
  lImage          : TGraphic;
  lBitmap         : TBitmap;
  lLeft           : Integer;
  lTop            : Integer;
  lRect           : TRect;
begin
    if Assigned (fCanvas) then begin
      lLeft := (ClientWidthEx - fBitmap.Width) div 2;
      lTop := (ClientHeightEx - fBitmap.Height) div 2;

      if Assigned (fBitmap.Canvas) then begin
        fCanvas.Draw(lLeft, lTop, fBitmap);
      end;
    end;
end;
Es funktioniert schon recht gut und die Effekte sind so wie ich es mir vorstelle...eigentlich fertig oder?? :gruebel:

Naja nicht ganz...wenn ich nämlich die Applikation beende bekomme ich im DrawBackground eine AccessViolation-Exception an der Draw-Position...drum hab ich dort auch schon alles abgetestet, was nil sein könnte??
Vielleicht findet ja wer gleich den Grund??

LG
Thomas

bingo72 5. Okt 2007 07:37

Re: Zeichnen auf MDI-Form...
 
Ich hab jetzt festgestellt, daß mein Resize-Event, nach dem Destroy nochmals die Background-Methode aufruft und da natürlich kracht es...
Is doch unlogisch oder, daß nach dem Destroy nochmals ein Resize aufgerufen wird....wie kann man das verhindern??

peschai 5. Okt 2007 07:41

Re: Zeichnen auf MDI-Form...
 
Hallo

Die Reihenfolge im Destroy und deine Variable fCanvas war noch mit einer Adresse belegt obwohl das Object eventuell schon freigegen war ... FreeAndNil!
Delphi-Quellcode:
ReleaseDC(ClientHandle, fCanvas.Handle);
FreeAndNil(fCanvas);
DeleteObject(fBkBrush);

bingo72 5. Okt 2007 07:50

Re: Zeichnen auf MDI-Form...
 
Vielen Dank für Deinen Tipp...

Dennoch besteht nachwievor das seltsame Verhalten, daß nach einem Destroy nochmals ein Resize aufgerufen wird. Der Grund den ich ermitteln konnte war, daß die fBitmap-Variable nach dem Destroy nil, aber dadurch das nachher nochmals Resize ausgeführt wird und somit DrawBackground kracht es natürlich. Ich hab mir jetzt mal dadurch abgeholfen, daß ich Assigned(fBitmap) im Resize checke und nur dann die DrawBackground ausgeführt wird, wenn fBitmap einen Wert hat.

Sauber find ichs nicht und ich würde gerne den Grund für dieses seltsame Verhalten in Erfahrung bringen...

Sidorion 5. Okt 2007 08:30

Re: Zeichnen auf MDI-Form...
 
Versuch mal im OnResize csDestroying im ComponentState abzufragen. Zeichnen tust Du dann nur wenn es nicht enthalten ist.

bingo72 5. Okt 2007 08:59

Re: Zeichnen auf MDI-Form...
 
Ja danke es funktioniert...ich hab noch zuwenig Erfahrung in Delphi....drum frag ich nochmals....ist ein Aufruf von Resize nach Destroy normal??

bingo72 5. Okt 2007 12:01

Re: Zeichnen auf MDI-Form...
 
Ein Problem hab ich allerdings noch wenn ich mit meinem linken Menübaum (der aus einer TreeView mit einem Splitter besteht) hin und herfahre...dann passiert es, daß es noch immer so aussieht...

http://www.bos.at/downloads/LogoNOK.jpg

Bitte um weitere Tipps... :wink:

Danke!!

bingo72 5. Okt 2007 12:06

Re: Zeichnen auf MDI-Form...
 
Wenn ich allerdings das Fenster minimiere und wieder aufklappe, dann zeichnet er es neu und damit richtig...
Gibt es keinen Befehl mit dem ich ein Minimieren 'Simulieren' kann, ohne das sich das Fenster zwar minimiert, aber dennoch auf die gleiche Weise neu zeichnet?? :?:


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