Programm reagiert nicht auf Nachricht (WM_TIMER)
-
Hi Leute, ich programmiere zu lernzweken ein kleines Moorhuhn ähnliches Prog. Ein Fadenkreutz und und eine Rechteckige Zielscheibe hab ich schon. Das Fadenkreutz bewegt sich schon ganz gut mit der Maus mit :). Die Zielscheibe soll sich im Timertackt bewegen. Leider scheint das Fenster irgendwie nicht auf den Timer zu reagieren. Wiso nicht?
Hier der Code:#include <windows.h> #include <stdlib.h> #define CX_FADENKREUTZ (cxClient/7) #define CY_FADENKREUTZ CX_FADENKREUTZ #define CX_ZIELSCHEIBE (cxClient/6) #define CY_ZIELSCHEIBE CX_ZIELSCHEIBE #define TIMER_ZIELSCHEIBE 1 LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); RECT DrawFadenkreutz(HWND, int, int); RECT DrawZielscheibe(HWND, int, int); int cxClient, cyClient; char szClassName[ ] = "WindowsApp"; int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { HWND hwnd; MSG messages; WNDCLASSEX wincl; wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; wincl.style = CS_VREDRAW|CS_HREDRAW; wincl.cbSize = sizeof (WNDCLASSEX); wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszMenuName = NULL; wincl.cbClsExtra = 0; wincl.cbWndExtra = 0; wincl.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); if (!RegisterClassEx (&wincl)) return 0; hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ "Shooter1", /* Title Text */ WS_OVERLAPPEDWINDOW, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ 544, /* The programs width */ 375, /* 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 */ ); ShowWindow (hwnd, SW_SHOW); UpdateWindow(hwnd); while (GetMessage (&messages, NULL, 0, 0)) { TranslateMessage(&messages); DispatchMessage(&messages); } return messages.wParam; } LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static RECT rectFadenkreutz, rectZielscheibe; static POINT pntFadenkreutz, pntZielscheibe; switch (message) { case WM_DESTROY: PostQuitMessage (0); break; case WM_CREATE: SetTimer(hwnd, TIMER_ZIELSCHEIBE, 1000, NULL); break; case WM_TIMER: MessageBeep(0); pntZielscheibe.x += (rand() % 10); pntZielscheibe.y += (rand() % 10); InvalidateRect(hwnd, &rectZielscheibe, TRUE); break; case WM_MOUSEMOVE: pntFadenkreutz.x = LOWORD(lParam); pntFadenkreutz.y = HIWORD(lParam); InvalidateRect(hwnd, &rectFadenkreutz, TRUE); break; case WM_PAINT: rectFadenkreutz = DrawFadenkreutz(hwnd, pntFadenkreutz.x, pntFadenkreutz.y); rectZielscheibe = DrawZielscheibe(hwnd, pntZielscheibe.x, pntZielscheibe.y); break; case WM_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); break; default: return DefWindowProc (hwnd, message, wParam, lParam); } return 0; } RECT DrawFadenkreutz(HWND hwnd, int xPos, int yPos) { HDC hdc; RECT rect; hdc = GetDC(hwnd); rect.left = xPos - CX_FADENKREUTZ/2; rect.top = yPos - CY_FADENKREUTZ/2; rect.right = xPos + CX_FADENKREUTZ/2; rect.bottom = yPos + CX_FADENKREUTZ/2; Arc(hdc, rect.left, rect.top, rect.right, rect.bottom, 0, 0, 0, 0); MoveToEx(hdc, rect.left + CX_FADENKREUTZ/2, rect.top, NULL); LineTo(hdc, rect.left + CX_FADENKREUTZ/2, rect.bottom); MoveToEx(hdc, rect.left, rect.top + CY_FADENKREUTZ/2, NULL); LineTo(hdc, rect.right, rect.top + CY_FADENKREUTZ/2); ReleaseDC(hwnd, hdc); return(rect); } RECT DrawZielscheibe(HWND hwnd, int xPos, int yPos) { HDC hdc; RECT rect; POINT pnt[5]; hdc = GetDC(hwnd); rect.left = xPos; rect.top = yPos; rect.right = xPos + CX_ZIELSCHEIBE; rect.bottom = yPos + CY_ZIELSCHEIBE; pnt[0].x = rect.left; pnt[0].y = rect.top; pnt[1].x = rect.right; pnt[1].y = rect.top; pnt[2].x = rect.right; pnt[2].y = rect.bottom; pnt[3].x = rect.left; pnt[3].y = rect.bottom; pnt[4] = pnt[0]; Polyline(hdc, pnt, 5); ReleaseDC(hwnd, hdc); return(rect); }Wenn ich bei WM_PAINT einen hdc mittels BeginPaint erstelle, und jeweils nur die hdc an die Zeichenfunktionen übergeben, funzt der timer. Leider sind dann die Zeichenfunktionen nicht wie gewünscht
.
Für eure Hilfe wäre ich Euch sehr dankbar.Gruss

-
Leider sind dann die Zeichenfunktionen nicht wie gewünscht
Dann beheb dort den Fehler. BeginPaint/EndPaint oder ValidateRect brauchst du in WM_PAINT oder du wirst nur noch mit WM_PAINT zugeballert.
-
ballermann schrieb:
BeginPaint/EndPaint oder ValidateRect brauchst du in WM_PAINT oder du wirst nur noch mit WM_PAINT zugeballert.
Vielen Dank für den Tip
Das hat mich schon weitergebracht. Mein WM_PAINT sieht nun wie folgt aus:case WM_PAINT: BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps); rectFadenkreutz = DrawFadenkreutz(hwnd, pntFadenkreutz.x, pntFadenkreutz.y); rectZielscheibe = DrawZielscheibe(hwnd, pntZielscheibe.x, pntZielscheibe.y); break;Der Timer funzt jetzt. Doch ein Problem gibt es jetzt. Das alte Rechteck (das wird ja mittels timer immer verschoben/neugezeichnet) wird nicht gelöscht. Das wundert mich jedoch, da bei WM_TIMER ja InvalidateRect() mit TRUE aufgerufen wird. Wo steckt da das Problem?
gruss

-
Es wird aber eben nur der über rectZielscheibe angegebene Bereich gelöscht und neugezeichnet...
-
es muss so aussehen:
PAINTSTRUCT ps; HDC hDC = BeginPaint(hWnd, &ps); DrawFadenkreutz(hDC, 10, 10); EndPaint(hWnd, &ps;In DrawFadenkreutz machst du GetDC und ReleaseDC ganz raus.