Einzelnen Beitrag anzeigen

Benutzerbild von geskill
geskill

Registriert seit: 17. Feb 2007
Ort: NRW
420 Beiträge
 
Delphi 2010 Professional
 
#1

Nachrichtenschleife bauen?

  Alt 8. Okt 2012, 18:24
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
Sebastian
  Mit Zitat antworten Zitat