Итого2: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 25.08.04 15:17
Оценка: 6 (2)
#Имя: FAQ.wtl.tooltip
Еще несколько маленьких доработок:

namespace UI2
{
    class Tooltip
        : public CWindowImpl<Tooltip, ATL::CWindow>
    {
    public:
        typedef CWindowImpl<Tooltip, ATL::CWindow> baseClass;
        typedef Tooltip thisClass;

        HWND     m_hWndOwner;

    private:
        TOOLINFO m_ToolInfo;
        bool     m_bVisible;
        bool     m_bShowAtCursor;

        enum { TIMER_MSG_DELAY_SHOW = 100, TIMER_MSG_DELAY_HIDE = 101, };

        static LPCTSTR GetWndClassName(){ return _T("Zaebis_Tooltip"); }

    public:
        DECLARE_WND_SUPERCLASS(GetWndClassName(), baseClass::GetWndClassName())

        BEGIN_MSG_MAP(thisClass)
            MESSAGE_HANDLER(WM_TIMER, OnTimer)
            MESSAGE_HANDLER(WM_SETCURSOR, OnMouseMessage) // Если хочется что бы над подказкой был такой-же курсор как и над хозяином
            MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage)
        END_MSG_MAP()


        Tooltip()
        : baseClass()
        , m_bVisible(false)
        , m_hWndOwner(0)
        {
            memset(&m_ToolInfo, 0, sizeof(m_ToolInfo));
        }

        ~Tooltip()
        { 
            DestroyWindow();
        }

        bool Create( HWND hWndParent, HWND hWndOwner = NULL )
        {
            DestroyWindow();

            HWND hWnd = ::CreateWindowEx(WS_EX_TOPMOST,
                TOOLTIPS_CLASS,
                NULL,
                TTS_NOPREFIX | TTS_ALWAYSTIP,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                hWndParent,
                NULL,
                NULL,
                NULL);

            ATLASSERT(hWnd);

            // initialize toolinfo struct
            m_ToolInfo.cbSize = sizeof(m_ToolInfo);
            m_ToolInfo.uFlags = TTF_TRACK | TTF_TRANSPARENT | TTF_SUBCLASS;
            m_ToolInfo.hwnd = hWndParent;

             m_hWndOwner = hWndOwner;

            ::SendMessage( hWnd, TTM_SETMAXTIPWIDTH, 0, SHRT_MAX );
            ::SendMessage( hWnd, TTM_ADDTOOL, 0, (LPARAM)(LPTOOLINFO)&m_ToolInfo );

            SubclassWindow( hWnd );

            return true;
        }


        void DestroyWindow()
        {
            if( m_hWnd )baseClass::DestroyWindow();

            delete [] m_ToolInfo.lpszText;
            memset(&m_ToolInfo, 0, sizeof(m_ToolInfo));
        }


        void SetBackColor( COLORREF c ){ ::SendMessage( m_hWnd, TTM_SETTIPBKCOLOR, c, 0 ); }
        void SetTextColor( COLORREF c ){ ::SendMessage( m_hWnd, TTM_SETTIPTEXTCOLOR, c, 0 ); }
        void SetMargins( const RECT* rectMargins ){ ::SendMessage(m_hWnd, TTM_SETMARGIN, 0, (LPARAM)rectMargins); }
        void SetMaxWidth( int maxWidth ){ ::SendMessage( m_hWnd, TTM_SETMAXTIPWIDTH, 0, (LPARAM)maxWidth ); }

        bool IsVisible(){ return m_bVisible; };

        const TCHAR* GetText()
        {
            ::SendMessage( m_hWnd, TTM_GETTEXT, 0, (LPARAM)&m_ToolInfo );
            return m_ToolInfo.lpszText;
        }

        void SetText( const TCHAR* text )
        {
            delete [] m_ToolInfo.lpszText;

            if( text )
            {
                m_ToolInfo.lpszText = new TCHAR[ _tcslen(text)+1 ];
                _tcscpy( m_ToolInfo.lpszText, text );
            }
            else m_ToolInfo.lpszText = NULL;

            ::SendMessage( m_hWnd, TTM_UPDATETIPTEXT, 0, (LPARAM)&m_ToolInfo );
        }

        void Move( int x, int y )
        {
            ::SendMessage( m_hWnd, TTM_TRACKPOSITION, 0, (LPARAM)(DWORD)MAKELONG( x, y ) );
        }

        void Show( int x, int y )
        {
            Move( x, y );
            Show();
        }

        void Show( const RECT* r )
        {
            m_bVisible = true;
            m_ToolInfo.rect = *r;

            ::SendMessage( m_hWnd, TTM_TRACKPOSITION, 0, (LPARAM)(DWORD) MAKELONG( r->left, r->top ) );
            ::SendMessage( m_hWnd, TTM_SETMAXTIPWIDTH, 0, (LPARAM)(r->right - r->left) );
            ::SendMessage( m_hWnd, TTM_TRACKACTIVATE, TRUE, (LPARAM)&m_ToolInfo );
        }

        void Show( BOOL bShow = TRUE )
        {
            m_bVisible = (bShow == TRUE);
            ::SendMessage( m_hWnd, TTM_TRACKACTIVATE, bShow, (LPARAM)&m_ToolInfo );
        }

        void ShowAtCursor()
        {
            POINT pt; ::GetCursorPos( &pt );
            Show( pt.x, pt.y+20 );
        }

        void ShowAfter( UINT delay, bool bAtCursor = false )
        {
            if( IsWindow() )
            {
                m_bShowAtCursor = bAtCursor;

                KillTimer( TIMER_MSG_DELAY_SHOW );
                SetTimer( TIMER_MSG_DELAY_SHOW, delay );
            }
        }

        void ShowAtCursorAfter( UINT delay )
        {
            ShowAfter( delay, true );
        }

        void HideAfter( UINT delay )
        {
            if( IsWindow() )
            {
                KillTimer( TIMER_MSG_DELAY_HIDE );
                SetTimer( TIMER_MSG_DELAY_HIDE, delay );
            }
        }

        void CancelShowAfter()
        {
            KillTimer( TIMER_MSG_DELAY_SHOW );
        }

        void CancelHideAfter()
        {
            KillTimer( TIMER_MSG_DELAY_HIDE );
        }

        operator HWND() { return m_hWnd; }


        // Message handlers

