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/)
-   -   Delphi Event verursacht Riched32.dll Exception (https://www.delphipraxis.net/142586-event-verursacht-riched32-dll-exception.html)

Alois 30. Okt 2009 22:50


Event verursacht Riched32.dll Exception
 
Hallo ich habe eine ActiveX-Komponente die in unregelmässigen Abständen Events abfeuert.

In meinem Projekt greift der Event auf das RichEdit-Objekt wie folgt zu:
Delphi-Quellcode:
procedure TForm1.AddLog(s: String);
begin
  Log.SelStart := Log.GetTextLen;
  Log.SelText := '[' + TimeToStr(Time) + '] ' + s + #13 + #10;
end;
Mit dieser Prozedur kommt es zu unregelmässigen Application Exceptions.


Erstaunlicherweise nehmen die Abbrüche ab, wenn ich folgendes als RichEdit-Ereignis einfüge:
Delphi-Quellcode:
procedure TForm1.LogChange(Sender: TObject);
begin
  Log.Perform(EM_SCROLLCARET, 0, 0); // Autoscroll Funktion für das RichEdit
end;
Wie geht man richtig vor um einen Text in das RichEdit-Fenster zu schreiben?

Gruss Alois ;)

himitsu 30. Okt 2009 22:57

Re: Event verursacht Riched32.dll Exception
 
Wie und was für Events sind das?

Laufen dieses im Kontext des Hauptthreads ab?
Wenn nicht, rufst du diese Prozedur synchronisiert auf? (threadsicher)

...

Lannes 30. Okt 2009 22:57

Re: Event verursacht Riched32.dll Exception
 
Hallo,

Delphi-Quellcode:
RichEdit.Lines.Add('[' + TimeToStr(Time) + '] ' + s);
Ich glaube nicht das die Application Exceptions in dem von Dir geposteten Code begründet sind.

Bernhard Geyer 31. Okt 2009 08:32

Re: Event verursacht Riched32.dll Exception
 
Bei solchen unerklärlichen Probleme hilft es ab un zu sich die Daten des Events zu merken und sich dann per PostMessage mit User-Message-Id sich selbst ein Event zu geben und dann dort die nachricht zu bearbeiten. Ist dann der Fall wenn man durch Aktionen im Event ansonsten den Aufrufstack "beschädigen" würde (z. B. Freigabe von Elementen welche das Event ausgelöst haben).

Alois 31. Okt 2009 12:37

Re: Event verursacht Riched32.dll Exception
 
Zitat:

Zitat von himitsu
Laufen dieses im Kontext des Hauptthreads ab?
Wenn nicht, rufst du diese Prozedur synchronisiert auf? (threadsicher)

Nein sie werden von der ActiveX Komponente gesteuert und laufen nicht threadsicher ab.

Zitat:

Zitat von Lannes
RichEdit.Lines.Add('[' + TimeToStr(Time) + '] ' + s);

Gibt es das gleiche Problem.



@Bernhard Geyer: Ja, über die Lösung über PostMessage habe ich schon gelesen. Ich weiss aber nicht wie man folgende Befehle an das RichEdit-Objekt sendet:
Delphi-Quellcode:
Log.SelAttributes.Color := clBlack;
Log.SelStart := Log.GetTextLen;
Log.SelText := '[' + TimeToStr(Time) + '] ' + s + #13 + #10;
Gibt's dafür ein Beispiel?

Gruss Alois ;)

Alois 31. Okt 2009 13:58

Re: Event verursacht Riched32.dll Exception
 
Hi,

ich konnte mein Problem inzwischen selber lösen.

Delphi-Quellcode:
const
  WMWriteLog = WM_USER + 101;

type
  TForm1 = class(TForm)
    procedure ReadWMWriteLog(var Msg: TMessage);
    message WMWriteLog;
    ...
  private
    { Private declarations }
  public
    { Public declarations }
  end;

procedure TForm1.AddLog(s: String);
var
  wParam: Word;
begin
  wParam := GlobalAddAtom(PChar(s));
  PostMessage(Self.Handle, WMWriteLog, wParam, 0);
end;

procedure TForm1.ReadWMWriteLog(var Msg: TMessage);
var
  Buffer: PChar;
  s: string;
begin
  Buffer := nil;
  try
    s := '';
    GetMem(Buffer, 255);
    if GlobalGetAtomName(Msg.wParam, Buffer, 255) > 0 then
      s := StrPas(Buffer);

    Log.SelStart := Log.GetTextLen;
    Log.SelText := '[' + TimeToStr(Time) + '] ' + s + #13 + #10;
  finally
    GlobalDeleteAtom(Msg.wParam);
    FreeMem(Buffer);
  end;
end;
Gruss Alois ;)

himitsu 31. Okt 2009 14:09

Re: Event verursacht Riched32.dll Exception
 
Delphi-Quellcode:
const
  WM_ADDMESSAGE = WM_USER + 1;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
    _CS: TRTLCriticalSection;
    _SL: TStrings;
    procedure WMAddMessage(var Message: TMsg); message WM_ADDMESSAGE;
  public
    { Public-Deklarationen }
    procedure AddLog(const S: String);
  end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  InitializeCriticalSection(_CS);
  _SL := TStringList.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  _SL.Free;
  DeleteCriticalSection(_CS);
end;

procedure TForm1.WMAddMessage(var Message: TMsg);
begin
  EnterCriticalSection(_CS);
  try
    Log.SelAttributes.Color := clBlack;
    Log.SelStart := Log.GetTextLen;
    Log.SelText := _SL.Text;
    _SL.Clear;
  finally
    LeaveCriticalSection(_CS);
  end;
end;

procedure TForm1.AddLog(const S: String);
begin
  EnterCriticalSection(_CS);
  try
    _SL.Add('[' + TimeToStr(Time) + '] ' + s);
  finally
    LeaveCriticalSection(_CS);
  end;
  PostMessage(Handle, WM_ADDMESSAGE, 0, 0);
end;
und von extern dann AddLog aufrufen

Alois 31. Okt 2009 14:12

Re: Event verursacht Riched32.dll Exception
 
Hi @himitsu,
das mit den CriticalSection kannte ich bisher auch noch nicht. Vielen Dank für das Beispiel :cheers:

Gruss Alois ;)

himitsu 31. Okt 2009 14:15

Re: Event verursacht Riched32.dll Exception
 
Es gibt auch noch die Klasse TCriticalSection, aber ich arbeite aus Gewohnheit lieber mit dieser Variante aus der Unit Windows.
(in der Unit SyncObjs sind auch noch andere nette Dinge drin)

PS: die Zeit hatte ich absichtlich in der Add-Methode schon zuaddiert, damit dieses die Zeit des Hinzufügens ist und nicht die Zeit, wo die GUI sich endlich mal im diese Message kümmerte :)

Alois 31. Okt 2009 14:34

Re: Event verursacht Riched32.dll Exception
 
Zitat:

Zitat von himitsu
Die Zeit hatte ich absichtlich in der Add-Methode schon zuaddiert, damit dieses die Zeit des Hinzufügens ist und nicht die Zeit, wo die GUI sich endlich mal im diese Message kümmerte :)

Das sehe ich genau so. Danke für den Hinweis. :cyclops:

Gruss Alois ;)


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