Autor |
Beitrag |
jjturbo
Beiträge: 516
Win2000 prof., WinXP prof.
D4 Stand., D5 Prof, D7 Prof, D2007 Prof.
|
Verfasst: Mi 02.02.22 10:51
Moin Forum,
ich habe auf meinem (FMX-)Form selbst geschriebene, von TRectangle abgeleitete Komponenten, diese erzeugen jeweils ein TLabel um das zugehörige TRectangle beschriften zu können. Funktioniert auch wunderbar.
Jetzt werden aus zwei weiteren Threads Informationen gesendet, die die Farben und/oder die Beschriftungen der Komponenten anpassen. Das passiert aus den beiden Threads ca. alle 200-300 Millisekunden. Irgendwann nach längerer Zeit, (undefinierbar, mal 30 Minuten, mal mehrere Stunden) kommt es zu einem Fehler:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| exception message : Zugriffsverletzung bei Adresse 656F5C31 in Modul 'DWRITE.DLL'. Lesen von Adresse FEEEFEEE.
thread $b18: 656f5c31 +000 DWRITE.DLL 008789fe +50a HC3079.exe FMX.Canvas.D2D 2651 +84 TTextLayoutD2D.DoRenderLayout 005d44b0 +01c HC3079.exe FMX.TextLayout 397 +6 TTextLayout.EndUpdate 00731a6e +4b2 HC3079.exe FMX.Objects 2778 +42 TText.Paint 005fb009 +1a1 HC3079.exe FMX.Graphics 6030 +24 TCanvas.SetMatrix 007644e5 +1a1 HC3079.exe FMX.Controls 3281 +14 DoPaintInternal 00764794 +198 HC3079.exe FMX.Controls 3312 +15 PaintAndClipChild 00764880 +064 HC3079.exe FMX.Controls 3329 +7 TControl.PaintInternal 00764ff8 +1a8 HC3079.exe FMX.Controls 3468 +34 TControl.PaintChildren 007e448c +02c HC3079.exe FMX.Controls.Presentation 952 +5 TPresentedControl.PaintChildren 0076458b +247 HC3079.exe FMX.Controls 3288 +21 DoPaintInternal 00764794 +198 HC3079.exe FMX.Controls 3312 +15 PaintAndClipChild 00764880 +064 HC3079.exe FMX.Controls 3329 +7 TControl.PaintInternal 00a09b7d +241 HC3079.exe FMX.Forms 6123 +47 TCustomForm.PaintRects 0097933c +274 HC3079.exe FMX.Platform.Win 1680 +40 WMPaint 0097a94c +47c HC3079.exe FMX.Platform.Win 2169 +74 WndProc 7664687a +07a USER32.dll GetWindowLongW 77384e9b +04b ntdll.dll KiUserCallbackDispatcher 009fc0df +03b HC3079.exe FMX.Forms 1875 +3 TApplication.HandleMessage 0097726a +03a HC3079.exe FMX.Platform.Win 800 +6 TPlatformWin.Run 009fcac7 +03f HC3079.exe FMX.Forms 2176 +3 TApplication.Run 01453b87 +2af HC3079.exe HC3079 98 +41 initialization 75e7fa27 +017 KERNEL32.DLL BaseThreadInitThunk |
In dieser Procedure, meistens in Zeile 99, manchmal aber auch in einer der Zeilen von 82-88:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105:
| unit FMX.Canvas.D2D;
procedure TTextLayoutD2D.DoRenderLayout; var TextRange: TDWriteTextRange; TextFormat: IDWriteTextFormat; I: Integer; Attr: TTextAttributedRange; TrimOptions: TDwriteTrimming; TrimmingSign: IDWriteInlineObject; FontDescriptor: TDWriteFontDescriptor; SolidBrush: ID2D1SolidColorBrush; begin FLayout := nil; FTextRect := TRectF.Empty;
FontDescriptor := GetFontStyles(Font);
if Succeeded(TCanvasD2D.SharedDWriteFactory.CreateTextFormat(PChar(FontDescriptor.FamilyName), FFontCollection, FontDescriptor.Weight, FontDescriptor.Style, FontDescriptor.Stretch, Font.Size, PChar(FLocaleName), TextFormat)) then try if RightToLeft then TextFormat.SetReadingDirection(DWRITE_READING_DIRECTION_RIGHT_TO_LEFT) else TextFormat.SetReadingDirection(DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);
if WordWrap then TextFormat.SetWordWrapping(DWRITE_WORD_WRAPPING_WRAP) else TextFormat.SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
FillChar(TrimOptions, SizeOf(TDwriteTrimming), 0); case Trimming of TTextTrimming.None: TrimOptions.granularity := DWRITE_TRIMMING_GRANULARITY_NONE; TTextTrimming.Character: TrimOptions.granularity := DWRITE_TRIMMING_GRANULARITY_CHARACTER; TTextTrimming.Word: TrimOptions.granularity := DWRITE_TRIMMING_GRANULARITY_WORD; end;
TrimmingSign := nil; if Trimming <> TTextTrimming.None then TCanvasD2D.SharedDWriteFactory.CreateEllipsisTrimmingSign(TextFormat, TrimmingSign); TextFormat.SetTrimming(TrimOptions, TrimmingSign); TrimmingSign := nil;
if Succeeded(TCanvasD2D.SharedDWriteFactory.CreateTextLayout(PChar(Text), Text.Length, TextFormat, MaxSize.X - Padding.Left - Padding.Right, MaxSize.Y - Padding.Top - Padding.Bottom, FLayout)) then begin TextRange.StartPosition := 0; TextRange.Length := Text.Length; FLayout.SetStrikethrough(TFontStyle.fsStrikeOut in Font.StyleExt.SimpleStyle, TextRange); [b]FLayout.SetUnderline(TFontStyle.fsUnderline in Font.StyleExt.SimpleStyle, TextRange);[/b] FLayout.SetFontWeight(FontDescriptor.Weight, TextRange);
for I := 0 to AttributesCount - 1 do begin Attr := Attributes[I]; TextRange.startPosition := Attr.Range.Pos; TextRange.length := Attr.Range.Length; if Attr.Attribute.Font <> nil then begin FLayout.SetStrikethrough(TFontStyle.fsStrikeOut in Attr.Attribute.Font.StyleExt.SimpleStyle, TextRange); FLayout.SetUnderline(TFontStyle.fsUnderline in Attr.Attribute.Font.StyleExt.SimpleStyle, TextRange); if not SameValue(Attr.Attribute.Font.Size, Font.Size, TEpsilon.FontSize) then FLayout.SetFontSize(Attr.Attribute.Font.Size, TextRange);
FontDescriptor := GetFontStyles(Attr.Attribute.Font); FLayout.SetFontWeight(FontDescriptor.Weight, TextRange); FLayout.SetFontStyle(FontDescriptor.Style, TextRange); FLayout.SetFontStretch(FontDescriptor.Stretch, TextRange); FLayout.SetFontFamilyName(PChar(FontDescriptor.FamilyName), TextRange); end; if (Attr.Attribute.Color <> TAlphaColorRec.Null) and Succeeded(TCanvasD2D.SharedRenderTarget.CreateSolidColorBrush(D2Color(Attr.Attribute.Color, Opacity), nil, SolidBrush)) then FLayout.SetDrawingEffect(SolidBrush, TextRange); end;
case HorizontalAlign of TTextAlign.Center: FLayout.SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER); TTextAlign.Leading: FLayout.SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING); TTextAlign.Trailing: FLayout.SetTextAlignment(DWRITE_TEXT_ALIGNMENT_TRAILING); end; case VerticalAlign of TTextAlign.Center: FLayout.SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER); TTextAlign.Leading: FLayout.SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR); TTextAlign.Trailing: FLayout.SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_FAR); end; FLayout.GetMetrics(FMetrics) FLayout.GetOverhangMetrics(FOverhangMetrics); UpdateTextRect; end; finally TextFormat := nil; end; end; |
_________________ Windows XP: Für die einen nur ein Betriebssystem - für die anderen der längste Virus der Welt...
|
|
Th69
Beiträge: 4791
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Mi 02.02.22 12:28
Ich tippe mal auf Threadsynchronisationsprobleme.
|
|
Sinspin
Beiträge: 1334
Erhaltene Danke: 118
Win 10
RIO, CE, Lazarus
|
Verfasst: Do 03.02.22 16:58
Hallo,
wie werden die Informationen denn gesendet?
Verwendest Du dafür eventuell ein Object das zu dem Zeitpunkt nil/nicht existent sein könnte?
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
|
|
jjturbo
Beiträge: 516
Win2000 prof., WinXP prof.
D4 Stand., D5 Prof, D7 Prof, D2007 Prof.
|
Verfasst: Fr 04.02.22 10:27
Ich habe mir einen MessageHandler geschrieben, der, ähnlich wie bei VCL, Botschaften an meine Mainform schickt. Dort werden sie ausgewertet und Werte auf visuellen Komponenten ausgegeben.
Keine der Komponenten die da benutzt werden sind NIL, diese existieren bereits zur Entwurfszeit.
_________________ Windows XP: Für die einen nur ein Betriebssystem - für die anderen der längste Virus der Welt...
|
|
Sinspin
Beiträge: 1334
Erhaltene Danke: 118
Win 10
RIO, CE, Lazarus
|
Verfasst: Di 08.02.22 08:51
Die Frage ist, wenn die Nachricht ankommt, wie dann die Verarbeitung stattfindet.
Lößt dein Threadcall direkt eine Aktion im Fenster aus?
Ich mache es immer so das mein Fenster nur eine Info bekommt (nur ein Flag) und sich dann zum passenden Zeitpunkt selber kümmert die echte Nachricht abzuhohlen und auszuwerten. Das funktioniert seit Jahren in allen Programmen problemlos.
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
|
|
|