        LRESULT OnTimer( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
        {
            if( TIMER_MSG_DELAY_SHOW == wParam )
            {
                m_bShowAtCursor?ShowAtCursor():Show();
                KillTimer( wParam );
            }
            else if( TIMER_MSG_DELAY_HIDE == wParam )
            {
                Show(FALSE);
                KillTimer( wParam );
            }

            bHandled = FALSE;
            return 0;
        }

        LRESULT OnMouseMessage( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
        {
            LRESULT ret = 0;

            // forward message to owner window 
            if( m_hWndOwner )
            {
                POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
                ClientToScreen( &pt ); ::ScreenToClient( m_hWndOwner, &pt );
                ret = ::SendMessage( m_hWndOwner, uMsg, wParam, MAKELONG( pt.x, pt.y ) );
            }

            //bHandled = TRUE;
            bHandled = FALSE;
            return ret;
        }
    };
}
... << RSDN@Home 1.1.4 @@subversion >>
Итого: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 20.08.04 16:54
Оценка: 12 (1)
Всем спасибо за сделанные замечания. Вот поправленная версия:

namespace UI2
{
    class Tooltip
        : public CWindowImpl<Tooltip, ATL::CWindow>
    {
    public:
        typedef CWindowImpl<Tooltip, ATL::CWindow> baseClass;
        typedef Tooltip thisClass;

        HWND     m_hWndOwner;

    private:
        TOOLINFO m_ToolInfo;
        bool     m_bActive;
        bool     m_bShowAtCursor;

        enum { TIMER_MSG_DELAY_SHOW = 100, TIMER_MSG_DELAY_HIDE = 101, };

        static LPCTSTR GetWndClassName(){ return _T("Zaebis_Tooltip"); }

    public:
        DECLARE_WND_SUPERCLASS(GetWndClassName(), baseClass::GetWndClassName())

        BEGIN_MSG_MAP(thisClass)
            MESSAGE_HANDLER(WM_TIMER, OnTimer)
            MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage)
        END_MSG_MAP()


        Tooltip()
        : baseClass()
        , m_bActive(false)
        , m_hWndOwner(0)
        {
            memset(&m_ToolInfo, 0, sizeof(m_ToolInfo));
        }

        ~Tooltip()
        { 
            delete m_ToolInfo.lpszText;
            m_ToolInfo.lpszText = NULL;
        }

        bool Create( HWND hWndParent, HWND hWndOwner = NULL )
        {
            HWND hWnd = ::CreateWindowEx(WS_EX_TOPMOST,
                TOOLTIPS_CLASS,
                NULL,
                TTS_NOPREFIX | TTS_ALWAYSTIP,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                hWndParent,
                NULL,
                NULL,
                NULL);

            ATLASSERT(hWnd);

            // initialize toolinfo struct
            memset(&m_ToolInfo, 0, sizeof(m_ToolInfo));
            m_ToolInfo.cbSize = sizeof(m_ToolInfo);
            m_ToolInfo.uFlags = TTF_TRACK | TTF_TRANSPARENT | TTF_SUBCLASS;
            m_ToolInfo.hwnd = hWndParent;

             m_hWndOwner = hWndOwner;

            ::SendMessage( hWnd, TTM_SETMAXTIPWIDTH, 0, SHRT_MAX);
            ::SendMessage( hWnd, TTM_ADDTOOL, 0, (LPARAM)(LPTOOLINFO)&m_ToolInfo);

            SubclassWindow( hWnd );

            return true;
        }

        void SetBackColor( COLORREF c ){ ::SendMessage( m_hWnd, TTM_SETTIPBKCOLOR, c, 0 ); }
        void SetTextColor( COLORREF c ){ ::SendMessage( m_hWnd, TTM_SETTIPTEXTCOLOR, c, 0 ); }
        void SetMargins( const RECT* rectMargins ){ ::SendMessage(m_hWnd, TTM_SETMARGIN, 0, (LPARAM)rectMargins ); }
        void SetMaxWidth( int maxWidth ){ ::SendMessage( m_hWnd, TTM_SETMAXTIPWIDTH, 0, (LPARAM)maxWidth ); }

        bool IsVisible(){ return m_bActive; };

        CString GetText()
        {
            ::SendMessage( m_hWnd, TTM_GETTEXT, 0, (LPARAM)&m_ToolInfo );
            return CString( m_ToolInfo.lpszText );
        }

        void SetText( const TCHAR* str )
        {
            delete m_ToolInfo.lpszText;

            if( str )
            {
                m_ToolInfo.lpszText = new TCHAR[ _tcslen(str)+1 ];
                _tcscpy( m_ToolInfo.lpszText, str );
            }
            else m_ToolInfo.lpszText = NULL;

            ::SendMessage( m_hWnd, TTM_UPDATETIPTEXT, 0, (LPARAM)&m_ToolInfo );
        }

        void Move( int x, int y )
        {
            ::SendMessage( m_hWnd, TTM_TRACKPOSITION, 0, (LPARAM)(DWORD)MAKELONG( x, y ) );
        }

        void Show( int x, int y )
        {
            Move( x, y );
            Show();
        }

        void Show( const RECT* r )
        {
            m_bActive = true;
            m_ToolInfo.rect = *r;

            ::SendMessage( m_hWnd, TTM_TRACKPOSITION, 0, (LPARAM)(DWORD) MAKELONG( r->left, r->top ) );
            ::SendMessage( m_hWnd, TTM_SETMAXTIPWIDTH, 0, (LPARAM)(r->right - r->left) );
            ::SendMessage( m_hWnd, TTM_TRACKACTIVATE, TRUE, (LPARAM)&m_ToolInfo );
        }

        void Show( BOOL bShow = TRUE )
        {
            m_bActive = (bShow == TRUE);
            ::SendMessage( m_hWnd, TTM_TRACKACTIVATE, bShow, (LPARAM)&m_ToolInfo );
        }

        void ShowAtCursor()
        {
            POINT pt; ::GetCursorPos( &pt );
            Show( pt.x, pt.y+20 );
        }

        void ShowAfter( UINT delay, bool bAtCursor = false )
        {
            if( IsWindow() )
            {
                m_bShowAtCursor = bAtCursor;

                KillTimer( TIMER_MSG_DELAY_SHOW );
                SetTimer( TIMER_MSG_DELAY_SHOW, delay );
            }
        }

        void ShowAtCursorAfter( UINT delay )
        {
            ShowAfter( delay, true );
        }

        void HideAfter( UINT delay )
        {
            if( IsWindow() )
            {
                KillTimer( TIMER_MSG_DELAY_HIDE );
                SetTimer( TIMER_MSG_DELAY_HIDE, delay );
            }
        }

        void CancelShowAfter()
        {
            KillTimer( TIMER_MSG_DELAY_SHOW );
        }

        void CancelHideAfter()
        {
            KillTimer( TIMER_MSG_DELAY_HIDE );
        }

        operator HWND() { return m_hWnd; }


        // Message handlers

        LRESULT OnTimer( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
        {
            if( TIMER_MSG_DELAY_SHOW == wParam )
            {
                m_bShowAtCursor?ShowAtCursor():Show();
        KillTimer( wParam );
            }
            else if( TIMER_MSG_DELAY_HIDE == wParam )
            {
                Show(FALSE);
                KillTimer( wParam );
            }

            bHandled = FALSE;
            return 0;
        }

        LRESULT OnMouseMessage( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
        {
            // forward message to owner window 
            if( m_hWndOwner )
            {
                POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
                ClientToScreen( &pt ); ::ScreenToClient( m_hWndOwner, &pt );
                ::SendMessage( m_hWndOwner, uMsg, wParam, MAKELONG( pt.x, pt.y ) );
            }

            bHandled = TRUE;
            return 0;
        }
    };
}
Думай, что хочешь, делай, что хочешь, живи, как хочешь -- всё тебе припомню!!
Re[2]: Поправить конструктор
От: WinterMute Россия http://yarrr.ru
Дата: 20.08.04 16:54
Оценка: +1
Здравствуйте, Odi$$ey, Вы писали:

WM>>

OE>
OE>      ~Tooltip()
OE>      { 
OE>          delete m_ToolInfo.lpszText; // << иначе утекает при уничтожении окна с текстом
OE>          m_ToolInfo.lpszText = NULL;
OE>      }
OE>

WM>>


Да, нужно еще поправить конструктор, иначе вызов деструктора объекта для которого не был применён метод Create приведёт к неопределённому поведению.

Правильный конструктор:

        Tooltip()
        : baseClass()
        , m_bActive(false)
        , m_hWndOwner(0)
        {
            memset(&m_ToolInfo, 0, sizeof(m_ToolInfo));
        }
Думай, что хочешь, делай, что хочешь, живи, как хочешь -- всё тебе припомню!!
Re: Итого: WTL: Подсказка в любом месте экрана
От: Alexey Goncharov Россия  
Дата: 21.08.04 17:03
Оценка: +1
Здравствуйте, WinterMute, Вы писали:

WM>Всем спасибо за сделанные замечания. Вот поправленная версия:


Еще маленькое замечание — раз память выделяется по new [], то и удалять надо по delete [], а не по delete
Re[2]: Итого: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 21.08.04 22:12
Оценка: +1
AG>Еще маленькое замечание — раз память выделяется по new [], то и удалять надо по delete [], а не по delete

Да, я тоже недавно заметил .
Думай, что хочешь, делай, что хочешь, живи, как хочешь -- всё тебе припомню!!
WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 18.08.04 14:15
Оценка:
В своё время меня не устроил стандартный CTooltipCtrl -- мне была нужена подсказка которая бы появлялась и пропадала когда ей скажут. Кроме того, нужно было, что бы подсказка была прозрачна для всех сообщений мыши (я делал т.н. inplace tooltip). Этот простой класс делает всё вышеперечисленное.

Короткое описание:

Маленькое замечание: при создании нужно указать окно хозяин, и это не тоже самое что окно владелец(m_hWndOwner). В качестве хозяина удобнее всего установить ::GetDesktopWindow(), в противном случае возникают малопонятные глюки с позиционированием.

namespace UI2
{
    class Tooltip
        : public CWindowImpl<Tooltip, ATL::CWindow>
    {
    public:
        typedef CWindowImpl<Tooltip, ATL::CWindow> baseClass;
        typedef Tooltip thisClass;

        HWND     m_hWndOwner;

    private:
        TOOLINFO m_ToolInfo;
        bool     m_bActive;

        enum { TIMER_MSG_DELAY_SHOW = 100, TIMER_MSG_DELAY_HIDE = 101, };

        static LPCTSTR GetWndClassName(){ return _T("Zaebis_Tooltip"); }

    public:
        DECLARE_WND_SUPERCLASS(GetWndClassName(), baseClass::GetWndClassName())

        BEGIN_MSG_MAP(thisClass)
            MESSAGE_HANDLER(WM_TIMER, OnTimer)
            MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage)
        END_MSG_MAP()


        Tooltip()
        : baseClass()
        , m_bActive(false)  // подсказка видна
        , m_hWndOwner(0)    // окно, которому будут передаваться мышиные сообщения
        {
        }

        virtual ~Tooltip()
        { }

        bool Create( HWND hWndParent, HWND hWndOwner = NULL )
        {
            HWND hWnd = ::CreateWindowEx(WS_EX_TOPMOST,
                TOOLTIPS_CLASS,
                NULL,
                TTS_NOPREFIX | TTS_ALWAYSTIP,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                hWndParent,
                NULL,
                NULL,
                NULL);

            ATLASSERT(hWnd);

            // initialize toolinfo struct
            memset(&m_ToolInfo, 0, sizeof(m_ToolInfo));
            m_ToolInfo.cbSize = sizeof(m_ToolInfo);
            m_ToolInfo.uFlags = TTF_TRACK | TTF_TRANSPARENT | TTF_SUBCLASS;
            m_ToolInfo.hwnd = hWndParent;

            ::SendMessage(hWnd, TTM_SETMAXTIPWIDTH, 0, SHRT_MAX);
            ::SendMessage(hWnd, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &m_ToolInfo);

            m_hWndOwner = hWndOwner;

            SubclassWindow( hWnd );

            return true;
        }

        void SetBackColor( COLORREF c ){ ::SendMessage(m_hWnd, TTM_SETTIPBKCOLOR, c, 0); }
        void SetTextColor( COLORREF c ){ ::SendMessage(m_hWnd, TTM_SETTIPTEXTCOLOR, c, 0); }
        void SetMargins( const RECT* rectMargins ){ ::SendMessage(m_hWnd, TTM_SETMARGIN, 0, (LPARAM)rectMargins); }
        void SetMaxWidth( int maxWidth ){ ::SendMessage(m_hWnd, TTM_SETMAXTIPWIDTH, 0, (LPARAM)maxWidth); }

        bool IsVisible(){ return m_bActive; };

        CString GetText()
        {
            ::SendMessage( m_hWnd, TTM_GETTEXT, 0, m_ToolInfo );
            return CString( m_ToolInfo.lpszText );
        }

        void SetText( const TCHAR* str )
        {
            delete m_ToolInfo.lpszText;
            if( str )
            {
                m_ToolInfo.lpszText = new TCHAR[ _tcslen(str)+1 ];
                _tcscpy( m_ToolInfo.lpszText, str );
            }
            else m_ToolInfo.lpszText = NULL;

            ::SendMessage( m_hWnd, TTM_UPDATETIPTEXT, 0, (LPARAM)(LPTOOLINFO) &m_ToolInfo );
        }

        void Show( int x, int y )
        {
            m_bActive = true;

            ::SendMessage( m_hWnd, TTM_TRACKPOSITION, 0, (LPARAM)(DWORD) MAKELONG( x, y ) );
            ::SendMessage( m_hWnd, TTM_TRACKACTIVATE, TRUE, (LPARAM)(LPTOOLINFO) &m_ToolInfo );
        }

