von Thread auf Variablen zugreifen?!?



  • Hallo,
    ich habe eine anwendung in der starte ich einen thread

    UINT thrFunc_3(LPVOID pParam)
    {
    	HWND hWnd = (HWND)pParam;
    	while(g_bCont) 
    	{
    		zahl = zahl +1;
    		SendMessage(hWnd, U_WM_BEEP, zahl, 0);
    		Sleep(1000);
    	}
    	return 0;
    }
    
    void CDlgBeepThreadDlg::OnBtnStart() 
    {
    	m_pThread = AfxBeginThread(thrFunc_3, m_hWnd);
    }
    

    jetzt hab ich schon begriffen dass es das beste ist variablen aus dem thread über SendMessage an den dialog zu geben.
    wie mache ich das jetzt wenn der thread auf variablen des dialogs zugreufen soll?

    der thread ist doch (so wie ich es oben gemacht habe) global definiert, oder?!?
    wie poste ich variablen zwischen verschiedenen Threads die in verschiedenen dialogen gestartet werden?
    wenn ich die threads immer global defniere, aber die threads in verschiedenen dialoge gestartet habe, wissen die voneinander bzw. kennen die ihre variablen und inhalte?
    danke schon mal
    Harald



  • Ich bin mir nicht sicher, aber versuchs mal so:

    hWnd->variable

    und definier die Variable in der ...Dlg.h

    ich habs bisher noch nie ausprobiert...



  • Hi,

    hier ein Beispiel für meine Thread-Funktion, die in einem CListCtrl des Dialogs nach Zellinhalten sucht, die der Benutzer im Dialog eingegeben hat.
    Hoffe das hilft etwas:

    UINT CsqalView::ThreadProc(LPVOID param)
    {
    		int nItemCount = 0; 
    		CString str = _T(""); 
    		CString find = _T("");
    		CsqalView* pSearchView = (CsqalView*) param; 
    		pSearchView->GetDlgItemText(IDC_EDIT2, find);
    		CListCtrl* pSearchListCtrl = NULL;
    		pSearchListCtrl = (CListCtrl*) pSearchView->GetDlgItem(IDC_LIST1);
    		nItemCount = pSearchListCtrl->GetItemCount();
    		for(int j=0; j<pSearchView->old_columns; j++) 
    		{
    		for(int i=0; i<nItemCount; i++)
    			{ 
    			if(semaphore == FALSE) break;
    			str = pSearchListCtrl->GetItemText(i,j); 
    					if(str == find)
    					{
    					pSearchListCtrl->EnsureVisible(i, FALSE);
    					pSearchListCtrl->SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
    					}
    			} 
    		}
    		pSearchView = NULL;
    		pSearchListCtrl = NULL;
    		return 0;
    }
    


  • danke für di antowort,
    balckviper: hWnd->variable funkioniert leider nicht,

    koreson: du hast den thread innerhalb der dialogklasse definiert nehme ich an, deswegen hast du auch zugriff auf die variablen, mein thread ist eine eben höher global definiert, deswegen funktioniert das nicht.

    gibt nicht ne möglichkeit, trotzdem auf die dialogklasse und ihre variablen zuzugreifen?
    danke



  • Hi,

    mein Thread ist schon in der Dialogklasse aber static, das wirkt sich doch so aus als wäre er global?

    Müsste auch bei dir funzen, denn ich hatte meinen auch erst global und dann wg der besseren optik 😉 als static deklariert.

    Dachte du kannst damit was anfangen

    Gruss
    koreson



  • doppelpost 🤡



  • hi koreson,
    blöde frage, woran sehe ich das dein thread statik ist?
    versteh ich nicht ganz, bin allerdings auch kein thread experte 🙂

    über welche zeilen greifst du auf deine dialog variablen zu?
    danke noch mal!



  • Hi,

    kannste nicht sehen, sorry.

    static UINT ThreadProc(LPVOID param); //Deklaration

    CsqalView* pSearchView = (CsqalView*) param; //Zeiger auf Dialog
    pSearchView->GetDlgItemText(IDC_EDIT2, find); //Zugriff auf Eingabefeld im Dialog, dessen Inhalt landet in find, dann halt weiterverarbeiten

    Das ganze ist ne FormView-Anwendung, funzt, denkt ich, auch mit normalen Dialogen.

    Probier mal etwa rum - kriegst du hin !



  • UINT myThread(LPVOID data){
     MyDialog* pDlg = (MyDialog*) data;
    
     //zugriff auf public variable oder public methode von MyDialog
     if(pDlg->IsOnline) pDlg->DoThat();
     return 0;
    }
    
    void MyDialog::OnButtonXYZ(){
    
     //starten von thread 'myThread', übergabe der eigenen dialogklasse (mit 'this')
     //damit im thread dann 'MyDialog' bekannt ist.
     AfxBeginThread(myThread, this, THREAD_PRIORITY_NORMA);
    }
    


  • hi skyp21b,
    ich bekomme leider eine access violation wenn ich deinen code versuche

    UINT CDlgBeepThreadDlg::thrFunc_3(LPVOID pParam) 
    {
    	int zahl;
    	zahl = 1;
    	int times;
    	HWND hWnd = (HWND)pParam;
    	CDlgBeepThreadDlg* pDlg = (CDlgBeepThreadDlg*) pParam;
    	times = pDlg->timesleep;
    	while(g_bCont) 
    	{
    		zahl = zahl +1;
    		::SendMessage(hWnd, U_WM_BEEP, zahl, 0);
    		Sleep(times);
    	}
    
    	return 0;
    }
    

    wenn ich diese zeile rausnehm, und den code entsprechen ändere bekomme ich keinen fehler

    times = pDlg->timesleep;
    

    ne idee?!?
    danke



  • youCanCallMeAl schrieb:

    ich bekomme leider eine access violation

    Hast du denn bei AfxBeginThread einen CDlgBeepThreadDlg* übergeben?



  • so hab ich gemacht

    m_pThread = AfxBeginThread(thrFunc_3, m_hWnd);
    

    bin mir nicht sicher ob ich versteh was du meinst.... 😕



  • Du kannst von allen Sachen die du aus deiner Applikation (App-Klasse) gestartet hast auf diese zugreifen.

    mit der Funktion AfxGetApp()

    Vielleicht nützt die das was



  • youCanCallMeAl schrieb:

    so hab ich gemacht

    m_pThread = AfxBeginThread(thrFunc_3, m_hWnd);
    

    bin mir nicht sicher ob ich versteh was du meinst.... 😕

    Das, was du bei AfxBeginThread als zweiten Parameter angibst, landet als pParam in deiner Threadfunktion. Wenn du ein HWND reingibst, und hinterher so tust, als ob es ein CDlgBeepThreadDlg* wäre, darfst du dich nicht wundern, wenn's knallt.



  • wenn ich dich richtig verstanden hab (entschuldige vorher die blöde frage :-))
    ich sollte als 2 parameter einen zeiger nicht ein handle übergeben?
    wie macht man das, bzw. ich habe irgendwo gelesen das zeiger nicht "threadsafe" wären?

    und bekomme ich durch die zeile

    CDlgBeepThreadDlg* pDlg = (CDlgBeepThreadDlg*) pParam;
    

    nicht einen zeiger auf den dialog.
    mein c++ zeigt mir bei pDlg->"alle variablen und funktionen" des dialogs an.
    greif ich drauf zu knallts....



  • youCanCallMeAl schrieb:

    ich sollte als 2 parameter einen zeiger nicht ein handle übergeben?

    Was du übergeben "sollst", hängt davon ab, was du in dem Thread brauchst.

    wie macht man das, bzw. ich habe irgendwo gelesen das zeiger nicht "threadsafe" wären?

    Ein Zeiger an sich ist erst mal gar nichts. Was du mit dem Zeiger machst, ist u.U. nicht threadsafe. Z.B. darfst du aus dem Workerthread nicht mit dem UI interagieren, aber das hast du ja offenbar nicht vor. Du holst ja nur den Member timesleep aus der Instanz.

    und bekomme ich durch die zeile

    CDlgBeepThreadDlg* pDlg = (CDlgBeepThreadDlg*) pParam;
    

    nicht einen zeiger auf den dialog.

    Du interpretierst das, was in pParam steckt, als Zeiger auf deinen Dialog. Dadurch ist es aber noch lange keiner. Dein Auto wird auch nicht zum Hubschrauber, nur weil du es sagst, es sei einer.

    Ist der Aufruf von AfxBeginThread in einer Memberfunktion von CDlgBeepThreadDlg? Dann kannst du als zweiten Parameter this übergeben, wie in sky21bs Beispiel.



  • youCanCallMeAl schrieb:

    mein c++ zeigt mir bei pDlg->"alle variablen und funktionen" des dialogs an.
    greif ich drauf zu knallts....

    ist auch völlig logisch, da deine Variable pDlg vom Typ CDlgBeepThreadDlg* ist und somit auch alle Variablen und Methoden hat. Das Problem ist der Zeiger den du castest.

    Theorethisch kannst du auch ein char* nach CDlgBeepThreadDlg* casten.

    übergebe als zweiten parameter (Beim Threadaufruf) mal den this-Zeiger

    [edit] zu langsam 😞 [/edit]



  • ok, übergebe ich den this zeiger, funktioniert der zugriff auf die dialog variablen,

    wie schaff ichs jetzt noch dass ::SendMessage(hWnd, U_WM_BEEP,0,0) funktionier?
    brauch ich den handle für sendmessage?



  • du kannst ja nun auch direkt auf die vars zu greifen.

    als parameter nutzt du pDlg->m_hWnd, wobei pDlg der gecastete this-zeiger ist



  • Doppelpost 🙂
    Nachfolgeversion ist besser..


Anmelden zum Antworten