nach gewissen Zeit Absturz der Anzeige



  • Hallo Forum

    Bin langsam am verzweifeln, das kleine Tool funktioniert soweit, nur mit der Anzeige stimmt was nicht. Nach einer gewissen Zeit und Nutzung der Buttons Malen + Gummi blockiert das Programm und der ganze Bildschirm flackert. Die Anzeige des Programms funktioniert nicht mehr.

    Liegt es an den selbstgemachten Buttons oder hab ich was übersehen, viel Grafik sodass der Speicher überläuft kann es ja kaum sein..

    Bin dankbar um jede Hilfe.

    #include <windows.h>
    #include <stdio.h> 
    #include <math.h>
    #include <string>
    
    #include <usb.h>    /* this is libusb, see http://libusb.sourceforge.net/ */
    
    #define USBDEV_SHARED_VENDOR    0x16C0  /* VOTI */
    #define USBDEV_SHARED_PRODUCT   0x05DC  /* Obdev's free shared PID */
    /* Use obdev's generic shared VID/PID pair and follow the rules outlined
     * in firmware/usbdrv/USBID-License.txt.
     */
    #define arr_len(a) (sizeof(a)/sizeof(a[0]))
    #define CMD_CHAR   0
    #define CMD_END    1
    #define CMD_CLEAR  2
    #define CMD_BLINK  3
    #define CMD_CONST  4
    #define CMD_FILE   5
    #define CMD_RUN    6
    
    #define ADR_NUL (0<<5)
    #define ADR_LAS (1<<5)
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); 
    //Deklaration der Windows-Nachrichten-Prozedur
    
    void matrix(HWND hwnd);
    void malen(HWND hwnd ,int x, int y);
    void Bild_senden();
    void Text_senden(char *data);
    void BOX(HDC hdc, int *pos, char *txt);
    void BUTTON(HDC hdc, int *pos, char *txt);
    void malebox(HDC hdc, int *pos);
    bool inbox(LPARAM lParam,int *pos);
    void c_aktiv(HWND hwnd,int *pos);
    void b_aktiv(HWND hwnd,int *pos);
    void inaktiv(HWND hwnd,int *pos);
    void Highbutton(HWND hwnd,int *pos);
    void Bild_datei(HWND hwnd);
    //static int  usbGetStringAscii(usb_dev_handle *dev, int index, int langid, char *buf, int buflen);
    //static int  usbOpenDevice(usb_dev_handle **device, int vendor, char *vendorName, int product, char *productName);
    
    //Typbezeichnung 
    //DO 0  Linke Maustaste 1 - Klick
    
    int Do = 0;
    int trix[32] = {0};
    int nBytes ;
    RECT rect;
    usb_dev_handle      *handle = NULL;
    int MAT[4]   = {15,15,529,145};
    int BLINK[5] = {300, 162, 315, 177,0};
    int LED[5]   = {300, 192, 315, 207,0};
    int RUN[5]   = {300, 222, 315, 237,0};
    /*
    struct button FLASH = {16,280,116,310,"Flashen",0};
    */
    int FLASH[5]  = {16 ,280, 116, 305,0};
    int MALEN[5]  = {16 ,160, 116, 185,0};
    int GUMMI[5]  = {16 ,190, 116, 215,0};
    int LOESCH[5] = {16 ,250, 116,275,0};
    int SENDEN[5] = {16 ,280, 116,305,0};
    int TEXT[5]   = {160,190, 260,215,0};
    int DATEI[5]  = {16, 330, 116,355,0};
    int CDATEI[5] = {16, 360, 116,385,0};
    int VDATEI[5] = {16, 390, 116,415,0};
    
    const HPEN redRa  = CreatePen( PS_SOLID,1,RGB(139,0,0)); // Linientyp,Dicke,Farbwert;
    const HBRUSH rot  = CreateSolidBrush(RGB(255, 48, 48));
    const HPEN aktiv  = CreatePen( PS_SOLID,4,RGB(230,56,56));
    const HPEN hgrau2 = CreatePen( PS_SOLID,2,RGB(181,181,181) ); // Linientyp,Dicke,Farbwert;
    const HPEN mgrau = CreatePen( PS_SOLID,1,RGB(38,38,38) ); // Linientyp,Dicke,Farbwert
    const HBRUSH schwarz = CreateSolidBrush(BLACK_BRUSH);
    const HBRUSH blau = CreateSolidBrush(RGB(63,63,92));
    const HPEN hgrau1 = CreatePen( PS_SOLID,1,RGB(181,181,181) );
    

    Standard WinMain

    int WINAPI WinMain (HINSTANCE hI, HINSTANCE hPrI, PSTR szCmdLine, int iCmdShow)
    {
    /*
    usb_init();
    if(usbOpenDevice(&handle, USBDEV_SHARED_VENDOR, "bjn", USBDEV_SHARED_PRODUCT, "Test") != 0){
            fprintf(stderr, "Kann den USB Anschluss nicht finden vid=0x%x pid=0x%x\n", USBDEV_SHARED_VENDOR, USBDEV_SHARED_PRODUCT);
            exit(1);
    }
    */
    
    static char szName[] = "Fensterklasse";
    WNDCLASS wc;
    
    wc.style         = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;   // Neuzeichnen
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hI;
    wc.hIcon         = LoadIcon (NULL, IDI_WINLOGO);
    wc.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // Hintergrundfarbe
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = szName;
    
    RegisterClass (&wc);
    
    HWND hwnd = CreateWindow (szName, "Matrix -> AVR", WS_OVERLAPPEDWINDOW, 
                              250, 250, 550, 500, NULL, NULL, hI, NULL);
    
    ShowWindow   (hwnd, iCmdShow);
    UpdateWindow (hwnd);
    
    // Nachrichten-Schleife
    MSG msg;
        while (GetMessage (&msg, NULL, 0, 0)>0)
        {
            TranslateMessage (&msg);
            DispatchMessage (&msg);
        }
    return msg.wParam;
    }
    
    // Windows-Nachrichten-Prozedur
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    HFONT Arial = CreateFont(18, 0, 0, 0, 0, FALSE, 0, 0, 0, 0, 0, 0, 0, "Arial");
    //HDC hdc;
    static HWND Ltext , tempo;
    int j;
    
    switch (message)
    {
    int x;
    int y;
    case WM_PAINT:
        matrix (hwnd);
        return 0;       
    
    case WM_CREATE :  // Schaltflächen erzeugen
        Ltext = CreateWindow ( "edit", "Hier text",
                                       WS_CHILD | WS_VISIBLE, 
                                       160, 160, 100, 20, 
                                       hwnd, (HMENU)5,(HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE), NULL);
        SendMessage(Ltext, WM_SETFONT, (WPARAM)Arial, MAKELPARAM(FALSE, 0));
        tempo = CreateWindow ( "edit", "500",
                                       WS_CHILD | WS_VISIBLE, 
                                       16, 420, 100, 20, 
                                       hwnd, (HMENU)5,(HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE), NULL);
        SendMessage(tempo, WM_SETFONT, (WPARAM)Arial, MAKELPARAM(FALSE, 0));
        return 0 ;
    
    case WM_COMMAND:  // Befehle der Wurzel Schaltflächen abfangen
          switch(LOWORD(wParam)) { 
              case 5:  //Text senden
                   break;
          } 
         return 0;
    
    case WM_DESTROY:  // Exit
        PostQuitMessage (0);
        return 0;
    
    case WM_LBUTTONDOWN:             //linke Maustaste
          Do |=  (1<<0);
          if (inbox(lParam,MAT)){
               malen(hwnd,LOWORD(lParam), HIWORD(lParam));
               //nBytes = usb_control_msg(handle, USB_TYPE_VENDOR, CMD_BLINK, BLINK[4], 0, (char *)buffer, sizeof(buffer), 5000);
          }else if (inbox(lParam,BLINK)){
               c_aktiv(hwnd,BLINK);
               //nBytes = usb_control_msg(handle, USB_TYPE_VENDOR, CMD_BLINK, BLINK[4], 0, (char *)buffer, sizeof(buffer), 5000);
          }else if(inbox(lParam,LED)){
               c_aktiv(hwnd,LED);
               //nBytes = usb_control_msg(handle, USB_TYPE_VENDOR, CMD_CLEAR, LED[4], 0, (char *)buffer, sizeof(buffer), 5000);
          }else if(inbox(lParam,RUN)){
               c_aktiv(hwnd,RUN);
               //nBytes = usb_control_msg(handle, USB_TYPE_VENDOR, CMD_RUN, RUN[4], 0, (char *)buffer, sizeof(buffer), 5000);
          }else if(inbox(lParam,FLASH)){
                //b_aktiv(hwnd,FLASH);
          }else if(inbox(lParam,MALEN)){
                inaktiv(hwnd,GUMMI);
                b_aktiv(hwnd,MALEN);
                Do |=  (1<<1);
          }else if(inbox(lParam,GUMMI)){
                inaktiv(hwnd,MALEN);
                b_aktiv(hwnd,GUMMI);
                Do &= ~(1<<1);
          }else if(inbox(lParam,LOESCH)){
                Do = 0;
                for(j=0;j<32;j++){
                   trix[j] = 0;                  
                }
                SetRect(&rect, MAT[0],MAT[1],MAT[2],MAT[3]);
                InvalidateRect(hwnd,&rect,TRUE); // Löschenhwnd,Rechteck,Darauf wird dann ein WM_PAINT ausgelöst.
          }else if(inbox(lParam,SENDEN)){
                Bild_senden();
          }else if(inbox(lParam,TEXT)){
               int iLenght ; 
               char *buffer;
               iLenght = GetWindowTextLength(Ltext); 
               buffer = new char[iLenght+1]; 
               GetWindowText(Ltext,buffer ,iLenght+1);
               //MessageBox(NULL,buffer,buffer,1);
               Text_senden(buffer);
          }else if(inbox(lParam,RUN)){
                //nBytes = usb_control_msg(handle, USB_TYPE_VENDOR, CMD_RUN, RUN[4], 0, (char *)buffer, sizeof(buffer), 5000);
          }else if(inbox(lParam,DATEI)){
                FILE *f;
                int i;
                f = fopen ("matrix.txt","a");
                if (f!=NULL)
                     for(i=0;i<arr_len(trix);i++){
                         char str[3];
                         sprintf(str,"%d,",trix[i]);
                         //MessageBox(NULL,str,NULL,1);
                         fputs(str, f);
                     }
                fclose (f);
                Bild_datei(hwnd);
          }else if(inbox(lParam,CDATEI)){
               FILE *f;
               if(f!=NULL)
                     f = fopen ("matrix.txt","w"); 
               fclose(f);
          }else if(inbox(lParam,VDATEI)){
    
           //OK
          }
          return 0; 
     case WM_LBUTTONUP:
          Do &= ~(1<<0);
          return 0;
     case WM_MOUSEMOVE:           //Mausbewegungen
          malen(hwnd ,LOWORD(lParam), HIWORD(lParam));                      
          return 0;
    
    }
    
    return DefWindowProc (hwnd, message, wParam, lParam);
    }
    

    Funktionen

    void matrix(HWND hwnd){
        PAINTSTRUCT ps;
        HDC  hdc = BeginPaint (hwnd, &ps);
        SelectObject (hdc,hgrau2);
        SelectObject (hdc,schwarz);
        malebox(hdc,MAT);
    
        SelectObject (hdc,mgrau);
        int i;
        for(i=2;i<33;i++){
           MoveToEx( hdc, 16*i  , 17, NULL );  //Linie von
           LineTo(   hdc, 16*i, 143 );        //nach                                      
        }
        for(i=2;i<9;i++){
           MoveToEx( hdc, 17  , 16*i, NULL );  //Linie von
           LineTo(   hdc, 527, 16*i );        //nach                                       
        }   
        BOX(hdc, BLINK, "Led blinken");
        BOX(hdc, LED, "Led Off / On");
        BOX(hdc, RUN, "Lauftext");
        BUTTON(hdc,FLASH,"Flashen");
        BUTTON(hdc,MALEN,"Malen");
        BUTTON(hdc,GUMMI,"Gummi");
        BUTTON(hdc,LOESCH,"Löschen");
        BUTTON(hdc,SENDEN,"Ansehen");
        BUTTON(hdc,TEXT,"Text senden");
        BUTTON(hdc,DATEI,"In Datei");
        BUTTON(hdc,CDATEI,"Datei löschen");
        BUTTON(hdc,VDATEI,"Datei ansehen");
        EndPaint (hwnd, &ps);
    }
    
    void malen(HWND hwnd ,int x, int y){
        if ((Do&1)&&(x>16)&&(x<528)&&(y>16)&&(y<144)) {
              x=(int)floor((x-1)/16)*16+3;
        	  y=(int)floor((y-1)/16)*16+3;                                  
              if(MALEN[4]){  
                    HDC hdc = GetDC(hwnd);
                    SelectObject (hdc,rot);
                    SelectObject (hdc,redRa);
                    Ellipse(hdc, x,y,x+12,y+12); 
                    trix[x/16-1] |= (1<<(8-(y/16))); 
                    ReleaseDC(hwnd, hdc);
              }else if(GUMMI[4]){
                    RECT rt;
                    SetRect(&rt, x,y,x+16,y+16);
                    InvalidateRect(hwnd,&rt,TRUE);    
                    trix[x/16-1] &= ~(1<<(8-(y/16)));
              }
    
          }     
    }
    
    void Bild_senden(){
    int i ;
    unsigned char       buffer[8];
        for(i=0;i<arr_len(trix);i++){
            //nBytes = usb_control_msg(handle, USB_TYPE_VENDOR, CMD_FILE, trix[i], 0, (char *)buffer, sizeof(buffer), 5000);
        }
            //nBytes = usb_control_msg(handle, USB_TYPE_VENDOR, CMD_END, 0, 0, (char *)buffer, sizeof(buffer), 5000);
    
    }
    
    void Text_senden(char *data){
        unsigned short i ,value , index ;
        unsigned char       buffer[8];
        while(*data){ 
                value = *data++;
                if(*data){
                     index = *data++;
                }else{
                     index = 0;
                }
                //nBytes = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CMD_CHAR, value, index, (char *)buffer, sizeof(buffer), 5000);              
            }
            //nBytes = usb_control_msg(handle, USB_TYPE_VENDOR, CMD_END, 0, 0, (char *)buffer, sizeof(buffer), 5000);
    }
    
    //Zeichnet ein Checkbox mit Text
    void BOX(HDC hdc, int *pos, char *txt){
        malebox(hdc,pos);
        RECT rt;
        SetRect(&rt, pos[0]+24, pos[1], pos[2]+95, pos[3]+3);
        SetBkColor(hdc, RGB(0,0,0));
        SetTextColor(hdc, RGB(181,181,181));
        DrawText(hdc, txt, lstrlen(txt), &rt, DT_SINGLELINE | DT_LEFT); 
    }
    
    void BUTTON(HDC hdc, int *pos, char *txt){
        SelectObject (hdc,blau);
        SelectObject (hdc,hgrau1);
        Rectangle(hdc, pos[0],pos[1],pos[2],pos[3]); 
        RECT rt;
        SetRect(&rt, pos[0], pos[1]+5, pos[2], pos[3]);
        SetBkMode(hdc,TRANSPARENT);
        SetTextColor(hdc, RGB(255,255,255));
        DrawText(hdc, txt, lstrlen(txt), &rt, DT_SINGLELINE | DT_CENTER); 
    }
    
    void malebox(HDC hdc, int *pos){
        Rectangle(hdc, pos[0],pos[1],pos[2],pos[3]); 
    }
    
    bool inbox(LPARAM lParam, int *pos){
        int x = LOWORD(lParam);
        int y = HIWORD(lParam);
        if ((x>pos[0])&&(x<pos[2])&&(y>pos[1])&&(y<pos[3]))
             return TRUE;
        else
             return FALSE;         
    }
    
    void c_aktiv(HWND hwnd,int *pos){
    
           if(pos[4]){
               RECT rt;
               SetRect(&rt, pos[0],pos[1],pos[2],pos[3]);
               InvalidateRect(hwnd,&rt,TRUE); 
               pos[4] = 0;    
           }else{
               HDC hdc = GetDC(hwnd);
               SelectObject (hdc,rot);
               SelectObject (hdc,redRa);
               Ellipse(hdc, pos[0]+2,pos[1]+2,pos[2]-2,pos[3]-2);
               ReleaseDC(hwnd, hdc); 
               pos[4] = 1;                                                                       
           }
    
    }
    
    void b_aktiv(HWND hwnd,int *pos){
    
           if(pos[4]){
               RECT rt;
               SetRect(&rt, 16,150,300,300);
               InvalidateRect(hwnd,&rt,TRUE); 
               pos[4] = 0;    
           }else{
               HDC hdc = GetDC(hwnd); 
               SelectObject (hdc,aktiv);
               MoveToEx( hdc, pos[0]+3,pos[1]+2,NULL); 
               LineTo  ( hdc, pos[0]+3, pos[3]-2 );                                                                     
               ReleaseDC(hwnd, hdc); 
               pos[4] = 1; 
           }
    
    }
    
    void inaktiv(HWND hwnd,int *pos){
        RECT rt;
           if(pos[4]){
               SetRect(&rt, 16,150,300,300);
               InvalidateRect(hwnd,&rt,TRUE); 
               pos[4] = 0;                                                                          
           } 
       UpdateWindow(hwnd);   
    }
    
    void Bild_datei(HWND hwnd){
         int c,z;
         z=0;
         RECT rt;
         HDC hdc = GetDC(hwnd);
         SetBkColor(hdc, RGB(0,0,0)); 
         SetTextColor(hdc, RGB(181,181,181));
          FILE *f;
                f = fopen ("matrix.txt","r");
                if (f!=NULL){
                     while ((c = fgetc(f)) != EOF ){
                          if (c == ','){ 
                                z++;
                          }
                     }
                char buffer[25];
                sprintf(buffer,"Datei hat %d Bilder",z/32);
                SetRect(&rt, 16,400,400,420);
                DrawText(hdc, buffer, lstrlen(buffer), &rt, DT_SINGLELINE | DT_CENTER);
                }
                fclose (f);
         ReleaseDC(hwnd, hdc);  
    }
    


  • Bitte editiere deinen Beitrag, sodass die [cpp]-Tags auch ihre Wirkung zeigen können. Am besten schränkst du das Problem dann auch gleich etwas ein, denn so viel Code wird sich wohl kaum einer gründlich durchlesen.



  • cooky451 schrieb:

    Am besten schränkst du das Problem dann auch gleich etwas ein, denn so viel Code wird sich wohl kaum einer gründlich durchlesen.

    Hier liegt das Problem, kann mir nicht erklären woher dieses Anzeigeproblem kommt.

    Benutze den DevCC



  • HFONT Arial = CreateFont(18, 0, 0, 0, 0, FALSE, 0, 0, 0, 0, 0, 0, 0, "Arial");
    

    ...da würde ich HFONT Arial static machen und CreateFont nur 1x in der WM_CREATE aufrufen.
    Beobachte mal im Taskmanager die Zahl bei der Spalte "GDI-Objekte"



  • SelectObject() wird falsch verwendet -> msdn



  • ..__--_ schrieb:

    SelectObject() wird falsch verwendet -> msdn

    Inwiefern? Dass das alte Objekt nicht gespeichert und anschließend nicht in den Kontext zurück gewählt wird ist zwar etwas unschön, aber dürfte nicht zu besagtem Fehler führen.
    geeky's Antwort ist schon richtig, ich habe mir gestern abend den Code angeschaut, dies aber nicht gesehen (schiebe ich mal auf die fehlenden cpp-Tags 😃 )
    Du kannst auch einfach nur ein static davor schreiben:

    static HFONT Arial = CreateFont(18, 0, 0, 0, 0, FALSE, 0, 0, 0, 0, 0, 0, 0, "Arial");
    

    ->Arial wird beim ersten Aufruf von WndProc konstuiert, ein DeleteObject im WM_DESTROY-Zweig wäre auch noch schön.
    Außerdem:

    buffer = new char[iLenght+1];
    

    buffer wird nicht wieder freigegeben. Wenn du schon C++ nutzt kannst du auch schreiben:

    std::vector<char> buffer(iLenght+1);
    

    und die C-Schnittstellen der WinApi per &buffer[0] nutzen. Um die Freigabe brauchst du dir dann keine Gedanken zu machen.
    Auch kannst du RAII an anderen Stellen nutzen:

    template<class T> class WindowsObject
    {
    public:
    	WindowsObject(T f=0):m_h(f) {}
    	WindowsObject& operator=(const WindowsObject& rhs)
    	{
    		DeleteObject(m_h);
    		m_h = rhs.reset();
    		return *this;
    	}
    	~WindowsObject() {delobj();}
    	void delobj() {DeleteObject(m_h); m_h=0;}
    	void Set(T h) {delobj();m_h=h;}
    	T reset() const {T h=m_h;m_h=0;return h;}
    	const T& operator *() const {return m_h;}
    private:
    	WindowsObject(const WindowsObject&);
    	mutable T	m_h;
    };
    

    Die Schrift könnte dann so konstruiert werden:

    static WindowsObject<HFONT> Arial(CreateFont(18, 0, 0, 0, 0, FALSE, 0, 0, 0, 0, 0, 0, 0, "Arial"));
    


  • Hii geeky

    geeky schrieb:

    HFONT Arial = CreateFont(18, 0, 0, 0, 0, FALSE, 0, 0, 0, 0, 0, 0, 0, "Arial");
    

    ...da würde ich HFONT Arial static machen und CreateFont nur 1x in der WM_CREATE aufrufen.
    Beobachte mal im Taskmanager die Zahl bei der Spalte "GDI-Objekte"

    Mensch, das wars. Die GDI Objekten gingen in die tausend hoch und mit der kleinen Änderung bleiben Sie bei 29 und der Bildschirmabsturz ist gelöst.

    An so kleinen Detail schlag ich mir die Zähne aus. .-}

    SelectObject() wird falsch verwendet -> msdn

    Muss das sein, auch wenn man den alten Stift nicht zurück will?

    Noch eine allgemeine Frage, die Buttonlösung habe ich mir so ausgedacht. Gibt es da andere einfache Ansätze. Die Standard Buttons sehen nicht gerade berauschend aus.

    Vielen Dank für die Hilfe



  • Wenn man sich nicht mal simpelste Vorgaben halten will, dann sollte man sich später auch nicht über komische Fehler wundern - es ist definitiv Falsch wie SelectObject() hier verwendet wird!


Anmelden zum Antworten