Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/55: Рейтинг темы: голосов - 55, средняя оценка - 4.60
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429

Движение фигуры по экрану

12.06.2017, 17:28. Показов 11038. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, нужно было сделать анимацию фигуры по экрану(движение шарика в окне с отражением от стенок по законам геометрической оптики), через классы.
Склеил что-то типо того, но не работает должным образом. Т.е. она работает, завершается успешно, но окно не появляется после компиляции.. вообще ничего не появляется..
Но процесс создается и висит, приходится убивать через диспетчер.
Помогите разобраться?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <windows.h>
#include <tchar.h>
#include <cmath>
#include <cstdlib>
#define M_PI           3.14159265358979323846  /* pi */
LRESULT CALLBACK  WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
TCHAR WinName[] = _T("MainFrame");
HDC dc;
 
class Window {
public:
    HWND hwnd;
    WNDCLASS we;
 
    bool Reg_Window(HINSTANCE hInstance, LPCWSTR lpzClassName, WNDPROC lpfnWndProc) {
        ZeroMemory(&we, sizeof(we));
        we.lpfnWndProc = WndProc;
        we.hInstance = hInstance;
        we.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        we.hCursor = LoadCursor(NULL, IDC_ARROW);
        we.style = CS_HREDRAW | CS_VREDRAW;       // Стиль окна
        we.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        we.lpszClassName = lpzClassName;
        we.lpszMenuName = NULL;       // Нет меню
        we.cbClsExtra = 0;            // Нет дополнительных данных класса
        we.cbWndExtra = 0;
        if (RegisterClass(&we) != 0)
            return true;
        else
            return false;
    }
 
    void Create_Window(HINSTANCE hInstance) {
        hwnd = CreateWindow(WinName, L"LAB 6",
            WS_OVERLAPPEDWINDOW, 200, 300, 400, 300,
            HWND_DESKTOP, NULL, hInstance, NULL);
    }
 
    void Show_Window() {
        ShowWindow(hwnd, SW_SHOW);
    }
 
    HDC Get_DC(HWND hwnd) {
        if (GetDC(hwnd) != NULL)
            return GetDC(hwnd);
        else
            return NULL;
    }
};
 
class Rect {
private:
    RECT rc;
    int x, y;   // Координаты места создания шарика т.с там где он появится в нашем окне // скорость нашего шара
    int R;      // Размер шара
    double vx, vy; // vx ; vy - скорось шарика
    double t;
public:
 
    void bones(HWND hwnd) {
        R = 15;     //vx=3 vy=3 - Создаем значения на выполнение (Начальные условия)
        t = (rand() % 360 - 180) * M_PI / 180.0;
        vx = 10.0 * cos(t);
        vy = 10.0 * sin(t);
 
        SetTimer(hwnd, 1, 25, NULL);
    }
 
    void invalidate(HWND hwnd) {
        InvalidateRect(hwnd, &rc, true);// Стираем старое положение шарика
        x += vx; y += vy; // новые координаты по задумке должно быть так x+=*vx;y+=*vy но компилятор ругается на умножение
        RECT rt;
        GetClientRect(hwnd, &rt);
        int w = rt.right;
        int h = rt.bottom;// длина и высота рабочей области
        if (x >= w - R)vx = -abs(vx); // проверка отражения от правой стенки
        if (y>h - R)vy = -abs(vy);// проверка низа
        if (x<R)vx = abs(vx); // проверка левой стенки
        if (y<R)vy = abs(vy); // проверка верха
 
        rc.left = x - R - 1;
        rc.top = y - R - 1;
        rc.right = x + R + 1;
        rc.bottom = y + R + 1;
        InvalidateRect(hwnd, &rc, false); // нарисовать новое положение
    }
 
    void createRect(HWND hwnd) {
        PAINTSTRUCT ps;
 
        dc = BeginPaint(hwnd, &ps);
        //============= (Окраска нашего круга) ===========
        HBRUSH br, obr;
        br = CreateSolidBrush(RGB(255, 0, 0));
        obr = (HBRUSH)SelectObject(dc, br);
        //============== (Рисуем наш круг) ============
        Ellipse(dc, x - R, y - R, x + R, y + R);
        // ===============================================
        SelectObject(dc, obr); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        DeleteObject(br); //  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        EndPaint(hwnd, &ps);
    }
};
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) {
    //дескриптор окна
    MSG Msg;   //структура всех сообщений
    Window MyObject; //объект класса создание окна
 
 
    if (MyObject.Reg_Window(hInstance, L"MyWindowClass", WndProc))
    {
        MyObject.Create_Window(hInstance);
        MyObject.Show_Window();
        //dc = MyObject.Get_DC(MyObject.hwnd);
 
 
        while (GetMessage(&Msg, NULL, 0, 0))
        {
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
        }
    }
    return 0;
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    Rect r;
    static int x, y;
 
    switch (message) {
    case WM_LBUTTONDOWN: // По нажатию левой кнопки мыши устанавливаем параметры и запускаем таймер который при значений NULL выполняет WM_TIMER 
        x = LOWORD(lParam);
        y = HIWORD(lParam);
        r.bones(hwnd);
        break;
 
    case WM_TIMER://Начинаем выполнять идем ниже
        r.invalidate(hwnd);
        break;
 
    case WM_PAINT:
        r.createRect(hwnd);
        break;
 
    case WM_DESTROY:
        KillTimer(hwnd, 1);// Удаляем наш таймер при закрытий окна
        PostQuitMessage(0);
        break;
 
    default:
        return (DefWindowProc(hwnd, message, wParam, lParam));
    }
}
Логи:
Кликните здесь для просмотра всего текста
Code
1
2
3
4
5
6
7
8
1>------ Сборка начата: проект: Win32Project2, Конфигурация: Debug Win32 ------
1>main.cpp
1>c:\users\andrew\documents\visual studio 2017\projects\win32project2\win32project2\main.cpp(71): warning C4244: +=: преобразование "double" в "int", возможна потеря данных
1>c:\users\andrew\documents\visual studio 2017\projects\win32project2\win32project2\main.cpp(154): warning C4715: WndProc: значение возвращается не при всех путях выполнения
1>Win32Project2.vcxproj -> c:\users\andrew\documents\visual studio 2017\Projects\Win32Project2\Debug\Win32Project2.exe
1>Win32Project2.vcxproj -> c:\users\andrew\documents\visual studio 2017\Projects\Win32Project2\Debug\Win32Project2.pdb (Partial PDB)
1>Сборка проекта "Win32Project2.vcxproj" завершена.
========== Сборка: успешно: 1, с ошибками: 0, без изменений: 0, пропущено: 0 ==========


Добавлено через 1 час 2 минуты
актуально
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
12.06.2017, 17:28
Ответы с готовыми решениями:

Движение шара по экрану (GDI+)
Добрый день, есть у кого какой пример под рукой, чтобы просто в окне отрисованный шар плыл слева на право экрана? А то меня пугает...

Движение фигуры по окружности. C++
Здравствуйте, помогите пожалуйста усовершенствовать/подсказать/исправить код движения круга по окружности, движение ещё кое как у меня...

Движение геометрической фигуры. Исправить программу
Все работает, но через какое-то время все заливается белым цветом. Как это исправить? #include &quot;iostream&quot; #include...

12
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
12.06.2017, 18:18
Окно-то зачем в класс? Проверяй, что функции возвращают.
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
12.06.2017, 18:24  [ТС]
Цитата Сообщение от nmcf Посмотреть сообщение
Окно-то зачем в класс?
что именно? создание окна?
вот тут все работает, делал по аналогии отсюда
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <windows.h>
#include <windowsx.h>
#include<stdlib.h>
#include <wchar.h>
 
LRESULT CALLBACK  WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam);
HPEN MyPen;
HDC dc;
 
class CButton
{
public:
    BOOL ShowButton(int x1,int y1,int x2,int y2,int kx,int ky);
private:
    int x1;
    int y1;
    int x2;
    int y2;
    HBRUSH MyBrush;
    HBRUSH CreateBrush(COLORREF color);
 
 
};
 
HBRUSH CButton::CreateBrush(COLORREF color)
{
if (CreateSolidBrush(color)!=NULL)
    return CreateSolidBrush(color);
else
    return NULL;
};
 
BOOL CButton::ShowButton(int x1,int y1,int x2,int y2,int kx,int ky)
{
    if ((kx>x1) & (kx<x2) & (ky>y1) & (ky<y2))
MyBrush=CreateBrush(RGB(255,120,300));
    else
MyBrush=CreateBrush(RGB(255,120,120));
 
 
SelectBrush(dc,MyBrush);
if (Rectangle(dc,x1,y1,x2,y2)!=NULL)
{
    return Rectangle(dc,x1,y1,x2,y2);
}   
else
    return NULL;
}
 
 
 
class WINDOWMAIN
{
public:
    
    
    HWND hwnd;
    void Create_Window(LPCWSTR Name_Prog);
    void Show_Window();
    WNDCLASS we;
    bool Reg_Window(HINSTANCE hInstance,LPCWSTR lpzClassName,WNDPROC lpfnWndProc);
    HDC Get_DC(HWND hwnd);
};
bool WINDOWMAIN::Reg_Window(HINSTANCE hInstance, LPCWSTR lpzClassName,WNDPROC lpfnWndProc)
   {
       ZeroMemory(&we,sizeof(we));
       we.lpfnWndProc=lpfnWndProc;
       we.hInstance=hInstance;
       we.hIcon=LoadIcon(NULL,IDI_APPLICATION);
       we.hCursor=LoadCursor(NULL,IDC_ARROW);
       we.hbrBackground=GetStockBrush(WHITE_BRUSH);
       we.lpszClassName= lpzClassName;
      if (RegisterClass(&we)!=0) 
            return true;
              else 
            return false;
   }
 
  void WINDOWMAIN::Create_Window(LPCWSTR Name_Prog)
  {
    hwnd=CreateWindow(L"MyWindowClass",Name_Prog,
WS_OVERLAPPEDWINDOW,500,200,230,250,
HWND_DESKTOP,NULL,NULL,NULL);  
  }
 
  void WINDOWMAIN::Show_Window()
  {
ShowWindow(hwnd,SW_SHOW);    
    
  }
 
 HDC WINDOWMAIN::Get_DC(HWND hwnd)
  {
     if (GetDC(hwnd)!=NULL)
      return GetDC(hwnd);
     else
         return NULL;
  }
   
 
  int WINAPI  WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int )
 
   {  
       
        //дескриптор окна
       MSG Msg;   //структура всех сообщений
       WINDOWMAIN MyObject; //объект класса создание окна
      
 
       if (MyObject.Reg_Window(hInstance,L"MyWindowClass",WndProc)) 
      {
          MyObject.Create_Window(L"Project");
          MyObject.Show_Window();
          dc=MyObject.Get_DC(MyObject.hwnd);
 
 
         while(GetMessage(&Msg,NULL,0,0))
           {    
             DispatchMessage(&Msg);
             TranslateMessage(&Msg);
           }
      }
return 0;
}
 
LRESULT CALLBACK  WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    static int x,y;
    CButton MyButton[8];
    switch(uMsg)
{
    case WM_LBUTTONDOWN:
                x=LOWORD(lParam); 
                y=HIWORD(lParam);
                MyButton[0].ShowButton(10,10,60,60,x,y);
                MyButton[1].ShowButton(80,10,130,60,x,y);
                MyButton[2].ShowButton(150,10,200,60,x,y);
                MyButton[3].ShowButton(10,80,60,130,x,y);
                MyButton[4].ShowButton(80,80,130,130,x,y);
                MyButton[5].ShowButton(150,80,200,130,x,y);
                MyButton[6].ShowButton(10,150,60,200,x,y);
                MyButton[7].ShowButton(80,150,130,200,x,y);
                MyButton[8].ShowButton(150,150,200,200,x,y);
        break;
 
 
case WM_DESTROY:
PostQuitMessage(0);
break;
 
default:
return(DefWindowProc(hWnd,uMsg,wParam,lParam)) ; 
}
}
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
12.06.2017, 19:39
Цитата Сообщение от Azazel-San Посмотреть сообщение
вот тут все работает
А почему hInstance не указан в CreateWindow()?
Если это точно работает, зачем менял-то?
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
12.06.2017, 19:44  [ТС]
Цитата Сообщение от nmcf Посмотреть сообщение
Если это точно работает, зачем менял-то?
ну мне нужно было, я б тогда сюда не писал.. пофиксил, окно открывает, но по нажатию курсором ничего не происходит..

Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#include <windows.h>
#include <tchar.h>
#include <cmath>
#include <cstdlib>
#define M_PI           3.14159265358979323846  /* pi */
LRESULT CALLBACK  WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
TCHAR WinName[] = _T("MainFrame");
 
class Window {
public:
    HWND hwnd;              // Дескриптор главного окна программы
    MSG msg;                // Структура для хранения сообщения
    WNDCLASS wc;  // Класс окна
                  // Определение класса окна
    bool reg_window(HINSTANCE This, LPCWSTR lpzClassName, WNDPROC lpfnWndProc) {
        wc.hInstance = This;
        wc.lpszClassName = WinName;                // Имя класса окна
        wc.lpfnWndProc = WndProc;                  // Функция окна
        wc.style = CS_HREDRAW | CS_VREDRAW;       // Стиль окна
        wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);    // Стандартная иконка
        wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Стандартный курсор
        wc.lpszMenuName = NULL;       // Нет меню
        wc.cbClsExtra = 0;            // Нет дополнительных данных класса
        wc.cbWndExtra = 0;            // Нет дополнительных данных окна
                                      // Заполнение окна белым цветом
        wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        if (!RegisterClass(&wc)) return 0;   // Регистрация класса окна
                                             // Создание окна
    }
 
    void create_window(HINSTANCE This) {
        hwnd = CreateWindow(WinName, // Имя класса окна
            L"LAB 6",  // Заголовок окна
            WS_OVERLAPPEDWINDOW,         // Стиль окна
            200, // x
            300, // y   Размеры окна
            400, // width
            300, // Height
            HWND_DESKTOP, // Дескриптор родительского окна
            NULL,         // Нет меню
            This,         // Дескриптор приложения
            NULL);        // Дополнительной информации нет
    }
 
    void show_window() {
        ShowWindow(hwnd, SW_SHOW); // Показать окно
    }
 
};
 
class Rect {
private:
    RECT rc;
    int x, y;   // Координаты места создания шарика т.с там где он появится в нашем окне // скорость нашего шара
    int R;      // Размер шара
    double vx, vy; // vx ; vy - скорось шарика
    double t;
public:
 
    void bones() {
        R = 15;     //vx=3 vy=3 - Создаем значения на выполнение (Начальные условия)
        t = (rand() % 360 - 180) * M_PI / 180.0;
        vx = 10.0 * cos(t);
        vy = 10.0 * sin(t);
    }
 
    void invalidate(HWND &hwnd) {
        InvalidateRect(hwnd, &rc, true);// Стираем старое положение шарика
        x += vx; y += vy; // новые координаты по задумке должно быть так x+=*vx;y+=*vy но компилятор ругается на умножение
        RECT rt;
        GetClientRect(hwnd, &rt);
        int w = rt.right;
        int h = rt.bottom;// длина и высота рабочей области
        if (x >= w - R)vx = -abs(vx); // проверка отражения от правой стенки
        if (y>h - R)vy = -abs(vy);// проверка низа
        if (x<R)vx = abs(vx); // проверка левой стенки
        if (y<R)vy = abs(vy); // проверка верха
 
        rc.left = x - R - 1;
        rc.top = y - R - 1;
        rc.right = x + R + 1;
        rc.bottom = y + R + 1;
        InvalidateRect(hwnd, &rc, false); // нарисовать новое положение
    }
 
    void createRect(HWND hwnd) {
        PAINTSTRUCT ps;
        HDC hdc;
 
        hdc = BeginPaint(hwnd, &ps);
        //============= (Окраска нашего круга) ===========
        HBRUSH br, obr;
        br = CreateSolidBrush(RGB(255, 0, 0));
        obr = (HBRUSH)SelectObject(hdc, br);
        //============== (Рисуем наш круг) ============
        Ellipse(hdc, x - R, y - R, x + R, y + R);
        // ===============================================
        SelectObject(hdc, obr); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        DeleteObject(br); //  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        EndPaint(hwnd, &ps);
    }
};
 
int WINAPI _tWinMain(HINSTANCE This, // Дескриптор текущего приложения
                     HINSTANCE,      // В современных системах всегда 0
                     LPTSTR,         // Командная строка
                     int mode)       // Режим отображения окна
{
    MSG msg;
    Window myWin;
 
    myWin.reg_window(This, L"MyWindowClass", WndProc);
    myWin.create_window(This);
    myWin.show_window();
 
                            // Цикл обработки сообщений
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg); // Функция трансляции кодов нажатой клавиши
        DispatchMessage(&msg);  // Посылает сообщение функции WndProc()
    }
    return 0;
}
 
RECT rc;
int x, y; // Координаты места создания шарика т.с там где он появится в нашем окне // скорость нашего шара
int R; // Размер шара
double vx, vy;
double t;
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    Rect r;
    //static int x, y;
    
    switch (message) {
    case WM_LBUTTONDOWN: // По нажатию левой кнопки мыши устанавливаем параметры и запускаем таймер который при значений NULL выполняет WM_TIMER 
        x = LOWORD(lParam);
        y = HIWORD(lParam);
        R = 15;     //vx=3 vy=3 - Создаем значения на выполнение (Начальные условия)
        t = (rand() % 360 - 180) * M_PI / 180.0;
        vx = 10.0 * cos(t);
        vy = 10.0 * sin(t);
        SetTimer(hwnd, 1, 25, NULL);
        break;
 
    case WM_TIMER://Начинаем выполнять идем ниже
    {
        InvalidateRect(hwnd, &rc, true);// Стираем старое положение шарика
        x += vx; y += vy; // новые координаты по задумке должно быть так x+=*vx;y+=*vy но компилятор ругается на умножение
        RECT rt;
        GetClientRect(hwnd, &rt);
        int w = rt.right;
        int h = rt.bottom;// длина и высота рабочей области
        if (x >= w - R)vx = -abs(vx); // проверка отражения от правой стенки
        if (y > h - R)vy = -abs(vy);// проверка низа
        if (x < R)vx = abs(vx); // проверка левой стенки
        if (y < R)vy = abs(vy); // проверка верха
 
        rc.left = x - R - 1;
        rc.top = y - R - 1;
        rc.right = x + R + 1;
        rc.bottom = y + R + 1;
        InvalidateRect(hwnd, &rc, false); // нарисовать новое положение
    }
        break;
 
    case WM_PAINT:
    {
        r.createRect(hwnd);
    }
        break;
 
    case WM_DESTROY:
        KillTimer(hwnd, 1);// Удаляем наш таймер при закрытий окна
        PostQuitMessage(0);
        break;
 
    default:
        return (DefWindowProc(hwnd, message, wParam, lParam));
    }
}
0
284 / 232 / 114
Регистрация: 07.09.2016
Сообщений: 584
12.06.2017, 20:43
в структуре Rect не инициализированы поля. Добавил инициализацию x, y и явный вызов bones в дефолтном конструкторе
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 ...
  Rect()
  {
    bones();
  }
 
  void bones() {
    R = 15;     //vx=3 vy=3 - Создаем значения на выполнение (Начальные условия)
    t = (rand() % 360 - 180) * M_PI / 180.0;
    vx = 10.0 * cos(t);
    vy = 10.0 * sin(t);
    x = 0; // добавлено
    y = 0; // добавлено
  }
...
Круг начал рисоваться в видимой части окна, но он не движется, потому что по таймеру вы никак не меняете
его координаты x и y. Думаю сами как-нибудь поправите

Добавлено через 17 минут
вот захаченная версия, в которой поля у Rect публичные, структурка Rect r из оконной процедуры стала глобальной, а прочие глобальные переменные стали ссылками, ссылающимися на поля этой структурки. остальное без изменений:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include <windows.h>
#include <tchar.h>
#include <cmath>
#include <cstdlib>
#define M_PI           3.14159265358979323846  /* pi */
LRESULT CALLBACK  WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
TCHAR WinName[] = _T("MainFrame");
 
class Window {
public:
  HWND hwnd;              // Дескриптор главного окна программы
  MSG msg;                // Структура для хранения сообщения
  WNDCLASS wc;  // Класс окна
                // Определение класса окна
  bool reg_window(HINSTANCE This, LPCWSTR lpzClassName, WNDPROC lpfnWndProc) {
    wc.hInstance = This;
    wc.lpszClassName = WinName;                // Имя класса окна
    wc.lpfnWndProc = WndProc;                  // Функция окна
    wc.style = CS_HREDRAW | CS_VREDRAW;       // Стиль окна
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);    // Стандартная иконка
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Стандартный курсор
    wc.lpszMenuName = NULL;       // Нет меню
    wc.cbClsExtra = 0;            // Нет дополнительных данных класса
    wc.cbWndExtra = 0;            // Нет дополнительных данных окна
                                  // Заполнение окна белым цветом
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    if (!RegisterClass(&wc)) return 0;   // Регистрация класса окна
                                         // Создание окна
  }
 
  void create_window(HINSTANCE This) {
    hwnd = CreateWindow(WinName, // Имя класса окна
      L"LAB 6",  // Заголовок окна
      WS_OVERLAPPEDWINDOW,         // Стиль окна
      200, // x
      300, // y   Размеры окна
      400, // width
      300, // Height
      HWND_DESKTOP, // Дескриптор родительского окна
      NULL,         // Нет меню
      This,         // Дескриптор приложения
      NULL);        // Дополнительной информации нет
  }
 
  void show_window() {
    ShowWindow(hwnd, SW_SHOW); // Показать окно
  }
 
};
 
class Rect {
public:
  RECT rc;
  int x, y;   // Координаты места создания шарика т.с там где он появится в нашем окне // скорость нашего шара
  int R;      // Размер шара
  double vx, vy; // vx ; vy - скорось шарика
  double t;
public:
 
  void bones() {
    R = 15;     //vx=3 vy=3 - Создаем значения на выполнение (Начальные условия)
    t = (rand() % 360 - 180) * M_PI / 180.0;
    vx = 10.0 * cos(t);
    vy = 10.0 * sin(t);
  }
 
  void invalidate(HWND &hwnd) {
    InvalidateRect(hwnd, &rc, true);// Стираем старое положение шарика
    x += vx; y += vy; // новые координаты по задумке должно быть так x+=*vx;y+=*vy но компилятор ругается на умножение
    RECT rt;
    GetClientRect(hwnd, &rt);
    int w = rt.right;
    int h = rt.bottom;// длина и высота рабочей области
    if (x >= w - R)vx = -abs(vx); // проверка отражения от правой стенки
    if (y>h - R)vy = -abs(vy);// проверка низа
    if (x<R)vx = abs(vx); // проверка левой стенки
    if (y<R)vy = abs(vy); // проверка верха
 
    rc.left = x - R - 1;
    rc.top = y - R - 1;
    rc.right = x + R + 1;
    rc.bottom = y + R + 1;
    InvalidateRect(hwnd, &rc, false); // нарисовать новое положение
  }
 
  void createRect(HWND hwnd) {
    PAINTSTRUCT ps;
    HDC hdc;
 
    hdc = BeginPaint(hwnd, &ps);
    //============= (Окраска нашего круга) ===========
    HBRUSH br, obr;
    br = CreateSolidBrush(RGB(255, 0, 0));
    obr = (HBRUSH)SelectObject(hdc, br);
    //============== (Рисуем наш круг) ============
    Ellipse(hdc, x - R, y - R, x + R, y + R);
    // ===============================================
    SelectObject(hdc, obr); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    DeleteObject(br); //  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    EndPaint(hwnd, &ps);
  }
};
 
int WINAPI _tWinMain(HINSTANCE This, // Дескриптор текущего приложения
  HINSTANCE,      // В современных системах всегда 0
  LPTSTR,         // Командная строка
  int mode)       // Режим отображения окна
{
  MSG msg;
  Window myWin;
 
  myWin.reg_window(This, L"MyWindowClass", WndProc);
  myWin.create_window(This);
  myWin.show_window();
 
  // Цикл обработки сообщений
  while (GetMessage(&msg, NULL, 0, 0))
  {
    TranslateMessage(&msg); // Функция трансляции кодов нажатой клавиши
    DispatchMessage(&msg);  // Посылает сообщение функции WndProc()
  }
  return 0;
}
 
Rect r;
RECT& rc = r.rc;
int& x = r.x;
int& y = r.y; // Координаты места создания шарика т.с там где он появится в нашем окне // скорость нашего шара
int& R = r.R; // Размер шара
double& vx = r.vx;
double& vy = r.vy;
double& t = r.t;
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
  //Rect r;
  //static int x, y;
 
  switch (message) {
  case WM_LBUTTONDOWN: // По нажатию левой кнопки мыши устанавливаем параметры и запускаем таймер который при значений NULL выполняет WM_TIMER 
    x = LOWORD(lParam);
    y = HIWORD(lParam);
    R = 15;     //vx=3 vy=3 - Создаем значения на выполнение (Начальные условия)
    t = (rand() % 360 - 180) * M_PI / 180.0;
    vx = 10.0 * cos(t);
    vy = 10.0 * sin(t);
    SetTimer(hwnd, 1, 25, NULL);
    break;
 
  case WM_TIMER://Начинаем выполнять идем ниже
  {
    InvalidateRect(hwnd, &rc, true);// Стираем старое положение шарика
    x += vx; y += vy; // новые координаты по задумке должно быть так x+=*vx;y+=*vy но компилятор ругается на умножение
    RECT rt;
    GetClientRect(hwnd, &rt);
    int w = rt.right;
    int h = rt.bottom;// длина и высота рабочей области
    if (x >= w - R)vx = -abs(vx); // проверка отражения от правой стенки
    if (y > h - R)vy = -abs(vy);// проверка низа
    if (x < R)vx = abs(vx); // проверка левой стенки
    if (y < R)vy = abs(vy); // проверка верха
 
    rc.left = x - R - 1;
    rc.top = y - R - 1;
    rc.right = x + R + 1;
    rc.bottom = y + R + 1;
    InvalidateRect(hwnd, &rc, false); // нарисовать новое положение
  }
  break;
 
  case WM_PAINT:
  {
    r.createRect(hwnd);
  }
  break;
 
  case WM_DESTROY:
    KillTimer(hwnd, 1);// Удаляем наш таймер при закрытий окна
    PostQuitMessage(0);
    break;
 
  default:
    return (DefWindowProc(hwnd, message, wParam, lParam));
  }
}
1
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
12.06.2017, 20:50  [ТС]
DU3, спасибо, а как можно сделать так что бы, к примеру после нажатия создавалось два шара, а не один?
можно реализовать типо так?
C++
1
2
3
Rect r[2];
    r[0].createRect(hwnd);
    r[1].createRect(hwnd);
