Timer - jede sec. Fenster neu zeichnen
-
memoryleak = lochfras in der birne oder alzheimer...
wie hustbaer schon sagt, du erzeugst löcher in deinem speicher die du nicht mehr beschreiben kannst und die weiterhin bestehn bleiben.
-
Hört sich ja übel an. Aber den speicher bekomm ich ja beim neustarten bestimmt wieder.
Hat noch jmd eine idee wie ich die hässlichen striche beim neuzeichnen weg machen kann?
//EDIT: wenn ich SetTimer() bei WM_INITDIALOG rein packe startet der timer nicht.
//EDIT2: SetDCBrushColor() funktioniert auch nicht. Ich habe alle nötigen Dateien inkludiert (die die in der msdk angegeben sind) aber ich bekomme trotzdem den fehler "SetDCBrushColor' undeclared (first use this function)". Dieses Problem scheinen auch andere Leute zu haben, aber ich habe noch keine Lösung gefunden
-
Aber den speicher bekomm ich ja beim neustarten bestimmt wieder
du hast noch nicht ganz verstanden worauf das hinausläuft...
klar bekommst du den speicher sogar beim neustart deines programms wieder (mittlerweile ist windows so gut)
aber dir scheint nicht klar zu sein, das dadurch fehler im speicher innerhalb deines programmes passieren. was zum absturz bzw. seltsamen verhalten deines programes führt.
-
Das problem mit den streifen/flackern hab ich jetzt mit double-buffering gelöst, Aber SetTimer() scheint nirgendwo anders zu funktionieren als in der message-schleife wie ich es am anfang schon hatte
-
Weil du ein vermutlich ein Fenster erzeugt hast und und somit WM_CREATE als erste Nachricht ankommt - WM_INITDIALOG wird, wie der Name vermuten lässt, nur Dialogen zugesandt.
SetDCBrushColor ist erst ab Win2000 verfügbar, vor dem Inludieren von windows.h müsstest du daher _WIN32_WINNT größer oder gleich 0x0500 definieren.Und ich hoffe doch, dass das Zeichnen nun außerhalb von WM_PAINT geschieht - ich habe es schon so oft gesehen, dass Double-Buffering verwendet wurde und dass alle Maloperationen immer noch in diesem Zweig durchgeführt wurden...
-
Ich dachte man zeichnet nur innerhalb von wm_paint? Aber es funktioniert trotzdem einwandfrei. SetTimer() in wm_create zu packen hab ich auch schon probiert, hat nicht funktioniert.
-
Weiss jemand wie ich formatierten Text richtig groß anzeigen kann? Also mit richtig großer Schriftgröße, andere Textfarbe und ohne die weiße Hinterlegung wie bei Funktionen wie TextOut()?
-
ich würde mich damit mal auseinander setzen
-
Hab mir gestern schon das (englische) Kapitel über fonts durch gelesen. Dadurch konnte ich dann auch die Schrift größer machen. Leider ist da aber immernoch diese hässliche weiße Hinterlegung der Schrift. Möglicherweise könnte ich das mit einer Vector-Schrift umgehen, aber leider hab ich dazu noch nichts bei google gefunden
-
Hab noch ein ziemlich gravierendes Problem: Mein programm funktioniert nicht auf einem 2. Bildschirm, d.h. es wird dort nicht mehr neugezeichnet.
woran kann das liegen?
-
Jochen Kalmbach schrieb:
Aktiviere den Timer bitte in WM_INITDIALOG...
Die Msg-Schleife solltest Du nicht verändern!so ist es.
Und ausserdem scheint auch KillTimer an der falschen Stelle zu sein ?
-
Und WM_PAINT postet man ganz gewisslich nicht...
http://blog.m-ri.de/index.php/2007/12/24/die-unsitte-windows-interne-nachrichten-zu-versenden/
-
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