ToolTips
От: Константин Ленин Франция  
Дата: 23.01.06 15:00
Оценка:
Никак не могу прикрутить тултипы к ListView



.h

class CSomeDlg: 
    public CDialogImpl<CSomeDlg>
{

public:

    BEGIN_MSG_MAP(CSomeDlg)
        ...
        NOTIFY_CODE_HANDLER(TTN_NEEDTEXT, OnToolTipText)        
    END_MSG_MAP()

    LRESULT OnToolTipText(int, LPNMHDR pNMHDR, BOOL& /*bHandled*/)
    {}

private:

    CListViewCtrl   m_jobList;
    CToolTipCtrl    m_jobToolTips;
};

.cpp

LRESULT CSomeDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
                m_jobToolTips.Create(*this);
        m_jobToolTips.AddTool(*this);
        m_jobList.SetToolTips(m_jobToolTips);        
}


OnToolTipText просто не вызывается
Re: ToolTips
От: Константин Ленин Франция  
Дата: 23.01.06 15:04
Оценка:
КЛ>LRESULT CSomeDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
КЛ>{
КЛ> m_jobToolTips.Create(*this); //OK
КЛ> m_jobToolTips.AddTool(*this); //TRUE
КЛ> m_jobList.SetToolTips(m_jobToolTips); //OK
КЛ>}

в Spy++ в Messages для jobToolTips вижу только TTN_POP и TTN_RELAYEVENT
Re: ToolTips
От: Константин Ленин Франция  
Дата: 23.01.06 16:52
Оценка:
Никто не знает???
Re[2]: ToolTips
От: BuHHunyx Беларусь  
Дата: 23.01.06 17:13
Оценка: 1 (1)
Здравствуйте, Константин Ленин, Вы писали:

КЛ>>LRESULT CSomeDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)

КЛ>>{
КЛ>> m_jobToolTips.Create(*this); //OK
КЛ>> m_jobToolTips.AddTool(*this); //TRUE
КЛ>> m_jobList.SetToolTips(m_jobToolTips); //OK
КЛ>>}

КЛ>в Spy++ в Messages для jobToolTips вижу только TTN_POP и TTN_RELAYEVENT


Посмотри как сделано здесь
А можно и просто этот классик поюзать...
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[3]: ToolTips
От: Константин Ленин Франция  
Дата: 23.01.06 18:01
Оценка:
Здравствуйте, BuHHunyx, Вы писали:

BHH>Здравствуйте, Константин Ленин, Вы писали:


КЛ>>>LRESULT CSomeDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)

КЛ>>>{
КЛ>>> m_jobToolTips.Create(*this); //OK
КЛ>>> m_jobToolTips.AddTool(*this); //TRUE
КЛ>>> m_jobList.SetToolTips(m_jobToolTips); //OK
КЛ>>>}

КЛ>>в Spy++ в Messages для jobToolTips вижу только TTN_POP и TTN_RELAYEVENT


BHH>Посмотри как сделано здесь

BHH>А можно и просто этот классик поюзать...

Проблема была в

КЛ>>> m_jobToolTips.AddTool(*this); //TRUE


Надо было m_jobToolTips.AddTool(m_jobList) тк CToolInfo::Init выглядит так:



void Init(UINT nFlags, HWND hWnd, UINT nIDTool = 0, LPRECT lpRect = NULL, LPTSTR lpstrText = LPSTR_TEXTCALLBACK, LPARAM lUserParam = NULL)
    {
        ATLASSERT(::IsWindow(hWnd));
        memset(this, 0, sizeof(TOOLINFO));
        cbSize = sizeof(TOOLINFO);
        uFlags = nFlags;
        if(nIDTool == 0)
        {
            hwnd = ::GetParent(hWnd);
            uFlags |= TTF_IDISHWND;
            uId = (UINT_PTR)hWnd;
        }
        else
        {
            hwnd = hWnd;
            uId = nIDTool;
        }
        if(lpRect != NULL)
            rect = *lpRect;
#if (_ATL_VER >= 0x0700)
        hinst = ATL::_AtlBaseModule.GetResourceInstance();
#else //!(_ATL_VER >= 0x0700)
        hinst = _Module.GetResourceInstance();
#endif //!(_ATL_VER >= 0x0700)
        lpszText = lpstrText;
        lParam = lUserParam;
    }
