Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
123
36 / 0 / 1
Регистрация: 18.03.2015
Сообщений: 221

Не работает клик мыши

06.03.2026, 06:52. Показов 6271. Ответов 66
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Отрисовываю треугольник на openGL.

Переменная qf должна при клике увеличиваться на 3 таким образом меняется координата нижней правой точки треугольника.
Но даже не рендерится...

C++
1
2
3
4
5
6
 case WM_LBUTTONDOWN:
        {
            //int xPos = GET_X_LPARAM(lParam);
          //  int yPos = GET_Y_LPARAM(lParam);
 
           // qf = qf*3;

||=== Build: Debug in quad+ (compiler: GNU GCC Compiler) ===|
++\quad+\main.c||In function 'WindowProc':|
++\quad+\main.c|125|error: implicit declaration of function 'GET_X_LPARAM'; did you mean 'GET_SC_WPARAM'? [-Wimplicit-function-declaration]|
++\quad+\main.c|126|error: implicit declaration of function 'GET_Y_LPARAM'; did you mean 'GET_SC_WPARAM'? [-Wimplicit-function-declaration]|
++\quad+\main.c|128|error: 'q' undeclared (first use in this function)|
++\quad+\main.c|128|note: each undeclared identifier is reported only once for each function it appears in|
++\quad+\main.c|126|warning: unused variable 'yPos' [-Wunused-variable]|
++\quad+\main.c|125|warning: unused variable 'xPos' [-Wunused-variable]|
||=== Build failed: 3 error(s), 2 warning(s) (0 minute(s), 3 second(s)) ===|
Могу уточнить детали если нужно.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
06.03.2026, 06:52
Ответы с готовыми решениями:

Клик мыши, как сделать?
Нужна просто команда или функция которая бы кликалы мыш в часть экрана где она установлена. Можно...

Клик мыши на пиксел
хочу написать код, который будет в заданных координатах кликать левой кнопкой мыши на пиксели...

Перемещение курсора мыши на заданные координаты и клик
Добрый день. Подскажите, пожалуйста, как можно реализовать сабж. Гугление выдает некоторые...

66
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,306
30.03.2026, 02:17
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от 8Observer8 Посмотреть сообщение
если точно, то нужно вызвать DestroyWindow() при обработке WM_CLOSE
... или просто разрешить WM_CLOSE провалиться дальше в обработчик по умолчанию, то есть в DefWindowProc. Дело вкуса.
1
9949 / 2950 / 497
Регистрация: 05.10.2013
Сообщений: 8,030
Записей в блоге: 242
30.03.2026, 03:37

Не по теме:

Я нашёл как вы выделяете текст - это тег [inline]



Я удалил строку case WM_CLOSE:, чтобы событие WM_CLOSE провалилось в обработчик по умолчанию:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_DESTROY:
            g_running = false;
            PostQuitMessage(0);
            return 0;
 
        /* ... */
 
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Добавил защиту для функции glViewport(x, y, width, height), чтобы не было ситуации передачи нулевых значений ширины и высоты вьюпорта. Вьюпорт это рамка, внутри которой рисует видеокарта. Нежелательно, чтобы высота или ширина рамки была равна нулю. При сворачивании окна размер приходит событие WM_SIZE и размеры клиентской области окна (то есть холста), равны нулю. Эта защита пригодится и для пересчёта матрицы проекции, чтобы не было деления на ноль внутри функции glm_ortho(left, right, bottom, top, near, far, projection):

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
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_DESTROY:
            g_running = false;
            PostQuitMessage(0);
            return 0;
        case WM_SIZE:
            int width = LOWORD(lParam);
            int height = HIWORD(lParam);
 
            // printf("Size: %d, %d\n", width, height);
 
            if (width == 0 || height == 0)
                return 0;
 
            if (g_hRC != NULL)
            {
                glViewport(0, 0, width, height);
 
                // Здесь можно пересчитать матрицу проекции, 
                // чтобы треугольник не растягивался
            }
            return 0;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Исправил код вращающегося треугольника из сообщения #58, чтобы он компилировался C++ компилятором. Основная правка коснулась передачи векторов в функции cglm (такие как glm_translate, glm_rotate). Поскольку C++ не поддерживает C-style составные литералы в аргументах функций, я вынес векторы в отдельные переменные vec3:

C++
1
2
3
// Пример исправления:
vec3 camera_pos = { 0.0f, 0.0f, -3.0f };
glm_translate(view, camera_pos);
main.cpp

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
#include <cglm/cglm.h>
#include <glad/glad.h>
#include <stdbool.h>
#include <windows.h>
#include <stdio.h>
 
const char *vertexShaderSource =
    "#version 330 core\n"
    "layout (location = 0) in vec3 aPosition;\n"
    "uniform mat4 mvp;\n"
    "void main()\n"
    "{\n"
    "   gl_Position = mvp * vec4(aPosition, 1.0);\n"
    "}\n";
 
const char *fragmentShaderSource =
    "#version 330 core\n"
    "out vec4 fragColor;\n"
    "void main()\n"
    "{\n"
    "   fragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
    "}\n";
 
HWND g_hWnd = NULL;
HDC g_hDC = NULL;
HGLRC g_hRC = NULL;
bool g_running = true;
 
typedef BOOL(WINAPI *PFNWGLSWAPINTERVALEXTPROC)(int interval);
 
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_DESTROY:
            g_running = false;
            PostQuitMessage(0);
            return 0;
        case WM_SIZE:
            int width = LOWORD(lParam);
            int height = HIWORD(lParam);
 
            // printf("Size: %d, %d\n", width, height);
 
            if (width == 0 || height == 0)
                return 0;
 
            if (g_hRC != NULL)
            {
                glViewport(0, 0, width, height);
 
                // Здесь можно пересчитать матрицу проекции, 
                // чтобы треугольник не растягивался
            }
            return 0;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    WNDCLASS wc = { 0 };
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = "Sample Window Class";
    wc.style = CS_OWNDC;
    RegisterClass(&wc);
 
    g_hWnd = CreateWindowEx(0, wc.lpszClassName, "OpenGL 3.3, WinAPI, C++",
        WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
        CW_USEDEFAULT, CW_USEDEFAULT, 350, 350,
        NULL, NULL, hInstance, NULL);
 
    ShowWindow(g_hWnd, nShowCmd); 
    UpdateWindow(g_hWnd);
 
    g_hDC = GetDC(g_hWnd);
    PIXELFORMATDESCRIPTOR pfd = { sizeof(pfd), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 32 };
    SetPixelFormat(g_hDC, ChoosePixelFormat(g_hDC, &pfd), &pfd);
 
    g_hRC = wglCreateContext(g_hDC);
    wglMakeCurrent(g_hDC, g_hRC);
 
    if (!gladLoadGL())
        return -1;
 
    // Compile vertex shader
    unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);
 
    // Compile fragment shader
    unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
 
    // Link shader program
    unsigned int shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
 
    // Setup triangle data
    float vertices[] = {
        -0.5f, -0.5f, 0.0f,
        0.5f, -0.5f, 0.0f,
        0.0f, 0.5f, 0.0f
    };
 
    unsigned int VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
 
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
    glEnableVertexAttribArray(0);
 
    int mvpLoc = glGetUniformLocation(shaderProgram, "mvp");
 
    glClearColor(50.f / 255.f, 50.f / 255.f, 50.f / 255.f, 1.f);
 
    // Get the function from the driver
    PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT =
        (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
 
    // Enable VSync (1 = On, 0 = Off)
    if (wglSwapIntervalEXT)
    {
        wglSwapIntervalEXT(1);
    }
 
    float rotation = 0.0f;
 
    // Setup a timer
    LARGE_INTEGER frequency, lastTime, currentTime;
    QueryPerformanceFrequency(&frequency);
    QueryPerformanceCounter(&lastTime);
 
    MSG msg = { 0 };
    while (g_running)
    {
        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
 
        glClear(GL_COLOR_BUFFER_BIT);
        glUseProgram(shaderProgram);
 
        QueryPerformanceCounter(&currentTime);
        float deltaTime = (float)(currentTime.QuadPart - lastTime.QuadPart) / frequency.QuadPart;
        lastTime = currentTime;
 
        // Rotate 1 radian per second
        rotation += 1.0f * deltaTime;
 
        // Model Matrix
        mat4 model;
        glm_mat4_identity(model);
 
        vec3 model_pos = { 0.2f, 0.0f, 0.0f };
        glm_translate(model, model_pos);
 
        vec3 axis_z = { 0.0f, 0.0f, 1.0f };
        glm_rotate(model, rotation, axis_z);
 
        vec3 model_scale = { 1.5f, 1.5f, 1.0f };
        glm_scale(model, model_scale);
 
        mat4 view;
        glm_mat4_identity(view);
 
        vec3 camera_pos = { 0.0f, 0.0f, -3.0f }; // Move camera back
        glm_translate(view, camera_pos);
 
        mat4 projection;
        // Arguments: left, right, bottom, top, near, far
        glm_ortho(-2.0f, 2.0f, -2.0f, 2.0f, 0.1f, 100.f, projection);
 
        mat4 mvp;
        glm_mat4_mul(projection, view, mvp);
        glm_mat4_mul(mvp, model, mvp); // Final MVP = P * V * M
 
        // Send the final matrix to shader
        glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, (float *)mvp);
 
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 3);
 
        SwapBuffers(g_hDC);
    }
 
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteProgram(shaderProgram);
 
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(g_hRC);
    ReleaseDC(g_hWnd, g_hDC);
 
    return 0;
}
0
9949 / 2950 / 497
Регистрация: 05.10.2013
Сообщений: 8,030
Записей в блоге: 242
30.03.2026, 03:59
Файлы проекта для примера вращающегося треугольника из предыдущего сообщения:
Вложения
Тип файла: zip transformed-triangle-opengl33-winapi-cpp.zip (4.1 Кб, 2 просмотров)
0
123
36 / 0 / 1
Регистрация: 18.03.2015
Сообщений: 221
06.04.2026, 13:01  [ТС]
000d60
Основы не мотивируют пока что. Пресные они...
3д именно и задумывается, но если не осилю то ок. Сомнительно но окэй.


8Observer8
Какая задумка для xPos и yPos?

Выдрал с сайта. Думал важно раз в них параметры.
0
Заблокирован
06.04.2026, 13:32
Цитата Сообщение от Андрей1926 Посмотреть сообщение
Основы не мотивируют пока что. Пресные они...
Без воды не сделать омлет.
Без кирпича не выловишь и рыбку.
Ты понял
0
Нарушитель
623 / 381 / 67
Регистрация: 09.03.2016
Сообщений: 4,217
06.04.2026, 15:07
Вот сочинил... Ничего что не по русски?

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
bool ClickMouse(DWORD mouse_keys_DOWN, POINT cur_Pos, RECT rect)
{
    bool n_enter{ true };
 auto control{ [&n_enter](DWORD mouse_keys, RECT rect)->bool {
    if (SetCursorPos(rect.left, rect.top)) {
            POINT cursorPos{};
            if (GetCursorPos(&cursorPos)) {
                HWND chrom_hwnd = WindowFromPoint(cursorPos);
                char className[64]{};
                GetClassNameA(chrom_hwnd, className, sizeof(className));
 
    if ((mouse_keys == MOUSEEVENTF_RIGHTDOWN && strcmp(className + 7, "WindowClass") != 0) ||
            (mouse_keys == MOUSEEVENTF_LEFTDOWN && strcmp(className + 7, "DropShadowWindowClass") != 0))
                {
                return false;
                }
                return true;
            }   }
      n_enter= false;// Будет вылет по ошибке, а нажатия не будет..
      return false;
 }   };
 
 //==================================================
    if (mouse_keys_DOWN == MOUSEEVENTF_LEFTDOWN) {
        Sleep(200);
        rect.top += 90;
        // Менюшник короткий по нему не попал.
        if (!control(MOUSEEVENTF_LEFTDOWN, rect))rect.top -= 90;
        else rect.top -= 58;// Менюшник длинный
    SetCursorPos(rect.left, rect.top);
    }
    else if (!control(MOUSEEVENTF_RIGHTDOWN, rect)) {
        
        SetCursorPos(cur_Pos.x, cur_Pos.y);
        MessageBox(NULL, L"Не попал!", L"Error", MB_OK |
            MB_ICONQUESTION | MB_SETFOREGROUND | MB_SYSTEMMODAL);   
        return false;
        }
if (n_enter) {
        INPUT input = { 0 };
        input.type = INPUT_MOUSE;
        input.mi.dwFlags = mouse_keys_DOWN; // Нажать кнопку
        SendInput(1, &input, sizeof(INPUT));
        Sleep(2);
        // Подготовка структуры ввода для отпускания левой кнопки
        ZeroMemory(&input, sizeof(INPUT));
        input.type = INPUT_MOUSE;
        //----------------------------
        if (mouse_keys_DOWN == MOUSEEVENTF_RIGHTDOWN)
            input.mi.dwFlags = MOUSEEVENTF_RIGHTUP; // Отпустить кнопку
        else input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
        SendInput(1, &input, sizeof(INPUT));
    return true;
    }
else {
    SetCursorPos(cur_Pos.x, cur_Pos.y);
    MessageBox(NULL, L"Не понятная ошибка!", L"Error", MB_OK |
        MB_ICONQUESTION | MB_SETFOREGROUND | MB_SYSTEMMODAL);
   return false;
}   }
Одна задержка в строке 25.
Как не странно работает корректно.
0
9949 / 2950 / 497
Регистрация: 05.10.2013
Сообщений: 8,030
Записей в блоге: 242
06.04.2026, 15:46
Цитата Сообщение от Андрей1926 Посмотреть сообщение
Какая задумка для xPos и yPos?
Выдрал с сайта. Думал важно раз в них параметры.
Главное, чтобы вы сейчас понимали, что это локальные переменные, то есть они видимы только в пределах фигурных скобок. Код из вашего сообщения #6:

C++
1
2
3
4
5
6
7
8
9
10
       case WM_LBUTTONDOWN:
        {
            int xPos = GET_X_LPARAM(lParam);
          int yPos = GET_Y_LPARAM(lParam);
 
        q = q*3.0f;
              // InvalidateRect(hWnd, NULL, TRUE);
 
            return 0; // Message processed
        }
Вы удалили весь код, который использовал xPos и yPos. Вы видите, что перед ними стоят объявления int. Это значит, что они локальные и вы оставляете эти объявления, думая, что они где-то пригодятся в других местах программы. Не могут эти локальные переменные где-то пригодиться, так как для них область видимости - это фигурные скобки между которыми они находятся. Эти локальные переменные невидимы за пределами фигурных скобок. Вам надо срочно взять книгу или туториал по основам C++ и прочитать первые главы про объявления переменных локальными и глобальными и про области видимости.

В xPos и yPos считываются координаты клика мыши. Придумывайте маленькие упражнения для практики - как использовать эти данные. Например, для начала, можно менять положение треугольника по клику мыши, то есть выводить треугольник, где вы кликнули. Потом можно будет дописать программу, чтобы можно было определять был ли клик внутри треугольника или снаружи. Можно цвет треугольника менять на зелёный если вы кликнули по треугольнику и на красный, если вы кликнули вне треугольника. Из комбинаций множества маленьких упражнений вырастают всё более крупные программы. Практиковаться надо регулярно.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
06.04.2026, 15:46

Клик мыши
Доброго времени суток. Помогите дойти до истины. Полазив по некоторым ресурсам, по раздумав сам я...

Клик мыши в координатах
Всем Привет, необходимо программно кликнуть допустим по координате (X;Y). Как это реализовать....

Реализовать движение мыши по какой-нибудь траектории, и в конце ее - клик левой кнопкой
Здравствуйте. Подскажите как реализовать движение мыши по какой-нибудь траектории и в конце вызвать...

Как сделать, чтобы клик мыши дублировался?
Как сделать так чтобы клик дублировался? То есть когда я нажал мышкой в координатах x,y , этот...

Клик мыши программно
Как заставить мышь кликнуть программно


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

Или воспользуйтесь поиском по форуму:
67
Ответ Создать тему
Новые блоги и статьи
Алиса нашла кучу ошибок компиляции и запуска в проекте, который без проблем компилировался и запускался)))
anaschu 30.06.2026
Я пока посмеюся, но завтра проверю. А вообще интерсно. Дал алисе файл, в котором точно нет ошибок компиляции и запуска, и попросил их найти. Нашла кучу))) Критические ошибки, мешающие компиляции и. . .
сукцессия 16. Общий обзор, в основном что бы другие ии поняли
anaschu 29.06.2026
# Передаточный документ: модель микоризной сукцессии (для нового чата) Этот документ предназначен для того, чтобы новый чат Claude мог продолжить работу без необходимости заново разбираться в. . .
сукцессия 15 неявная схема
anaschu 29.06.2026
Алиса Калибровка параметров симбиотической модели: технический обзор Содержание: Введение Постановка проблемы Технические аспекты реализации Процесс внедрения изменений
сукцессия 14. Обновленная схема модели
anaschu 28.06.2026
ГЛОБАЛЬНАЯ ОПИСАТЕЛЬНАЯ СПЕЦИФИКАЦИЯ ЭКОСИСТЕМНОЙ МОДЕЛИ «SOIL CHEMISTRY & MYCORRHIZA 2. 0» https:/ / ibb. co/ NnkGpfMd Представленная интегрированная схема описывает непрерывную нелинейную. . .
сукцессия 13. Питон модель трехзонного мицелия, пока что в основном арбускулярного
anaschu 28.06.2026
## Разработка агентной модели микоризной сукцессии: от выявления артефактов к созданию комплексной системы ### Аннотация Представлено исследование по разработке агентной модели микоризной. . .
сукцессия 12. краткий список проверок модели перед запуском.
anaschu 27.06.2026
Скрытые отказы в моделях систем динамики (SD-models) экологических систем: два случая из практики Контекст Разбирался прототип модели систем динамики (SD-модели) микоризной сукцессии: пять. . .
Сукцессия 11. Проверка орудий перед войной: разработка через тестирование
anaschu 27.06.2026
Как не дать модели соврать самой себе: проверки для симуляции микоризной сукцессии Введение Когда вы строите математическую модель живой системы — грибов, растений, почвы — главная опасность. . .
10 сукцессия. Питон код войны грибов и растений
anaschu 27.06.2026
import numpy as np class PlantAgent: def __init__(self, name, strategy, initial_biomass): self. name = name self. strategy = strategy # "greedy" (широколиственные) или. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru