1 / 1 / 0
Регистрация: 05.05.2009
Сообщений: 13
1

Создание контекстного меню в MFC

16.05.2009, 16:20. Показов 8924. Ответов 3
Метки нет (Все метки)

Есть список (лист бокс) в нем несколько строк, так вот я хотел чтобы по клику правой кнопкой, вывилось меню из пунктов ,."Удалить" и "редактировать".
(опишу что яделал, чтобы понять что не так)
Сначала я начал пробовать делать через ресурсы, создал ресурс МЕНЮ, и там сделал МЕНю (+2 сабменю - "Удалить" и "редактировать") Но как его отобразить, я не знал, нашёл кое-где стрчоку как отобразить с помощью Loadmenu, но выводилась куча ошибок. Потом попрбовал сделать ка к в статье http://www.rsdn.ru/article/qna/ui/mnushow.xml

Вот этот код
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
case WM_CONTEXTMENU:
{
    // Извлекаем координаты курсора мыши из lParam
    POINT pt;
    pt.x = GET_X_LPARAM(lParam);
    pt.y = GET_Y_LPARAM(lParam);
 
    if(pt.x == -1 && pt.y == -1)
    {
        // Вызов с клавиатуры
        RECT rect;
        GetWindowRect(hWnd, &rect);
        // Выводим меню радом с левым верхним углом окна
        pt.x = rect.left + 5;
        pt.y = rect.top + 5;
    }
 
    // Загружаем меню из ресурсов
    HMENU hMenu, hPopupMenu;
    hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1));
    hPopupMenu = GetSubMenu(hMenu, 0);
    
    // Отображаем меню
    TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hWnd, NULL);
 
    // Уничтожаем меню
    DestroyMenu(hMenu);
}
Вставил в действие по нажатию кнопки (для простоты). Но не получается... что я делаю не так? (использую MFC). Может мне показать вес код CPP окна, в котором я пытаюсь сделать это всё?
Помогите пожалуйста!
(Visual Studio 2008)

Добавлено через 11 минут 52 секунды
----
Ах, да, ошибки:
Error 8 error C2046: illegal case
Error 9 error C2065: 'lParam' : undeclared identifier
Error 10 error C2065: 'lParam' : undeclared identifier
Error 11 error C2065: 'hWnd' : undeclared identifier
Error 12 error C2065: 'hInstance' : undeclared identifier
Error 13 error C2065: 'hWnd' : undeclared identifier

И всё, же, мой 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
// seachframe.cpp : implementation file
 
#include "stdafx.h"
#include "resager_program.h"
#include "seachframe.h"
#include "myfuns.h"
#include "windowsx.h"
 
// seachframe dialog
CString datablok[255][10];
IMPLEMENT_DYNAMIC(seachframe, CDialog)
 
seachframe::seachframe(CWnd* pParent /*=NULL*/)
    : CDialog(seachframe::IDD, pParent)
{
 
}
 
seachframe::~seachframe()
{
}
 
void seachframe::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_EDIT1, fp_nom);
    DDX_Control(pDX, IDC_EDIT2, fp_data1);
    DDX_Control(pDX, IDC_EDIT3, fp_data2);
    DDX_Control(pDX, IDC_EDIT4, fp_name);
    DDX_Control(pDX, IDC_EDIT5, fp_isp);
    DDX_Control(pDX, IDC_EDIT6, fp_prim);
    DDX_Control(pDX, IDC_LIST1, seachlist);
 
    seachlist.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
 
    seachlist.InsertColumn(0,"№",0,90);
    seachlist.InsertColumn(1,"Дата",0,100);
    seachlist.InsertColumn(2,"Название приказа",0,450);
    //HMENU hPopupMenu = CreatePopupMenu();
    //AppendMenu(hPopupMenu, MF_STRING, ID_EDIT_UNDO, "&Изменить");       // Undo    Ctrl+Z
    //AppendMenu(hPopupMenu, MF_SEPARATOR, 0, 0);                             // --------------
    //AppendMenu(hPopupMenu, MF_STRING, ID_EDIT_CUT, "&Удалить");         // Cut     Ctrl+X
}
 
 
BEGIN_MESSAGE_MAP(seachframe, CDialog)
    ON_BN_CLICKED(IDC_BUTTON1, &seachframe::OnBnClickedButton1)
    ON_NOTIFY(LVN_ITEMACTIVATE, IDC_LIST1, &seachframe::OnLvnItemActivateList1)
    ON_BN_CLICKED(IDC_BUTTON3, &seachframe::OnBnClickedButton3)
END_MESSAGE_MAP()
 
 
 
void seachframe::OnBnClickedButton1()
{
    // Тут много чего было, но я полагаю, к делу не относится
}
 
void seachframe::OnLvnItemActivateList1(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMITEMACTIVATE pNMIA = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
    // TODO: Add your control notification handler code here
    *pResult = 0;
        // Тут много чего было, но я полагаю, к делу не относится
}
void seachframe::OnBnClickedButton3()
{
    case WM_CONTEXTMENU:
{
    // Извлекаем координаты курсора мыши из lParam
    POINT pt;
    pt.x = GET_X_LPARAM(lParam);
    pt.y = GET_Y_LPARAM(lParam);
 
    if(pt.x == -1 && pt.y == -1)
    {
        // Вызов с клавиатуры
        RECT rect;
        GetWindowRect(hWnd, &rect);
        // Выводим меню радом с левым верхним углом окна
        pt.x = rect.left + 5;
        pt.y = rect.top + 5;
    }
 
    // Загружаем меню из ресурсов
    HMENU hMenu, hPopupMenu;
    hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1));
    hPopupMenu = GetSubMenu(hMenu, 0);
    
    // Отображаем меню
    TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hWnd, NULL);
 
    // Уничтожаем меню
    DestroyMenu(hMenu);
}
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.05.2009, 16:20
Ответы с готовыми решениями:

Зависание VC++ при открытии контекстного меню
Есть кусок кода:MyClient::MyClient(const QString&amp; strHost, int ...

MFC и меню
Добрый вечер. Подскажите пожалуйста, как создать меню, пункты которого зависят от значения...

меню в mfc
подскажите как создать меню в mfc

Добавление пункта меню MFC
Есть приложение созданное визардом, создал 2 своих меню в ресурсах, ID_MAIN_MANU(1) и...

3
48 / 48 / 8
Регистрация: 30.01.2009
Сообщений: 168
18.05.2009, 10:02 2
Оператор case используется только внутри оператора switch, с чем ты, собственно, WM_CONTEXTMENU пытаешься сравнивать? Перемести код из OnBnClickedButton3() в PreTranslateMessage(MSG* pMsg) (поставь там switch (pMsg->message)), либо используй MFC-шный обработчик сообщения WM_CONTEXTMENU - OnContextMenu(...).

Добавлено через 3 минуты 17 секунд
И если уж взялся использовать MFC, используй класс CMenu.
0
48 / 48 / 8
Регистрация: 30.01.2009
Сообщений: 168
19.05.2009, 19:17 3
Дополнительных вопросов не последовало, но раз уж я это написал - покажу, авось пригодится кому-нибудь.

Итак, как это делается на самом деле.

Нам нужен ListBox со встроенным в него меню - вот именно так и нужно делать! Создаем класс-наследник от CListBox, помещаем в него меню и показываем последнее при нажатии правой кнопки мыши.
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
//****************************************************************************************//
//****************************************************************************************//
//******************                                                    ******************//
//******************        ListBox со встроенным всплывающим меню      ******************//
//******************                                                    ******************//
//******************                                                    ******************//
//******************             Версия 0.0.0.0 от 18.05.2009           ******************//
//******************                                                    ******************//
//******************                  (c) ******** 2009                 ******************//
//******************                                                    ******************//
//****************************************************************************************//
//****************************************************************************************//
 
class C_ListBox : public CListBox
{
public:
    virtual BOOL PreTranslateMessage(MSG* pMsg)
    {
        // Если нажата правая кнопка мыши, показываем меню
        if (pMsg->message == WM_RBUTTONDOWN)
        {
            POINT current_point;
            GetCursorPos(&current_point);
            m_Menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, current_point.x, current_point.y, this);
        }
 
        // Если было получено сообщение WM_COMMAND, проверяем, какая строка была выбрана
        if (pMsg->message == WM_COMMAND)
        {
            switch (LOWORD(pMsg->wParam))
            {
                case ID_STRING1:
                {
                    AfxMessageBox("Была выбрана первая строчка меню");
                    break;
                }
                case ID_STRING2:
                {
                    AfxMessageBox("Была выбрана вторая строчка меню");
                    break;
                }
                case ID_STRING3:
                {
                    AfxMessageBox("Была выбрана третья строчка меню");
                    break;
                }
            };
        }
 
        // Так надо
        return CListBox::PreTranslateMessage(pMsg);
    }
 
private:
    // Меню, однако
    CMenu m_Menu;
 
    // Список идентификаторов для строк меню
    enum
    {
        ID_STRING1=10001,
        ID_STRING2,
        ID_STRING3
    };
 
public:
    C_ListBox(void)
    {
        // Создаем всплывающее меню
        m_Menu.CreatePopupMenu();
 
        // Добавляем в него нужные строки
        m_Menu.AppendMenu(MF_STRING, ID_STRING1, "Первая строка");
        m_Menu.AppendMenu(MF_STRING, ID_STRING2, "Вторая строка");
        m_Menu.AppendMenu(MF_STRING, ID_STRING3, "Третья строка");
    }
 
    virtual ~C_ListBox(void) {}
};
Осталось только добавить дейтвия, которые должны выполняться при выборе строк меню и можно пользоваться.
1
fanshtorm
09.04.2012, 16:23 4
Цитата Сообщение от Шерсть-На-Носу Посмотреть сообщение
Дополнительных вопросов не последовало, но раз уж я это написал - покажу, авось пригодится кому-нибудь.

Итак, как это делается на самом деле.

Нам нужен ListBox со встроенным в него меню - вот именно так и нужно делать! Создаем класс-наследник от CListBox, помещаем в него меню и показываем последнее при нажатии правой кнопки мыши.

.......

Осталось только добавить дейтвия, которые должны выполняться при выборе строк меню и можно пользоваться.
Сделал точно так же, но с CListCtrl-ом. Меню всплывает по нажатию правой кнопки мыши, но при выборе любого пункта меню не срабатывает код в теле условия "if (pMsg->message == WM_COMMAND)". То ли сообщение контролу вовсе не посылается, то ли не WM_COMMAND... Ни у кого нет мыслей на этот счёт?

Добавлено через 17 часов 54 минуты
ХА!!! Я сам решил проблему:
Сделал так:
Добавил для своего лист-контрола обработчик события "NM_RClick" в котором написал:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    m_Menu.CreatePopupMenu();
 
    POINT current_point;
    GetCursorPos(&current_point);
 
    m_Menu.AppendMenu(MF_STRING, 1000, _T("Первая строка"));
    m_Menu.AppendMenu(MF_STRING, 1001, _T("Вторая строка"));
    m_Menu.AppendMenu(MF_STRING, 1002, _T("Третья строка"));
 
    m_Menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,
                          current_point.x,
                          current_point.y,
                          this);
    
    m_Menu.DestroyMenu();
Потом в описании класса моего ДИАЛОГОВОГО ОКНА "унаследовал" метод PreTranslateMessage и в нём написал всё точно как в примере.
Кстати, такой подход имеет одно приятное преимущество: прямо из этого метода теперь можно оперировать остальными контролами связанными с их переменными-классами через DDX_Control в этом диалоге.
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.04.2012, 16:23

Загрузка иконок в меню используя MFC
Подскажите, как добавить в пункт меню иконку? Работаю на в MFC проект на диалоге. Заранее спасибо.

Как изменить подписи в меню? (MFC)
Есть проект, созданный на основе MFC (диалоговый). В нем есть меню созданное через визуальный...

Новые элементы меню не появляются (MFC)
Я создаю MFC application потом class view/add/resource/menu. Создаю элементы меню ,и запускаю...

Как создать меню в mfc в msvs 2008?
может кто подскажет, как меню создать


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.