Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 Аватар для Наталья8
523 / 373 / 66
Регистрация: 09.03.2016
Сообщений: 3,963

Как вам вот такое вот извращённое создание UP-DOWN control. Вообще работает. Как такое можно?

21.12.2025, 02:43. Показов 914. Ответов 9

Студворк — интернет-сервис помощи студентам
Как это всё описать то?
Сверху создание элемента UP-DOWN с привязанным к нему EDIT для циферок.
При переключении UP-DOWN вызываеться лямбда функция (case WM_NOTIFY внизу)
Лямбда в начале --- LRESULT CALLBACK WndProc(HWND hWnd,...
Это переключение закладок...
А мне надо, что бы на клик по EDIT, вызывалась та же лямбда...
Здесь callback на EDIT и вызов этой лямбды из другого обработчика.
LRESULT CALLBACK EditProc(HWND 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
#include <functional> // Для std::function
 
// Глобальное хранилище для нашего колбэка (если нужно хранить его долго)
std::function<void(int)> g_callback_storage;// Вызов лямбды извне (Лямбда находиться в основном обработчике формы)
 
void register_callback(std::function<void(int)> callback) {
    g_callback_storage = callback; // Сохраняем лямбду
}
// ====================
WNDPROC EditDefault;
LRESULT CALLBACK EditProc(HWND, UINT, WPARAM, LPARAM); // наша функция которая будет обрабатывать события edit'a
LRESULT DoDebugDialog(HWND hwndApp, LPVOID pvData);
// ----------------------------------------------------
void CreateControls(HWND hwnd) {
    //  Обеспечивает загрузку DLL - библиотеки общего элемента управления(Comctl32.dll)
    //      и регистрирует из неё определённые классы общих элементов управления.
    //  Приложение должно вызвать эту функцию перед созданием общего элемента управления.
    INITCOMMONCONTROLSEX icex;
    icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
    icex.dwICC = ICC_UPDOWN_CLASS;
    InitCommonControlsEx(&icex);
    
    HWND hUpDown, hEdit, hStatic;
    hUpDown = CreateWindowW(UPDOWN_CLASSW, NULL, WS_CHILD | WS_VISIBLE
        | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_WRAP,
        0, 0, 0, 0, hwnd, (HMENU)ID_UPDOWN, NULL, NULL);
 
    hEdit = CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDITW, NULL, WS_CHILD
        | WS_VISIBLE | ES_RIGHT, 0, 0, 0, 0, hwnd,
        (HMENU)ID_EDIT2, NULL, NULL);
 
    EditDefault = (WNDPROC)GetWindowLongPtr(hEdit, GWLP_WNDPROC); // здесь получили указатель на нее (Клик по EDIT)
    SetWindowLongPtr(hEdit, GWLP_WNDPROC, (LONG_PTR)EditProc); // меняем указатель на нашу функцию LRESULT CALLBACK EditProc(
 
    SendMessageW(hUpDown, UDM_SETBUDDY, (WPARAM)hEdit, 0);
    SendMessageW(hUpDown, UDM_SETRANGE, 0, MAKELPARAM(15, 0));// Минус один, что бы по кругу включался ноль, (было ноль.)
    SendMessageW(hUpDown, UDM_SETPOS32, 0, 0);
}
 
 
??????????????????????????????????
??????????????????????????????????
 
HWND hWnd_n;// Надо для работы HWND основного обработчика, то что ниже - гавно
 
LRESULT CALLBACK EditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case  WM_LBUTTONDOWN:
    {
// ======================== Эта х ня в скобочках, выполняет клик по EDIT привязанному к UPDOWN закладок.
        char for_dg[4]{};// Ставит курсор туда по цифре в EDIT
        GetWindowTextA(GetDlgItem(hWnd_n, ID_EDIT2), for_dg, BUFSIZ);// Поискать линок и установить на него курсор
//std::atoi - Строка в стиле C(const char*)
//std::stoi -         C++ std::string
        int for_pos = std::atoi(for_dg); // Convert the string to int
    if (g_callback_storage)
        g_callback_storage(for_pos); // Вызываем сохраненную лямбду
    }
  break;
    default:
return CallWindowProc(EditDefault, hWnd, message, wParam, lParam); // все остальные события пусть обрабатывает стандартный обработчик
    }
    return 0;
}
 
 
 
// =========== 1669 case WM_NOTIFY: ===================== Up-Down Control ====================
// Функция на выполнение восемью строками ниже ( auto setcur{[]{}} )
// ==================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
hWnd_n = hWnd;
 
    LRESULT retval = 0;
    short indent{};
    static std::vector<std::string> bookmarks;// Надо обязательно static.. А то пересоздаёться
// =======================================
    auto setcur{ [&](int val) {// =========================== Установим курсор  щелчками по up - down
        if (val < 1 ||val > bookmarks.size()) return;
std::wstring erty{};
    const int req_size = MultiByteToWideChar(CP_UTF8, 0, bookmarks[val-1].c_str(), -1, nullptr, 0);
    erty.resize(req_size);
    MultiByteToWideChar(CP_UTF8, 0, bookmarks[val-1].c_str(), -1, &erty[0], req_size);
    
    int indx// Индекс найденного в LISTBOX линка(или -1)
       = get_index(hWnd_n, (wchar_t*)erty.c_str());
 if(indx > -1) Beep(3000, 10);
      else return;
 
  SendMessage(GetDlgItem(hWnd_n, IDC_LISTBOX1), LB_SETCURSEL, (WPARAM)indx, 0);// Установить курсор      
    } };
// =======================================
 
    static short *ln_cnt = NULL; // указатель для поимения массива с количеством строк между линками
static wchar_t buf[BUFSIZ]{};//Под путь на рабочий стол
static HMENU hEdit{};
static HMENU hMenubar{};
static CMenuToolTip mi_ToolTip;
switch (uMsg)
{
case WM_CREATE:
{
    register_callback(setcur); // Регистрируем лямбду
 
 
???????????????????????????
???????????????????????????
 
case WM_NOTIFY:
{// ========================================================= Up-Down Control ======================
if (((LPNMHDR)lParam)->code == UDN_DELTAPOS) {
        LPNMUPDOWN lpnmud;
        lpnmud = (NMUPDOWN *)lParam;
    setcur(lpnmud->iPos + lpnmud->iDelta);
    }  }
break;
Название: NewPicture14.png
Просмотров: 195

Размер: 674 байт
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.12.2025, 02:43
Ответы с готовыми решениями:

Моё извращённое сознание
Задача для идиотов, но я с ней не справился: Вычислить приближённое значение бесконечной суммы с...

Вот такое вот кажется лёгкое задание но не как не могу решить.
задание 223(В,И)Картинки загружайте на форум, во избежание их удаления или потери на сторонних...

вот такой вот пример
даны числа a1,a2,...,a10.Определить их сумму оператор цикла и условного оператора! как это ?

9
фрилансер
 Аватар для Алексей1153
6454 / 5655 / 1129
Регистрация: 11.10.2019
Сообщений: 15,057
21.12.2025, 15:34
Лучший ответ Сообщение было отмечено Наталья8 как решение

Решение

Наталья8, у тебя при каждом вызове оконной процедуры создаётся новый экземпляр лямбды auto setcur. Тебе это точно именно так нужно?
Захватывается локальный контекст по ссылке (опасненько, так как ты потом в глобальную обёртку сохраняешь лямбду)
register_callback(setcur);

при этом почему-то вызываешь всё равно локальный вариант
setcur(lpnmud->iPos + lpnmud->iDelta);

Отсюда такие мысли:
g_callback_storage - не нужен

bookmarks сделать глобальным, саму лямбду - тоже (в виде функции)

(форматирование и комментарии автора сохранены)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <functional>
#include <string>
 
std::vector<std::string> bookmarks;
 
void setcur(int val) {// =========================== Установим курсор  щелчками по up - down
        if (val < 1 ||val > bookmarks.size()) return;
std::wstring erty{};
    const int req_size = MultiByteToWideChar(CP_UTF8, 0, bookmarks[val-1].c_str(), -1, nullptr, 0);
    erty.resize(req_size);
    MultiByteToWideChar(CP_UTF8, 0, bookmarks[val-1].c_str(), -1, &erty[0], req_size);
    
    int indx// Индекс найденного в LISTBOX линка(или -1)
       = get_index(hWnd_n, (wchar_t*)erty.c_str());
 if(indx > -1) Beep(3000, 10);
      else return;
 
  SendMessage(GetDlgItem(hWnd_n, IDC_LISTBOX1), LB_SETCURSEL, (WPARAM)indx, 0);// Установить курсор      
    }
1
 Аватар для Наталья8
523 / 373 / 66
Регистрация: 09.03.2016
Сообщений: 3,963
21.12.2025, 23:44  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
Отсюда такие мысли:
Да мы тут вместе с этим интелектом.
Но я его долго напрягал. Я тоже работал.
Я спрашивал как вызвать лямбду из другой функции.
Вот он мне такое и вывернул.... (#include <functional> // Для std::function)
Вообще меня в этом возбуждает только то,
что извне вызываеться лямбда в локальной зоне. И использует вектор.

Написан ещё вариант на булевой переменной в глобале.
if (enter_buk) { и вызывает лямбду.... (Локально вызывает)
А кальбак на EDIT только переменную опрокидывает.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// ============================ Нажатие П.К.М. ============ (Мышь)
case WM_SETCURSOR:// Эта  курсор портит на краю формы
 
    if (enter_buk) {
// ======================== Эта  в скобочках, выполняет клик по EDIT привязанному к UPDOWN закладок.
    char for_dg[4]{};// Ставит курсор туда по цифре в EDIT
    GetWindowTextA(GetDlgItem(hWnd, ID_EDIT2), for_dg, BUFSIZ);// Поискать линок и установить на него курсор    
    int for_pos = std::atoi(for_dg); // Convert the string to an int
setcur(for_pos);
enter_buk = false;
   }
    if (GetDlgItem(hWnd, IDC_LISTBOX1) == (HWND)wParam)
            {
        switch (*(1 + (WORD*)&lParam))
case WM_RBUTTONDOWN:// Переписываеться строка из листбокс в EDIT
            {
    Beep(4800, 8);
            int nIndex = SendMessage(GetDlgItem(hWnd, IDC_LISTBOX1), LB_GETCURSEL, (WPARAM)0, (LPARAM)0);
Я сделаю лямбду static ---
C++
1
2
3
4
5
6
7
8
9
10
LRESULT retval = 0;
    short indent{};
    static std::vector<std::string> bookmarks;// Надо обязательно static.. А то пересоздаёться
// =======================================
    static auto setcur{ [&](int val) {// ================ Установим курсор  щелчками по up - down
        if (val < 1 ||val > bookmarks.size()) return;
std::wstring erty{};
    const int req_size = MultiByteToWideChar(CP_UTF8, 0, bookmarks[val-1].c_str(), -1, nullptr, 0);
    erty.resize(req_size);
    MultiByteToWideChar(CP_UTF8, 0, bookmarks[val-1].c_str(), -1, &erty[0], req_size);
Тогда она не будет пересоздаваться?

Добавлено через 2 минуты
Цитата Сообщение от Алексей1153 Посмотреть сообщение
bookmarks сделать глобальным, саму лямбду - тоже (в виде функции)
Была такая мысль. Не хотелось делать вектор глобальным.
0
фрилансер
 Аватар для Алексей1153
6454 / 5655 / 1129
Регистрация: 11.10.2019
Сообщений: 15,057
22.12.2025, 06:25
Цитата Сообщение от Наталья8 Посмотреть сообщение
Тогда она не будет пересоздаваться?
не будет, но это, на мой взгляд, хуже, чем глобальный объект и глобальная функция.

А если у тебя окон на данной оконной процедуре будет несколько, как будешь контролировать этот момент?
Впрочем, с глобальными тоже такая проблема. Тут можно std::map заюзать, кстати.

А где у тебя размер вектора меняется ?

Добавлено через 49 секунд
Цитата Сообщение от Наталья8 Посмотреть сообщение
Я спрашивал как вызвать лямбду из другой функции.
ну тебе такое не требуется, у тебя одна функция же
0
 Аватар для Наталья8
523 / 373 / 66
Регистрация: 09.03.2016
Сообщений: 3,963
22.12.2025, 12:43  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
А где у тебя размер вектора меняется ?
При развёртывании экзешника заполняеться из текста как бы любимыми адресами.
Курсор ставить на найденные адреса. Закладки. Типа.
Вектор просто читаеться. Зачем его размер менять?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
case WM_CREATE:
// ????????????????????
while ((contr[num_of] = fgetc(file_ptr)) != EOF && num_of++ < 10);
            if (memcmp(contr, liter, strlen(liter)) != 0) {
                MessageBoxA(NULL, "the text in the bookmarks file is not defined", "warning", MB_OK | MB_ICONSTOP | MB_SETFOREGROUND | MB_SYSTEMMODAL);
            }
            else {
                fseek(file_ptr, cur_dt, SEEK_SET);
                unsigned at{ cur_dt };
                do {
                    memset(data_n, 0, strlen(data_n));
                    fscanf(file_ptr, "%384[^\n\r]", data_n);
 
    if (bool_control)bookmarks.push_back(data_n);// Вставлять в вектор, то что после последнего умного слова
                    if (strncmp(data_n, liter_n, strlen(liter_n)) == 0)bool_control = true;
                    at += strlen(data_n) + 2;
                    fseek(file_ptr, at, SEEK_SET); //go back to where we were
                } while (strncmp(data_n, liter, strlen(liter)) != 0);
            }
            fclose(file_ptr);
Добавлено через 2 минуты
Цитата Сообщение от Алексей1153 Посмотреть сообщение
у тебя одна функция же
Кальбак - это функция или не функция?
Это когда клик по связанному EDIT.

Две кальбак функции. В одной лямбда. Лямбда вызываеться глобально, из кальбак EDIT
и локально из case WM_NOTIFY: -- основного кальбак


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
LRESULT CALLBACK EditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case  WM_LBUTTONDOWN:
    {
// ======================== Эта  в скобочках, выполняет клик по EDIT привязанному к UPDOWN закладок.
        char for_dg[4]{};// Ставит курсор туда по цифре в EDIT
        GetWindowTextA(GetDlgItem(hWnd_n, ID_EDIT2), for_dg, BUFSIZ);// Поискать линок и установить на него курсор
//std::atoi - Строка в стиле C(const char*)
//std::stoi -         C++ std::string
        int for_pos = std::atoi(for_dg); // Convert the string to int
    if (g_callback_storage)
        g_callback_storage(for_pos); // Вызываем сохраненную лямбду
    }
  break;
    default:
return CallWindowProc(EditDefault, hWnd, message, wParam, lParam); // все остальные события пусть обрабатывает стандартный обработчик
    }
    return 0;
}
0
фрилансер
 Аватар для Алексей1153
6454 / 5655 / 1129
Регистрация: 11.10.2019
Сообщений: 15,057
22.12.2025, 13:36
Цитата Сообщение от Наталья8 Посмотреть сообщение
Вектор просто читаеться. Зачем его размер менять?
так вектор изначально пустой, если размер не задавать, будет UB

но я не увидел, где размер bookmarks меняется


Цитата Сообщение от Наталья8 Посмотреть сообщение
Две кальбак функции.
а, всё, да.

Но тем более лучше вариант с глобальной функцией вместо лямбды и глобальным вектором bookmarks
0
 Аватар для Наталья8
523 / 373 / 66
Регистрация: 09.03.2016
Сообщений: 3,963
22.12.2025, 14:26  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
если размер не задавать, будет UB
Да ну... Если делать push_back(); то он сам растягиваеться. Мне скорость не надо.
Есть десять штук.

0
 Аватар для Наталья8
523 / 373 / 66
Регистрация: 09.03.2016
Сообщений: 3,963
22.12.2025, 14:30  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
Но тем более лучше вариант с глобальной функцией
Как сказать... Я люблю разные методы, разные подходы туда вставлять. Это как бы кладезь...
Разбираеться на запчасти. Мало ли понадобиться.
Прикольно...
0
 Аватар для Наталья8
523 / 373 / 66
Регистрация: 09.03.2016
Сообщений: 3,963
22.12.2025, 14:35  [ТС]
0
фрилансер
 Аватар для Алексей1153
6454 / 5655 / 1129
Регистрация: 11.10.2019
Сообщений: 15,057
22.12.2025, 15:24
Цитата Сообщение от Наталья8 Посмотреть сообщение
Если делать push_back();
в первом посте не было
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.12.2025, 15:24
Помогаю со студенческими работами здесь

Что сделать с вот такой вот кодировкой
Тема выделена из темы: https://www.cyberforum.ru/cpp-builder/thread622714.html По поводу вызовов...

Нужна помощь с Source Control, Bug Control
Очень нужна помощь с таким вопросом: 1) надо организовать работу нескольких программеров с кодом ...

Связь Edit control и Spin Control
Здравствуйте. Имеется spin control и связанный с ним edit и множество прочих editов. Надо добиться...

Вписать один Picture control в другой Picture Control на MFC C++
Добрый день, господа! Подскажите пожалуйста как в экранных координатах (проект MFC C++) один...

Как инициализовать string в таком случае и можно ли вообще?
Всем привет. Суть задачи - если пользователь вводит цифру - вывести эту цифру словами ( 1 - one),...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
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 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru