Canvas Does Not Allow Drawing



  • Hallo mal wieder.

    Ich hoffe, dass ihr mir weiterhelfen könnt. Ich habe folgenden Programmaufbau:

    void __fastcall (__closure *OnReceive)(HANDLE hPipe, char *buf, int BytesRead);
    
    void __fastcall TPipeServer::FOnReceive(HANDLE hPipe,char *chRequest, int cbBytesRead)
    {
    	if (OnReceive) {
    		(OnReceive)(hPipe,chRequest,cbBytesRead);
    	}
    //    MessageBox(NULL,chRequest, "", MB_OK);
    }
    //---------------------------------------------------------------------------
    

    Die Funktion FOnReceive wird in einem Thread meiner Klasse TPipeServer ausgelöst. Der Thread wurde mit CreateThread erstellt. Ich habe also (glaube ich zumindest) keinen Zugriff auf die Funktion Synchronize.
    Bei OnReceive handelt es sich um einen Funktionszeiger, der auf die Funktion mOnReceive in der VCL-Anwendung verweist.

    TPipeServer ps;
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    ps = new TPipeServer("MappsPipe");
    ps->Activate();
    ps->OnReceive = mOnReceive;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::mOnReceive(HANDLE hPipe,char *chRequest, int cbBytesRead)
    {
    //Form1->Canvas->Lock(); Funktioniert leider auch nicht :(
    ShowMessage(String(chRequest));
    }
    

    Es passiert also folgendes:
    1. Die Klasse TPipeServer wird initialisiert.
    2. Der Funktionszeiger OnReceive wird auf die Funktion mOnReceive gesetzt.
    3. In einem EIGENEN Thread wird die Pipe ausgelesen. Ist der Vorgang erfolgreich ruft der Thread die Funktion FOnReceive auf.
    4. FOnReceive soll jetzt TForm1::mOnReceive ausführen und den gelesenen Text anzeigen

    Hier liegt nun das Problem. Die Exception mit der Nachricht "Canvas does not allow drawing" wird ausgelöst. Was muss ich ändern, damit dieser Fehler nicht mehr eintritt?

    Vielen Dank,

    Mapp



  • Hallöchen!

    Hat einer von euch schonmal so etwas programmiert? Ich vermute mal, dass es sich tatsächlich um ein Synchronisationproblem zwischen MainThread und meinem externen Thread handelt.

    Wie kann ich die beiden Threads synchronisieren?

    Thx

    Mapp



  • luag mal in der Doku: hats da TCanvas::Lock() oder so
    vielleicht auch interessant ist TCriticalSection oder so wenn du selber synchronisieren willst, ausserdem TThread::Synchronize()



  • hmmm 😃

    1. TThread kann ich nicht benutzen.

    Der Thread wurde mit CreateThread erstellt. Ich habe also (glaube ich zumindest) keinen Zugriff auf die Funktion Synchronize.

    2.

    //Form1->Canvas->Lock(); Funktioniert leider auch nicht 😞

    Was mache ich falsch?
    3. Ich werde mal schauen, ob ich eine WinApi-Alternative zu TCriticalSection (vermutlich CriticalSection :)) finde.



  • TCriticalSection behebt den Fehler auch nicht. Welchen Bereich in dem Code würdet ihr denn absichern? Ich habe schon versucht entweder den Code in FOnReceive oder mOnReceive folgendermaßen abzusichern:

    TCriticalSection *cs = new TCriticalSection() // global in der Klasse TPipeServer bzw. TForm1 definiert
    
    void __fastcall Class::Funktion()
    {
    cs->Aquire();
    ShowMessage("bla");
    cs->Release();
    }
    

    Beide Versuche sind leider erfolglos geblieben.


Anmelden zum Antworten