CMultiDocTemplate dll проблема с сообщениями в строке статус
От: alexhack  
Дата: 07.02.07 15:56
Оценка:
Не отображаются все подсказки типа tooltip, а также не выводятся сообщения в статусной строке, которые были созданы для меню или тулбара.
Почти 100% процентов это связано с тем что сам шаблон создается в dll в программу возвращается только указатель на CMultiDocTemplate, который регестрируется.

В момент создания шаблона используется макрос AFX_MANAGE_STATE,
чтобы нашлось меню и т.д., но сами подсказки потом просто не выводятся,
как будто их нет, у меня даже таблица клавиш ускорителей работает,
если у нее такой же id что и у меню, а вот подсказки нет

Сами подсказки и подсказки для строки статуса при выделении пункта меню храняться в ресурсе string table (по умолчанию так делается в редакторе ресурсов).

Подскажите, где бряку в сырцах добавить mfc классов, чтобы понять в этом ли дело, где можно прочитать про приоритет просмотр хандлов ресурсов в случае с dll и как сделать так, чтобы мои ресурсы главное приложение тоже просматривало, я так понимаю, когда я меню выбираю, обработка идет в основном exe модуле, но он не видит ресурсы из dll, так как она подключается через pragma (это я так подразумеваю, но как докапаться пока не знаю). Но сами обработчики для меню работают и все остальное работает как надо.

Вариант с принудительной загрузкой не предлагать, по идее может какую то функцию обработчик сообщений еще перегрузить надо в CFrameWnd и там искать ID в своей dll таблице строковых ресурсов и если находятся не передавать обработку дальше?

Может кто знает где и что раскапать. Все в основном касается только tooltip и статусных сообщений.

Извиняюсь за ламерство.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: CMultiDocTemplate dll проблема с сообщениями в строке ст
От: Pavel Dvorkin Россия  
Дата: 08.02.07 12:22
Оценка:
Здравствуйте, alexhack, Вы писали:

A>Не отображаются все подсказки типа tooltip, а также не выводятся сообщения в статусной строке, которые были созданы для меню или тулбара.

A>Почти 100% процентов это связано с тем что сам шаблон создается в dll в программу возвращается только указатель на CMultiDocTemplate, который регестрируется.

Попробуем поискать, благо исходники MFC под рукой. VC 7.1

Во-первых, поищем TOOLTIPTEXT. Ясно, что без нее не обойдется никак

Я буду многое из исходного кода опускать и заменять ...

winmdi.cpp
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)

там же OnToolTipText

// otherwise, handle it ourselves
return CFrameWnd::OnToolTipText(msg, pNMHDR, pResult);

Пойдем в CFrameWnd::OnToolTipText (winfrm.cpp)

ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)

BOOL CFrameWnd::OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult)

// don't handle the message if no string resource found
if (AfxLoadString((UINT)nID, szFullText) == 0)
return FALSE;

Можно продолжить тем же способом и дальше, но хватит и этого. Ясно, что AfxLoadString из двух мест пытаться загружать не будет (если из двух, то почему не из всех DLL, которые тут могут быть . А загружает она не оттуда, откуда ты хочешь, судя по всему. Откуда именно она у тебя не загружает — можешь выяснить сам трассировкой, начиная с этого места.

Ну а решение простое. Имеем

BOOL CFrameWnd::OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult)

Ее надо перекрыть в своей CMainFrame::OnToolTipText, вызвать родительскую и , если она вернула FALSE, попробовать обработать самому, действуя по тому же принципу. А может, вызывать AFX_MANAGE_STATE до вызова родительской и самому не обрабатывать. Поэкспериментируй — получится, если строка есть в ресурсах
With best regards
Pavel Dvorkin
Re[2]: CMultiDocTemplate dll проблема с сообщениями в строке
От: alexhack  
Дата: 08.02.07 21:32
Оценка:
Спасибо Павел за такой нужный отклик.
Сразу скажу у меня NET2003, но разница не большая.
Вот что получилось.

В методе
OnCreate(LPCREATESTRUCT lpCreateStruct)

я вызвал в соответствии с MSDN вызов
EnableToolTips(TRUE);


Далее в cpp добавил
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)


В h добавил

afx_msg BOOL OnToolTipText(UINT msg, NMHDR* pNMHDR, LRESULT* pResult);


Тело функции в классе унаследованного от CMDIChildWnd
Добавленный мной код выделен жирным шрифтом,
курсивом проверку без которой все упадет.
Опытнымпутем выяснил, что для одного ID функция у меня вызывается,подчеркиваю, кажется 4 раза.

BOOL ...::OnToolTipText(UINT msg, NMHDR* pNMHDR, LRESULT* pResult)
{
ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);
    UNUSED(pNMHDR);

    // check to see if the message is going directly to this window or not
    const MSG* pMsg = GetCurrentMessage();
    if (pMsg->hwnd != m_hWnd)
    {
        // let top level frame handle this for us
        return FALSE;
    }
    
    if(pNMHDR->code == TTN_NEEDTEXT)
    {
        UINT nID =pNMHDR->idFrom;  
        //Следующий вызов обязателен,
        //если строковый ресурс подсказка,
        //так же как и сам этот код находятся в dll(MFCEXT)
        //Его действие распространяется на блок в рамках которого он вызван
        AFX_MANAGE_STATE(AfxGetStaticModuleState());
        HINSTANCE l_hInst = AfxFindStringResourceHandle(nID);
        //Тут все ястно, если хандл ресурса найден, значит работаем с ним.
        if(l_hInst)
        {
            TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
            pTTT->lpszText = MAKEINTRESOURCE(nID);
            pTTT->hinst = l_hInst;
            return(TRUE);
        }
    }
    //Иначе так
    return CFrameWnd::OnToolTipText(msg, pNMHDR, pResult);
}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: CMultiDocTemplate dll проблема с сообщениями в строке ст
От: alexhack  
Дата: 08.02.07 23:30
Оценка:
Здравствуйте, alexhack, Вы писали:

Еще бы разобраться со статусной строкой и иконкой CMDIChildWnd окна, думается мне что грабли все теже, просто поиск строки status в исходниках пока еще ничего мне не дал,
буду снова рад любой инфе.

Иконка все время белая, хотя в ресурсах она не белая,там рисунок есть.
А в статусной строке не показываются подсказки к пунктам меню, которые выбираются
в меню,подсказки только у тех пунктов, которые от exe файла остались
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: CMultiDocTemplate dll проблема с сообщениями в строке
От: alexhack  
Дата: 09.02.07 00:12
Оценка:
Здравствуйте, alexhack, Вы писали:

A>Здравствуйте, alexhack, Вы писали:


A>Еще бы разобраться со статусной строкой и иконкой CMDIChildWnd окна, думается мне что грабли все теже, просто поиск строки status в исходниках пока еще ничего мне не дал,

A>буду снова рад любой инфе.

A>Иконка все время белая, хотя в ресурсах она не белая,там рисунок есть.

A>А в статусной строке не показываются подсказки к пунктам меню, которые выбираются
A>в меню,подсказки только у тех пунктов, которые от exe файла остались

С иконкой разобрался так, я переопределил две функции,хотя думаю хавтило бы одной последней в нужных местах где ищутся и грузятся ресурсы вызвал AFX_MANAGE_STATE

virtual BOOL LoadFrame(UINT nIDResource, DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, CWnd* pParentWnd = NULL, CCreateContext* pContext = NULL);
virtual LPCTSTR GetIconWndClass(DWORD dwDefaultStyle, UINT nIDResource);

Их содержимое пришлось скопировать из классов предков, с этой точки зрения мне не очень нравится,может естькакаянить функция setXXX,которая заставляет функции
AfxFindResourceHandle
LoadIcon
AfxGetInstanceHandle
LoadString

искать ресурсы из dll

проблема в том, что область видимости макроса AFX_MANAGE_STATE ограничена блоком, то есть если функцию вызвали после вызова макроса, то это никакне повлияет на работу самой функции,ресурсы так и не будут найдены,потому приходится копировать содержимое методов, что не есть гуд.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: CMultiDocTemplate dll проблема с сообщениями в строке
От: alexhack  
Дата: 09.02.07 00:18
Оценка:
Кроме того иконка не появится если поставить вызов макроса перед условием
if (cs.lpszClass != NULL &&
            GetClassInfo(AfxGetInstanceHandle(), cs.lpszClass, &wndcls) &&
            wndcls.hIcon != hIcon)
        {


В перегруженном методе GetIconWndClass
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.