        void Show( const RECT* r )
        {
            m_bActive = true;

            m_ToolInfo.rect = *r;

            ::SendMessage( m_hWnd, TTM_TRACKPOSITION, 0, (LPARAM)(DWORD) MAKELONG( r->left, r->top ) );
            ::SendMessage( m_hWnd, TTM_SETMAXTIPWIDTH, 0, (LPARAM)(r->right - r->left) );
            ::SendMessage( m_hWnd, TTM_TRACKACTIVATE, TRUE, (LPARAM)(LPTOOLINFO)&m_ToolInfo );
        }

        void Show( BOOL bShow = TRUE )
        {
            KillTimer( TIMER_MSG_DELAY_SHOW );
            KillTimer( TIMER_MSG_DELAY_HIDE );

            m_bActive = (bShow == TRUE);

            ::SendMessage( m_hWnd, TTM_TRACKACTIVATE, bShow, (LPARAM)(LPTOOLINFO) &m_ToolInfo );
        }

        void Move( int x, int y )
        {
            ::SendMessage( m_hWnd, TTM_TRACKPOSITION, 0, (LPARAM)(DWORD) MAKELONG( x, y ) );
        }

        void DelayShowAtCursor( UINT timeToShow )
        {
            KillTimer( TIMER_MSG_DELAY_SHOW );
            SetTimer( TIMER_MSG_DELAY_SHOW, timeToShow );
        }

        operator HWND() { return m_hWnd; }


        // Message handlers

        LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
        {
            if( TIMER_MSG_DELAY_SHOW == wParam )
            {
                POINT pt; ::GetCursorPos( &pt );
                Show( pt.x, pt.y+20 );
                KillTimer( wParam );
            }
            else if( TIMER_MSG_DELAY_HIDE == wParam )
            {
                Show(FALSE);
                KillTimer( wParam );
            }

            bHandled = FALSE;
            return 0;
        }

        LRESULT OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
        {
            // forward message to owner window 
            if( m_hWndOwner )
            {
                POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
                ClientToScreen( &pt ); ::ScreenToClient( m_hWndOwner, &pt );
                lParam = PtToLPARAM(pt);

                ::SendMessage( m_hWndOwner, uMsg, wParam, lParam );
            }

            bHandled = TRUE;
            return 0;
        }
    };

    // ----------------------------------------------------
    
    inline LPARAM PtToLPARAM( POINT pt )
    {
        LPARAM lParam = 0;
        WORD*  pLParam = (WORD*)&lParam;
    
        pLParam[0] = (short)pt.x;
        pLParam[1] = (short)pt.y;
    
        return lParam;
    }
}
Думай, что хочешь, делай, что хочешь, живи, как хочешь -- всё тебе припомню!!
Re: WTL: Подсказка в любом месте экрана
От: _nn_ www.nemerleweb.com
Дата: 18.08.04 16:25
Оценка:
Здравствуйте, WinterMute, Вы писали:

А в чем выражается нужда в виртуальном деструкторе ?

Еще хочу заметить что в WTL принято делать два класса : SomeClassImpl в котором вся функциональность и SomeClass производный от SomeClassImpl, где устанавливается класс окна через DECLARE_WND_SUPERCLASS.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 18.08.04 16:57
Оценка:
__>А в чем выражается нужда в виртуальном деструкторе ?
Да ни в чём, убрать конечно же.

__>Еще хочу заметить что в WTL принято делать два класса : SomeClassImpl в котором вся функциональность и SomeClass производный от SomeClassImpl, где устанавливается класс окна через DECLARE_WND_SUPERCLASS.


Знаю, но в этом случае с трудом представляю зачем это может понадобиться.
Думай, что хочешь, делай, что хочешь, живи, как хочешь -- всё тебе припомню!!
Re[3]: WTL: Подсказка в любом месте экрана
От: _nn_ www.nemerleweb.com
Дата: 19.08.04 06:38
Оценка:
Здравствуйте, WinterMute, Вы писали:

__>>А в чем выражается нужда в виртуальном деструкторе ?

WM>Да ни в чём, убрать конечно же.


__>>Еще хочу заметить что в WTL принято делать два класса : SomeClassImpl в котором вся функциональность и SomeClass производный от SomeClassImpl, где устанавливается класс окна через DECLARE_WND_SUPERCLASS.


WM>Знаю, но в этом случае с трудом представляю зачем это может понадобиться.

Для того чтобы кто-то смог в дальнейшем расширить функциональность класса.
Так принято в WTL и отходить от этого стиля не стоит.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 19.08.04 21:24
Оценка:
Здравствуйте, _nn_, Вы писали:

WM>>Знаю, но в этом случае с трудом представляю зачем это может понадобиться.

__>Для того чтобы кто-то смог в дальнейшем расширить функциональность класса.

Да нафиг, и так нормально работает . KISS
Думай, что хочешь, делай, что хочешь, живи, как хочешь -- всё тебе припомню!!
Re: WTL: Подсказка в любом месте экрана
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 20.08.04 06:48
Оценка:
Здравствуйте, WinterMute, Вы писали:

WM>


      ~Tooltip()
      { 
          delete m_ToolInfo.lpszText; // << иначе утекает при уничтожении окна с текстом
          m_ToolInfo.lpszText = NULL;
      }


WM> ...

WM>        CString GetText()
WM>        {
WM>            //::SendMessage( m_hWnd, TTM_GETTEXT, 0, m_ToolInfo ); << очипатка, должно быть
               ::SendMessage( m_hWnd, TTM_GETTEXT, 0, (LPARAM)&m_ToolInfo );
                
WM>            return CString( m_ToolInfo.lpszText );
WM>        }

WM>
Re: WTL: Подсказка в любом месте экрана
От: _nn_ www.nemerleweb.com
Дата: 20.08.04 07:46
Оценка:
Здравствуйте, WinterMute, Вы писали:

::SendMessage(m_hWnd...)
В чем смысл в этм если можно писать просто SendMessage ?

Функцию PtToLPARAM слудует пересмотреть, можно это заменить одной строкой
Вдобавок лучше ее сделать статической функцией класса.

По возможности стоит избегать использования CString в классе или же через условную компиляцию добавлять функции.
А то не все пользуются CString и может вылезти ошибка.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 20.08.04 08:24
Оценка:
Здравствуйте, _nn_, Вы писали:

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


__>::SendMessage(m_hWnd...)

__>В чем смысл в этм если можно писать просто SendMessage ?

Как то пришлось переносить WTL-ные библиотеки на WinApi, теперь, если не особой разницы, я стараюсь пользоваться API функциями.

__>Функцию PtToLPARAM слудует пересмотреть, можно это заменить одной строкой


Как? Напиши пож, а то я сначала сделал одной строкой, дак она глючила.

__>Вдобавок лучше ее сделать статической функцией класса.


Мне она была нужна и в других классах, поэтому она глобальная.

__>По возможности стоит избегать использования CString в классе или же через условную компиляцию добавлять функции.

__>А то не все пользуются CString и может вылезти ошибка.

Приму во внимание.
Думай, что хочешь, делай, что хочешь, живи, как хочешь -- всё тебе припомню!!
Re[2]: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 20.08.04 08:24
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

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



OE>
OE>      ~Tooltip()
OE>      { 
OE>          delete m_ToolInfo.lpszText; // << иначе утекает при уничтожении окна с текстом
OE>          m_ToolInfo.lpszText = NULL;
OE>      }
OE>

Вот это большое спасибо. У меня подсказка создавалась статически, поэтому наверное, и не заметил.


WM>> ...



WM>>        CString GetText()
WM>>        {
WM>>            //::SendMessage( m_hWnd, TTM_GETTEXT, 0, m_ToolInfo ); << очипатка, должно быть
OE>               ::SendMessage( m_hWnd, TTM_GETTEXT, 0, (LPARAM)&m_ToolInfo );
                
WM>>            return CString( m_ToolInfo.lpszText );
WM>>        }


Ага, добавил в последний момент, мне то она была не нужна.
Думай, что хочешь, делай, что хочешь, живи, как хочешь -- всё тебе припомню!!
Re[3]: WTL: Подсказка в любом месте экрана
От: _nn_ www.nemerleweb.com
Дата: 20.08.04 09:14
Оценка:
Здравствуйте, WinterMute, Вы писали:

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


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


__>>::SendMessage(m_hWnd...)

__>>В чем смысл в этм если можно писать просто SendMessage ?

WM>Как то пришлось переносить WTL-ные библиотеки на WinApi, теперь, если не особой разницы, я стараюсь пользоваться API функциями.

По CString это не заметно
А вообще все же не принято писать ::SendMessage(m_hWnd...)
Это выглядит мазохизмом, мы ведь в WTL пишем все же

__>>Функцию PtToLPARAM слудует пересмотреть, можно это заменить одной строкой


WM>Как? Напиши пож, а то я сначала сделал одной строкой, дак она глючила.

Ну попробую :
Оригинал :
 inline LPARAM PtToLPARAM( POINT pt )
    {
        LPARAM lParam = 0;
        WORD*  pLParam = (WORD*)&lParam;
    
        pLParam[0] = (short)pt.x;
        pLParam[1] = (short)pt.y;
    
        return lParam;
    }

В младщую чать идет координата x, а в старшую часть идет координата y.
inline LPARAM PtToLPARAM(const POINT& pt)
{ return (LPARAM)(pt.x+pt.y<<16); }

Или же можно воспользоваться MAKEWORD
MAKEWORD(pt.x,pt.y)
И все

__>>Вдобавок лучше ее сделать статической функцией класса.


WM>Мне она была нужна и в других классах, поэтому она глобальная.

Понятно.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 20.08.04 13:18
Оценка:
Здравствуйте, _nn_, Вы писали:

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


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


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


__>>>::SendMessage(m_hWnd...)

__>>>В чем смысл в этм если можно писать просто SendMessage ?

WM>>Как то пришлось переносить WTL-ные библиотеки на WinApi, теперь, если не особой разницы, я стараюсь пользоваться API функциями.

__>По CString это не заметно

Я СString тоже переносил, как-то хитро откусывая хвосты. И в случае чего опроедлить свой "CString" не проблема, там ведь всё что от СString используется это конструирование из константной строки и приведение к константной строке, такое из std::string в два счёта делается. А использовать строки без обёрток это как-то не по мне.

__>А вообще все же не принято писать ::SendMessage(m_hWnd...)

__>Это выглядит мазохизмом, мы ведь в WTL пишем все же

Правильно, я же мазохист .

__>>>Функцию PtToLPARAM слудует пересмотреть, можно это заменить одной строкой


WM>>Как? Напиши пож, а то я сначала сделал одной строкой, дак она глючила.

__>Ну попробую :
__>Оригинал :
__>
__> inline LPARAM PtToLPARAM( POINT pt )
__>    {
__>        LPARAM lParam = 0;
__>        WORD*  pLParam = (WORD*)&lParam;
    
__>        pLParam[0] = (short)pt.x;
__>        pLParam[1] = (short)pt.y;
    
__>        return lParam;
__>    }
__>

__>В младщую чать идет координата x, а в старшую часть идет координата y.
__>
__>inline LPARAM PtToLPARAM(const POINT& pt)
__>{ return (LPARAM)(pt.x+pt.y<<16); }
__>


Это работает только если координаты положительны.

__>Или же можно воспользоваться MAKEWORD

__>MAKEWORD(pt.x,pt.y)
__>И все

Да, похоже на то, только MAKELONG.
Думай, что хочешь, делай, что хочешь, живи, как хочешь -- всё тебе припомню!!
Re: Итого: WTL: Подсказка в любом месте экрана
От: _nn_ www.nemerleweb.com
Дата: 20.08.04 17:42
Оценка:
Здравствуйте, WinterMute, Вы писали:

WM>Всем спасибо за сделанные замечания. Вот поправленная версия:


Еще поправка :
LPCTSTR GetText()
{
  SendMessage(TTM_GETTEXT, 0, (LPARAM)&m_ToolInfo);
  return m_ToolInfo.lpszText;
}


Кроме того что это избавляет от использования CString, это не вызвает лишний конструктор.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Итого: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 20.08.04 21:56
Оценка:
__>Еще поправка :
__>
__>LPCTSTR GetText()
__>{
__>  SendMessage(TTM_GETTEXT, 0, (LPARAM)&m_ToolInfo);
__>  return m_ToolInfo.lpszText;
__>}
__>


__>Кроме того что это избавляет от использования CString, это не вызвает лишний конструктор.


Ты прав, константный указатель на строку лучше.
Думай, что хочешь, делай, что хочешь, живи, как хочешь -- всё тебе припомню!!
Re[5]: WTL: Подсказка в любом месте экрана
От: _nn_ www.nemerleweb.com
Дата: 21.08.04 06:56
Оценка:
Здравствуйте, WinterMute, Вы писали:

WM>Это работает только если координаты положительны.


WM>Да, похоже на то, только MAKELONG.

Конечно

Так устроит ?
MAKELONG((short)pt.x,(short)pt.y)
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 21.08.04 10:27
Оценка:
__>Так устроит ?
__>
__>MAKELONG((short)pt.x,(short)pt.y)
__>


Устроит. Но приведение к "short" лишнее, в макросе MAKELONG все компоненты усекаются по маске 0xffff.
Думай, что хочешь, делай, что хочешь, живи, как хочешь -- всё тебе припомню!!
Re: WTL: Подсказка в любом месте экрана
От: swap Россия  
Дата: 09.11.07 10:52
Оценка:
Данный код не работает (тултипы не появляются) если есть макрос
#define _WIN32_WINNT 0x0501
который например нужен для atltheme.h
Re[2]: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 09.11.07 11:11
Оценка:
Здравствуйте, swap, Вы писали:

S>Данный код не работает (тултипы не появляются) если есть макрос

S>#define _WIN32_WINNT 0x0501
S>который например нужен для atltheme.h :(

У меня в текущем проекте он используется в том числе с кодом для отрисовки тем. Там, правда определён макрос
"#define _WIN32_WINNT 0x0500"

Ты уверен что дело в макросе, есть какие-нибудь другие "симптомы"?
Re[2]: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 09.11.07 11:37
Оценка:
Толькло что попробовал с макросом 0x0501 -- всё работает.
Покажи как ты используешь класс.

S>Данный код не работает (тултипы не появляются) если есть макрос

S>#define _WIN32_WINNT 0x0501
S>который например нужен для atltheme.h :(
Re[3]: WTL: Подсказка в любом месте экрана
От: swap Россия  
Дата: 09.11.07 11:58
Оценка:
Здравствуйте, WinterMute, Вы писали:

WM>Толькло что попробовал с макросом 0x0501 -- всё работает.

WM>Покажи как ты используешь класс.

Да, дело в нем. Если ставишь 0x0500 все работает, но atltheme.h требует 0x0501.

Использую так:
WTL 7.5, VC 80 SP1, создаю через визард WTL проект с главным дилоговым окном. в CMainDlg объявляю переменнкю UI::Tooltip m_tooltip.
В OnInitDialog делаю

m_tooltip.Create(m_hWnd);

И, например, в CMainDlg::OnLButtonDown делаю

m_tooltip.SetText("bla bla bla");
m_tooltip.ShowAtCursor();

в stdafx.h такие макросы:

#define WINVER 0x0500
#define _WIN32_WINNT 0x0501
#define _WIN32_IE 0x0501
#define _RICHEDIT_VER 0x0100
Re[4]: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 09.11.07 12:19
Оценка:
У меня другая версия VS и, видимо, ATL. Возможно дело в этом.
Можешь посмотреть отладчиком, создаётся ли вообще окно,
и что происходит после вызова ShowAtCursor() -- GetLastError()
в смысле.

Да, и для подержки тем, по идее, не нужен _WIN32_WINNT 0x0501,
достаточно вручную прописать
#ifndef WM_THEMECHANGED
#   define WM_THEMECHANGED                 0x031A
#endif

По крайней мере, с моей версией библиотек, больше ничего не потребовалось.


WM>>Толькло что попробовал с макросом 0x0501 -- всё работает.

WM>>Покажи как ты используешь класс.

S>Да, дело в нем. Если ставишь 0x0500 все работает, но atltheme.h требует 0x0501.


S>Использую так:

S>WTL 7.5, VC 80 SP1, создаю через визард WTL проект с главным дилоговым окном. в CMainDlg объявляю переменнкю UI::Tooltip m_tooltip.
S>В OnInitDialog делаю

S>m_tooltip.Create(m_hWnd);


S>И, например, в CMainDlg::OnLButtonDown делаю


S>m_tooltip.SetText("bla bla bla");

S>m_tooltip.ShowAtCursor();

S>в stdafx.h такие макросы:


S>#define WINVER 0x0500

S>#define _WIN32_WINNT 0x0501
S>#define _WIN32_IE 0x0501
S>#define _RICHEDIT_VER 0x0100
Re[5]: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 09.11.07 12:29
Оценка:
Про поддержку тем, это я загнул конечно. Просто у меня используется своя библиотека для поддержки тем, ей действительно плевать на макросы.
Re[5]: WTL: Подсказка в любом месте экрана
От: swap Россия  
Дата: 09.11.07 12:34
Оценка:
Здравствуйте, WinterMute, Вы писали:

WM>У меня другая версия VS и, видимо, ATL. Возможно дело в этом.

WM>Можешь посмотреть отладчиком, создаётся ли вообще окно,
WM>и что происходит после вызова ShowAtCursor() -- GetLastError()
WM>в смысле.

WM>Да, и для подержки тем, по идее, не нужен _WIN32_WINNT 0x0501,

WM>достаточно вручную прописать
WM>
WM>#ifndef WM_THEMECHANGED
WM>#   define WM_THEMECHANGED                 0x031A
WM>#endif
WM>

WM>По крайней мере, с моей версией библиотек, больше ничего не потребовалось.

Окно создается, все ::SendMessage возвращают вроде то что должны (для тех сообщений что должны что-то возвращать), GetLastError после ShowAtCursor возвращает 0.
Вопщем с виду все ОК вроде, но тултип не появляется, меняешь на 0x0500 — появляется

У меня в atltheme.h есть такой код
#if (_WIN32_WINNT < 0x0501)
#error atltheme.h requires _WIN32_WINNT >= 0x0501
#endif // (_WIN32_WINNT < 0x0501)
Re[4]: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 09.11.07 14:41
Оценка:
Посмотри как выполняется SubclassWindow( hWnd ), в Create(). Инициализирован-ли m_hWnd?
Re[5]: WTL: Подсказка в любом месте экрана
От: swap Россия  
Дата: 12.11.07 10:13
Оценка:
Здравствуйте, WinterMute, Вы писали:

WM>Посмотри как выполняется SubclassWindow( hWnd ), в Create(). Инициализирован-ли m_hWnd?


Да, там все нормально, видимых в отладчике ошибок нет. Более того, на другой машине с той же версией WTL c VC8 (не SP1) все работает.
Ума не приложу в чем дело
Re: WTL: Подсказка в любом месте экрана
От: kaz  
Дата: 14.11.07 11:03
Оценка:
Здравствуйте, WinterMute, Вы писали:

WM>В своё время меня не устроил стандартный CTooltipCtrl -- мне была нужена подсказка которая бы появлялась и пропадала когда ей скажут. Кроме того, нужно было, что бы подсказка была прозрачна для всех сообщений мыши (я делал т.н. inplace tooltip). Этот простой класс делает всё вышеперечисленное...


Я новичек в ВТЛ подскажите пожалуйста как обработать сообщения мыши тултипа... В дебагере смотрел он даже в OnMouseMessage не заходит
Re: WTL: Подсказка в любом месте экрана
От: kaz  
Дата: 14.11.07 11:18
Оценка:
Здравствуйте, WinterMute, Вы писали:

WM>В своё время меня не устроил стандартный CTooltipCtrl -- мне была нужена подсказка которая бы появлялась и пропадала когда ей скажут. Кроме того, нужно было, что бы подсказка была прозрачна для всех сообщений мыши (я делал т.н. inplace tooltip). Этот простой класс делает всё вышеперечисленное...


Да и еще кто-нибудь сталкивался с проблемой определения координат иконки в трее? Я там хочу тултип выводить когда окно свернуто...?
P.S. Идею с перемещение курсора мыши на иконку и получения координат через сообщение считаю не спортивной, так как:
а)трей может свернуться, и придется заного водить туда мышь
б)в трей может добавиться еще другая прога и придется заного водить туда мышь
в)а также если запущенны два экземпляра программы, то нужно будет еще различать где какой
Re[2]: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 14.11.07 12:22
Оценка:
Здравствуйте, kaz, Вы писали:

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


WM>>В своё время меня не устроил стандартный CTooltipCtrl -- мне была нужена подсказка которая бы появлялась и пропадала когда ей скажут. Кроме того, нужно было, что бы подсказка была прозрачна для всех сообщений мыши (я делал т.н. inplace tooltip). Этот простой класс делает всё вышеперечисленное...


kaz>Я новичек в ВТЛ подскажите пожалуйста как обработать сообщения мыши тултипа... В дебагере смотрел он даже в OnMouseMessage не заходит


Не понятно что именно надо, опиши задачу подробнее. Если ты о том, чтобы показывать подсказку по сообщению мыши, то это нужно делать вручную, вызвав Show().
Re[3]: WTL: Подсказка в любом месте экрана
От: kaz  
Дата: 14.11.07 13:24
Оценка:
Здравствуйте, WinterMute, Вы писали:

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


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


WM>>>В своё время меня не устроил стандартный CTooltipCtrl -- мне была нужена подсказка которая бы появлялась и пропадала когда ей скажут. Кроме того, нужно было, что бы подсказка была прозрачна для всех сообщений мыши (я делал т.н. inplace tooltip). Этот простой класс делает всё вышеперечисленное...


kaz>>Я новичек в ВТЛ подскажите пожалуйста как обработать сообщения мыши тултипа... В дебагере смотрел он даже в OnMouseMessage не заходит


WM>Не понятно что именно надо, опиши задачу подробнее. Если ты о том, чтобы показывать подсказку по сообщению мыши, то это нужно делать вручную, вызвав Show().


Задача такая: при клике мышой на тултипе скрывать его... А мышиные сообщения не обрабатываются... пробовал субклассить тултип... но тоже без результатов:




LRESULT CALLBACK SubclasProc(HWND hwnd, UINT ms, WPARAM wp, LPARAM lp)
{
if(ms > WM_MOUSEFIRST && ms<WM_MOUSELAST)
{
MessageBox(hwnd, "Close", 0,0);
return 0;
}

return CallWindowProcA (oldTipProc, hwnd, ms, wp, lp);;
}

WNDPROC oldTipProc;



 bool Create( HWND hWndParent, HWND hWndOwner = NULL )
{
DestroyWindow();

            HWND hWnd = ::CreateWindowEx(WS_EX_TOPMOST,
                TOOLTIPS_CLASS,
                NULL,
                TTS_NOPREFIX | TTS_ALWAYSTIP|TTS_BALLOON,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                hWndParent,
                NULL,
                NULL,
                NULL);
....
oldTipProc = (WNDPROC)::GetWindowLongPtr(hWnd, GWL_WNDPROC);
::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)SubclasProc);
 return true;
 }



LRESULT CALLBACK SubclasProc(HWND hwnd, UINT ms, WPARAM wp, LPARAM lp)
{
    if(ms > WM_MOUSEFIRST && ms<WM_MOUSELAST)
    {
        MessageBox(hwnd, "Close", 0,0);
        return 0;
    }
    
    return CallWindowProcA (oldTipProc, hwnd, ms, wp, lp);;
}
Re[2]: WTL: Подсказка в любом месте экрана
От: Xander Zerge Россия www.zerge.com
Дата: 14.11.07 13:28
Оценка:
Здравствуйте, kaz, Вы писали:

kaz>Да и еще кто-нибудь сталкивался с проблемой определения координат иконки в трее? Я там хочу тултип выводить когда окно свернуто...?

kaz>P.S. Идею с перемещение курсора мыши на иконку и получения координат через сообщение считаю не спортивной, так как:
kaz>а)трей может свернуться, и придется заного водить туда мышь
kaz>б)в трей может добавиться еще другая прога и придется заного водить туда мышь
kaz>в)а также если запущенны два экземпляра программы, то нужно будет еще различать где какой

Когда показываете пиктограмму в трее, в Shell_NotifyIcon передаётся структура, содержащая HWND окошка, которая будет принимать сообщение, ID сообщения, ID пиктограммы (чтоб различать несколько от одного окна), текст тултипа. Потом ловите это сообщение в окне, получая ID пиктограммы и WM_чототам, что случилось с пиктограммой, WM_LBUTTONDBLCLK, например. Тултип система сама выведет, кстати.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Серёжа Новиков,
программист
Re[3]: WTL: Подсказка в любом месте экрана
От: kaz  
Дата: 14.11.07 13:35
Оценка:
Здравствуйте, WinterMute, Вы писали:

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


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


WM>>>В своё время меня не устроил стандартный CTooltipCtrl -- мне была нужена подсказка которая бы появлялась и пропадала когда ей скажут. Кроме того, нужно было, что бы подсказка была прозрачна для всех сообщений мыши (я делал т.н. inplace tooltip). Этот простой класс делает всё вышеперечисленное...


kaz>>Я новичек в ВТЛ подскажите пожалуйста как обработать сообщения мыши тултипа... В дебагере смотрел он даже в OnMouseMessage не заходит


WM>Не понятно что именно надо, опиши задачу подробнее. Если ты о том, чтобы показывать подсказку по сообщению мыши, то это нужно делать вручную, вызвав Show().


он утебя в OnMouseMessage не заходит, пробовал ставить брекпоинт.

LRESULT OnMouseMessage( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
        {
-->>> сюда не заходит      LRESULT ret = 0; 

            // forward message to owner window 
            if( m_hWndOwner )
            {
                POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
                ClientToScreen( &pt ); ::ScreenToClient( m_hWndOwner, &pt );
                ret = ::SendMessage( m_hWndOwner, uMsg, wParam, MAKELONG( pt.x, pt.y ) );
            }

            //bHandled = TRUE;
            bHandled = FALSE;
            return ret;
        }
Re[3]: WTL: Подсказка в любом месте экрана
От: kaz  
Дата: 14.11.07 13:40
Оценка:
Здравствуйте, Xander Zerge, Вы писали:

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


kaz>>Да и еще кто-нибудь сталкивался с проблемой определения координат иконки в трее? Я там хочу тултип выводить когда окно свернуто...?

kaz>>P.S. Идею с перемещение курсора мыши на иконку и получения координат через сообщение считаю не спортивной, так как:
kaz>>а)трей может свернуться, и придется заного водить туда мышь
kaz>>б)в трей может добавиться еще другая прога и придется заного водить туда мышь
kaz>>в)а также если запущенны два экземпляра программы, то нужно будет еще различать где какой

XZ>Когда показываете пиктограмму в трее, в Shell_NotifyIcon передаётся структура, содержащая HWND окошка, которая будет принимать сообщение, ID сообщения, ID пиктограммы (чтоб различать несколько от одного окна), текст тултипа. Потом ловите это сообщение в окне, получая ID пиктограммы и WM_чототам, что случилось с пиктограммой, WM_LBUTTONDBLCLK, например. Тултип система сама выведет, кстати.


