Kleines Problem bei C++ und WinAPI

Gast #2521660
Lesenswert?

Hallo, ich bin dabei, mich ein bisschen in die Themen C++, speziell mit 
der WinAPI einzulesen und habe folgendes Programm zum testen 
geschrieben.

Was kann ich machen, dass sich die beiden Kreise nicht selber übermalen?

Mfg
1
#include <windows.h>
2
#include <math.h>
3

4
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
5

6
#define ID_ERSTER_TIMER 1
7

8
wchar_t szAppName[] = L"Ball 'n rollin'";
9

10
int fahrt_v1 = 5;
11
int fahrt_h1 = 5;
12

13
int fahrt_v2 = 5;
14
int fahrt_h2 = 5;
15

16
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
17
{
18
  MSG      msg;
19
  HWND    hWnd;
20
  WNDCLASS  wc;
21

22
  wc.cbClsExtra    = 0;
23
  wc.cbWndExtra    = 0;
24
  wc.hbrBackground  = (HBRUSH) GetStockObject(WHITE_BRUSH);
25
  wc.hCursor      = LoadCursor(NULL, IDC_CROSS);
26
  wc.hIcon      = LoadIcon(NULL, IDI_APPLICATION);
27
  wc.hInstance    = hInstance;
28
  wc.lpfnWndProc    = WndProc;
29
  wc.lpszClassName  = szAppName;
30
  wc.lpszMenuName    = NULL;
31
  wc.style      = CS_HREDRAW | CS_VREDRAW;
32

33
  RegisterClass(&wc);
34

35
  hWnd = CreateWindow( szAppName,
36
             szAppName,
37
             WS_OVERLAPPEDWINDOW,
38
             CW_USEDEFAULT,
39
             CW_USEDEFAULT,
40
             CW_USEDEFAULT,
41
             CW_USEDEFAULT,
42
             NULL,
43
             NULL,
44
             hInstance,
45
             NULL);
46

47
  ShowWindow(hWnd, iCmdShow);
48
  UpdateWindow(hWnd);
49

50
  while(GetMessage(&msg, NULL, 0, 0))
51
  {
52
    TranslateMessage(&msg);
53
    DispatchMessage(&msg);
54
  }
55
  return msg.wParam;
56
}
57

58
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
59
{
60
  static RECT    rect;
61
  static double  horizontal_1;
62
  static double  vertikal_1;
63

64
  static double  horizontal_2;
65
  static double  vertikal_2;
66

67
  switch(message)
68
  {
69
    case WM_CREATE:
70
    {
71
      SetTimer(hWnd, ID_ERSTER_TIMER, 1, NULL);
72
      return 0;
73
    }
74

75
    case WM_SIZE:
76
    {
77
      rect.right  = LOWORD(lParam);
78
      rect.bottom  = HIWORD(lParam);
79
      return 0;
80
    }
81

82
    case WM_PAINT:
83
    {
84
      PAINTSTRUCT  ps;
85
      HDC      hDC;
86

87
      hDC = BeginPaint(hWnd, &ps);
88

89

90
      {
91
        HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, CreateSolidBrush(RGB(0,0,255)));
92

93
        Ellipse(hDC, 
94
          0          +horizontal_1,
95
          0          +vertikal_1,
96
          50          +horizontal_1,
97
          50          +vertikal_1); //links, oben, rechts, unten
98

99
        Ellipse(hDC, 
100
          0          +horizontal_2,
101
          rect.bottom/2-25  +vertikal_2,
102
          50          +horizontal_2,
103
          rect.bottom/2+25  +vertikal_2);
104

105
        DeleteObject(SelectObject(hDC,hOldBrush));
106
      }
107
      EndPaint(hWnd, &ps);
108
      return 0;
109
    }
110

111
    case WM_TIMER:
112
    {
113
      switch(wParam)
114
      {
115
        case ID_ERSTER_TIMER:
116
        {
117
          RECT InvalRect1;
118
          RECT InvalRect2;
119

120
          if(horizontal_1 >= rect.right-50)
121
            fahrt_h1 = -5;
122
          
123
          if(horizontal_1 <= 0)
124
            fahrt_h1 = 5;
125

126
          if(vertikal_1 >= rect.bottom-50)
127
            fahrt_v1 = -5;
128
          
129
          if(vertikal_1 <= 0)
130
            fahrt_v1 = 5;
131

132

133
          if(horizontal_2 >= rect.right-50)
134
            fahrt_h2 = -5;
135
          
136
          if(horizontal_2 <= 0)
137
            fahrt_h2 =  5;
138

139
          if(vertikal_2 >= rect.bottom/2-25)
140
            fahrt_v2 = -5;
141
          
142
          if(vertikal_2 <= -rect.bottom/2+25)
143
            fahrt_v2 =  5;
144

145
          vertikal_1    += fahrt_v1;
146
          horizontal_1  += fahrt_h1;
147

148
          horizontal_2  += fahrt_h2;
149
          vertikal_2    += fahrt_v2;
150

151
          InvalRect1.left    =   0 + horizontal_2  -5;
152
          InvalRect1.top    =   0 + vertikal_2    -5;
153
          InvalRect1.right  =  50 + horizontal_2  +5;
154
          InvalRect1.bottom  =  50 + vertikal_2    +5;
155

156
          InvalRect2.left    =   0          + horizontal_2    -5;
157
          InvalRect2.top    =  rect.bottom/2-25  + vertikal_2    -5;
158
          InvalRect2.right  =  50          + horizontal_2    +5;
159
          InvalRect2.bottom  =  rect.bottom/2+25  + vertikal_2    +5;
160

161
          InvalidateRect(hWnd, &InvalRect1, TRUE);
162
          InvalidateRect(hWnd, &InvalRect2, TRUE);
163

164
          break;
165
        }
166
      }
167
      return 0;
168
    }
169

170
    case WM_DESTROY:
171
    {
172
      KillTimer(hWnd, ID_ERSTER_TIMER);
173
      PostQuitMessage(0);
174
      return 0;
175
    }
176
  }
177
  return DefWindowProc(hWnd, message, wParam, lParam);
178
}
Gast #2521742
Lesenswert?

Es gibt sicherlich eine Mange was man besser machen müsste,
aber zuerstmal:

InvalidateRect(hWnd, &InvalRect1, TRUE);
InvalidateRect(hWnd, &InvalRect2, TRUE);

muß im Timer auch passieren, BEVOR die Ellipsen verschoben wurden, damit 
beim WM_PAINT dann bei BeginPaint die dortigen Stellen mit der 
hbrBackground übermalt werden.

Daß man bei animierten Sachen prinzipiell nicht direkt auf den 
Bildschirm schreiben sollte, sondern erst in eine bildschirmkompatible 
Bitmap, und erst wenn alles gemalt wurde diese auf den Bildschirm 
blittet an Stelle des bisherigen Inhalts, sollte zur Vermeidung von 
Flimmereffekten klar sein - aber nicht mal Microsoft behrzigt dies 
immer.

Und daß man heute bei SCHNELLER Animation mit DirectX ein komplett 
anderes API verwenden muß, nennt Microsoft Fortschritt.

Die REIHENFOLGE der Ellipsen, also welche vorne zu liegen scheint und 
welche hinten, ist durch die Reihenfolge im WM_PAINT bestimmt (Z-Order), 
und falls man sie ändern will, muß man dort die Reihenfolge ändern.

Du hast keinen PEN selected, und daher nicht spezifziert wie die 
Umrandung der blau gefüllten Ellipse aussehen soll.
Gast #2521763
Lesenswert?

Ok, vielen Dank!
Dann werde ich das alles mal überarbeiten müssen.
Ich steh wie gerade noch ganz am Anfang, mich mit WinAPI auseinander zu 
setzen, DirectX wird der nächste Schritt sein.
Vielleicht finde ich ja noch ein gutes Tutorial in diesem Gebiet; das, 
wovon ich mein Programm abgeleitet habe, scheint dafür ja nicht 100% 
gemacht zu sein. ;)

Danke nochmal!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren