Bitmap bewegen
-
Ich arbeite zur zeit an einem eigenen Bildschirmschoner. Dieser soll ein Bild über den Bildschirm bewegen. Nun habe ich dabei leider ein Problem:
und zwar bewegt sicher das Bild zwar am anfang ohne Probleme über den Bilschirm, aber irgendwann hört es einfach auf. Ich habe mir auch schon anzeigen lassen ob sich die X und Y pos immer schön erhöht (alle 10millisekunden) und das tuen sie auch. Nur passiert einfach nichts mehr. Hier mal der Auschnitt der die X und Y Position erhöht und das Bitmap anzeigt:
case WM_TIMER: //Bitmap laden und setzen hR4a = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_R4a)); SelectObject (hdc2, hR4a); BitBlt (hdc1, pos.X, pos.Y, 327, 240, hdc2, 0, 0, SRCCOPY) ; switch(run) { //nach Rechts bewegen case 1: if(pos.X < r-327) { pos.X = pos.X+1; } else { if(run < 5) { run += 1; InvalidateRect(hWnd, NULL, true); } else { run = 1; } } break; //nach unten bewegen case 2: if(pos.Y < u-240) { pos.Y = pos.Y+1; } else { if(run < 5) { run += 1; InvalidateRect(hWnd, NULL, true); } else { run = 1; } } break; //nach links bewegen case 3: if(pos.X > l) { pos.X = pos.X-1; } else { if(run < 5) { run += 1; InvalidateRect(hWnd, NULL, true); } else { run = 1; } } break; //nach oben bewegen case 4: if(pos.Y > o) { pos.Y = pos.Y-1; } else { if(run < 5) { run += 1; InvalidateRect(hWnd, NULL, true); } else { run = 1; } } break; } break;Kurze erklärung: Es bewgt das Bitmap in einem Rechteck mit einem abstand von 100px vom Bildschirmrand. es fängt bei der Pos x=100 und y=100 an und läuft so lange nach Rechts bis es 100px vom rechten Rand entfernt ist. Dann sollte es sich nach unten bewegen bis es vom unteren rand auch 100px entfernt ist. aber so weit kommt es nicht da es aufhört sich zu bewegen
ich hoffe ihr könnt mir helfen
mfg dimo
-
Ist denn die if-Bedingung im unten-case erfüllt? Setze doch mal einen Breakpoint auf diesen case und überprüfe die betreffenden Werte.
-
welchen case meinst du jetzt genau...der Fehler müsste doch wenn dann in diesem liegen:
//nach unten bewegen case 2: if(pos.Y < u-240) { pos.Y = pos.Y+1; } else { if(run < 5) { run += 1; InvalidateRect(hWnd, NULL, true); } else { run = 1; } } break;
-
Den mein ich. Setz doch einfach mal einen Breakpoint (Haltepunkt) an diese Stelle, gehe schrittweise (F10, F11) mit dem Debugger durch, und überprüfe Ablauf und Variableninhalte.
-
also:
pos.X erhör sich nicht muss es aber ja auch nicht
pos.Y erhöht sich immer schön weiter
run is wie es sein muss 2Nur das Bitmap bewegt sich nicht mehr. Kann das auch an was anderem liegen? Ich denke eher es liegt irgendwie daran das ich das Bitmap immer wieder neu lade, aber wenn ich das nicht mache wird es nicht angezeigt. Gibt es auch eine andere Methode das Bitmap anzuzeigen?
mfg Dimo
-
Dimo schrieb:
Ich denke eher es liegt irgendwie daran das ich das Bitmap immer wieder neu lade
Gibst Du das Bitmap auch nach Gebrauch (und vor allem VOR dem neuen Laden!) wieder frei?
Grundsätzlich: Ich denke mal, daß nur ein einziges mal Laden des Bitmaps zu Beginn (z.B. bei der Initialisierung) nötig ist. Ein ständiges Nachladen ist meiner Meinung nach unnötig.
(Ich gehe davon aus, Du redest von einem Bitmap, das immer gleich bleibt?)mfg Martin
-
Mmacher hat Recht, das ständige Bitmap-Laden ist nicht nötig (einmal bei Programmstart reicht). Btw, sieh dir mal die Doku zu SelectObject an. Die Funktion hat auch einen Rückgabewert (altes Objekt speichern, um es später wieder zu setzen...).
-
normalerweise funktioniert des auch mit dem einmal laden und immer wieder neu an zeigen, aber ich mache einen Bildschirmschoner und da funktioniert alles etwas anders. So ist das wohl auch mit dem. Es funktioniert nur wenn ich es jedesmal neu lade.
Jetzt ist noch ein problem: entweder ich finde es nicht oder es steht nicht drin, aber wie gebe ich das BITMAP wieder frei?? Dann könnte ich es mal damit versuchen.
mfg Dimo
-
Dimo schrieb:
normalerweise funktioniert des auch mit dem einmal laden und immer wieder neu an zeigen, aber ich mache einen Bildschirmschoner und da funktioniert alles etwas anders. So ist das wohl auch mit dem. Es funktioniert nur wenn ich es jedesmal neu lade.
Glaub ich nicht.
Dimo schrieb:
Jetzt ist noch ein problem: entweder ich finde es nicht oder es steht nicht drin, aber wie gebe ich das BITMAP wieder frei?? Dann könnte ich es mal damit versuchen.
Steht wohl drin, zumindest in der Doku zur Funktion. Fragt sich, wo du nachsiehst.

Microsoft schrieb:
The application must call the DeleteObject function to delete each bitmap handle returned by the LoadBitmap function.
Komplett hier:
http://msdn.microsoft.com/en-us/library/dd145033(VS.85).aspx
Sonst kriegst du wahrscheinlich irgendwann ein Problem mit dem Speicher, oder zu vielen GDI-Handles, oder wasweißich...
Und denke daran, dir die Doku zu SelectObject nochmal anzusehen (so mit altem Objekt des Typs speichern und wieder 'reinselektieren und so...).
-
also zu dem ersten...ich kanns auch net glauben aber das ein oder andere will nicht so wies normalerweise funktioniert.
zu DeleteObject: habs schon geafunden..habe es aus irgend einem Grund überlesen...musste aber leider vorher weg und hatte keine Zeit mehr des zu schreiben...werde es noch testen
mfg Dimo
-
Ständing neu Laden ist schlecht.
ich versuchs mal aus dem kopf hinzubekommen
HBITMAP hbitmap; BITMAP bmpinfo; int WINAPI WinMain(...) { CreateWindow(...) hbitmap = LoadBitmap GetObject(hbitmap, sizeof(bitmapinfo), &bitmapinfo); SetTimer(...) MessageLoop(...) } WNDPROC: WM_TIMER: const unsigned abstand = 100; switch (run % 4) { case 0: ++pos.x; run += pos.x + bmpinfo.width / 2 + abstand > width; break; case 1: ++pos.y; run += pos.y + bmpinfo.height / 2 + abstand > height; break; case 2: --pos.x; run += pos.x - bmpinfo.width / 2 - anstand > 0; break; case 3: --pos.y; run += pos.y - bmpinfo.height / 2 - abstand > 0; break; } InvalidateRect(hWnd, 0, 1); WM_PAINT PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); HDC memdc = CreateCompatibleDC(hdc); HGDIOBJ old = SelectObject(memdc, hbitmap); BitBlt(...) SelectObject(memdc, old); DeleteDC(memdc); EndPaint(hWnd, &ps);so im groben sollte das funktionieren

-
also: ich habs mit DeleteObeject versucht, aber es stoppt immer noch.
des mit dem einmal laden will ja nicht qwarum auch immer. Außerdem ist ein Bildschirmschoner anders aufgebaut wie ein normales Programm
-
Dimo schrieb:
des mit dem einmal laden will ja nicht qwarum auch immer. Außerdem ist ein Bildschirmschoner anders aufgebaut wie ein normales Programm
Ja wie machst du das denn? Zeig mal deinen Versuch!