Мне надо чтобы тултип в трее выводился не по какому-то событию (WM_MOUSEMOVE, WM_LBUTTONDOWN), а по другим причинам (например, значение переменной вышло за заданный диапазон)
Re[4]: WTL: Подсказка в любом месте экрана
От: Xander Zerge Россия www.zerge.com
Дата: 14.11.07 15:09
Оценка:
Здравствуйте, kaz, Вы писали:

kaz>Мне надо чтобы тултип в трее выводился не по какому-то событию (WM_MOUSEMOVE, WM_LBUTTONDOWN), а по другим причинам (например, значение переменной вышло за заданный диапазон)

Для того balloon есть. Делается через ту же Shell_NotifyIcon, через NIF_INFO.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Серёжа Новиков,
программист
Re[4]: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 14.11.07 15:16
Оценка:
WM>>Не понятно что именно надо, опиши задачу подробнее. Если ты о том, чтобы показывать подсказку по сообщению мыши, то это нужно делать вручную, вызвав Show().

kaz>Задача такая: при клике мышой на тултипе скрывать его... А мышиные сообщения не обрабатываются... пробовал субклассить тултип... но тоже без результатов:


Убери стиль TTF_TRANSPARENT в строчке:
m_ToolInfo.uFlags = TTF_TRACK | TTF_TRANSPARENT | TTF_SUBCLASS;

-- Тогда должны ловиться мышиные сообщения.
Re[5]: WTL: Подсказка в любом месте экрана
От: kaz  
Дата: 14.11.07 15:29
Оценка:
Здравствуйте, WinterMute, Вы писали:

WM>>>Не понятно что именно надо, опиши задачу подробнее. Если ты о том, чтобы показывать подсказку по сообщению мыши, то это нужно делать вручную, вызвав Show().


kaz>>Задача такая: при клике мышой на тултипе скрывать его... А мышиные сообщения не обрабатываются... пробовал субклассить тултип... но тоже без результатов:


WM>Убери стиль TTF_TRANSPARENT в строчке:

WM>m_ToolInfo.uFlags = TTF_TRACK | TTF_TRANSPARENT | TTF_SUBCLASS;

WM>-- Тогда должны ловиться мышиные сообщения.


Ок, спасибо за помощь. Только еще один ньюанс... В родительском окне (которое hwndOwner)я ловлю WM_LBUTTONDBLCLK

BEGIN_MSG_MAP(CMainDlg)

...

MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDown)

...


и при нажатии мышой на тултип приходит сообщение, но при нажатии на клиентскую облать родительского диалога оно не приходит (меня это устраивает), но
так... интересно как же его если что отловить!
Re[5]: WTL: Подсказка в любом месте экрана
От: kaz  
Дата: 14.11.07 15:35
Оценка:
Здравствуйте, Xander Zerge, Вы писали:

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


kaz>>Мне надо чтобы тултип в трее выводился не по какому-то событию (WM_MOUSEMOVE, WM_LBUTTONDOWN), а по другим причинам (например, значение переменной вышло за заданный диапазон)

XZ>Для того balloon есть. Делается через ту же Shell_NotifyIcon, через NIF_INFO.
Да, я догодался уже, через NIF_MODYFY оно появляется... Но все равно спкасибо за беспокойство!

правда обидно что максимальный размер 255, а у меня возможна такая ситуация когда размер выводимого в тултипе текста 32000*64...
поэтому я вывожу тултип в трее несколько раз, если размер выводимого текста > 256...
Может есть способ это обойти? Т.е. увеличить размер буффера передаваемогоо через NOTIFYICONDATA?
Re[6]: WTL: Подсказка в любом месте экрана
От: kaz  
Дата: 14.11.07 15:39
Оценка:
Здравствуйте, kaz, Вы писали:

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


WM>>>>Не понятно что именно надо, опиши задачу подробнее. Если ты о том, чтобы показывать подсказку по сообщению мыши, то это нужно делать вручную, вызвав Show().


kaz>>>Задача такая: при клике мышой на тултипе скрывать его... А мышиные сообщения не обрабатываются... пробовал субклассить тултип... но тоже без результатов:


WM>>Убери стиль TTF_TRANSPARENT в строчке:

WM>>m_ToolInfo.uFlags = TTF_TRACK | TTF_TRANSPARENT | TTF_SUBCLASS;

WM>>-- Тогда должны ловиться мышиные сообщения.


kaz>Ок, спасибо за помощь. Только еще один ньюанс... В родительском окне (которое hwndOwner)я ловлю WM_LBUTTONDBLCLK


kaz>
kaz>BEGIN_MSG_MAP(CMainDlg)

kaz>...

kaz>MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDown)

kaz>...

kaz>


kaz>и при нажатии мышой на тултип приходит сообщение, но при нажатии на клиентскую облать родительского диалога оно не приходит (меня это устраивает), но

kaz>так... интересно как же его если что отловить!


Ааааа... нет вру... я просто по ТулБару кликал, приходит все...
Тогда встречный вопрос... Как тогда понять в родительском окне что клик по тултипу, а не по самому окну!?
Re[7]: WTL: Подсказка в любом месте экрана
От: WinterMute Россия http://yarrr.ru
Дата: 14.11.07 19:43
Оценка:
kaz>Ааааа... нет вру... я просто по ТулБару кликал, приходит все...
kaz>Тогда встречный вопрос... Как тогда понять в родительском окне что клик по тултипу, а не по самому окну!?

Очевидно что тултип на самом верху, поэтому можно взять GetWindowRect() тултипа и посмотреть попадают-ли в него координаты курсора.
Re[8]: WTL: Подсказка в любом месте экрана
От: kaz  
Дата: 15.11.07 10:07
Оценка:
Здравствуйте, WinterMute, Вы писали:

kaz>>Ааааа... нет вру... я просто по ТулБару кликал, приходит все...

kaz>>Тогда встречный вопрос... Как тогда понять в родительском окне что клик по тултипу, а не по самому окну!?

WM>Очевидно что тултип на самом верху, поэтому можно взять GetWindowRect() тултипа и посмотреть попадают-ли в него координаты курсора.

спасибо
Re[6]: WTL: Подсказка в любом месте экрана
От: Аноним  
Дата: 30.01.08 18:59
Оценка:
Такая же лажа. В режиме отладки заметно что tooltip на самом деле появлятся но потом сразу исчезает.
Re[7]: WTL: Подсказка в любом месте экрана
От: Аноним  
Дата: 30.01.08 19:16
Оценка:
Все, снялся с ручника, работает
Re[8]: WTL: Подсказка в любом месте экрана
От: Mr.  
Дата: 30.05.08 07:15
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Все, снялся с ручника, работает


Та же хрень, как исправить, не понял
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.