Hallo,
ich hab mich schon ein bisschen durch das Forum gewühlt auf der Suche wie man eine Nachrichtenschleife baut und diese selbst abarbeitet ohne zu großen Aufwand zu treiben.
Zum Ausgangsproblem. Ich habe mehrere Komponenten (Edits, Comboboxen etc.) diese habe ich in einem Interface gebündelt und man kann auf dessen aktuellen Wert zugreifen. Das ganze soll aber aus dem Hauptthread passieren und aus N verschiedenen anderen Threads.
Ich hatte das bis jetzt per SendMessage() gemacht, was soweit geklappt hat, aber irgendwann kam es dann zu Problemen wenn mehrere Threads darauf zugreifen.
Hier mal der Codeausschnitt:
Delphi-Quellcode:
procedure TIBasic.WndProc(var Msg: TMessage);
begin
if Msg.Msg = WM_CONTROL_VALUE_CHANGE then
begin
SetControlValue(WideString(Msg.WParam));
end
else
Msg.Result := DefWindowProc(FHandle, Msg.Msg, Msg.WParam, Msg.LParam);
end;
constructor TIBasic.Create;
begin
FHandle := AllocateHWnd(WndProc);
// [...]
end;
function TIBasic.GetValue;
begin
FValueLock.BeginRead;
try
Result := FValue;
finally
FValueLock.EndRead;
end;
end;
procedure TIBasic.SetValue(AValue: WideString);
begin
// SendMessage würde hier funktionieren
PostMessage(FHandle, WM_CONTROL_VALUE_CHANGE, Integer(AValue), 0);
end;
procedure TIBasic.ControlOnChange(Sender: TObject);
begin
FValueLock.BeginWrite;
try
FValue := GetControlValue;
finally
FValueLock.EndWrite;
end;
// [...]
end;
function TIBasic.GetControlValue;
begin
Result := FEdit.Text;
end;
procedure TIBasic.SetControlValue(AValue: WideString);
begin
FEdit.Text := AValue;
end;
Man soll (so ist es jedenfalls gedacht) per Get/SetValue auf den Wert der Komponente zugreifen können. Dazu wird für jede Komponente bei der Erstellung ein virtuelles Fenster erzeugt. Wenn sich der Wert verändert, wird über das OnChange Event der aktuelle Wert in ein string (hier: FValue) geschrieben (durch MREW gesichert). Beim lesen über GetValue wird also nicht direkt von der
VCL Komponente gelesen sondern von der FValue, was an sich ja ThreadSafe ist. Wenn jetzt jemand diesen Wert außerhalb des Eingabefeldes ändern möchte sollte dies über SetValue("Blub"); geschehen, aber das läuft noch gar nicht rund.
Da bekomme ich dann Teilweise ganz andere (von anderen Nachrichten) Werte in diese Felder, also irgendwie muss da noch was drum herum gebaut werden damit das läuft, aber da hakt es :/
Grüße