Форум программистов, компьютерный форум CyberForum.ru

Остановка движения через поток - C++

Восстановить пароль Регистрация
 
lowlol
2 / 2 / 2
Регистрация: 02.12.2012
Сообщений: 102
02.05.2013, 21:42     Остановка движения через поток #1
Есть приложение, создающее три фигуры, которые вертятся и отталкиваются от границ окна
Вопрос такой: как нужно запустить поток, чтобы при его приостановке фигуры замирали, а при возобновлении опять двигались.
Кнопки старта и паузы в меню.
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
#include <windows.h>
#include <math.h>
#include "header.h"
LRESULT CALLBACK WinFun(HWND, UINT, WPARAM, LPARAM);
char WinName[]="Обработка событий от таймера"; // Имя класса окна
int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR arg, int WinMode)
{
    HWND hwnd; // Дескриптор окна
    MSG msg; // Содержит инф. о сообщении, посылаемом Windows
    WNDCLASSEX wcl; // Определяет класс окна
    // Определение класса окна
    wcl.hInstance=hIns; // Дескриптор данного экземпляра
    wcl.lpszClassName=WinName; //Имя класса
    wcl.lpfnWndProc=WinFun; //Функция окна
    wcl.style=0; //стиль по умолчанию
    wcl.cbSize=sizeof(WNDCLASSEX); //Размер структуры 
    wcl.hIcon=LoadIcon(NULL, IDI_APPLICATION); //Большая пиктограмма
    wcl.hIconSm=LoadIcon(NULL, IDI_WINLOGO); //Малая пиктограмма
    wcl.hCursor=LoadCursor(NULL, IDC_ARROW); //Форма курсора
    wcl.lpszMenuName=NULL; //Меню не используется
    wcl.cbClsExtra=0; // Дополнительная информация отсутствует
    wcl.cbWndExtra=0;
    // Фон окна задается белым
    wcl.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    // Регистрация класса окна
    if (!RegisterClassEx(&wcl)) return 0;
    // Создание окна
    hwnd=CreateWindow(
        WinName, // Имя класса окна
        "Обработка событий от таймера", // Заголовок
        WS_OVERLAPPEDWINDOW, // Стандартное окно
        CW_USEDEFAULT, // Координата X- определяется Windows 
        CW_USEDEFAULT, // Координата Y- определяется Windows 
        CW_USEDEFAULT, // ширина- определяется Windows 
        CW_USEDEFAULT, // высота- определяется Windows 
        HWND_DESKTOP, // Родительского окна нет
        NULL, // Меню нет
        hIns, // дескриптор данного экземпляра приложения
        NULL); // дополнительных аргументов нет
    // Отображение окна
    ShowWindow(hwnd, WinMode);
    UpdateWindow(hwnd);
    // Цикл сообщений
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg); // Разрешает использование клавиатуры
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
#define ID_TIMER  105 // Идентификатор таймера
Figure *pFig[3];
LRESULT CALLBACK WinFun(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    switch(message)
    {
    case WM_CREATE:
        {
        HMENU hMenubar=CreateMenu();
        HMENU hThread=CreateMenu();
 
        AppendMenu(hMenubar, MF_POPUP, (UINT_PTR)hThread, "Поток"); 
        AppendMenu(hThread, MFT_STRING, NULL, "Start");
        AppendMenu(hThread, MFT_STRING, NULL, "Pause");
        AppendMenu(hThread, MFT_STRING, NULL, "Stop");
        AppendMenu(hThread, MFT_STRING, NULL, "Restart");
 
        SetMenu(hwnd, hMenubar);
        pFig[0]=new Square(400, 400, 50, 10, 45, RGB(0, 0, 255));
        pFig[1]=new Square(250, 250, 50, 3, 0, RGB(255 , 0 ,0));
        pFig[2]=new Triangle(300,300, 50, 1, 90, RGB(0, 255, 0));
        SetTimer(hwnd, ID_TIMER, 1, NULL); // Таймер генерирует сообщение каждые 5 миллисекунд
        break;
        }
 
    case WM_DESTROY: // Завершение программы
        KillTimer(hwnd, ID_TIMER); // Обязательно уничтожаем таймер перед завершением приложения
        PostQuitMessage(0);
        break;
    case WM_TIMER: // Обработка сообщений таймера
        hdc=GetDC(hwnd);
        for(int i=0; i<3; i++)
        {
        pFig[i]->draw(hdc, 0); // Стираем старую фигуру, а если не стирать, то будет круче
        pFig[i]->step(); // Меняем угловое положение
        pFig[i]->draw(hdc, 1);  // Рисуем фигуру 
        }
        ReleaseDC(hwnd, hdc);
        break;
 
 
    default:
        // Позволяет Windows обрабатывать любые сообщения,
        // не указанные в предыдущем случае
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}
описание классов header.h
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
#include <windows.h>
#include <math.h>
class Figure
{
protected:
    int x0, y0;
    int R;
    int angle; // Угол поворота за 1 единицу времени 
    int Pos; // Текущее угловое положение
    COLORREF col;
public:
    Figure(int x0, int y0, int r, int ang, int pos,
        COLORREF col)
    {
        this->x0=x0;
        this->y0=y0;
        this->R=r;
        this->angle=ang;
        this->Pos=pos;
        this->col=col;
    }
    virtual void step()
    {
        Pos+=angle;
        if (Pos>360) Pos-=360;
    }
    virtual void draw(HDC hdc, int flag)=0;
};
 
 
class Square: public Figure
{
private:    
    int x1, y1, x2, y2, x3, y3, x4, y4; // Координаты концов отрезка
    int vx, vy;
public:
 
    Square(int x0, int y0, int R, int ang, int p, COLORREF col);
    void step(); // Метод изменяет угловое положение фигуры
    void draw(HDC dc, int flag); // Метод рисует фигуру
    
};
Square::Square(int x0, int y0, int r, int ang, int p, COLORREF col):Figure(x0, y0, r, ang, p, col)
{
    this->vx=5;
    this->vy=3;
}
void Square::step()
{
    Figure::step();
    double PI=3.14159265358979323846;
    double ang=Pos*(PI/180); // Угловое положение в радианах
    x1=x0+R*cos(ang);
    y1=y0+R*sin(ang);
    x2=x0+R*cos(ang+PI/2);
    y2=y0+R*sin(ang+PI/2);
    x3=x0+R*cos(ang+PI);
    y3=y0+R*sin(ang+PI);
    x4=x0+R*cos(ang+(3*PI/2));
    y4=y0+R*sin(ang+(3*PI/2));
}
void Square::draw(HDC dc, int flag)
{
    if (x0>1000) vx=-vx;
    if (x0<100) vx=-vx;
    if (y0>1000) vy=-vy;
    if (y0<100) vy=-vy;
    x0=x0+vx;
    y0=y0+vy;
    HPEN p;
    if (flag) p=(HPEN)CreatePen(PS_SOLID, 1, col);
    else p=(HPEN)GetStockObject(WHITE_PEN);
    SelectObject(dc, p);
    POINT point;
    MoveToEx(dc, x1, y1, &point);
    LineTo(dc, x2, y2);
    MoveToEx(dc, x2,y2, &point);
    LineTo(dc, x3, y3);
    MoveToEx(dc, x3, y3, &point);
    LineTo(dc, x4, y4);
    MoveToEx(dc, x4, y4, &point);
    LineTo(dc, x1, y1);
    if (flag) DeleteObject(p);
}
class Triangle:public Figure
{
private:
    int x1, x2, x3, y1, y2, y3;
    int vx, vy;
public:
    Triangle(int x0, int y0, int R, int ang, int p, COLORREF col);
    void step();
    void draw(HDC dc, int flag);
};
Triangle::Triangle(int x0, int y0, int r, int ang, int p, COLORREF col):Figure(x0, y0, r, ang, p, col)
{
    this->vx=3;
    this->vy=5;
}
void Triangle::step()
{
    Figure::step();
    double PI=3.14159265358979323846;
    double ang=Pos*(PI/180); // Угловое положение в радианах
    x1=x0+R*cos(ang);
    y1=y0+R*sin(ang);
    x2=x0+R*cos(ang+PI/2);
    y2=y0+R*sin(ang+PI/2);
    x3=x0+R*cos(ang+PI);
    y3=y0+R*sin(ang+PI);
}
void Triangle::draw(HDC dc, int flag)
{
    if (x0>1000) vx=-vx;
    if (x0<100) vx=-vx;
    if (y0>1000) vy=-vy;
    if (y0<100) vy=-vy;
    x0=x0+vx;
    y0=y0+vy;
    HPEN p;
    if (flag) p=(HPEN)CreatePen(PS_SOLID, 1, col);
    else p=(HPEN)GetStockObject(WHITE_PEN);
    SelectObject(dc, p);
    POINT point;
    MoveToEx(dc, x1, y1, &point);
    LineTo(dc, x2, y2);
    MoveToEx(dc, x2,y2, &point);
    LineTo(dc, x3, y3);
    MoveToEx(dc, x3, y3, &point);
    LineTo(dc, x1, y1);
    if (flag) DeleteObject(p);
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.05.2013, 21:42     Остановка движения через поток
Посмотрите здесь:

как через поток .. C++
STL. Не работает вывод через << в поток когда использую итераторы :( C++
Нужно создать базу данных (создать пустой бинарный файл). Через поток. Поток бинарного файла описать в виде локальной переменной внутри функции. C++
Асинхронный вызов функции, возможно через другой поток C++
C++ Остановка второго потока останавливает также первый поток по непонятной причине
Скопировать поток и добавить ошибки в поток C++
C++ Чтение отдельных строк через поток
C++ Функции работы с файлами через поток не работают! Подскажите ошибку?

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ответ Создать тему
Опции темы

Текущее время: 15:47. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru