Wie kann man OnPaint veranlassen Geraete Context neu zu zeichnen



  • Hallo leute!!
    Ich arbeite an einem Projekt. Genauer ich muss eine Programm für Prozessüberwachung an einer Werkzeugmaschine scheeiben.
    Also meine Programm liest die Daten von dem Maschinensensoren und muss sie dann
    an einem Bildschirm online ausgeben. Das Ausgabefenster sieht wie beim Osziloscop aus.
    Die Daten werden von einem Thread gesammelt und in einen globalen Array geschrieben , der Array wird in OnPaint ausgelesen und dann soll es gezeichne
    werden...aber das tut es nicht.
    Wie kann ich die Fkt OnPaint zum neuzeichnen veranlassen und möglichst ohne flackern. Danke!

    hier ist der code für OnPaint:

    void CPage1::OnPaint()
    	{
    
    		//	CPaintDC dc(this);
    			int nPanStyle =PS_SOLID;
    			int Width=1;
    			int Width1=2;
    			int x=0,y=0;
    
    			CRect picrect(0,0,700,300);
    
    			GetDlgItem(IDC_STATIC)->GetWindowRect(&picrect);
    
    			picrect.TopLeft().y+=7;
    		         CWnd* pLeinwand = GetDlgItem(IDC_STATIC);
                               pLeinwand->GetWindowRect(&picrect);
    			pLeinwand->GetClientRect(&picrect);
    			pLeinwandDC =pLeinwand->GetDC();
    
    			pLeinwand->Invalidate(FALSE);
    			pLeinwand->UpdateWindow();
    		         pLeinwandDC->SelectStockObject(LTGRAY_BRUSH  );
    
    			pLeinwandDC->Rectangle(&picrect);
                               pLeinwandDC->GetClipBox(picrect);
    			pLeinwand->ValidateRect(&picrect);
    
    //////////// ////////////////////////////////////////////////////////7777
    
                               COLORREF farbe= RGB (0,0,0);
    		 	COLORREF farbe1= RGB (255,255,0);
    			COLORREF farbe2= RGB (255,255,255);
    	///////////////////////////////////////////////////////////////		
    
    			CPen pen;
    		 	pen.CreatePen(nPanStyle,Width,farbe);
    		 	CPen *pOldPen =pLeinwandDC->SelectObject(&pen);
            ///////////////////////////////////////////////////////////// 
    
    		    CPoint point1;
    		    CPoint point2;
    			point2.x=0;
    			point2.y=0;
    
         	 for(int i=0;i<13;i++){
    			point2.x+=50;
    			point2.y+=300;
               	         pLeinwandDC->MoveTo(point2.x,0);
    		   	pLeinwandDC->LineTo(point2);
    			point2.y=0;
    		}
    
                               point1.x=0;
    			point1.y=0;
    
    		for(int j=0;j<5;j++){
                                point1.x+=700;
    			point1.y+=50;
                               pLeinwandDC->MoveTo(0,point1.y);
    			pLeinwandDC->LineTo(point1);
    			point1.x=0;
    
    		 }
            	                  pen.DeleteObject();
    
    			int cx=	pLeinwandDC->GetDeviceCaps(HORZRES);
    			int cy=pLeinwandDC->GetDeviceCaps(VERTRES);
    
    			CPen pen1;
    			pen1.CreatePen(nPanStyle,Width1,farbe1);
    		         CPen *pOldPen1 =pLeinwandDC->SelectObject(&pen1);
    
    		 	CPoint point;
                                point1.x=0;
    			point1.y=0;
    
    			//pLeinwandDC->SetMapMode(MM_HIMETRIC);	
                               point=myArray.GetAt(0);
    		  	pLeinwandDC->MoveTo(point);
    	////////////////////////////////////////////////////////////////////7		//i=0;
    
                             for (i=0;i<=myArray.GetUpperBound();i++){
                                  point= myArray.GetAt(i);
                                   pLeinwandDC->LPtoDP(&point);
    		           if (i==0)
    			   pLeinwandDC->MoveTo(point);
    		           else
    			   pLeinwandDC->LineTo(point);
    
    		}
                                  pLeinwandDC->SelectObject(pOldPen1);
    
     ////////////////////////////////////////////////////////////////////77
                                  pLeinwand->ReleaseDC(pLeinwandDC);
                                  pen1.DeleteObject();
    
    		}
    
    und das ist mein Thread:
    
    UINT ThreadTest(LPVOID pParam)
    {
    	CPage1* obj=(CPage1*)pParam;
         CRect picrect(0,0,700,300);
    	InitAndSetToDummy();
    	StarteDatenSammelThread();
    	while (!(*obj).threadStoppen)
    	{
    			CPoint point3;
    			float k=0;
    			float Buffer;
    			float dummy;
    			int geleseneDatensaetze=1;
    			myArray.FreeExtra();
    			myArray1.FreeExtra();
    
    			while (geleseneDatensaetze>0) {
    				geleseneDatensaetze=GetFromRingbuffer(1,&Buffer,&dummy,&dummy,&dummy,&dummy,&dummy,&dummy,&dummy);
    				myArray1.Add(Buffer);
    
    				point3.y = -1*(myArray1.GetAt(index))+150;
    				point3.x=index;
    				myArray.Add(point3);
    
    				index++;
    
    }
                                    Sleep(100);
    	}
    	StoppeDatenSammelThread();
    
    	return 0;
    }
    


  • Mit InvalidateRect geht das normalerweise, aber haste ja schon Invalidate drin 🙄



  • Ich hatte das gleiche Problem mit Daten aus der RS232. Habe mich dann für folgenden Lösungsansatz entschieden. Daten in Thread einlesen und in einer STL deque in CDoc speichern. Aus der CDoc kann man dann über CDoc::UpdateAllView() die Ansichtsklasse CView::OnDraw() zum Neuzeichen auffordern. In dieser habe ich in OnInitial() ein Speicherkontext angelegt, indem ich dann die Aktualisierungen zeichne, am Ende wird dann dieser Speicherkontext per BitBlt() in den sichtbaren Kontext von OnDraw kopiert. Wichtig ist nur, dass man beim Aufruf von UpdateAllView() den alten Inhalt nicht löscht. Bei jedenfalls ist dadurch absolut kein flackern zu erkennen.

    MfG



  • Geht das auch bei dialogbasierten Anwendung?


Anmelden zum Antworten