AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Artefakte beim Zeichnen auf Edit Canvas

Ein Thema von Roaster · begonnen am 14. Okt 2009 · letzter Beitrag vom 15. Okt 2009
Antwort Antwort
Roaster

Registriert seit: 21. Jul 2004
Ort: bei mir zu Hause
107 Beiträge
 
#1

Artefakte beim Zeichnen auf Edit Canvas

  Alt 14. Okt 2009, 16:24
Hi,

ich habe JvEdit so abgeändert, dass ich in einer Art Präfix vor dem eigentlichen Edit Text eine Grafik darstellen kann, siehe Bild.
Das Problem, dass ich habe ist, dass oberhalb und auf der linken Seite der Grafik, oder genauer gesagt Hintergrund, manchmal Reste von anderen Fenstern stehen bleiben.
Ich habe dies mal im Bild mit gelber Farbe markiert.

Den Code, den ich verwende ist:

Delphi-Quellcode:
procedure TJvEdit.WndProc(var Msg: TMessage);
begin
  case Msg.Msg of
    CN_CTLCOLORSTATIC,
    CN_CTLCOLOREDIT:
      if Images <> nil then
        ExcludeClipRect(Msg.WParam, 1, 1, Images.Width + FImageMarginRight + 2, Images.Height);
  end;

  inherited WndProc(Msg);

  case Msg.Msg of
    WM_SIZE, WM_SETFONT, WM_FONTCHANGE, WM_WINDOWPOSCHANGED,
    CM_FONTCHANGED, CM_BORDERCHANGED, CM_CTL3DCHANGED:
      if not (csLoading in ComponentState) then
        UpdateEditMargins;
  end;
end;

procedure TJvEdit.WMPaint(var Msg: TWMPaint);
var
  MyDC: Boolean;
  ps: TPaintStruct;
  NewPen, OldPen: HPEN;
  Canvas: TCanvas;
begin
  if Images <> nil then
  begin
    if UpdateEditMargins then
      Exit; // UpdateEditMargins called Invalidate()

    MyDC := Msg.DC = 0;
    if MyDC then
      Msg.DC := BeginPaint(Handle, ps);

    inherited;

    // Draw gradient filled rectangle
    Canvas := TCanvas.Create;
    Canvas.Handle := Msg.DC;
    GradientFillCanvas(Canvas, FPrefixColorFrom, FPrefixColorTo,
      Rect(0, 0, Images.Width + FImageMarginRight + 2, Images.Height + 1),
      FPrefixColorDirection);

    // Draw bitmap
    if ImageIndex <> -1 then
      case FImageAlignment of
        taLeftJustify : ImageList_Draw(Images.Handle, ImageIndex,
                          Msg.DC, 0, 1, ILD_NORMAL);
        taRightJustify: ImageList_Draw(Images.Handle, ImageIndex,
                          Msg.DC, FImageMarginRight, 1, ILD_NORMAL);
        taCenter: ImageList_Draw(Images.Handle, ImageIndex, Msg.DC,
                          (FImageMarginRight div 2), 1, ILD_NORMAL);
      end;

    // Show separator line
    if FShowLine then
    begin
      NewPen := CreatePen(PS_SOLID, 1, ColorToRGB(FLineColor));
      OldPen := SelectObject(Msg.DC, NewPen);

      MoveToEx(Msg.DC, Images.Width + FImageMarginRight + 1, 0, Nil );
      LineTo(Msg.DC, Images.Width + FImageMarginRight + 1, Height);

      SelectObject(Msg.DC, OldPen);
      DeleteObject(NewPen);
    end;

    if MyDC then
      EndPaint(Handle, ps);

    Canvas.Free;
  end
  else
    inherited;
end;

function TJvEdit.UpdateEditMargins: Boolean;
var
  Margins: Integer;
  LeftMargin: Integer;
begin
  Result := False;
  if HandleAllocated then
  begin
    LeftMargin := 0;
    if Images <> nil then
      LeftMargin := Images.Width + FImageMarginRight + 2;

    Margins := SendMessage(Handle, EM_GETMARGINS, 0, 0);
    if (Margins and $FFFF) <> LeftMargin then
    begin
      SendMessage(Handle, EM_SETMARGINS, EC_LEFTMARGIN, MakeLong(LeftMargin, 0));
      Invalidate;
      Result := True;
    end;
  end;
end;
Im fehlenden Code sind hauptsächlich noch die Setter und Getter für die Properties drin. Das Zeichnen findet im o.g. Coding statt.
Wie gesagt es funktioniert alles, bis auf die Überbleibsel rund um die Grafik/Hintergund herum.

Weiß jemand Rat? Danke!

Credits: Die Codebasis stammt übrigens von Andreas Hausladen - Danke auf diesem Weg nochmals!
Miniaturansicht angehängter Grafiken
artefakte_jvedit_179.png  
cu, Michael

Windows 7, WinXP Pro, Vista, WinXP Home, Win98 SE
D4 C/S, D7 Enterprise, Turbo Delphi Pro, Delphi 2009
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#2

Re: Artefakte beim Zeichnen auf Edit Canvas

  Alt 14. Okt 2009, 16:57
das problem wird sein -- ohne deinen code genau angeschaut zu haben -- dass du auf diesen stellen nie zeichnest. fang mal nicht bei x = 1 an, sondern bei 0! wenn du einen abstand haben willst, dann zeichne da mal einfach eine weiße linie, d.h. auf x = 0
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Roaster

Registriert seit: 21. Jul 2004
Ort: bei mir zu Hause
107 Beiträge
 
#3

Re: Artefakte beim Zeichnen auf Edit Canvas

  Alt 14. Okt 2009, 18:46
Armin,

danke für deine Antwort.
Ich habe genau das schon probiert - an allen möglichen Stellen, wo derzeit eine 1 als X- oder Y-Koordinate eine Null zu schreiben. Meistens mit dem Ergebnis, dass sogar der Rand des TJvEdit's überschrieben wurde.
cu, Michael

Windows 7, WinXP Pro, Vista, WinXP Home, Win98 SE
D4 C/S, D7 Enterprise, Turbo Delphi Pro, Delphi 2009
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#4

Re: Artefakte beim Zeichnen auf Edit Canvas

  Alt 15. Okt 2009, 00:27
Aber du bist doch 1px vom Rand entfernt mit deiner Grafik!? Sicher, dass es nicht daran liegt?

Was passiert, wenn du hier noch ein Repaint einfügst:

Delphi-Quellcode:
...

  case Msg.Msg of
    WM_SIZE, WM_SETFONT, WM_FONTCHANGE, WM_WINDOWPOSCHANGED,
    CM_FONTCHANGED, CM_BORDERCHANGED, CM_CTL3DCHANGED:
      if not (csLoading in ComponentState) then
        UpdateEditMargins;

      //
      // Repaint
      //

  end;

...
(Vergiss bitte das begin und end nicht )
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Roaster

Registriert seit: 21. Jul 2004
Ort: bei mir zu Hause
107 Beiträge
 
#5

Re: Artefakte beim Zeichnen auf Edit Canvas

  Alt 15. Okt 2009, 08:47
Armin,

das Repaint brachte ebenfalls keine Änderungen.

Zum anderen, ja ich dachte auch ich bin schon an Position 0,0 mit dem Image, aber trotzdem stehen, wie im Bild gezeigt, an oberster Linie und am linken Rand diese Pixel.

Ich habe jetzt mal folgendes noch getestet:
Delphi-Quellcode:
    
procedure TJvEdit.WMPaint(var Msg: TWMPaint);
var
  MyDC: Boolean;
  ps: TPaintStruct;
  NewPen, OldPen: HPEN;
  Canvas: TCanvas;
begin
  if Images <> nil then
  begin
    if UpdateEditMargins then
      Exit; // UpdateEditMargins called Invalidate()

    MyDC := Msg.DC = 0;
    if MyDC then
      Msg.DC := BeginPaint(Handle, ps);

    inherited;
  inherited;
  Brush.Color := clNavy;
  FillRect(Msg.DC, Rect(0, 0, 16,16), Brush.Handle);
    if MyDC then
      EndPaint(Handle, ps);
  end
  else
    inherited;
end;
D.h. ich habe das eigentliche Zeichnen des Bitmaps und sonstiges Zeug mal entfernt. Ich dachte, dass FillRect() jetzt ein Rechteck an Position 0,0 zeichnen wird, aber weit gefehlt. Es ist nach wie vor ein Rand von einem Pixel, der entweder weiß bleibt oder mit undefinierten Pixel gezeichnet wird, siehe Bild.

Es sieht irgendwie so aus als ob hier das TJvEdit oder in der Basisklasse noch etwas passiert oder evtl. sogar von der Windows API her. Oder ich mache noch was falsch...

Nachtrag:
Es sieht irgendwie so aus, als ob diese Zeilen hier dafür verantwortlich sind:

Delphi-Quellcode:
procedure TJvEdit.WndProc(var Msg: TMessage);
begin
  case Msg.Msg of
    CN_CTLCOLORSTATIC,
    CN_CTLCOLOREDIT:
      if Images <> nil then
        ExcludeClipRect(Msg.WParam, 1, 1, Images.Width + FImageMarginRight + 2, Images.Height);
  end;
Genau genommen das ExcludeClipRect(Msg.wParam, 1,1...

Nur wenn ich hier ExcludeClipRect(Msg.wParam, 0,0... schreiben, dann es nicht viel besser aus, es wird jetzt zusätzlich auch der Rand des Edits überzeichnet, siehe zweites Bild 'Rand überezeichnet'
Miniaturansicht angehängter Grafiken
wei_er_rand_198.png  
Angehängte Grafiken
 
cu, Michael

Windows 7, WinXP Pro, Vista, WinXP Home, Win98 SE
D4 C/S, D7 Enterprise, Turbo Delphi Pro, Delphi 2009
  Mit Zitat antworten Zitat
Roaster

Registriert seit: 21. Jul 2004
Ort: bei mir zu Hause
107 Beiträge
 
#6

Re: Artefakte beim Zeichnen auf Edit Canvas

  Alt 15. Okt 2009, 10:05
Hm,

ich glaube es liegt irgendwie an der TJvEdit Komponente.

Wenn ich mit der Maus darüberfahre, dann kann ich manchmal beobachten, dass ein zusätzlicher Rahmen innerhalb des Client-Bereichs von ca. 1 Pixel gezeichnet wird, der zwar weiß zu sein scheint,aber er ist zumindest dort, wo ich mit ExcludeClipRect() einen Bereich ausgeschlossen habe, nicht mehr korrekt dargestellt, also die Pixel-Artefakte angezeigt werden.

Es sieht so aus als ob es eine Art Focus-Rahmen sein soll, wenn mit der Maus ins Control gefahren wird.

Muss jetzt nochmals forschen, an welcher Stelle dies passiert um zu sehen, ob man das Verhalten nicht doch irgendwie ändern kann.
cu, Michael

Windows 7, WinXP Pro, Vista, WinXP Home, Win98 SE
D4 C/S, D7 Enterprise, Turbo Delphi Pro, Delphi 2009
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:04 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