![]() |
Von Thread aus auf WinForm zugreifen (und Objekte ändern) ?
Guten Tag,
ich habe ein einfaches WinForm Formular, welches LEDs ethält. Diese LEDs haben die Property value (boolean) mit deren Hilfe ich sie an- und ausschalten kann. Nun möchte ich aus einem eigenen Thread auf die LEDs zugreifen und sie SICHER an- und ausschalten. Mache das mit einem Delegaten und einem Invoke auf die LED
Delphi-Quellcode:
Bin mir im Moment nich schlüssig, wie diese Zeilen auszusehen haben...und was sie bewirken:
unit LaserStateWatcherThread;
interface uses MainForm, LaserState, System.Drawing, System.Windows.Forms, Remotefunctions, System.Threading, Led; type updateDelegate = procedure(led:TLed; value : boolean) of object; TLaserStateWatcherThread = class private m_MainForm : TMainForm; m_WatcherThread : Thread; m_ThreadRunning:boolean; procedure running(); procedure safeUpdate(led:TLed; value : boolean); //procedure safeUpdate(); public constructor Create(form : TMainForm); procedure start(); procedure stop(); end; implementation constructor TLaserStateWatcherThread.Create(form : TMainForm); begin inherited Create(); m_MainForm := form; m_WatcherThread := Thread.Create(running); end; procedure TLaserStateWatcherThread.running; unsafe; var helpDelegate : updateDelegate; begin helpDelegate := &Self.safeUpdate; while (m_ThreadRunning) do begin try //Wo liegt mein Fehler in dieser Zeile: m_MainForm.LEDLaserConnected.Invoke(System.Delegate(@helpDelegate(m_MainForm.LEDLaserConnected,false))); //Compiler meldet: //[Pascal Warnung] LaserStateWatcherThread.pas(67): W1047 Unsicherer Code '@-Operator' //[Pascal Fehler] LaserStateWatcherThread.pas(67): E2036 Variable erforderlich //So war es vorher: //m_MainForm.LEDLaserConnected.value:= false; end; Thread.Sleep(1000); end; end; procedure TLaserStateWatcherThread.safeUpdate(led:TLed; value : boolean); begin led.Value := value; end; procedure TLaserStateWatcherThread.start; begin self.m_WatcherThread.Start(); m_ThreadRunning := true; end; procedure TLaserStateWatcherThread.stop; begin m_ThreadRunning := false; m_WatcherThread.Abort; end; end.
Delphi-Quellcode:
wenn ich die 2.Zeile abändere,
//Sollte stimmen:
helpDelegate := &Self.safeUpdate; //compilerfehler (wie oben beschrieben): m_MainForm.LEDLaserConnected.Invoke(System.Delegate(@helpDelegate(m_MainForm.LEDLaserConnected,false)));
Delphi-Quellcode:
compiliert der Compiler zwar, aber dann weiss meine Funktion ja nie, auf welche
m_MainForm.Invoke(System.Delegate(@helpDelegate));
LED sie zugreifen soll... Kann mir jemand helfen? gruß und danke, winx |
Re: Von Thread aus auf WinForm zugreifen (und Objekte ändern
Es gibt von Control.Invoke eine überladene Version, die auch die Argumente für den Delegaten übernimmt.
|
Re: Von Thread aus auf WinForm zugreifen (und Objekte ändern
Danke, und wie müsste ich diese dann aufrufen???
würde es so passen:
Delphi-Quellcode:
???
helpDelegate := &Self.safeUpdate;
changeLEDState(m_MainForm.LEDLaserConnected,false,helpDelegate); ... procedure TLaserStateWatcherThread.changeLEDState(led: TNWLed; value: boolean;helpDelegate:updateDelegate); var args : ArrayList; begin args := ArrayList.Create(); args.Clear; args.Add(led); args.Add(TObject(value)); led.Invoke(System.Delegate(@helpDelegate),args.ToArray); end; danke |
Re: Von Thread aus auf WinForm zugreifen (und Objekte ändern
Wie genau das in Delphi aussehen muss, weiß ich nicht. Insbesondere die Warnung "Unsicherer Code" macht mich da stutzig, aber ich habe auch kein Delphi.NET zum Nachgucken.
In C# muss grundsätzlich der Delegat instanziiert werden. Also prinzipiell eine Variable vom Typ des Delegaten (und nicht der Methode), die initialisiert wird mit einem Methodenzeiger. Und diese Variable übergibt man an Invoke. Du castest lediglich den Methodenzeiger in einen Delegaten. Ich weiß aber nicht, wie Delphi das genau handhabt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz