Autor Beitrag
jjturbo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 516

Win2000 prof., WinXP prof.
D4 Stand., D5 Prof, D7 Prof, D2007 Prof.
BeitragVerfasst: Mi 02.02.22 11: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:


ausblenden 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:

ausblenden volle Höhe Delphi-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:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 02.02.22 13:28 
Ich tippe mal auf Threadsynchronisationsprobleme.
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1321
Erhaltene Danke: 117

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Do 03.02.22 17: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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 516

Win2000 prof., WinXP prof.
D4 Stand., D5 Prof, D7 Prof, D2007 Prof.
BeitragVerfasst: Fr 04.02.22 11: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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1321
Erhaltene Danke: 117

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Di 08.02.22 09: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?