Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как динамически загружать в меню строки ? 
:(
    Опции темы
En_t_end
Дата 6.12.2006, 20:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 2
Всего: 20



Есть системное меню. Хочу динамически(run time) загружать в него строки. Сразу встает вопрос, если можно, то как быть с обработкой выбора этих строк пользователем ?
PM MAIL ICQ Skype GTalk Jabber   Вверх
Earnest
Дата 6.12.2006, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



По крайней мере, в MSDN написано, что можно. Насчет ид-ров вопрос интересный (вроде перечень комманд зафиксирован). Надо, видимо, пробовать.



--------------------
...
PM   Вверх
En_t_end
Дата 7.12.2006, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 2
Всего: 20



Earnest, 
Цитата(Earnest @  7.12.2006,  00:48 Найти цитируемый пост)
По крайней мере, в MSDN написано, что можно

Знаю... но надо их загрузить таким образом, чтобы использовать, как нормальные select варианты. Иначе, зачем ещё меню ?

Добавлено @ 15:32 
Цитата(Earnest @  7.12.2006,  00:48 Найти цитируемый пост)
 Надо, видимо, пробовать.

Я просто не могу представить... неужели вместе с ON_COMMAND как номер элемента меню приходит что-то типа IDC_NULL_MENU+i, где i - номер выбранного элемента ? smile врядли...
PM MAIL ICQ Skype GTalk Jabber   Вверх
Earnest
Дата 8.12.2006, 08:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Во-первый, приходит WM_SYSCOMMAND, а не WM_COMMAND, во-вторых, не номер, а идентификатор. Посмотри описание OnSysCommand...
Вроде ничего крамольного в добавлении своих элементов нет. Только следи, что их ID не пересекались со стандартными CS_XXX. Там еще написано, что нестандартные ид-ры нельзя пускать в стандартный обработчик.


--------------------
...
PM   Вверх
En_t_end
Дата 12.12.2006, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 2
Всего: 20



Earnest, 
Спасибо, натолкнула на мысль...
То есть я перегружаю OnSysCommand, где обрабатываю SC_MOUSEMENU ? В lParam тогда там будет идентификатор выбранного пункта меню ?

Добавлено @ 14:43 
А нет...
PM MAIL ICQ Skype GTalk Jabber   Вверх
Earnest
Дата 12.12.2006, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Не перегружаешь, а просто пишешь (и добавляешь в карту обработчиков) - это ведь не виртуальный метод.
И не lParam, а ID. 


--------------------
...
PM   Вверх
En_t_end
Дата 12.12.2006, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 2
Всего: 20



Сделал так:
Код

LRESULT MProgramm::my_OnSysCommand(WPARAM wPar,LPARAM lPar)
{
    switch(wPar & 0xFFF0)
    {
    case SC_MOUSEMENU:
//        if(LOWORD(lPar) == 1)
//        {
            MessageBox("ok");
            return 0;
//        }
    default:
        OnSysCommand(HIWORD(wPar),lPar);
        return 1;
    }
    //return 0;
}

Как здесь мне отловить нажатие на конкретный пункт конкретного submenu системного menu ?
В lPar содержится x и y координаты указателя мыши, так ? Мне нужен идентификатор.


Добавлено @ 19:34 
Кстати Earnest, спасибо, что помогаешь.

Добавлено @ 19:38 
кстати понравилось, как ИМХО такую проблему решают в си-шарпе:
http://www.progs.biz/csharp/win/lessons/008.aspx
Гибко..........

Это сообщение отредактировал(а) En_t_end - 12.12.2006, 19:51
PM MAIL ICQ Skype GTalk Jabber   Вверх
bel_nikita
Дата 12.12.2006, 19:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 2
Всего: 47



Как вариант, меню можно читать из xml файл.


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
En_t_end
Дата 12.12.2006, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 2
Всего: 20



bel_nikita, 
Не понял...

Добавлено @ 20:00 
У меня ещё есть более удачный вариант:
ON_MESSAGE(WM_MENUSELECT,OnWMMenuSelect)
Код

LRESULT MProgramm::my_OnMenuSelect(WPARAM wPar,LPARAM lPar)    
{
    if(HIWORD(wPar) == MF_MOUSESELECT
    && ((AfxGetMainWnd()->GetMenu())->GetSubMenu(1))->GetSafeHmenu() == (HMENU)lPar)
        MessageBox("ok");
return 0;    
}

Но фишка в том, что если убрать условие HIWORD(wPar) == MF_MOUSESELECT то просто наведя на пункт у меня сработает MessageBox("ok"); А мне нужно именно после нажатия на нём левой кнопкой мышки.

Добавлено @ 20:02 
А само MF_MOUSESELECT у меня при всевозможных ухищрениях так и не вылезло, как с ним работать, вопрос ?
PM MAIL ICQ Skype GTalk Jabber   Вверх
bel_nikita
Дата 12.12.2006, 22:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 2
Всего: 47



А как добавляешь меню?
Если не ошибает память, там же ID пункта меню нужно указывать. Т.е. ID меню у тебя есть, а на их можно повесить свои хандлеры: std::map<ID,pFunc>
Можно сделать один мегаобработчик: 
Код

#define ID_DYNAMIC_MENU 32767
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    //{{AFX_MSG_MAP(CMainFrame)
    ON_WM_CREATE()
    ON_WM_SETFOCUS()
    ON_COMMAND_RANGE(1,ID_DYNAMIC_MENU, OnMenu)
    //}}AFX_MSG_MAP
  ON_MENUXP_MESSAGES()
END_MESSAGE_MAP()

void CMainFrame::OnMenu(UINT nID) 
{
    // TODO: Add your command handler code here
    CMenu menuMain;
    CString strText;
    menuMain.Attach( ::GetMenu( GetSafeHwnd() ) );

  // у нас есть ID меню, теперь читаем текст меню
  CString csMenuTest = _T("");
  menuMain.GetMenuString(nID, csMenuTest, MF_BYCOMMAND);
  AfxMessageBox(csMenuTest);

  // т.к. у нас есть ID выбранного пользователем меню, то мы можем из std::map<ID,pFunc> извлечь нужный нам обработчик pFunc
  // ... тонскости реализации пропускаем

    menuMain.Detach();
}



--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
Earnest
Дата 13.12.2006, 09:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Стоп, какой еще MenuSelect? 
Меню-селект срабатывает, при выделении соответствующего пункта меню, а не при выборе, это для вывода подсказок. Тебе нужно именно WM_SYSCOMMAND.
Есть же стандартный макрос для обработчика WM_SYSCOMMAND: ON_WM_SYSCOMMAND. Соответствующий обработчик должен иметь имя и сигнатуру afx_msg void OnSysCommand (UINT nID, LPARAM lPar);
В конце его, если не обработал команду, просто вызывешь Default():
Код

void CMyWindow::OnSysCommand (UINT nID, LPARAM lPar)
{
   if (nID == XXX)
   {
      // что-то делаешь
   }
   else Default();
}



--------------------
...
PM   Вверх
En_t_end
Дата 13.12.2006, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 2
Всего: 20



Earnest, 
Спасибо!
PM MAIL ICQ Skype GTalk Jabber   Вверх
En_t_end
Дата 14.12.2006, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 2
Всего: 20



nID & 0xFFF0 - в моем случае SC_MOUSEMENU
lPar - младшие биты - абцисса указателя мыши, старшие - ордината. В итоге: я опять у той же стены. smile
PM MAIL ICQ Skype GTalk Jabber   Вверх
En_t_end
Дата 14.12.2006, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 2
Всего: 20



Всё всем спасибо, кстати проблему решил способом bel_nikita, тут даже старые обработчики других выпадающих меню не похезались, вообщем рад... вышел с наименьшими потерями smile thnks
PM MAIL ICQ Skype GTalk Jabber   Вверх
Earnest
Дата 14.12.2006, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Ты хочешь сказать, что что бы ты не выбирал, всегда приходит SC_MOUSEMENU? Да быть не может. Стандартные команды нормально ходят, это точно. Покажи, что ли, как ты меню модифицируешь...


--------------------
...
PM   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0583 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.