Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » VC++ / MFC » Thread

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: [ 1 ] > 2 < [ 3 ]
010
18.10.2004, 14:27 Uhr
~Susanne
Gast


Tut mir leid wenn ich dich nerve aber könntest du mir verraten wie diese Typanpassungen aussehen? Da mein Programm kein Fehler anzeigt weiß ich nicht wo ich ansetzen soll damit das setzen des Textes klappt.
Wäre nett wenn du dein Codebeispiel für mich anpassen könntest.
Dankeschön

Gruß
Susanne
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
011
18.10.2004, 16:28 Uhr
Spacelord
Hoffnungsloser Fall


Naja die bessere Lösung wäre es in der View Klasse ne Methode zu schreiben die macht was du möchtest,dann sendest du aus dem Thread nur eine benutzerdefinierte Nachricht an die View und diese reagiert mit der Methode darauf.
Ist definitiv die beste Lösung und aufgrund der sequentiellen Nachrichtenabarbeitung auch aus dem Thread heraus sicher.
Wenn du im Thread ne Variable inkrementieren möchtest musst du mit InterlockedIncrement usw. arbeiten um diese Variable sicher zu ändern.Das entfällt alles wenn du die View selbst die Arbeit verrichten lässt und das Ganze nur durch ne Nachricht anstösst.
So ähnlich wie hier:
www.fun-soft.de/showtopic.php?threadid=7941&post_start=20&time=
Ab Post 20 etwa....



Zitat:
Tut mir leid wenn ich dich nerve......



Kein Problem,wenn mich das nerven würde wäre ich ja nicht hier...
Wenn du mit dem Link oben überhaupt nicht weiter kommst kannst du dich ja wieder melden

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.

Dieser Post wurde am 18.10.2004 um 16:29 Uhr von Spacelord editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
012
18.10.2004, 16:30 Uhr
Spacelord
Hoffnungsloser Fall


Wollte eigentlich den anderen Post editieren...
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.

Dieser Post wurde am 18.10.2004 um 16:37 Uhr von Spacelord editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
013
19.10.2004, 09:26 Uhr
~Susanne
Gast


So ,hab da mal das für mich interessante herausgesucht:

C++:
HWND hDlg=(AfxGetApp()->GetMainWnd())->m_hWnd;

    //IDs der Controls:IDOK,IDCANCEL ist wohl klar
    //IDC_PROGRESS1 ist die Fortschrittsanzeige
    HWND ButtonOK = GetDlgItem(hDlg,IDOK);
    HWND ButtonCANCEL = GetDlgItem(hDlg,IDCANCEL);
    HWND Progress = GetDlgItem(hDlg,IDC_PROGRESS1);
    ShowWindow(Progress,SW_HIDE);
    ShowWindow(ButtonOK,SW_SHOW);
    ShowWindow(ButtonCANCEL,SW_SHOW);



und das in mein Programm eingesetzt. Das läuft auch wunderbar....... in einer dialogfeldbasierten Anwendung. In meiner SDI - Anwendung bekomm ich keine Fehler aber leider passiert da auch nichts.


Also ich habe eine SDI-Anwendung mit CFormView als Basisklasse wie gehabt.
In einem Fenster habe ich 2 Buttons und ein Eingabefeld. Mit den Buttons kann ich den Thread starten oder stoppen und in dem Eingabefeld wird eine Variable in jeden Threaddurchlauf hochgezählt.

Für den Anfang hab ich Versucht nur den Button verschwinden zu lassen wie ic deinem Beispiel was ja leider nicht geklappt hat.

hier mal mein Code:

Ich habe die Funktionen in PortView.h deklariert:

C++:
void Connect();
static UINT thrFunction (LPVOID pParam);



In PortView.ccp sind die Funkionen der Buttons und die Thread - Funktion hinterlegt:



C++:
void CPortView::OnBUTTON_STARTHTREAD()
{
    m_Flag = 1;
    CWinThread* pThread = AfxBeginThread (thrFunction, this);    
}            

void CPortView::OnBUTTON_STOPTHREAD()
{
     m_Flag = 0;
}



UINT CPortView:: thrFunction(LPVOID pParam)
{
    CPortView* pView = ( CPortView*) pParam;
      pView->Connect();
             return 0;
}

void CPortView::Connect()
{
  while (m_Flag)  
  {
      UINT Msg = 2;
      HWND hDlg=(AfxGetApp()->GetMainWnd())->m_hWnd;
      HWND ButtonOK = ::GetDlgItem(hDlg,IDC_BUTTON_STARTTHREAD);
               ::ShowWindow(ButtonOK,SW_HIDE);
  }
}




Vielleicht kannst du mir ja damit sagen wo mein Fehler liegt und warum es nur in einer dialogfeldbasierten Anwendung läuft. Würd das nämlich auch gern verstehen und nicht nur einfügen und läuft.......

Gruß
Susanne
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
014
19.10.2004, 09:39 Uhr
~Spacelord
Gast


Heute nachmittag mach ich mal nen kleines Beispielprojekt fertig.
Zu dem Thema wollte ich schon längst mal nen Beitrag für die FAQ geschrieben haben aber die Zeit fehlt irgendwie...

MfG Spacelord
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
015
19.10.2004, 10:45 Uhr
~Susanne
Gast


Super.
Hab auch schon gesehen das sich so einige an Threads die Zähne ausbeißen......
Mich eingeschlossen...

Gruß
Susanne
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
016
19.10.2004, 19:51 Uhr
Spacelord
Hoffnungsloser Fall


Also ich hab das Projekt fertig.
Wenn du magst kann ich dir das Ganze per Mail zuschicken.
Dann kannst du dir das ja erstmal angucken und bei den Punkten wo du Probleme hast konkrete Fragen stellen.

Die Kernfunktionalität ist aber diese:

C++:
//Die Message_Map der FormView
BEGIN_MESSAGE_MAP(CCFVthreadView, CFormView)
    //{{AFX_MSG_MAP(CCFVthreadView)
    ON_BN_CLICKED(IDC_THREAD_START, OnThreadStart)
    ON_BN_CLICKED(IDC_THREAD_STOP, OnThreadStop)
    //}}AFX_MSG_MAP
    // Standard-Druckbefehle
    ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_DIRECT, CFormView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, CFormView::OnFilePrintPreview)
    /***************************************************************
    ganz wichtig ist es diese Zeile einzufügen damit die View auf
    die Nachricht WM_USER+22 reagiert!!
    Die Zahl 22 ist übrigens willkürlich.*/

    ON_MESSAGE(WM_USER+22,OnThreadMessage)
    //**************************************************************

END_MESSAGE_MAP()



und die relevanten Methoden:

C++:
void CCFVthreadView::OnThreadStart()
{
    stillrunning=true;//stillrunning ist global als volatile bool deklariert
    AfxBeginThread (Thread,GetSafeHwnd());
}

void CCFVthreadView::OnThreadStop()
{
    stillrunning = false;
}

UINT CCFVthreadView::Thread(LPVOID param)
{
    HWND hView = (HWND)param;//Parameter wieder in ein HWND casten
    while(stillrunning)
    {
        Sleep(1000);
        //Der View die Nachricht WM_USER+22 senden
        ::PostMessage(hView,WM_USER+22,NULL,NULL);
    }
    return 0;
}


void CCFVthreadView::OnThreadMessage()
{
    //Der Thread gibt der View  nur eine Nachricht und die
    //View kann dann alles wie gewohnt machen.
    //-keine Synchronisationsprobleme!
    //-und vor allem keine Assertion Failures weil im Thread fehlerhaft
    //MFC Pointer verwendet wurden!!
    CString temp;
    temp.Format("Tach Post zum %i.",dieZahl);//dieZahl ist ein int Attribut
    m_Text.SetWindowText(temp);//m_Text ist ein Attribut vom Typ CStatic
    dieZahl++;
}




Die FormView hat 2 Button Start/Stopp und ein CStatic zur Textausgabe.Ist also in etwa so wie bei dir.
Das Prinzip ist jetzt folgendes:
Der Thread wird bei Buttondruck gestartet.
Die Threadfunktion wartet ca.1000 ms und sendet dann die Benutzernachricht WM_USER+22 an die View.Dafür nutzt der Thread das übergebene HWND und PostMessage.
Im primären Thread holt die View die Nachricht aus der Warteschlange und führt daraufhin
OnThreadMessage() aus.Die eigentliche Funktionalität stellt also die View selbst bereit.
Damit gehst du sehr vielen Problemen aus dem Weg.
Grundsätzlich gilt dass man MFC-Fenster/CDC/Menü-Objekte nur in dem Thread benutzen sollte der sie erstellt hat!
Das tust du bei dieser Lösung.

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.

Dieser Post wurde am 19.10.2004 um 19:58 Uhr von Spacelord editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
017
19.10.2004, 20:33 Uhr
Guybrush Threepwood
Gefürchteter Pirat
(Operator)



Zitat von Spacelord:
ganz wichtig ist es diese Zeile einzufügen damit die View auf
die Nachricht WM_USER+22 reagiert!!
Die Zahl 22 ist übrigens willkürlich.*/


Korrigiere mich wenn ich falsch liege aber damit sollte man Vorsichtig sein. Wenn du zufällig die ID einer anderen Nachricht erwischst könnte das ungewollte Folgen haben.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
018
19.10.2004, 20:57 Uhr
Spacelord
Hoffnungsloser Fall


In dem Bereich liegen aber keine anderen Nachrichten,ausser man hat die neue Nachricht bereits selber vergeben(das sollte man aber ja wohl unter Kontrolle kriegen ).
Falls du damit auf RegisterWindowMessage anspielst ist diese Funktion gedacht um systemweit einen garantiert eindeutige ID zu bekommen.Innerhalb der eigenen Anwendung kann mit WM_USER aber nichts schieflaufen.Wäre mir zumindest neu und auch noch nicht passiert.

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
019
19.10.2004, 21:15 Uhr
Guybrush Threepwood
Gefürchteter Pirat
(Operator)


Argh sorry hab nicht richtig gelesen

Nee mit WM_USER + X bekommst du keine Probleme da hast du schon recht.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: [ 1 ] > 2 < [ 3 ]     [ VC++ / MFC ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: