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!