Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
-3 / 3 / 1
Регистрация: 21.03.2015
Сообщений: 133

Как сделать чтобы перерисовывалось то же что и было?

20.12.2015, 20:40. Показов 990. Ответов 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
//////////////////////////////////////////////////////////////////////
// Scribble.cpp
#include <windows.h>
#include "KWnd.h"
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    KWnd mainWnd("Scribble", hInstance, nCmdShow, WndProc); 
 
    while (GetMessage(&msg, NULL, 0, 0))  {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
 
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    static HDC hDC;
    static int x, y;  // позиция курсора мыши
    static BOOL bTracking = FALSE; 
    HDC hdcMem;
    HBITMAP hbmMem;
    HANDLE hOld;
    RECT rect;
    PAINTSTRUCT ps;
 
    switch (uMsg)
    {
    case WM_PAINT:
 
        
        break;
    case WM_CREATE:
        hDC = GetDC(hWnd);
        break;
 
    case WM_LBUTTONDOWN: 
        bTracking = TRUE;
        // начальная позиция
        x = LOWORD(lParam);
        y = HIWORD(lParam);
        MoveToEx(hDC, x, y, NULL);
        break; 
 
    case WM_LBUTTONUP:
        if (bTracking)
            bTracking = FALSE; 
        break; 
 
    case WM_MOUSEMOVE: 
 
        if (bTracking) {
 
            
 
            HPEN hPen1; 
            
            hPen1 = CreatePen(PS_DOT, 5, RGB(0,128,256));
            SelectObject(hDC, hPen1);
 
            // новая позиция
            x = LOWORD(lParam);
            y = HIWORD(lParam);
            LineTo(hDC, x, y);
            
        } 
        break;
 
    case WM_DESTROY:    
        ReleaseDC(hWnd, hDC); 
        PostQuitMessage(0);
        break;
 
        case WM_RBUTTONUP:
        /*RECT rect;
        SetBkColor(hDC, RGB(0,0,0));
        ExtTextOut(hDC, 0, 0, ETO_OPAQUE, rect, NULL, 0, NULL);
        GetClientRect (hWnd, &rect);
        FillRect (hDC, &rect, (HBRUSH)(COLOR_WINDOW+1));
        */
        RECT rect; 
        GetClientRect(hWnd, &rect);
        InvalidateRect(hWnd, &rect, true);
        break;
 
 
    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}
//////////////////////////////////////////////////////////////////////
Вопрос очень простой, видел что нужно делать снимок и потом его выводить (Типа больше никак)
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
20.12.2015, 20:40
Ответы с готовыми решениями:

как сделать , чтобы программа запоминала что было раньше
Я делаю домино на QBasic и там я сделал перемещение фишки по &quot;столу&quot; таким образом , чтобы при нажатии определённой клавиши экран очищался ...

Как сделать так чтобы было видно что подставляться в уравнения
Я хочу чтобы через равно програма подставляла числа, а через следующие результат, тоесть как бы в ручну считалось. Как это делать, можете...

как сделать разделение для столбца и строчки, в программе, чтобы было понятно что к чему
program n1; uses crt; var a:array of integer; b:array of integer; i,j:integer; begin randomize; for i:=1 to 13 do ...

1
183 / 181 / 66
Регистрация: 15.02.2015
Сообщений: 515
21.12.2015, 12:40
В общем, дело вот как обстоит.
Получить контекст устройства для рисования можно двумя основными способами:
- BeginPaint(HWND, PAINTSTRUCT*) в обработке сообщения WM_PAINT (не забыть вызвать EndPaint);
- и GetDC(HWND), вызывается когда угодно и рисовать можно когда угодно.
Первый способ нужен для отрисовки недействительной области окна (регион который необходимо перерисовать). Второй используется для рисования в окне "когда нам это надо", но в этом случае нельзя забывать про WM_PAINT, так как при первом же перекрытии окна или его "ресайзе" все наши труды пропадут.
Т.е. нам надо, что бы в WM_PAINT производилось всё то рисование, что мы делали до этого, надо это как-то и где-то "запоминать". По мне, так есть два основных способа: первый, менее ресурсоёмкий, но медленный, это векторный способ - запоминаем все действия (вызываемые GDI функции) и повторяем их в WM_PAINT, можно с помощью метафайлов, можно самому что-нибудь придумать, в любом случае для вашей ситуации это не подходит; второй - это хранить все свои труды в растровом буфере (в простонародье BITMAP), это ещё называют "Двойная буферизация".
Суть двойной буферизации в следующем: все рисование выполняется в буфере (связка совместимого контекста устройства и совместимого битмапа), который лучше всего подготовить заранее и следить за актуальностью его параметров (например размер битмапа), в обработчике WM_PAINT нужно будет просто перенести изображение в контекст устройства нашего окна (та самая BitBlt). Теперь нам не составит труда рисовать линии указателем мыши, нужно просто нарисовать линию в буфере и вызвать функцию InvalidateRect для переноса измененного буфера на экран.

Добавлено через 1 час 21 минуту
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>
 
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
 
ATOM RegClass(HINSTANCE, WNDPROC, LPCWSTR);
 
void OnPaint(HWND, LPPAINTSTRUCT);
void OnSize(HWND, LPSIZE);
void UpdateBuffer(HWND, LPSIZE);
 
LPCWSTR className = L"Main Window";
LPCWSTR windowText = L"Главное окно";
 
HDC memDC = NULL;
HBITMAP memBM = NULL;
SIZE memSize = { 0, 0 };
 
INT WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, INT nCmdShow)
{
    if (!RegClass(hInst, MainWndProc, className)) {
        MessageBoxW(NULL, L"Register main window class Fail!", L"Error", MB_OK | MB_ICONERROR);
        return 1;
    }
    HWND hWnd = CreateWindowW(
        className, 
        windowText,
        WS_OVERLAPPEDWINDOW, 
        CW_USEDEFAULT, 0, 
        CW_USEDEFAULT, 0, 
        NULL, 
        NULL, 
        hInst, 
        NULL);
    if (!hWnd) {
        MessageBoxW(NULL, L"Create main wndow Fail!", L"Error", MB_OK | MB_ICONERROR);
        return 2;
    }
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
 
    MSG msg;
 
    while (GetMessageW(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessageW(&msg);
    }
    return 0;
}
 
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    SIZE size;
    static BOOL bTracking = FALSE;
    switch (msg) {
    case WM_CREATE:
        RECT rect;
        GetClientRect(hWnd, &rect);
        UpdateBuffer(hWnd, (LPSIZE)&rect.right);
        break;
    case WM_PAINT:
        BeginPaint(hWnd, &ps);
        OnPaint(hWnd, &ps);
        EndPaint(hWnd, &ps);
        break;
    case WM_ERASEBKGND:
        return 1;
    case WM_SIZE:
        SIZE size;
        size.cx = LOWORD(lParam);
        size.cy = HIWORD(lParam);
        OnSize(hWnd, &size);
        break;
    case WM_LBUTTONDOWN:
        bTracking = TRUE;
        size.cx = LOWORD(lParam);
        size.cy = HIWORD(lParam);
        MoveToEx(memDC, size.cx, size.cy, NULL);
        break;
    case WM_LBUTTONUP:
        bTracking = FALSE;
        break;
    case WM_MOUSEMOVE:
        if (bTracking) {
            HPEN pen = CreatePen(PS_SOLID, 5, RGB(0, 128, 256));
            HGDIOBJ old = SelectObject(memDC, pen);
            size.cx = LOWORD(lParam);
            size.cy = HIWORD(lParam);
            LineTo(memDC, size.cx, size.cy);
            InvalidateRect(hWnd, NULL, FALSE);
        }
        break;
    case WM_DESTROY:
        if (memDC && memBM) {
            memBM = (HBITMAP)SelectObject(memDC, memBM);
            DeleteObject(memBM);
            DeleteDC(memDC);
        }
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProcW(hWnd, msg, wParam, lParam);
    }
    return 0;
}
 
ATOM RegClass(HINSTANCE hInst, WNDPROC proc, LPCWSTR className)
{
    WNDCLASS wc = { 0 };
    wc.hInstance = hInst;
    wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
    wc.lpszClassName = className;
    wc.lpfnWndProc = proc;
    wc.style = CS_HREDRAW | CS_VREDRAW;
 
    return RegisterClassW(&wc);
}
 
void OnPaint(HWND hWnd, LPPAINTSTRUCT lpps)
{
    if (!memDC)
        UpdateBuffer(hWnd, (LPSIZE)&lpps->rcPaint.right);
    BitBlt(lpps->hdc,
        lpps->rcPaint.left,
        lpps->rcPaint.top,
        lpps->rcPaint.right - lpps->rcPaint.left,
        lpps->rcPaint.bottom - lpps->rcPaint.top,
        memDC,
        lpps->rcPaint.left,
        lpps->rcPaint.top,
        SRCCOPY);
}
void OnSize(HWND hWnd, LPSIZE lpSize)
{
 
    if (memSize.cx < lpSize->cx || memSize.cy < lpSize->cy) {
        SIZE newSize = {
            max(memSize.cx, lpSize->cx),
            max(memSize.cy, lpSize->cy)
        };
        UpdateBuffer(hWnd, &newSize);
    }
}
void UpdateBuffer(HWND hWnd, LPSIZE lpSize)
{
    BITMAP bitmap;
    HDC hdc = GetDC(hWnd);
    HDC newDC = CreateCompatibleDC(hdc);
    HBITMAP newBM = CreateCompatibleBitmap(hdc, lpSize->cx, lpSize->cy);
    ReleaseDC(hWnd, hdc);
    newBM = (HBITMAP)SelectObject(newDC, newBM);
    RECT rect = {
        0, 0,
        lpSize->cx,
        lpSize->cy
    };
    FillRect(newDC, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
    if (memBM && memDC) {
        BitBlt(newDC, 0, 0, memSize.cx, memSize.cy, memDC, 0, 0, SRCCOPY);
        memBM = (HBITMAP)SelectObject(memDC, memBM);
        DeleteObject(memBM);
        DeleteDC(memDC);
    }
    memDC = newDC;
    memBM = newBM;
    memSize = *lpSize;
}
Добавлено через 29 минут
Вот с комментариями:
Кликните здесь для просмотра всего текста
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
#include <Windows.h>
 
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
 
ATOM RegClass(HINSTANCE, WNDPROC, LPCWSTR);
 
void OnPaint(HWND, LPPAINTSTRUCT);  //обработчик WM_PAINT
void OnSize(HWND, LPSIZE);               //обработчик WM_SIZE
void UpdateBuffer(HWND, LPSIZE);       //обновление буфера с новыми размерами
 
LPCWSTR className = L"Main Window";
LPCWSTR windowText = L"Главное окно";
 
HDC memDC = NULL;          //совместимый контекст устройства для буфера
HBITMAP memBM = NULL;   //совместимый битмап (по сути сам буфер)
SIZE memSize = { 0, 0 };    //размеры буфера (чтобы лишний раз не спрашивать об этом у memDC или memBM)
 
INT WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, INT nCmdShow)
{
    if (!RegClass(hInst, MainWndProc, className)) {
        MessageBoxW(NULL, L"Register main window class Fail!", L"Error", MB_OK | MB_ICONERROR);
        return 1;
    }
    HWND hWnd = CreateWindowW(
        className, 
        windowText,
        WS_OVERLAPPEDWINDOW, 
        CW_USEDEFAULT, 0, 
        CW_USEDEFAULT, 0, 
        NULL, 
        NULL, 
        hInst, 
        NULL);
    if (!hWnd) {
        MessageBoxW(NULL, L"Create main wndow Fail!", L"Error", MB_OK | MB_ICONERROR);
        return 2;
    }
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
 
    MSG msg;
 
    while (GetMessageW(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessageW(&msg);
    }
    return 0;
}
 
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    SIZE size;
    static BOOL bTracking = FALSE;
    switch (msg) {
    case WM_CREATE:
        RECT rect;
        GetClientRect(hWnd, &rect);
                //обновляем буфер (так как старого нет, то будет просто создан новый)
        UpdateBuffer(hWnd, (LPSIZE)&rect.right);
        break;
    case WM_PAINT:
        BeginPaint(hWnd, &ps);
        OnPaint(hWnd, &ps);
        EndPaint(hWnd, &ps);
        break;
    case WM_ERASEBKGND:
                //для того чтобы система не закрашивала нам рабочую область
        return 1;
    case WM_SIZE:
        SIZE size;
        size.cx = LOWORD(lParam);
        size.cy = HIWORD(lParam);
        OnSize(hWnd, &size);
        break;
    case WM_LBUTTONDOWN:
        bTracking = TRUE;
        size.cx = LOWORD(lParam);
        size.cy = HIWORD(lParam);
        MoveToEx(memDC, size.cx, size.cy, NULL);
        break;
    case WM_LBUTTONUP:
        bTracking = FALSE;
        break;
    case WM_MOUSEMOVE:
        if (bTracking) {
            HPEN pen = CreatePen(PS_SOLID, 5, RGB(0, 128, 256));
            HGDIOBJ old = SelectObject(memDC, pen);
            size.cx = LOWORD(lParam);
            size.cy = HIWORD(lParam);
            LineTo(memDC, size.cx, size.cy);
                        //делаем рабочую область нашего окна недействительной для переноса наших трудов на экран
            InvalidateRect(hWnd, NULL, FALSE);
        }
        break;
    case WM_DESTROY:
        if (memDC && memBM) { //удаляем буфер
            memBM = (HBITMAP)SelectObject(memDC, memBM);
            DeleteObject(memBM);
            DeleteDC(memDC);
        }
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProcW(hWnd, msg, wParam, lParam);
    }
    return 0;
}
 
ATOM RegClass(HINSTANCE hInst, WNDPROC proc, LPCWSTR className)
{
    WNDCLASS wc = { 0 };
    wc.hInstance = hInst;
    wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
    wc.lpszClassName = className;
    wc.lpfnWndProc = proc;
    wc.style = CS_HREDRAW | CS_VREDRAW;
 
    return RegisterClassW(&wc);
}
 
void OnPaint(HWND hWnd, LPPAINTSTRUCT lpps)
{
    if (!memDC)
                //если буфер всё ещё не создан, то надо создать (на всякий)
        UpdateBuffer(hWnd, (LPSIZE)&lpps->rcPaint.right);
        //собственно сам "БитБлт" (переносим изображение из буфера на экран)
    BitBlt(lpps->hdc,
        lpps->rcPaint.left,
        lpps->rcPaint.top,
        lpps->rcPaint.right - lpps->rcPaint.left,
        lpps->rcPaint.bottom - lpps->rcPaint.top,
        memDC,
        lpps->rcPaint.left,
        lpps->rcPaint.top,
        SRCCOPY);
}
void OnSize(HWND hWnd, LPSIZE lpSize)
{
        //обновляем буфер только если его нужно увеличить (чтобы сохранялось нарисованное)
    if (memSize.cx < lpSize->cx || memSize.cy < lpSize->cy) {
        SIZE newSize = {
            max(memSize.cx, lpSize->cx),
            max(memSize.cy, lpSize->cy)
        };
        UpdateBuffer(hWnd, &newSize);
    }
}
void UpdateBuffer(HWND hWnd, LPSIZE lpSize)
{
    HDC hdc = GetDC(hWnd);
        //создаём совместимый контекст (совместимый с контекстом экрана)
    HDC newDC = CreateCompatibleDC(hdc);   
        //и совместимый битмап
    HBITMAP newBM = CreateCompatibleBitmap(hdc, lpSize->cx, lpSize->cy);   
    ReleaseDC(hWnd, hdc);
        //обязательно выбираем битмап в контекст (по правилам хорошего тона, после работы с контекстом перед его удалением/освобождением, нужно выбрать в него "старые" GDI объекты, поэтому я сохраняю старый битмап)
    newBM = (HBITMAP)SelectObject(newDC, newBM);
    RECT rect = {
        0, 0,
        lpSize->cx,
        lpSize->cy
    };
        //рисуем на белом фоне
    FillRect(newDC, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
    if (memBM && memDC) {
                //если есть старый буфер, то копируем его содержимое в новый
        BitBlt(newDC, 0, 0, memSize.cx, memSize.cy, memDC, 0, 0, SRCCOPY);
                //а старый удаляем
        memBM = (HBITMAP)SelectObject(memDC, memBM);
        DeleteObject(memBM);
        DeleteDC(memDC);
    }
        //буер обновлён
    memDC = newDC;
    memBM = newBM;
    memSize = *lpSize;
}
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.12.2015, 12:40
Помогаю со студенческими работами здесь

Как сделать чтобы значение переменной было ВСЕГДА равно тому, что написано в textbox'e?
вопрос в заголовке

Как сделать так, чтобы маткад не учитывал всё, что было написано раньше в документе?
У меня есть маткадовский документ. Я хочу продолжить в нём писать дальше, но программа у меня будет работать не корректно из-за того что...

Как сделать чтобы не выполнялось, при нажатии на Space, то что было вызвано ранее кликом мышки
Всем доброго времени суток. В C# я новичок. Сделал простой видео проигрыватель, теперь пытаюсь связать кнопки с событием на клавиатуре: ...

Как сделать, чтобы при нажатии на ссылку, ссылка пропадала, а у меня было, видно, что я на неё нажал?
Здравствуйте, вопрос такой.У меня есть много ссылок я пользователь под именем user, как сделать так что бы при нажатии на ссылку мной,...

Что сделать, чтобы было ноль?
Добрый день!Ребята, помогите, если сможете с решением. Задана матрица Z(5,4). В каждой строке найти первый отрицательный элемент и...


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

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