![]() |
Artefakte beim Zeichnen auf Edit Canvas
Liste der Anhänge anzeigen (Anzahl: 1)
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:
Im fehlenden Code sind hauptsächlich noch die Setter und Getter für die Properties drin. Das Zeichnen findet im o.g. Coding statt.
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; 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! |
Re: Artefakte beim Zeichnen auf Edit Canvas
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
|
Re: Artefakte beim Zeichnen auf Edit Canvas
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. |
Re: Artefakte beim Zeichnen auf Edit Canvas
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:
(Vergiss bitte das begin und end nicht ;) )
...
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; ... |
Re: Artefakte beim Zeichnen auf Edit Canvas
Liste der Anhänge anzeigen (Anzahl: 2)
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:
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.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; 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:
Genau genommen das ExcludeClipRect(Msg.wParam, 1,1...
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; 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' |
Re: Artefakte beim Zeichnen auf Edit Canvas
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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:22 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz