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/)
-   -   Komponente wird nicht sauber gezeichnet (https://www.delphipraxis.net/157221-komponente-wird-nicht-sauber-gezeichnet.html)

norwegen60 3. Jan 2011 21:39

Komponente wird nicht sauber gezeichnet
 
Hallo zusammen,

ich arbeite seit Jahren mit der Komponente "TDBLookupComboPlus". Jetzt bin ich am Umstellen von Delphi 7 auf XE und habe die Komponente auch soweit, dass sie mit Delphi XE arbeitet. Beim Einsatz von TMS-Controls, z.B. ADVPageControl oder ADVPanel habe ich jetzt aber das Problem, dass die Lookup-Komponente nicht mehr sauber gezeichnet wird. Sobald ich in der IDE ein Fenster darüber ziehe, bleiben in dem Combo-Feld die Reste des darüber gezogenen Fensters stehen. Beim ausgeführten Programm funktioniert es etwas besser. Da bleiben nur am Rand kleine Reste eines darüber gezogenen Fensters hängen. Richtig schön aussehen tut es aber auch da nicht.
Ich habe mich noch nie mit dem Erstellen von Komponenten befasst und möchte es eigentlich auch nicht. Die Suche nach misslungenen Paint-Versuchen hat mir auch nicht viel weiter geholfen. Ich stelle deshalb mal das Original Paint-Ereignis hier rein. Vielleicht sieht ja einer woran es liegen könnte.

Delphi-Quellcode:
procedure TDBLookupComboPlus.WMPaint(var Message: TWMPaint);
var
{$IFNDEF Win32}
  S: array[0..255] of Char;
{$ELSE}
  S : Variant; //String;
{$ENDIF}
  PS: TPaintStruct;
  ARect: TRect;
  TextLeft, TextTop: Integer;
  Focused: Boolean;
  DC: HDC;
  Metrics : TTextMetric;                {new 1/23/96}
begin
  if (Editable or (fstyle = csIncSearch)) and (Text <> '')
{$IFDEF Win32}
  and not (csPaintCopy in ControlState)
{$ENDIF}
     then
  begin
    inherited;
    Exit;
  end;
  { if not editable with focus, need to do drawing to show proper focus }
  if FCanvas = nil then
  begin
    FCanvas := TControlCanvas.Create;
    FCanvas.Control := Self;
  end;
  DC := Message.DC;
  if DC = 0 then DC := BeginPaint(Handle, PS);
  FCanvas.Handle := DC;
  try
    Focused := (GetFocus = Handle) {$IFDEF Win32}and not(csPaintCopy in ControlState){$ENDIF};
    FCanvas.Font := Font;
    with FCanvas do
    begin
      ARect := ClientRect;
      if (BorderStyle = bsSingle) then
      begin
        Brush.Color := clWindowFrame;
 {$IFNDEF Win32}
        FrameRect(ARect);  { draw the border }
 {$ENDIF}
        InflateRect(ARect, -1, -1);
      end;
      if not (Editable or (fstyle = csIncSearch)) or
             ((Text = '') and (fstyle = csIncSearch))
{$IFDEF Win32}
             or (csPaintCopy in ControlState)
{$ENDIF}
             then
      begin
        Brush.Style := bsSolid;  {fill the recttangle inside the boarder with color}
        Brush.Color := Color;
        FillRect (ARect);
        if (BorderStyle = bsSingle) then
          TextTop := FTopTextMargin
        else {bsNone}
          TextTop := FTopTextMargin;
        if ShowSpeedButton then
          ARect.Right := FBtnControl.Left - 1
        else
          ARect.Right := ClientWidth - 2; {new 1/21/96 Deven report added '- 2'}
{$IFNDEF Win32}
        StrPCopy (S, Text);
{$ENDIF}
        TextLeft := FLeftTextMargin;
        if Focused then {draw the focus rectangle}
        begin
          Brush.Color := clHighlight;
          Font.Color := clHighlightText;
          ARect.Top := ARect.Top + FTopTextMargin;
{}        GetTextMetrics(FCanvas.Handle, Metrics); {new 1/23/96}
          ARect.Bottom := ARect.Top + Metrics.tmHeight;
        end;
{$IFDEF Win32}
{CtlGrid}      if (csPaintCopy in ControlState) and (FFieldLink.Field <> nil) and
{CtlGrid}          (LookupSource <> nil) then
{CtlGrid}      begin
{CtlGrid}        If (LookupField = LookupDisplay) or (FFieldLink.Field.DisplayText = '') then {don't do the lookup if not necessary}
{CtlGrid}          S := FFieldLink.Field.DisplayText
{CtlGrid}        else
{CtlGrid}          S := LookupSource.DataSet.Lookup(LookupField, FFieldLink.Field.DisplayText,
{CtlGrid}            LookupDisplay);
{CtlGrid}        If VarIsNull(S) then
{CtlGrid}          S := ''
{CtlGrid}        else if not VarIsEmpty(S) then S := '';
{CtlGrid}        ExtTextOut(FCanvas.Handle, TextLeft, TextTop, ETO_OPAQUE or ETO_CLIPPED, @ARect,
{CtlGrid}        PChar(String(S)), Length(String(S)), nil);
{CtlGrid}      end
{CtlGrid}      else
        ExtTextOut(FCanvas.Handle, TextLeft, TextTop, ETO_OPAQUE or ETO_CLIPPED, @ARect,
          PChar(Text), Length(Text), nil);
{$ELSE}
        ExtTextOut(FCanvas.Handle, TextLeft, TextTop, ETO_OPAQUE or ETO_CLIPPED, @ARect,
          S, StrLen(S), nil);
{$ENDIF}
        If assigned(FBtnControl) then FBtnControl.refresh;
        if Focused then
          DrawFocusRect (ARect);
      end;
    end;
  finally
    FCanvas.Handle := 0;
    if Message.DC = 0 then EndPaint(Handle, PS);
  end;
end;
Vielen Dank für eure Hilfe
Gerd

sx2008 4. Jan 2011 04:35

AW: Komponente wird nicht sauber gezeichnet
 
Gibt es einen bestimmten Grund, weshalb du einen Windows-Message-Handler namens WMPaint benützt?
Ich meine normalerweise gibt es ja die Methode [TControl.]Paint().

Das Abfangen der Message WM_PAINT ist auf einem niedrigerem Abstraktionslevel als das Überschreiben der Paint-Methode.
Es könnte nun sein, dass die Paint-Methode aufgerufen wird ohne dass eine WM_PAINT Message gesendet wird.
Was ich damit sagen will ist, dass es wahrscheinlich sicherer ist die Paint-Methode zu überschreiben.

mkinzler 4. Jan 2011 05:39

AW: Komponente wird nicht sauber gezeichnet
 
Es scheint nicht sein Code, sondern der der Fremdkomponente zu sein

norwegen60 5. Jan 2011 10:00

AW: Komponente wird nicht sauber gezeichnet
 
Stimmt, der Auszug ist aus der Fremdkomponente. Ich wollte es mal mit Paint probieren. Scheitert daran, dass

Delphi-Quellcode:
 TDBLookupComboPlus = class(TCustomEdit)


und CustomEdit noch kein Paint hat.

Ein Tipp, was ich ändert müsste um das Paint korrekt hinzubekommen? Die Aussage, dass es beim Ausführen des Programms klappt ist übrigens nicht ganz richtig. Das sieht nur so aus solange der Text in der Edit-Feld ersetzt wird. Sobald man ein Fenster drüber zieht, bleiben auch dort die Reste im Edit-Feld stehen.
Komisch ist ja, dass es nur bei Verwendung der TMS-Komponenten nicht geht.


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