Timer - jede sec. Fenster neu zeichnen
-
Das mit WM_PAINT hab ich schon geändert, aber es stand so in einem Tutorial dads ich verwendet habe, daher habe ich es übernommen.
Seit ich die Hintergrundfarbe nur noch alle 15min verändern lasse hört das fenster einfach nach ein paar sekunden auf neu zu zeichnen. Selbst wenn ich das neuzeichnen durch z.B. minimieren und dann wieder maximieren erzwinge wird das Fenster nicht neugezeichnet.
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { const RECT* rect; static RECT drawrect; int R, G, B; int a = 1; char Zeit[9]; char Stunden[3]; int Minuten; int Sekunden; char Minutenbuf[3]; char Sekundenbuf[3]; const char TextRoteZeit[] = "Nur ShortCourse"; const char TextWeisseZeit[] = "Nur Buggys & Truggys"; const char Kein18[] = "KEIN 1:8"; int Hintergrundfarbe; //1 = weiss | 2 = rot bool eineZeit = 0; char text[3]; RECT rechteck = {0, 0, 1280, 1024}; _strtime(Zeit); strncpy(Minutenbuf, Zeit + 3, 4); //die minuten isolieren 6,7 für Sekunden! Minuten = (Minutenbuf[0] - '0') * 10 + Minutenbuf[1] - '0'; //minuten in int umwandeln _strtime(Zeit); strncpy(Sekundenbuf, Zeit + 6,7); Sekunden = (Sekundenbuf[0] - '0') * 10 + Sekundenbuf[1] - '0'; switch (message) /* handle the messages */ { case WM_DESTROY: { KillTimer(hwnd, TimerID); //Timer wieder freimachen PostQuitMessage (0); /* send a WM_QUIT to the message queue */ break; } case WM_CREATE: { SetTimer(hwnd, TimerID, 100, NULL); //timer erstellen, 1000 = milliSekunden, NULL = WM_TIMER geht an hwnd wenn der timer zu ende ist } case WM_PAINT: { PAINTSTRUCT ps; HDC hDC; hDC = BeginPaint(hwnd, &ps); HDC hDCbuffer = CreateCompatibleDC(hDC); //zweites DC zum Double-buffering um das flackern beim zeichnen weg zu machen HBITMAP bufferBMP = CreateCompatibleBitmap(hDC, 1280, 1024); //eine bitmap für's double-buffering SelectObject(hDCbuffer, bufferBMP); //auch fürs double-buffering HFONT Schriftart = CreateFont(156, 91, 0, 00, //Schriftart erstellen und größe der Buchstaben festlegen FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, //normale Schriftqualität DEFAULT_PITCH | FF_ROMAN, //Times New Roman "Times New Roman"); HFONT kleineSchriftart = CreateFont(70, 40, 0, 00, //Schriftart erstellen und größe der Buchstaben festlegen FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, //normale Schriftqualität DEFAULT_PITCH | FF_ROMAN, //Times New Roman "Times New Roman"); { HBRUSH RechteckFarben = (HBRUSH)CreateSolidBrush(RGB(100, 100, 100)); //diese farbe wenn farbwechsel nicht funktioniert if(eineZeit == 1){ RechteckFarben = (HBRUSH)CreateSolidBrush(RGB(100, 100, 100)); SetBkColor(hDCbuffer, RGB(100,100,0)); //Hintergrundfarbe des Textes ändern!!! } else if(Minuten >= 0 && Minuten < 15){ RechteckFarben = (HBRUSH)CreateSolidBrush(RGB(255, 0, 0)); //RGB farben des fensters Hintergrundfarbe = 2; //1 = weiss | 2 = rot SetBkColor(hDCbuffer, RGB(255,0,0)); //Hintergrundfarbe des Textes ändern!!! } else if(Minuten >= 15 && Minuten < 30){ RechteckFarben = (HBRUSH)CreateSolidBrush(RGB(255, 255, 255)); //RGB farben des fensters Hintergrundfarbe = 1; //1 = weiss | 2 = rot SetBkColor(hDCbuffer, RGB(255,255,255)); //Hintergrundfarbe des Textes ändern!!! } else if(Minuten >= 30 && Minuten < 45){ RechteckFarben = (HBRUSH)CreateSolidBrush(RGB(255, 0, 0)); //RGB farben des fensters Hintergrundfarbe = 2; //1 = weiss | 2 = rot SetBkColor(hDCbuffer, RGB(255,0,0)); //Hintergrundfarbe des Textes ändern!!! } else if(Minuten >= 45){ RechteckFarben = (HBRUSH)CreateSolidBrush(RGB(255, 255, 255)); //RGB farben des fensters Hintergrundfarbe = 1; //1 = weiss | 2 = rot SetBkColor(hDCbuffer, RGB(255,255,255)); //Hintergrundfarbe des Textes ändern!!! } HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, CreateSolidBrush(RGB(100,220,120))); Rectangle( //rechteck hDCbuffer, //hdcbuffer fürs double-buffering | wenn kein double-buffering -> hDC rechteck.left, //x-koordinaten der oberen linken ecke rechteck.top, //y-koordinaten der oberen linken ecke rechteck.right, //x-koordinaten der rechten unteren ecke rechteck.bottom //y-koordinaten der rechten unteren ecke ); FillRect( //rechteck einfärben hDCbuffer, //hdcbuffer fürs double-buffering | wenn kein double-buffering -> hDC &rechteck, //rect-struktur des fensters RechteckFarben //HBRUSH strukture mit den farben ); DeleteObject(SelectObject(hDC, hOldBrush)); //Objekt löschen bevor mit SelectObject ein neues ausgewählt wird DeleteObject(SelectObject(hDC, RechteckFarben)); //Objekt löschen bevor mit SelectObject ein neues ausgewählt wird SelectObject(hDCbuffer,Schriftart); //schriftart auswählen die für TextOut usw. benutzt werden soll TextOut(hDCbuffer, 250, 240, Zeit, sizeof(Zeit)-1); //hdcbuffer fürs double-buffering | wenn kein double-buffering -> hDC DeleteObject(Schriftart); //Objekt wieder freigeben, für eine neue schriftart SelectObject(hDCbuffer,kleineSchriftart); //NEUE KLEINERE auswählen die für TextOut usw. benutzt werden soll if(Hintergrundfarbe == 1) { //1 = weiss | 2 = rot TextOut(hDCbuffer, 190, 420, TextWeisseZeit, sizeof(TextWeisseZeit)-1); } else if(Hintergrundfarbe == 2) { //1 = weiss | 2 = rot TextOut(hDCbuffer, 310, 420, TextRoteZeit, sizeof(TextRoteZeit)-1); } TextOut(hDCbuffer, 450, 490, Kein18, sizeof(Kein18)-1); DeleteObject(kleineSchriftart); //Objekt wieder freigeben } BitBlt(hDC, 0, 0, 1280, 1024, hDCbuffer, 0, 0, SRCCOPY); //buffer zeichnen, alten brush überzeichnen DeleteObject(SelectObject(hDC, bufferBMP)); ReleaseDC (hwnd, hDCbuffer); //DC wieder freigeben ReleaseDC(hwnd, hDC); //DC wieder freigeben EndPaint(hwnd, &ps); break; } case WM_TIMER: { InvalidateRect(hwnd,&rechteck,TRUE); if(Minuten == 00 || Minuten == 15 || Minuten == 30 || Minuten == 45){ if(Sekunden == 00){ mciSendString("open truckhupeNEU.mp3", NULL, 0, NULL); //MUSIKDATEI ÖFFNEN GEHT AUCH MIT VIDEOS mciSendString("play truckhupeNEU.mp3 wait", NULL, 0, NULL); // MUSIKDATEI ABSPIELEN mciSendString("close truckhupeNEU.mp3", NULL, 0, NULL); //MUSIKSATEI WIEDER SCHLIESSEN } } break; } case ID_1ZEIT: eineZeit = 1; break; case ID_2ZEITEN: break; case ID_3ZEITEN: break; case ID_VERSION: { MessageBox(hwnd,"This is a beta version," "please report all bugs!", "", MB_OK); default: /* for messages that we don't deal with */ return DefWindowProc (hwnd, message, wParam, lParam); } return 0; }
-
//PUSH
-
Was solll bitte der KillTimer in der WndProc?
-
wo soll ich ihn sonst hin tun? wenn ich ihn ausserhalb hin packe wird er ja nicht aufgerufen und der Timer wird nicht mehr deaktiviert, oder hab ich da gerade einen Denkfehler?
-
Dein Problem ist doch jetzt, dass nach einigen Sekunden nichts mehr gezeichnet wird, oder? KillTimer im WM_DESTROY-Zweig ist okay, was nicht okay ist, sind die ganzen Variablendeklarationen und der Code, der bei jedem Funktionsaufruf durchlaufen wird (auch bei Mausereignissen usw.).
Du musst dir vor allen überlegen, wie du alle Objekte zerstören kannst, die du erzeugt hast:
HBRUSH RechteckFarben = (HBRUSH)CreateSolidBrush(RGB(100, 100, 100)); ... RechteckFarben = (HBRUSH)CreateSolidBrush(RGB(255, 0, 0)); ... HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, CreateSolidBrush(RGB(100,220,120))); ... DeleteObject(SelectObject(hDC, hOldBrush));
So auf jeden Fall nicht. Es stecken aber mit Sicherheit viele weitere Fehler in dem Code.
Tipp: Neuschreiben, diesmal ohne copy & paste, sondern mit Überlegung!
- DC_BRUSH nutzen
- Code nur da, wo er ausgeführt werden muss (WM_TIMER)
- einige wenig statische Variablen
- da die Schriftarten immer gleich bleiben, kannst du sie statisch deklarieren und sofort initialisieren (zerstören bei WM_DESTROY)
- ebenso die Bitmap, die bei Größenänderungen im WM_SIZE-Zweig ans Fenster angepasst werden kann
- im WM_PAINT-Zweig nur Blitten der Bitmap
- ansonsten neue Funktion im WM_TIMER aufrufen, die das Zeichnen in die Bitmap übernimmt
- ggf. sofort mit RAII arbeiten
- Überlegen und kein copy & paste aus irgendwelchen unsinnigen Tutorials
-
Naja, ich hab nie einen kurs oder was ähnliches gemacht, alles was ich darüber weiß hab ich aus Foren, Tutorials, Code-Beispielen und der msdk.
Dann werde ich nochmal neu anfangen, aber ohne fremde Hilfe wird das nix
-
Ich hab jetzt nochmal neu angefangen. Hab aber wieder ein problem: Woran kann es zum Beispiel liegen, wenn das Programm anstürzt, wenn man die mouse sehr schnell hin und her bewegt?
-
Cody227 schrieb:
Woran kann es zum Beispiel liegen, wenn das Programm anstürzt, wenn man die mouse sehr schnell hin und her bewegt?
Erwartest Du das wir raten ?
Etwas Quelltext würde helfen
-
//PROJEKT OPTIONEN -> LINKER -> libwinmm.a HINZUFÜGEN //PROJEKT OPTIONEN -> LINKER -> libgdi32.a HINZUFÜGEN #ifndef _WIN32_WINNT ////////////////////////////////////// #define _WIN32_WINNT 0x0500 //muss definiert sein, damit neuere funktionen zur verfügung stehen undzwar VOR <windows.h> #endif ////////////////////////////////////// #include <windows.h> #include <time.h> #include "header.h" ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// HWND hwnd; /* This is the handle for our window */ PAINTSTRUCT ps; HDC hDC = GetDC(hwnd); HDC hDCbuffer = CreateCompatibleDC(hDC); HBITMAP bufferBMP = CreateCompatibleBitmap(hDC, 1280, 1024); //eine bitmap für's double-buffering HFONT Schriftart = CreateFont(156, 91, 0, 00, //Schriftart erstellen und größe der Buchstaben festlegen FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, //normale Schriftqualität DEFAULT_PITCH | FF_ROMAN, //Times New Roman "Times New Roman"); HFONT kleineSchriftart = CreateFont(70, 40, 0, 00, //Schriftart erstellen und größe der Buchstaben festlegen FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, //normale Schriftqualität DEFAULT_PITCH | FF_ROMAN, //Times New Roman "Times New Roman2"); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* Declare Windows procedure */ LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); /* Make the class name into a global variable */ char szClassName[ ] = "RC GLASHAUS RACE TIMER"; int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { MSG messages; /* Here messages to the application are saved */ WNDCLASSEX wincl; /* Data structure for the windowclass */ /* The Window structure */ wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ wincl.style = CS_DBLCLKS; /* Catch double-clicks */ wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszMenuName = NULL; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ wincl.cbWndExtra = 0; /* structure or the window instance */ /* Use Windows's default color as the background of the window */ wincl.hbrBackground = (HBRUSH) GetStockObject(NULL_BRUSH); //auf null_brush setzen um flackern weg zu machen + double buffering; /* Register the window class, and if it fails quit the program */ if (!RegisterClassEx (&wincl)) return 0; /* The class is registered, let's create the program*/ hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ "RC GLASHAUS RACE TIMER", /* Title Text */ WS_OVERLAPPEDWINDOW, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ 1280, /* The programs width */ 1024, /* and height in pixels */ HWND_DESKTOP, /* The window is a child-window to desktop */ NULL, /* No menu */ hThisInstance, /* Program Instance handler */ NULL /* No Window Creation data */ ); /* Make the window visible on the screen */ ShowWindow (hwnd, nFunsterStil); SetTimer(hwnd, TimerID, 100, NULL); //timer erstellen, 1000 = milliSekunden, NULL = WM_TIMER geht an hwnd wenn der timer zu ende ist /* Run the message loop. It will run until GetMessage() returns 0 */ while (GetMessage (&messages, NULL, 0, 0)) { /* Translate virtual-key messages into character messages */ TranslateMessage(&messages); /* Send message to WindowProcedure */ DispatchMessage(&messages); } /* The program return-value is 0 - The value that PostQuitMessage() gave */ return messages.wParam; } /* This function is called by the Windows function DispatchMessage() */ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) /* handle the messages */ { case WM_DESTROY: PostQuitMessage (0); /* send a WM_QUIT to the message queue */ break; case WM_QUIT: KillTimer(hwnd, TimerID); //Timer wieder freimachen break; case WM_TIMER: InvalidateRect(hwnd,NULL,TRUE); _strtime(Zeit); //Systemzeit im char Zeit speichern strncpy(Sekundenbuf, Zeit + 6,7); //Sekunden isolieren und im char Sekundenbuf speichern | 6,7 für Sekunden | 4,5 für Sekunden | Sekunden = (Sekundenbuf[0] - '0') * 10 + Sekundenbuf[1] - '0'; //Sekundenbuf in ein int umwandeln und in int Sekunden speichern strncpy(Minutenbuf, Zeit + 3,4); //Sekunden isolieren und im char Sekundenbuf speichern | 6,7 für Sekunden | 4,5 für Sekunden | Minuten = (Minutenbuf[0] - '0') * 10 + Minutenbuf[1] - '0'; //Sekundenbuf in ein int umwandeln und in int Sekunden speichern if(Sekunden >= 0 && Sekunden < 15){ R = 255; G = 255; B = 255; } else if(Sekunden >= 15 && Sekunden < 30){ R = 255; G = 0; B = 0; } else if(Sekunden >= 30 && Sekunden < 45){ R = 255; G = 255; B = 255; } else if(Sekunden >= 45){ R = 255; G = 0; B = 0; } if((Minuten == 00) || (Minuten == 15) || (Minuten == 30) || (Minuten == 45)){ if(Sekunden == 00){ mciSendString("open truckhupeNEU.mp3", NULL, 0, NULL); //MUSIKDATEI ÖFFNEN GEHT AUCH MIT VIDEOS mciSendString("play truckhupeNEU.mp3 wait", NULL, 0, NULL); // MUSIKDATEI ABSPIELEN mciSendString("close truckhupeNEU.mp3", NULL, 0, NULL); //MUSIKSATEI WIEDER SCHLIESSEN } } break; case WM_PAINT: { hDC = BeginPaint(hwnd, &ps); SelectObject(hDCbuffer, bufferBMP); //auch fürs double-buffering SelectObject(hDCbuffer, GetStockObject(DC_BRUSH)); //alten brush auswählen damit er erneuert werden kann SetDCBrushColor(hDCbuffer,RGB(R,G,B)); //farbe des DC setzen Rectangle(hDCbuffer,0,0,1280,1024); SetBkColor(hDCbuffer, RGB(R,G,B)); //Hintergrundfarbe des Textes ändern!!! SelectObject(hDCbuffer,Schriftart); //schriftart auswählen die für TextOut usw. benutzt werden soll TextOut(hDCbuffer, 250, 240, Zeit, sizeof(Zeit)-1); SelectObject(hDCbuffer,kleineSchriftart); //NEUE KLEINERE auswählen die für TextOut usw. benutzt werden soll TextOut(hDCbuffer, 450, 490, Kein18, sizeof(Kein18)-1); if(G == 0){ TextOut(hDCbuffer, 310, 420, TextRoteZeit, sizeof(TextRoteZeit)-1); } else if(G == 255){ TextOut(hDCbuffer, 190, 420, TextWeisseZeit, sizeof(TextWeisseZeit)-1); } BitBlt(hDC, 0, 0, 1280, 1024, hDCbuffer, 0, 0, SRCCOPY); //buffer zeichnen, alten brush überzeichnen DeleteObject(kleineSchriftart); //Objekt wieder löschen gegen memoryleaks DeleteObject(Schriftart); ReleaseDC(hwnd, hDC); //DC wieder freigeben ReleaseDC(hwnd, hDCbuffer); //DC wieder freigeben EndPaint(hwnd, &ps); } default: /* for messages that we don't deal with */ return DefWindowProc (hwnd, message, wParam, lParam); } return 0; }
header.h
#include <windows.h> const char TextRoteZeit[] = "Nur ShortCourse"; const char TextWeisseZeit[] = "Nur Buggys & Truggys"; const char Kein18[] = "KEIN 1:8"; const int TimerID = 1; //ID des Timers const RECT* rect; RECT rechteck = {0,0,1280,1024}; int R,G,B; //die farben des DC_BRUSH, also hintergrundfarbe int Sekunden; //Die Sekunden der Systemzeit int Minuten; //Die Minuten der Systemzeit char Sekundenbuf[3]; //buffer für die Sekunden char Minutenbuf[3]; //buffer für die Sekunden char Zeit[9]; //Variable für die systemzeit
mittlerweile hab ich aber noch ein anderes problem: irgendwie wird nur die letzte der beiden schriftarten verwendet
-
//PUSH