Re[3]: ToolTips
От: Константин Ленин Франция  
Дата: 24.01.06 13:22
Оценка:
Здравствуйте, BuHHunyx, Вы писали:

BHH>Здравствуйте, Константин Ленин, Вы писали:


КЛ>>>LRESULT CSomeDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)

КЛ>>>{
КЛ>>> m_jobToolTips.Create(*this); //OK
КЛ>>> m_jobToolTips.AddTool(*this); //TRUE
КЛ>>> m_jobList.SetToolTips(m_jobToolTips); //OK
КЛ>>>}

КЛ>>в Spy++ в Messages для jobToolTips вижу только TTN_POP и TTN_RELAYEVENT


BHH>Посмотри как сделано здесь

BHH>А можно и просто этот классик поюзать...

Какой-то он децл глючный, при наведении тултип показывается в одном месте, а потом быстро "перебигает" в другое, под курсор
И еще, есть мысль создавать background окно для обработки сообщений парэнт-окну. WM_TIMER например, чтобы не конфликтовать с таймерами парэнта.
Re[4]: ToolTips
От: programmater  
Дата: 24.01.06 14:59
Оценка:
Здравствуйте, Константин Ленин, Вы писали:

КЛ>Здравствуйте, BuHHunyx, Вы писали:


BHH>>Здравствуйте, Константин Ленин, Вы писали:


КЛ>>>>LRESULT CSomeDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)

КЛ>>>>{
КЛ>>>> m_jobToolTips.Create(*this); //OK
КЛ>>>> m_jobToolTips.AddTool(*this); //TRUE
КЛ>>>> m_jobList.SetToolTips(m_jobToolTips); //OK
КЛ>>>>}

КЛ>>>в Spy++ в Messages для jobToolTips вижу только TTN_POP и TTN_RELAYEVENT


BHH>>Посмотри как сделано здесь

BHH>>А можно и просто этот классик поюзать...

КЛ>Какой-то он децл глючный, при наведении тултип показывается в одном месте, а потом быстро "перебигает" в другое, под курсор

КЛ>И еще, есть мысль создавать background окно для обработки сообщений парэнт-окну. WM_TIMER например, чтобы не конфликтовать с таймерами парэнта.

Вообщето для того, чтобы подсовывать типы для ListView надо обрабатывать не TTN_NEEDTEXT а LVN_GETINFOTIP. Это первое, что я заметил. В добавлении ToolItem-а не стал разбираться, возможно у тебя все правильно. Я делаю так:
    ListView_SetExtendedListViewStyle(m_hWnd,LVS_EX_INFOTIP);
    m_Tip.Create(m_hWnd,NULL,NULL,WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,WS_EX_TOPMOST);    
    m_Tip.SetWindowPos(HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
    CListViewCtrl::SetToolTips(m_Tip.m_hWnd);    
    m_Tip.AddTool(m_hWnd,LPSTR_TEXTCALLBACK,&RectTool,1);        
    m_Tip.Activate(true);

и у меня все прекрасно работает. Возможно что-то здесь и лишнее, но разбираться было уже лень, т.к. пришел я к такому варианту через огромное количество глюков . Надеюсь, что помог.
Удачи.
Re[5]: ToolTips
От: programmater  
Дата: 24.01.06 15:02
Оценка:
Здравствуйте, programmater, Вы писали:

P>Вообщето для того, чтобы подсовывать типы для ListView надо обрабатывать не TTN_NEEDTEXT а LVN_GETINFOTIP. Это первое, что я заметил. В добавлении ToolItem-а не стал разбираться, возможно у тебя все правильно. Я делаю так:

P>
P>    ListView_SetExtendedListViewStyle(m_hWnd,LVS_EX_INFOTIP);
P>    m_Tip.Create(m_hWnd,NULL,NULL,WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,WS_EX_TOPMOST);    
P>    m_Tip.SetWindowPos(HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
P>    CListViewCtrl::SetToolTips(m_Tip.m_hWnd);    
P>    m_Tip.AddTool(m_hWnd,LPSTR_TEXTCALLBACK,&RectTool,1);        
P>    m_Tip.Activate(true);

P>

Да, забыл сказать, что это код функции OnCreate(...).
Re[6]: ToolTips
От: Константин Ленин Франция  
Дата: 24.01.06 16:02
Оценка:
Здравствуйте, programmater, Вы писали:

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


P>>Вообщето для того, чтобы подсовывать типы для ListView надо обрабатывать не TTN_NEEDTEXT а LVN_GETINFOTIP. Это первое, что я заметил. В добавлении ToolItem-а не стал разбираться, возможно у тебя все правильно. Я делаю так:

P>>
P>>    ListView_SetExtendedListViewStyle(m_hWnd,LVS_EX_INFOTIP);
P>>    m_Tip.Create(m_hWnd,NULL,NULL,WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,WS_EX_TOPMOST);    
P>>    m_Tip.SetWindowPos(HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
P>>    CListViewCtrl::SetToolTips(m_Tip.m_hWnd);    
P>>    m_Tip.AddTool(m_hWnd,LPSTR_TEXTCALLBACK,&RectTool,1);        
P>>    m_Tip.Activate(true);

P>>

P>Да, забыл сказать, что это код функции OnCreate(...).

Не получается(



.h

BEGIN_MSG_MAP(CUploadManagerDlg)
          NOTIFY_HANDLER(IDC_LIST_JOBS, LVN_GETINFOTIP, OnToolTipText)
END_MSG_MAP()

CListViewCtrl   m_jobList;
СToolTipCtrl    m_jobToolTips;

.cpp

LRESULT ...::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
        m_jobList.SetExtendedListViewStyle( LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_ONECLICKACTIVATE | LVS_EX_INFOTIP );
        m_jobToolTips.Create(m_jobList, NULL, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, WS_EX_TOPMOST);    
        m_jobToolTips.SetWindowPos(HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
    m_jobList.SetToolTips(m_jobToolTips);
    m_jobToolTips.AddTool(m_jobList);
    m_jobToolTips.Activate(true);

}


OnToolTipText не вызывается
Re[7]: ToolTips
От: programmater  
Дата: 24.01.06 16:05
Оценка:
Здравствуйте, Константин Ленин, Вы писали:

[]
Часом не под юникод ли компилишь?
Re[7]: ToolTips
От: programmater  
Дата: 24.01.06 16:34
Оценка: 1 (1)
Здравствуйте, Константин Ленин, Вы писали:

КЛ>Здравствуйте, programmater, Вы писали:


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


P>>>Вообщето для того, чтобы подсовывать типы для ListView надо обрабатывать не TTN_NEEDTEXT а LVN_GETINFOTIP. Это первое, что я заметил. В добавлении ToolItem-а не стал разбираться, возможно у тебя все правильно. Я делаю так:

P>>>
P>>>    ListView_SetExtendedListViewStyle(m_hWnd,LVS_EX_INFOTIP);
P>>>    m_Tip.Create(m_hWnd,NULL,NULL,WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,WS_EX_TOPMOST);    
P>>>    m_Tip.SetWindowPos(HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
P>>>    CListViewCtrl::SetToolTips(m_Tip.m_hWnd);    
P>>>    m_Tip.AddTool(m_hWnd,LPSTR_TEXTCALLBACK,&RectTool,1);        
P>>>    m_Tip.Activate(true);

P>>>

P>>Да, забыл сказать, что это код функции OnCreate(...).
Причем OnCreate класса, который сабклассится к ListView и обрабатывает отраженные сообщения, соответственно m_hWnd — это хендл окна ListView, а не родительского диалога. Но идею ты понял верно.

КЛ>Не получается(



КЛ>

КЛ>.h

КЛ>BEGIN_MSG_MAP(CUploadManagerDlg)
КЛ>          NOTIFY_HANDLER(IDC_LIST_JOBS, LVN_GETINFOTIP, OnToolTipText)
КЛ>END_MSG_MAP()

КЛ>CListViewCtrl   m_jobList;
КЛ>СToolTipCtrl    m_jobToolTips;

КЛ>.cpp

КЛ>LRESULT ...::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
КЛ>{
КЛ>        m_jobList.SetExtendedListViewStyle( LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_ONECLICKACTIVATE | LVS_EX_INFOTIP );
КЛ>        m_jobToolTips.Create(m_jobList, NULL, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, WS_EX_TOPMOST);    
КЛ>        m_jobToolTips.SetWindowPos(HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
КЛ>    m_jobList.SetToolTips(m_jobToolTips);
КЛ>    m_jobToolTips.AddTool(m_jobList);
КЛ>    m_jobToolTips.Activate(true);

КЛ>}

КЛ>


КЛ>OnToolTipText не вызывается

Да, у меня в таком варианте (см. выделенную строку) тоже не работало, уж не знаю почему. Опытным путем пришел к строке, которая у меня.
RECT RectTool={0,0,1000,1000};
m_jobToolTips.AddTool(m_jobList.m_hWnd,LPSTR_TEXTCALLBACK,&RectTool,1);

Надеюсь поможет.
Re[8]: ToolTips
От: Константин Ленин Франция  
Дата: 24.01.06 18:12
Оценка:
КЛ>>OnToolTipText не вызывается
P>Да, у меня в таком варианте (см. выделенную строку) тоже не работало, уж не знаю почему. Опытным путем пришел к строке, которая у меня.
P>
P>RECT RectTool={0,0,1000,1000};
P>m_jobToolTips.AddTool(m_jobList.m_hWnd,LPSTR_TEXTCALLBACK,&RectTool,1);
P>

P>Надеюсь поможет.

Компилю под юникод.
Да, работает если только заданы lpRectTool и nIDTool
Причем если почитать документацию по TOOLINFO и посмотреть CToolInfo то вообще-то должно работать и без них. В общем хрень какая-то.
TOOLINFO.hwnd по MSDN должен содержать хэндл парент окна, которое будет получать LVN_GETTIPINFO, а при наших условиях он содержит хэндл листвью контрола. Походу документация врет...
НО, у меня это все равно глючит! Они мне нужны для отображения текста, если он слишком длинный и не помещается в листвью. Но вот как раз на таких айтемах тулипы мигают, либо сразу пропадают, а на коротких все ок.
Вот это х...
Re[9]: ToolTips
От: programmater  
Дата: 24.01.06 18:40
Оценка:
Здравствуйте, Константин Ленин, Вы писали:

КЛ>>>OnToolTipText не вызывается

P>>Да, у меня в таком варианте (см. выделенную строку) тоже не работало, уж не знаю почему. Опытным путем пришел к строке, которая у меня.
P>>
P>>RECT RectTool={0,0,1000,1000};
P>>m_jobToolTips.AddTool(m_jobList.m_hWnd,LPSTR_TEXTCALLBACK,&RectTool,1);
P>>

P>>Надеюсь поможет.

КЛ>Компилю под юникод.

КЛ>Да, работает если только заданы lpRectTool и nIDTool
КЛ>Причем если почитать документацию по TOOLINFO и посмотреть CToolInfo то вообще-то должно работать и без них. В общем хрень какая-то.
КЛ>TOOLINFO.hwnd по MSDN должен содержать хэндл парент окна, которое будет получать LVN_GETTIPINFO, а при наших условиях он содержит хэндл листвью контрола. Походу документация врет...
Эй-эй, по-осторожнее! Читай внимательней! по MSDN TOOLINFO.hwnd должен содержать хэндл парент окна, которое будет получать TTN_GETDISPINFO notification messages. Соображаешь? А это именно хэндл листвью контрола, и ни что иное. А листвью контрол уже соображает, над каким айтемом находится мышиный курсор и переводит TTN_GETDISPINFO в LVN_GETINFOTIP с указанием конкретного айтема, чтобы тебе было удобнее обрабатывать. Так что тут все правильно.
КЛ>НО, у меня это все равно глючит! Они мне нужны для отображения текста, если он слишком длинный и не помещается в листвью. Но вот как раз на таких айтемах тулипы мигают, либо сразу пропадают, а на коротких все ок.
КЛ>Вот это х...
Морганий у меня не было. Возможно потому, что не работал с in-place хинтами (у меня просто подсказка вылезает и все). С юникодом у меня была след трабла (я об этом писал): если текст записывать в буфер, на который указывает pszText структуры NMLVGETINFOTIP, то все нормально, но если самому изменить pszText так, чтобы он указывал на твой буфер, то подсказка не вылезает. С ANSI работает и так и этак. Подробнее здесь
Автор: programmater
Дата: 10.12.05
. Хотя ответа на вопрос, почему так происходит я так и не получил, все равно глянь, а вдруг пригодится.
Re[10]: ToolTips
От: Константин Ленин Франция  
Дата: 25.01.06 10:19
Оценка:
P>Эй-эй, по-осторожнее! Читай внимательней! по MSDN TOOLINFO.hwnd должен содержать хэндл парент окна, которое будет получать TTN_GETDISPINFO notification messages. Соображаешь? А это именно хэндл листвью контрола, и ни что иное. А листвью контрол уже соображает, над каким айтемом находится мышиный курсор и переводит TTN_GETDISPINFO в LVN_GETINFOTIP с указанием конкретного айтема, чтобы тебе было удобнее обрабатывать. Так что тут все правильно.

Спасибо, почитаю.
И где же это написано, что это должне быть именно листвью?

Создал тестовую аппликуху и у меня отлично работает такой вот код


#define TIMER_ID 500

    class CListViewTrackTip : public CMessageMap
    {            
        CContainedWindowT<CListViewCtrl>    m_ctrlList;
        CToolTipCtrl                        m_ctrlTip;
        CWindow                                m_wndOwner;
        TOOLINFO                            m_Info;
        int                                    m_nCurItem;
        bool                                m_bTrackingMouseLeave;

    public:

        BEGIN_MSG_MAP(CListViewTrackTip)
            NOTIFY_CODE_HANDLER(TTN_NEEDTEXT, OnToolTip);
        ALT_MSG_MAP(1)
        END_MSG_MAP()


    public:
        CListViewTrackTip() : m_ctrlList(this, 1), m_nCurItem(-1), m_bTrackingMouseLeave(false){}

        ~CListViewTrackTip()
        {
            if( m_ctrlTip.IsWindow() ) m_ctrlTip.DestroyWindow();
            if( m_ctrlList.IsWindow() ) m_ctrlList.UnsubclassWindow();
        }

        void Attach( CListViewCtrl ctrlList,  HWND hwndOwner )
        {
            HWND hwndList = ctrlList;

            ATLASSERT(::IsWindow(hwndOwner));
            ATLASSERT(::IsWindow(hwndList));
            ATLASSERT(!m_ctrlList.IsWindow()); // Only attach once      

            m_wndOwner = hwndOwner;
            m_ctrlList.SubclassWindow(hwndList);

            // Create the tooltip
            DWORD dwStyle = WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP;
            m_ctrlTip.Create(hwndList, CWindow::rcDefault, NULL, dwStyle, WS_EX_TOPMOST);
            ATLASSERT(m_ctrlTip.IsWindow());
            m_ctrlTip.SetWindowPos(HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

            // Add the ListView as a ToolTip tool...
            m_Info = CToolInfo(TTF_IDISHWND | TTF_TRACK | TTF_ABSOLUTE, hwndList);
            m_Info.hwnd = m_wndOwner;//owner may be not a direct parent
            m_ctrlTip.AddTool(&m_Info);
            m_ctrlTip.TrackActivate(&m_Info, FALSE);
        }

        LRESULT OnToolTip(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
        {
            LPNMTTDISPINFO lpnmtdi = (LPNMTTDISPINFO) pnmh;
            if( pnmh->hwndFrom != m_ctrlTip )
            {
                bHandled = FALSE;
                return 0;
            }

            _bstr_t bsText;
            m_ctrlList.GetItemText(m_nCurItem, 0, bsText.GetBSTR());

            lpnmtdi->lpszText = new TCHAR[ bsText.length() + 1 ];//тут нужно выделять пямять под lpnmtdi->lpszText?
            _tcscpy(lpnmtdi->lpszText, (LPCTSTR)bsText);
            return 0;
        }
    };


Так вот в тестовой все работает отлично, а вмоем проекте тултипы показываются за(!) диалогом
Re[11]: ToolTips
От: programmater  
Дата: 25.01.06 10:53
Оценка:
Здравствуйте, Константин Ленин, Вы писали:

P>>Эй-эй, по-осторожнее! Читай внимательней! по MSDN TOOLINFO.hwnd должен содержать хэндл парент окна, которое будет получать TTN_GETDISPINFO notification messages. Соображаешь? А это именно хэндл листвью контрола, и ни что иное. А листвью контрол уже соображает, над каким айтемом находится мышиный курсор и переводит TTN_GETDISPINFO в LVN_GETINFOTIP с указанием конкретного айтема, чтобы тебе было удобнее обрабатывать. Так что тут все правильно.


КЛ>Спасибо, почитаю.

КЛ>И где же это написано, что это должне быть именно листвью?
Нигде. Это следует из простых логических рассуждений. Листвью получает TTN_GETDISPINFO и форвардит его тебе в виде LVN_GETINFOTIP, чтобы тебе было удобно его обрабатывать. Если листвью не получит TTN_GETDISPINFO, то ты не получишь LVN_GETINFOTIP, только и всего. Это действительно написано. Если же ты работаешь с TTN_GETDISPINFO (или TTN_NEEDTEXT) напрямую, то флаг переполнения тебе в руки (это шутка такая) , тогда TOOLINFO.hwnd может быть действительно любое окно (которое способно обрабатывать это сообщение). Только из твоего примера тестовой апликухи я не понял, откуда ты возьмешь
m_ctrlList.GetItemText(m_nCurItem, 0, bsText.GetBSTR());

насколько я понимаю LVN_GETINFOTIP как раз и отвечает за передачу тебе корректного CurItem-а, над которым в данный момент находится курсор, чтобы ты этим не занимался.

КЛ>Так вот в тестовой все работает отлично, а вмоем проекте тултипы показываются за(!) диалогом

Ну....
Re[12]: ToolTips
От: Константин Ленин Франция  
Дата: 25.01.06 15:02
Оценка:
Только из твоего примера тестовой апликухи я не понял, откуда ты возьмешь
P>
P>m_ctrlList.GetItemText(m_nCurItem, 0, bsText.GetBSTR());
P>


А OnToolTip оказывается и не вызывался
Re[12]: ToolTips
От: Константин Ленин Франция  
Дата: 26.01.06 10:48
Оценка:
Аот это у меня работает на 100%. Взято с viskoe.dk и чуть-чуть переписано
У ListViewCtrl'а не надо ставить LVS_EX_INFOTIP, а то будет 2 тултипа)



#define TIMER_ID 500

    class CListViewTrackTip : public CMessageMap
    {            
        CContainedWindowT<CListViewCtrl>    m_ctrlList;
        CToolTipCtrl                        m_ctrlTip;
        CWindow                                m_wndOwner;
        TOOLINFO                            m_Info;
        int                                    m_nCurItem;
        bool                                m_bTrackingMouseLeave;    
        POINT                                m_Standing;

    public:

        BEGIN_MSG_MAP(CListViewTrackTip)
            MESSAGE_HANDLER(WM_TIMER, OnTimer)
            NOTIFY_CODE_HANDLER(TTN_NEEDTEXT, OnToolTip);
        ALT_MSG_MAP(1)
            MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
            MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave)
        END_MSG_MAP()

    public:
        CListViewTrackTip() : m_ctrlList(this, 1), m_nCurItem(-1), m_bTrackingMouseLeave(false)
        {                
        }

        ~CListViewTrackTip()
        {
            if( m_ctrlTip.IsWindow() ) m_ctrlTip.DestroyWindow();
            if( m_ctrlList.IsWindow() ) m_ctrlList.UnsubclassWindow();
        }

        void Attach( CListViewCtrl ctrlList,  HWND hwndOwner )
        {
            HWND hwndList = ctrlList;

            ATLASSERT(::IsWindow(hwndOwner));
            ATLASSERT(::IsWindow(hwndList));
            ATLASSERT(!m_ctrlList.IsWindow()); // Only attach once      

            m_wndOwner = hwndOwner;
            m_ctrlList.SubclassWindow(hwndList);

            // Create the tooltip
            DWORD dwStyle = WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP;
            m_ctrlTip.Create(NULL, CWindow::rcDefault, NULL, dwStyle, WS_EX_TOPMOST);
            ATLASSERT(m_ctrlTip.IsWindow());
            m_ctrlTip.SetWindowPos(HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

            // Add the ListView as a ToolTip tool...
            m_Info = CToolInfo(TTF_IDISHWND | TTF_TRACK | TTF_ABSOLUTE, hwndList);
            m_Info.hwnd = m_wndOwner;//owner may be not a direct parent
            m_ctrlTip.AddTool(&m_Info);
            m_ctrlTip.TrackActivate(&m_Info, FALSE);
        }

        // Message handlers

        LRESULT OnMouseLeave(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
        {            
            m_bTrackingMouseLeave = false;
            m_wndOwner.KillTimer(TIMER_ID);
            m_ctrlTip.TrackActivate(&m_Info, FALSE);
            bHandled = FALSE;
            return 0;
        }
        LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
        {            
            bHandled = FALSE;                
            m_wndOwner.KillTimer(TIMER_ID);

            POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };                                
            m_Standing = pt;
            UINT iFlags = 0;
            int item = m_ctrlList.HitTest(pt, &iFlags);
            if( item == -1 )
            {
                // Not hovering over any list item? Turn ToolTip off.
                m_ctrlTip.TrackActivate(&m_Info, FALSE);
            }
            else
            {
                bool bTipVisible = m_ctrlTip.GetCurrentTool(NULL) != 0;
                if( !bTipVisible )
                {
                    // Start a timer. If it triggers, the ToolTip has hovered over
                    // the same item for some time...
                    m_wndOwner.SetTimer(TIMER_ID, m_ctrlTip.GetDelayTime(TTDT_INITIAL));
                    m_nCurItem = item;
                }
                else if( m_nCurItem != item )
                {                        
                    m_nCurItem = item;
                    m_ctrlTip.TrackActivate(&m_Info, FALSE);                        
                }
            }
            return 0;
        }
        LRESULT OnTimer(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
        {
            bHandled = FALSE;
            if( wParam != TIMER_ID ) return 0;

            POINT pt = m_Standing;
            m_ctrlList.ClientToScreen(&pt);
            m_ctrlTip.TrackPosition(pt.x + 15, pt.y + 15);
            m_ctrlTip.TrackActivate(&m_Info, TRUE);
            return 0;
        }
        LRESULT OnToolTip(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
        {
            LPNMTTDISPINFO lpnmtdi = (LPNMTTDISPINFO) pnmh;
            if( pnmh->hwndFrom != m_ctrlTip )
            {
                bHandled = FALSE;
                return 0;
            }

            _bstr_t bsText;
            m_ctrlList.GetItemText(m_nCurItem, 0, bsText.GetBSTR());

            lpnmtdi->lpszText = new TCHAR[ bsText.length() + 1 ];
            _tcscpy(lpnmtdi->lpszText, (LPCTSTR)bsText);
            return 0;
        }
    };
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.