вот код:
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include <windows.h>
#include <tchar.h>
#include <cmath>
#include <cstdlib>
#define M_PI           3.14159265358979323846  /* pi */
LRESULT CALLBACK  WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
TCHAR WinName[] = _T("MainFrame");
 
class Window {
public:
    HWND hwnd;              // Дескриптор главного окна программы
    MSG msg;                // Структура для хранения сообщения
    WNDCLASS wc;  // Класс окна
                  // Определение класса окна
    bool reg_window(HINSTANCE This, LPCWSTR lpzClassName, WNDPROC lpfnWndProc) {
        wc.hInstance = This;
        wc.lpszClassName = WinName;                // Имя класса окна
        wc.lpfnWndProc = WndProc;                  // Функция окна
        wc.style = CS_HREDRAW | CS_VREDRAW;       // Стиль окна
        wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);    // Стандартная иконка
        wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Стандартный курсор
        wc.lpszMenuName = NULL;       // Нет меню
        wc.cbClsExtra = 0;            // Нет дополнительных данных класса
        wc.cbWndExtra = 0;            // Нет дополнительных данных окна
                                      // Заполнение окна белым цветом
        wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        if (!RegisterClass(&wc)) return 0;   // Регистрация класса окна
                                             // Создание окна
    }
 
    void create_window(HINSTANCE This) {
        hwnd = CreateWindow(WinName, // Имя класса окна
            L"LAB 6",  // Заголовок окна
            WS_OVERLAPPEDWINDOW,         // Стиль окна
            200, // x
            300, // y   Размеры окна
            400, // width
            300, // Height
            HWND_DESKTOP, // Дескриптор родительского окна
            NULL,         // Нет меню
            This,         // Дескриптор приложения
            NULL);        // Дополнительной информации нет
    }
 
    void show_window() {
        ShowWindow(hwnd, SW_SHOW); // Показать окно
    }
 
};
 
RECT rc;
int x, y;   // Координаты места создания шарика т.с там где он появится в нашем окне // скорость нашего шара
int R;      // Размер шара
double vx, vy; // vx ; vy - скорось шарика
double t;
 
class Rect : Window {
public:
 
    void bones(HWND hwnd) {
        R = 15;     //vx=3 vy=3 - Создаем значения на выполнение (Начальные условия)
        t = (rand() % 360 - 180) * M_PI / 180.0;
        vx = 10.0 * cos(t);
        vy = 10.0 * sin(t);
 
        SetTimer(hwnd, 1, 25, NULL);
    }
 
    void invalidate(HWND hwnd, RECT &rc) {
        InvalidateRect(hwnd, &rc, true);// Стираем старое положение шарика
        x += vx; y += vy; // новые координаты по задумке должно быть так x+=*vx;y+=*vy но компилятор ругается на умножение
        RECT rt;
        GetClientRect(hwnd, &rt);
        int w = rt.right;
        int h = rt.bottom;// длина и высота рабочей области
        if (x >= w - R)
            vx = -abs(vx); // проверка отражения от правой стенки
        if (y>h - R)
            vy = -abs(vy);// проверка низа
        if (x<R)
            vx = abs(vx); // проверка левой стенки
        if (y<R)
            vy = abs(vy); // проверка верха
 
        rc.left = x - R - 1;
        rc.top = y - R - 1;
        rc.right = x + R + 1;
        rc.bottom = y + R + 1;
        InvalidateRect(hwnd, &rc, false); // нарисовать новое положение
    }
 
    void createRect(HWND &hwnd) {
        PAINTSTRUCT ps;
        HDC hdc;
 
        hdc = BeginPaint(hwnd, &ps);
        //============= (Окраска нашего круга) ===========
        HBRUSH br, obr;
        br = CreateSolidBrush(RGB(255, 0, 0));
        obr = (HBRUSH)SelectObject(hdc, br);
        //============== (Рисуем наш круг) ============
        Ellipse(hdc, x - R, y - R, x + R, y + R);
        // ===============================================
        SelectObject(hdc, obr); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        DeleteObject(br); //  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        EndPaint(hwnd, &ps);
    }
 
};
 
int WINAPI _tWinMain(HINSTANCE This, // Дескриптор текущего приложения
                     HINSTANCE,      // В современных системах всегда 0
                     LPTSTR,         // Командная строка
                     int mode)       // Режим отображения окна
{
    MSG msg;
    Window myWin;
 
    if (myWin.reg_window(This, L"MyWindowClass", WndProc)) {
        myWin.create_window(This);
        myWin.show_window();
 
        // Цикл обработки сообщений
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg); // Функция трансляции кодов нажатой клавиши
            DispatchMessage(&msg);  // Посылает сообщение функции WndProc()
        }
    }
    return 0;
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    Rect r[2];
    //static int x, y;
    
    switch (message) {
    case WM_LBUTTONDOWN: // По нажатию левой кнопки мыши устанавливаем параметры и запускаем таймер который при значений NULL выполняет WM_TIMER 
        x = LOWORD(lParam);
        y = HIWORD(lParam);
        r[0].bones(hwnd);
        //r[1].bones(hwnd);
        SetTimer(hwnd, 1, 25, NULL);
        break;
 
    case WM_TIMER://Начинаем выполнять идем ниже
    {
        r[0].invalidate(hwnd, rc);
        //r[1].invalidate(hwnd, rc);
    }
        break;
 
    case WM_PAINT:
    {
        r[0].createRect(hwnd);
        //r[1].createRect(hwnd);
    }
        break;
 
    case WM_DESTROY:
        KillTimer(hwnd, 1);// Удаляем наш таймер при закрытий окна
        PostQuitMessage(0);
        break;
 
    default:
        return (DefWindowProc(hwnd, message, wParam, lParam));
    }
}
0
284 / 232 / 114
Регистрация: 07.09.2016
Сообщений: 584
12.06.2017, 20:57
да, примерно так. делаете массив объектов. у каждого надо обновлять их позиции, каждый надо рендерить.
в текущем варианте реализации это будет все коряво. все эти шаги надо либо в в метод объекта Rect засовывать,
либо в отдельный какой-то метод, который это будет делать. Вот тут консольный вариант того же самого, там обработка
движения не в методах объектов, а в отдельной функции ProcessObject:
Движение в консоли
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
12.06.2017, 21:47  [ТС]
Цитата Сообщение от DU3 Посмотреть сообщение
каждый надо рендерить.
а как отрендерить новый?
как-то у меня не получается.. после нажатия всеравно только 1 шарик

Добавлено через 27 минут
помогите плес
0
284 / 232 / 114
Регистрация: 07.09.2016
Сообщений: 584
12.06.2017, 22:09
Лучший ответ Сообщение было отмечено Azazel-San как решение

Решение

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#include <windows.h>
#include <tchar.h>
#include <cmath>
#include <cstdlib>
#include <vector>
 
#define M_PI           3.14159265358979323846  /* pi */
LRESULT CALLBACK  WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
TCHAR WinName[] = _T("MainFrame");
 
class Window {
public:
  HWND hwnd;              // Дескриптор главного окна программы
  MSG msg;                // Структура для хранения сообщения
  WNDCLASS wc;  // Класс окна
                // Определение класса окна
  bool reg_window(HINSTANCE This, LPCWSTR lpzClassName, WNDPROC lpfnWndProc) {
    wc.hInstance = This;
    wc.lpszClassName = WinName;                // Имя класса окна
    wc.lpfnWndProc = WndProc;                  // Функция окна
    wc.style = CS_HREDRAW | CS_VREDRAW;       // Стиль окна
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);    // Стандартная иконка
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Стандартный курсор
    wc.lpszMenuName = NULL;       // Нет меню
    wc.cbClsExtra = 0;            // Нет дополнительных данных класса
    wc.cbWndExtra = 0;            // Нет дополнительных данных окна
                                  // Заполнение окна белым цветом
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    if (!RegisterClass(&wc)) return 0;   // Регистрация класса окна
                                         // Создание окна
  }
 
  void create_window(HINSTANCE This) {
    hwnd = CreateWindow(WinName, // Имя класса окна
      L"LAB 6",  // Заголовок окна
      WS_OVERLAPPEDWINDOW,         // Стиль окна
      200, // x
      300, // y   Размеры окна
      400, // width
      300, // Height
      HWND_DESKTOP, // Дескриптор родительского окна
      NULL,         // Нет меню
      This,         // Дескриптор приложения
      NULL);        // Дополнительной информации нет
  }
 
  void show_window() {
    ShowWindow(hwnd, SW_SHOW); // Показать окно
  }
 
};
 
class Rect {
public:
  RECT rc;
  int x, y;   // Координаты места создания шарика т.с там где он появится в нашем окне // скорость нашего шара
  int R;      // Размер шара
  double vx, vy; // vx ; vy - скорось шарика
  double t;
public:
 
  void bones() {
    R = 15;     //vx=3 vy=3 - Создаем значения на выполнение (Начальные условия)
    t = (rand() % 360 - 180) * M_PI / 180.0;
    vx = 10.0 * cos(t);
    vy = 10.0 * sin(t);
  }
 
  void invalidate(HWND &hwnd) {
    InvalidateRect(hwnd, &rc, true);// Стираем старое положение шарика
    x += vx; y += vy; // новые координаты по задумке должно быть так x+=*vx;y+=*vy но компилятор ругается на умножение
    RECT rt;
    GetClientRect(hwnd, &rt);
    int w = rt.right;
    int h = rt.bottom;// длина и высота рабочей области
    if (x >= w - R)vx = -abs(vx); // проверка отражения от правой стенки
    if (y>h - R)vy = -abs(vy);// проверка низа
    if (x<R)vx = abs(vx); // проверка левой стенки
    if (y<R)vy = abs(vy); // проверка верха
 
    rc.left = x - R - 1;
    rc.top = y - R - 1;
    rc.right = x + R + 1;
    rc.bottom = y + R + 1;
    InvalidateRect(hwnd, &rc, false); // нарисовать новое положение
  }
 
  /*
  void createRect(HWND hwnd) {
    PAINTSTRUCT ps;
    HDC hdc;
 
    hdc = BeginPaint(hwnd, &ps);
    //============= (Окраска нашего круга) ===========
    HBRUSH br, obr;
    br = CreateSolidBrush(RGB(255, 0, 0));
    obr = (HBRUSH)SelectObject(hdc, br);
    //============== (Рисуем наш круг) ============
    Ellipse(hdc, x - R, y - R, x + R, y + R);
    // ===============================================
    SelectObject(hdc, obr); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    DeleteObject(br); //  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    EndPaint(hwnd, &ps);
  }
  */
 
  void drawRect(HDC hdc) const
  {
    Ellipse(hdc, x - R, y - R, x + R, y + R);
  }
 
};
 
int WINAPI _tWinMain(HINSTANCE This, // Дескриптор текущего приложения
  HINSTANCE,      // В современных системах всегда 0
  LPTSTR,         // Командная строка
  int mode)       // Режим отображения окна
{
  MSG msg;
  Window myWin;
 
  myWin.reg_window(This, L"MyWindowClass", WndProc);
  myWin.create_window(This);
  myWin.show_window();
 
  // Цикл обработки сообщений
  while (GetMessage(&msg, NULL, 0, 0))
  {
    TranslateMessage(&msg); // Функция трансляции кодов нажатой клавиши
    DispatchMessage(&msg);  // Посылает сообщение функции WndProc()
  }
  return 0;
}
 
std::vector<Rect> rects;
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
 
  switch (message) {
  case WM_LBUTTONDOWN: // По нажатию левой кнопки мыши устанавливаем параметры и запускаем таймер который при значений NULL выполняет WM_TIMER 
    Rect r;
    r.x = LOWORD(lParam);
    r.y = HIWORD(lParam);
    r.R = 15;     //vx=3 vy=3 - Создаем значения на выполнение (Начальные условия)
    r.t = (rand() % 360 - 180) * M_PI / 180.0;
    r.vx = 10.0 * cos(r.t);
    r.vy = 10.0 * sin(r.t);
    rects.push_back(r);
    if (rects.size() == 1)
    {
      SetTimer(hwnd, 1, 25, NULL);
    }
    break;
 
  case WM_TIMER://Начинаем выполнять идем ниже
  {
    for (Rect& r : rects)
    {
      InvalidateRect(hwnd, &r.rc, true);// Стираем старое положение шарика
      r.x += r.vx;
      r.y += r.vy;
      RECT rt;
      GetClientRect(hwnd, &rt);
      int w = rt.right;
      int h = rt.bottom;// длина и высота рабочей области
      if (r.x >= w - r.R)
        r.vx = -abs(r.vx); // проверка отражения от правой стенки
      if (r.y > h - r.R)
        r.vy = -abs(r.vy);// проверка низа
      if (r.x < r.R)
        r.vx = abs(r.vx); // проверка левой стенки
      if (r.y < r.R)
        r.vy = abs(r.vy); // проверка верха
 
      r.rc.left = r.x - r.R - 1;
      r.rc.top = r.y - r.R - 1;
      r.rc.right = r.x + r.R + 1;
      r.rc.bottom = r.y + r.R + 1;
      InvalidateRect(hwnd, &r.rc, false); // нарисовать новое положение
    }
  }
  break;
 
  case WM_PAINT:
  {
    PAINTSTRUCT ps;
    HDC hdc;
 
    hdc = BeginPaint(hwnd, &ps);
 
    HBRUSH br, obr;
    br = CreateSolidBrush(RGB(255, 0, 0));
    obr = (HBRUSH)SelectObject(hdc, br);
 
    for (Rect& r : rects)
    {
      r.drawRect(hdc);
    }
 
    SelectObject(hdc, obr); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    DeleteObject(br); //  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    EndPaint(hwnd, &ps);
  }
  break;
 
  case WM_DESTROY:
    KillTimer(hwnd, 1);// Удаляем наш таймер при закрытий окна
    PostQuitMessage(0);
    break;
 
  default:
    return (DefWindowProc(hwnd, message, wParam, lParam));
  }
}
1
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
12.06.2017, 22:30  [ТС]
DU3, спасибо! но имелось ввиду что бы при одном нажатии сразу два шарика или больше, в зависимости от кол-ва массива объектов??
Цитата Сообщение от Azazel-San Посмотреть сообщение
к примеру после нажатия создавалось два шара, а не один?
0
284 / 232 / 114
Регистрация: 07.09.2016
Сообщений: 584
12.06.2017, 22:46
ну смотрите код елки палки. на одно нажатие в массив добавляется один рект. хотите два - добавляйте по два или что хотите делайте с массивом. сейчас рендерится весь массив. будет в нем два объекта - будет два рисоваться, будет тыща - значит тыща нарисуется. я надеюсь вы догадаетесь разные параметры ректам задать, чтобы они один на другом не рисовались и чтобы это не выглядело как движение одного объекта.
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
12.06.2017, 22:47  [ТС]
DU3, разобрался уже, ещё раз спасибо)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.06.2017, 22:47
Помогаю со студенческими работами здесь

Написать программу, демонстрирующую движение одной плоской фигуры относительно другой
Ребята, есть такое задание:Написать программу, демонстрирующую движение одной плоской фигуры относительно другой (неподвижной)....

Изобразить движение фигуры по экрану
#include &lt;stdio.h&gt; #include &lt;math.h&gt; #include &lt;conio.h&gt; main() { int x,y,k; float n; window(1,1,80,25); textbackground(7); ...

Передвижение фигуры по экрану
Помогите пожалуйста, нужно символ .model small .stack 100h .data string0 db '############### ', '$' string1 db...

Движение слова по экрану
Надо чтоб слово двигалось по экрану...

движение элемента по экрану
Добрый день. Мне нужно сделать так что бы рисунок медленно проплыл вдоль экрана и исчез за рамками экрана. Я написал примерно так ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru