Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.74/288: Рейтинг темы: голосов - 288, средняя оценка - 4.74
188 / 120 / 4
Регистрация: 23.01.2010
Сообщений: 1,320

Учебная статья - создание меню средствами API C++

31.07.2012, 01:44. Показов 57187. Ответов 32
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Учебная статья - создание меню средствами API C++\СИ
Добрый день, решил поделиться инфой по созданию меню VS 2010 средствами только API. Если есть желающие опишите что я не успею.

Значит чтобы создать меню существует такая функция:

C++
1
  HMENU hMenu = CreateMenu(void);
данную функцию надо вызывать при создании меню. Т.е. меню создается, но вы его не увидете до тех пор пока не добавите элемент в меню.

Чтобы добавить элемент существует функция:
C++
1
 BOOL = AppendMenu();
ее например вызывает с такими параметрами:

C++
1
  AppendMenu(hmenu1, MF_STRING, 0, L"File");
Добавлено через 2 минуты
Затем надо вызывать функцию что бы привязать созданый пункт к окну меню, для этого существует функция:

C++
1
  SetMenu(hwndA, hmenu1);
у которой первый параметр хендл окна полученный от createwindow а второй параметр hmenu1 и затем первый образец уже можно полюбоваться
15
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
31.07.2012, 01:44
Ответы с готовыми решениями:

Учебная статья - создаем строку состояния на API
Строка состояния на API Необходимо добавить код: #include <CommCtrl.h> #pragma comment(lib,"ComCtl32.Lib") ...

Создание меню окна в Win32 API
Здравствуйте. Пожалуйсто помогите создать меню окна с помощью Win32 API! Не могу разобраться. :(

Статья на rsdn, перехват API-функций
Разбираю статью на рсдн, а именно Метод 1. Перехват API непосредственной записью в код системной функции. dll вроде скомпилировал, дошел...

32
Software Developer
 Аватар для fastb1t
315 / 229 / 113
Регистрация: 03.05.2017
Сообщений: 1,336
16.06.2017, 00:36
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от oleg rus Посмотреть сообщение
А как в под меню указать стрелочку в виде треугольника при наведение на это под меню выскакивало бы всплывающее меню?
В ресурсах:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Menu MENU
{
    POPUP "Test1"
    {
         POPUP "Test3"
         {
              MENUITEM "command1", 10
              MENUITEM "command2", 20
         }
         MENUITEM "command3", 30
         MENUITEM SEPARATOR
         MENUITEM "command4", 40
    }
    POPUP "Test2"
    {
         MENUITEM "command5", 50
    }
}
И в коде создания окна:
C++
1
2
3
4
5
...
WNDCLASS wc = {0};
...
wc.lpszMenuName = "Menu";
...
1
6 / 6 / 0
Регистрация: 13.05.2012
Сообщений: 593
16.06.2017, 22:34
decrement, Ну я не использую ресурсов,без ресурсов есть такая возможность?
0
Software Developer
 Аватар для fastb1t
315 / 229 / 113
Регистрация: 03.05.2017
Сообщений: 1,336
16.06.2017, 23:42
Цитата Сообщение от oleg rus Посмотреть сообщение
Ну я не использую ресурсов,без ресурсов есть такая возможность?
Есть
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
HMENU hMenu = CreateMenu ();
HMENU hMenu1 = CreatePopupMenu ();
HMENU hMenu2 = CreatePopupMenu ();
 
AppendMenu (hMenu, MF_POPUP, (UINT)hMenu1, "&test");
 
AppendMenu (hMenu1, MF_STRING, 1000, "test1");
AppendMenu (hMenu1, MF_STRING, 2000, "test2");
AppendMenu (hMenu1, MF_STRING, 3000, "test3");
AppendMenu (hMenu1, MF_SEPARATOR, 0, NULL);
 
AppendMenu (hMenu2, MF_STRING, 4000, "test5");
AppendMenu (hMenu1, MF_STRING | MF_POPUP, (UINT)hMenu2, "test4");
 
SetMenu (hwnd, hMenu);
2
1 / 1 / 1
Регистрация: 12.05.2016
Сообщений: 29
19.06.2017, 13:10
Как можно один пункт меню поместить в правый угол строки меню? Т.е. несколько пунктов идут по умолчанию слева, а один справа. Меню делается через ресурсы.
0
Software Developer
 Аватар для fastb1t
315 / 229 / 113
Регистрация: 03.05.2017
Сообщений: 1,336
19.06.2017, 14:04
Цитата Сообщение от T-59 Посмотреть сообщение
Как можно один пункт меню поместить в правый угол строки меню? Т.е. несколько пунктов идут по умолчанию слева, а один справа. Меню делается через ресурсы.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "main.h"
 
MyMENU MENU
{
    POPUP "&File"
    {
         MENUITEM "Open", ID_OPEN
         MENUITEM "Save", ID_SAVE
         
    }
    POPUP "Others"
    {
         MENUITEM "About", ID_ABOUT
         MENUITEM "Help", ID_HELP
    }
    MENUITEM "&Exit", ID_EXIT, HELP
}
2
6 / 6 / 0
Регистрация: 13.05.2012
Сообщений: 593
19.06.2017, 17:19
А как под полосой меню нарисовать ещё одно меню?
0
18 / 19 / 4
Регистрация: 27.06.2016
Сообщений: 236
04.02.2018, 19:14
Обидно что не показали как сделать реакцию на нажатие акселератов.
0
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
22.01.2019, 13:56
А можно ли (и как) установить для меню фонт?
0
Software Developer
 Аватар для fastb1t
315 / 229 / 113
Регистрация: 03.05.2017
Сообщений: 1,336
22.01.2019, 14:13
Цитата Сообщение от Байт Посмотреть сообщение
А можно ли (и как) установить для меню фонт?
Вот как я делал когда-то... признаю, код не идеален, делал когда только начинал программировать, после этого как-то даже ни разу и не пригодилось... Но в любом случае будет от чего оттолкнуться.
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
// [OnCreate]: WM_CREATE
static BOOL OnCreate(HWND hWnd, LPCREATESTRUCT lpcs)
{
    HMENU hMenu = CreateMenu();
    HMENU hPopupMenu1 = CreatePopupMenu();
 
    AppendMenu(hMenu, MF_OWNERDRAW | MF_STRING | MF_POPUP, (UINT_PTR)hPopupMenu1, _T("Tools"));
    {
        AppendMenu(hPopupMenu1, MF_OWNERDRAW | MF_STRING, IDM_SYSTEM_INFO, _T("System info"));
        AppendMenu(hPopupMenu1, MF_OWNERDRAW | MF_STRING, IDM_BROWSE_WINDOW, _T("Browse window"));
    }
    AppendMenu(hMenu, MF_OWNERDRAW | MF_STRING, IDM_ABOUT, _T("About"));
 
    MENUINFO mi;
    RtlZeroMemory(&mi, sizeof(MENUINFO));
    mi.cbSize = sizeof(MENUINFO);
    mi.fMask = MIIM_ID;
    mi.hbrBack = GetStockBrush(LTGRAY_BRUSH);
 
    SetMenuInfo(hMenu, &mi);
    SetMenuInfo(hPopupMenu1, &mi);
 
    SetMenu(hWnd, hMenu);
    return TRUE;
}
// [/OnCreate]
 
 
// [OnDrawItem]: WM_DRAWITEM
static void OnDrawItem(HWND hWnd, const DRAWITEMSTRUCT *lpdis)
{
   if (lpdis->CtlType & ODT_MENU)
    {
        if (lpdis->itemState & ODS_SELECTED)
            FillRect(lpdis->hDC, &lpdis->rcItem, GetStockBrush(GRAY_BRUSH));
        else
            FillRect(lpdis->hDC, &lpdis->rcItem, GetStockBrush(LTGRAY_BRUSH));
 
        TCHAR szText[256] = { 0 };
        memset(szText, 0, sizeof(szText));
        memcpy(szText, (void *)lpdis->itemData, sizeof(szText));
 
        int iOldBkMode = SetBkMode(lpdis->hDC, TRANSPARENT);
        COLORREF clrOldColor = SetTextColor(lpdis->hDC, RGB(20, 20, 20));
        HFONT hOldFont = (HFONT)SelectObject(lpdis->hDC, hFont);
 
        TEXTMETRIC tm;
        GetTextMetrics(lpdis->hDC, &tm);
 
        TextOut(
            lpdis->hDC,
            lpdis->rcItem.left + (GetSystemMetrics(SM_CXMENUCHECK) >> 1),
            lpdis->rcItem.top + ((lpdis->rcItem.bottom - lpdis->rcItem.top - tm.tmHeight) >> 1),
            szText,
            _tcslen(szText));
 
        /*
        switch (lpdis->itemID)
        {
        case IDM_ABOUT:
            TextOut(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, "A", 1);
            break;
        }
        */
 
        SelectObject(lpdis->hDC, hOldFont);
        SetTextColor(lpdis->hDC, clrOldColor);
        SetBkMode(lpdis->hDC, iOldBkMode);
    }
}
// [/OnDrawItem]
 
 
// [OnMeasureItem]: WM_MEASUREITEM
static void OnMeasureItem(HWND hWnd, MEASUREITEMSTRUCT *lpmis)      
{
    if (lpmis->CtlType & ODT_MENU)
    {
        TCHAR szText[256] = { 0 };
        memset(szText, 0, sizeof(szText));
        memcpy(szText, (void *)lpmis->itemData, sizeof(szText));
        
        HDC hDC = GetDC(hWnd);
        if (hDC)
        {
            HFONT hOldFont = (HFONT)SelectObject(hDC, hFont);
 
            SIZE size;
            GetTextExtentPoint32(hDC, szText, lstrlen(szText), &size);
 
            SelectObject(hDC, hOldFont);
            
            ReleaseDC(hWnd, hDC);
 
            lpmis->itemWidth = size.cx;
            lpmis->itemHeight = size.cy + 2;
        }
        else
        {
            lpmis->itemWidth = 150;
            lpmis->itemHeight = 20;
        }
    }
}
// [/OnMeasureItem]
1
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
26.08.2020, 22:41
Цитата Сообщение от n971030 Посмотреть сообщение
Учебная статья - создание меню средствами API C++\СИ
Добрый день, решил поделиться инфой по созданию меню VS 2010 средствами только API. Если есть желающие опишите что я не успею.

Значит чтобы создать меню существует такая функция:
C++
1
  HMENU hMenu = CreateMenu(void);
данную функцию надо вызывать при создании меню. Т.е. меню создается, но вы его не увидете до тех пор пока не добавите элемент в меню.
Чтобы добавить элемент существует функция:
C++
1
 BOOL = AppendMenu();
Так меню создается до вызова Windproc, или эти функции прописываются уже внутри Windproc ?
0
Software Developer
 Аватар для fastb1t
315 / 229 / 113
Регистрация: 03.05.2017
Сообщений: 1,336
27.08.2020, 10:05
Цитата Сообщение от Optimus11 Посмотреть сообщение
Так меню создается до вызова Windproc, или эти функции прописываются уже внутри Windproc ?
Нету разницы. Меню можно создавать и до создания окна, главное что-бы созданное меню присваивалось уже созданному окну (SetMenu).
1
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
28.08.2020, 19:11
Цитата Сообщение от n971030 Посмотреть сообщение
Создание выпадающего меню.

Например нам надо в меню файл сделать выпадающие пункты, новый, сохранить, открыть, выход. Для этого надо использоваться такой код:

C++
1
2
3
4
5
6
7
8
9
10
                HMENU hMainMenu = CreateMenu();
                HMENU hPopMenuFile = CreatePopupMenu();
 
                AppendMenu(hMainMenu, MF_STRING | MF_POPUP, (UINT)hPopMenuFile, L"Файл");
                AppendMenu(hMainMenu, MF_STRING, 1000, L"Справка");
                
                AppendMenu(hPopMenuFile, MF_STRING , 1001, L"Отправить данные");
 
                SetMenu(hwnd, hMainMenu);
                SetMenu(hwnd, hPopMenuFile);
...
А вроде бы даже без CreatePopupMenu можно выпадающий список сделать. Просто через AppendMenu:

C++
1
2
3
4
5
6
7
8
9
10
11
12
HMENU My_Main_Menu_Bar = CreateMenu();
HMENU My_File_Menu = CreateMenu();
HMENU My_Help_Menu = CreateMenu();
 
//Добавим кнопки в само меню:
BOOL My_bool_AppendMenu1 = AppendMenuA(My_Main_Menu, MF_POPUP, (UINT_PTR)My_File_Menu, "File");
BOOL My_bool_AppendMenu2 = AppendMenuA(My_Main_Menu, MF_POPUP, (UINT_PTR)My_Help_Menu, L"Help");
 
//Добавим выпадающий список в кнопку File:
 
BOOL My_bool_Append_to_File1 = AppendMenuA(My_File_Menu, MF_STRING, NULL, "Open");
BOOL My_bool_Append_to_File2 = AppendMenuA(My_File_Menu, MF_STRING, NULL, "Close");
Чем такой вариант менее правильный, чем через CreatePopupMenu ?
0
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
29.08.2020, 17:21
Цитата Сообщение от n971030 Посмотреть сообщение
Создание выпадающего меню.

Например нам надо в меню файл сделать выпадающие пункты, новый, сохранить, открыть, выход. Для этого надо использоваться такой код:

C++
1
2
3
4
5
6
7
8
9
10
                HMENU hMainMenu = CreateMenu();
                HMENU hPopMenuFile = CreatePopupMenu();
 
                AppendMenu(hMainMenu, MF_STRING | MF_POPUP, (UINT)hPopMenuFile, L"Файл");
                AppendMenu(hMainMenu, MF_STRING, 1000, L"Справка");
                
                AppendMenu(hPopMenuFile, MF_STRING , 1001, L"Отправить данные");
 
                SetMenu(hwnd, hMainMenu);
                SetMenu(hwnd, hPopMenuFile);
Кстати вызова SetMenu с дескриптором hPopMenuFile - не нужно. Если проверить его на возвращаемое значение:
C++
1
2
3
BOOL My_bool = SetMenu(hwnd, hPopMenuFile);
cout<<My_bool<<endl;
cout<<GetLastError()<<endl;
То это будет значение 0, а GetLastError выдаст ошибку 87 - некорректный параметр.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
29.08.2020, 17:21

Учебная статья
В данной статье расматриваються безусловные переходы на delphi и реализации альтернативы в с помощью вставки asm. Я статью выложел на своем...

Учебная статья - основы работы с реестром в C#
Учебная статья - основы работы с реестром в C# Для начинающих предлагаю эту учебную статью, если в ней чего та нет допишите, пишите...

Как создать DLL в Delphi (Учебная статья)
Вобщем я решил в каществе учебной статьи выложить видео по созданию DLL тут все просто для начинающих пойдет. Текст файла...

Файлы конфигурации в Delphi и С++ Builder (Учебная статья)
Файлы конфигурации в Delphi и С++ Builder Введение. Это небольшая вводная статься посвящена введению работы с файлами конфигурации для...

Возможно ли создание меню с иконками средствами VB?
Возможно ли создание меню с иконками средствами VB?


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

Или воспользуйтесь поиском по форуму:
33
Ответ Создать тему
Новые блоги и статьи
Установка нескольких штампов электронной подписи в строго определенных местах файла docx
ВладимирСамохин 19.07.2026
(В!) Работа с Электронной подписью - это неотъемлемая часть современного документооборота. Но что делать, если нужно поставить несколько штампов электронной подписи в строго определенных местах. . .
сукцессия 35. Научная статья о проделанной работе
anaschu 19.07.2026
Написал в формате латекс и пдф
Вангую, что это не пройдёт модерацию, и на неделе я запущу свой сервер.
Hrethgir 19.07.2026
Эта публикация сейчас в песочнице и ждёт приглашения. https:/ / habr. com/ ru/ sandbox/ 295048/ начало и оглавление - Как «пернатого» заставить осваивать новые горизонты опыта через масштабирование. . .
сукцессия 33. открытые вопросы от клауде
anaschu 19.07.2026
"Что накопилось за эту часть А — тринадцать правок, из которых шесть пришли из ваших вопросов и каждая оказалась реальной ошибкой, а не калибровкой: односторонний симбиоз, отсутствующий листопад,. . .
32 сукцессия
anaschu 19.07.2026
сукцессия 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не «подкручивает» сходимость —. . .
сукцессия 31: модель микоризы - это модель ещё нескольких явлений, социальных и экономических
anaschu 18.07.2026
Теория «Всего»: апдейт v1. 1. 2 — 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не. . .
сукцессия 30. Массив проверяющих друг друга моделей
anaschu 18.07.2026
Архитектура сети взаимопроверяющих моделей микоризной сукцессии (v2. 0) Развитие тензорного ОДУ-ядра и создание кросс-платформенного калибровочного полигона Уважаемые коллеги! В продолжение. . .
Грибы - это женщины, деревья - это мужчины. Анти инь янь для союза мужчины и женщины.
anaschu 18.07.2026
ГЛАВНЫЙ НАУЧНО-ФИЛОСОФСКИЙ ВЫВОД: Сексуально-Репродуктивный Капитализм против Государства Моногамии Коллеги, мы вышли на финишную прямую 20-мерного ОДУ-моделирования вековой сукцессии (ветка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru