Меню UI-активного объекта в MFC
Очень нужна ваша помощь. Переношу проект написанный на C++ и WINAPI под MFC. От MFC нужен красивый UI. В проекте есть поддержка серверов документов OLE. Хочется оставить реализацию интерфейсов контейнера без изменений не прибегая к помощи MFC. Пока все шло нормально, но столкнулся с проблемой после активации сервера. Проблема в следующем :
HRESULT STDMETHODCALLTYPE COleInPlaceFrame::SetMenu(
/* [in] */ __RPC__in HMENU hmenuShared,
/* [in] */ __RPC__in HOLEMENU holemenu,
/* [in] */ __RPC__in HWND hwndActiveObject)
{
if (holemenu != NULL) {
CMainFrame * pMainFrame = (CMainFrame*)theApp.GetMainWnd();
pMainFrame->DelayUpdateFrameMenu(hmenuShared); // Взято из стандартного MFC-класса //COleFrameHook
HRESULT hResult = OleSetMenuDescriptor(holemenu,pMainFrame->GetSafeHwnd(),hwndActiveObject,
NULL, NULL);
}
...
...
}
Т.е. мне нужно установить меню сервера документов. После упомянутого выше кода у меня появляется меню сервера документов, но естественно оно каркасом обрабатывается неправильно. Доступные только пункты меню ID которых случайным образом совпало с ID стандартного меню. Пробовал так же
ON_UPDATE_COMMAND_UI для ID, который появиться только после активации объекта (но это не выход). Ни в том, ни в другом случае команда меню не попадает в окно активного объекта. Короче говоря, мне нужно следующее:
1. Чтобы после активации объекта были доступны пункты меню, ID которых заведомо неизвестно
2. Чтобы команды меню проходили в окно UI-активного объкта (насколько я понимаю, OleSetMenuDescriptor субклассирует мое главное окно)
На данном этапе это MDI-приложение с CMFCMenuBar-меню .
Заранее благодарен за Вашу помощь.
Огромное спасибо за ссылку. Не совсем то, но все равно (там под чистую MFC реализацию, а мне ее нужно было обойти).
На самом деле я не до конца разобрался в внутренностями маршрутизации команд и не могу понять (точнее не смотрел) куда девается команда из главного цикла. В цикл она точно попадает, а до главного окна не доходит, должна была бы перехватится с OleSetMenuDescriptor. Я ей немного помог :
BOOL COleEditorApp::PreTranslateMessage(MSG* pMsg)
{
if (this->m_bActiveObject)
{
if (pMsg->message == WM_COMMAND)
{
CMainFrame * pMainFrame = (CMainFrame*)this->GetMainWnd();
CChildFrame * pChildFrame = dynamic_cast<CChildFrame*>(pMainFrame->GetActiveFrame());
// моя реализация контейнера
CContainerDoc * pContainerDoc = (CContainerDoc*)
GetWindowLong(pChildFrame->m_wndView.GetSafeHwnd(),GWL_USERDATA);
HWND hwndActive = NULL;
// посылаем сообщение напрямую (фактически OleSetMenuDescriptor не нужен т.к. своих команд я не добавляю)
pContainerDoc->m_pIOleInPlaceUIWindow->m_pIOleInPlaceActiveObject->GetWindow(&hwndActive);
if (hwndActive)
{
SendMessage(hwndActive,WM_COMMAND,pMsg->wParam,pMsg->lParam);
}
return TRUE;
}
}
}
Остался только первый вопрос : как сделать все пункты меню доступными?