Сварачивание окна в SystemTray (шаблон WTL)
От: Splin Беларусь  
Дата: 05.02.03 17:13
Оценка: 9 (1)
Привет всем!

Сразу прошу прощения за столь избитый сабж.

Начну с использования:

1. Наследуем...
    class CMyWindow : public CSystemTrayWindow<CMyWindow> ...



2. Включаем в карту сообщений...
    BEGIN_MSG_MAP(CMyWindow)
        CHAIN_MSG_MAP(CSystemTrayWindow<CMyWindow>)
    ...


3. Создаем иконку где нибудь при создании окна...
    // create notify icon and sets context menu
    CreateNotifyIcon();
    SetNotifyIconContextMenu(IDM_POPUP);


Вот собственно и все, т.к. расписывать как работает шаблон мне лень...
Ах да... чуть не забыл — сам шаблон:

template <class T>
class CSystemTrayWindow
{
public:
    CSystemTrayWindow()
    {
        m_uID = 0;
        m_hIcon = NULL;
        m_szTip[0] = '\0';
        m_uMessage = WM_NULL;
        
        m_bAdded = FALSE;
        
        m_uIDMenu = 0;
    }

    virtual ~CSystemTrayWindow()
    {
        DestroyNotifyIcon();

        if(m_hIcon)
        {
            ::DestroyIcon(m_hIcon);
            m_hIcon = NULL;
        }
    }

public:
    BOOL CreateNotifyIcon(UINT uID = 1, UINT nMessage = WM_NULL)
    {
        m_uID = uID;
        
        if (nMessage != WM_NULL)
            m_uMessage = nMessage;
        else
            m_uMessage = GetDefaultNotifyIconMsg();

        return UpdateNotifyIcon();
    }

    BOOL CreateNotifyIcon(UINT uIDIcon, UINT uIDTip, UINT uID = 1, UINT nMessage = WM_NULL)
    {
        HINSTANCE hResource = _Module.GetResourceInstance();
        HICON hIcon;
        TCHAR szTip[64];
        
        if (0 == ::LoadString(hResource, uIDTip, szTip, _countof(lpszTip)))
            return FALSE;
        
        hIcon = (HICON)::LoadImage(hResource, MAKEINTRESOURCE(uIDIcon), 
            IMAGE_ICON, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);
        if(!hIcon)
            return FALSE;
        
        m_uID = uID;
        
        if (nMessage != WM_NULL)
            m_uMessage = nMessage;
        else
            m_uMessage = GetDefaultNotifyIconMsg();
        

        SaveNotifyIconTip(szTip);
        
        if (hIcon)
        {
            if (m_hIcon)
            {
                ::DestroyIcon(m_hIcon);
                m_hIcon = NULL;
            }
            m_hIcon = hIcon;
        }
        
        return AddNotifyIcon();
    }

    BOOL UpdateNotifyIcon()
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));

        if(!IsWindow(pT->m_hWnd))
            return FALSE;

        // get window icon
        HICON hIcon = (HICON)pT->SendMessage(WM_GETICON, ICON_SMALL, 0);
        if(!hIcon)
            hIcon    = (HICON)pT->SendMessage(WM_GETICON, ICON_BIG, 0);

        if (hIcon == NULL)
            return FALSE;

        // get window text
        TCHAR szTip[64];
        szTip[0] = _T('\0');
        int nTitle = pT->GetWindowText(szTip, _countof(szTip));
        if (nTitle > _countof(szTip))
        {
            szTip[_countof(szTip)-1] = _T('.');
            szTip[_countof(szTip)-2] = _T('.');
            szTip[_countof(szTip)-3] = _T('.');
            szTip[_countof(szTip)] = _T('\0');
        }

        SaveNotifyIconTip(szTip);
        
        if (hIcon)
        {
            if (m_hIcon)
            {
                ::DestroyIcon(m_hIcon);
                m_hIcon = NULL;
            }
            m_hIcon = hIcon;
        }

        if (IsAddedNotifyIcon())
            return ModifyNotifyIcon();
        else
            return AddNotifyIcon();
    }

    BOOL DestroyNotifyIcon()
    {
        if (IsAddedNotifyIcon())
            return DeleteNotifyIcon();
        else
            return TRUE;
    }

    void SetNotifyIconContextMenu(UINT uIDMenu)
    {
        m_uIDMenu = uIDMenu;
    }
    
    BOOL SetNotifyIconTip(LPCTSTR lpszTip)
    {
        SaveNotifyIconTip(lpszTip);
        return ModifyNotifyIcon();
    }
    
    BOOL ModifyNotifyIcon(HINSTANCE hInstRes, UINT uIDIcon, UINT uIDTip)
    {
        TCHAR lpszTip[64];
        
        if (0 == ::LoadString(hInstRes, uIDTip, lpszTip, _countof(lpszTip)))
            return FALSE;
        else
            return ModifyNotifyIcon(hInstRes, uIDIcon, lpszTip);
    }
    
    BOOL ModifyNotifyIcon(HINSTANCE hInstRes, UINT uIDIcon, LPCTSTR lpszTip = NULL)
    {
        HICON hIcon;
        
        hIcon = (HICON)::LoadImage(hInstRes, MAKEINTRESOURCE(uIDIcon), 
            IMAGE_ICON, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);

        if(!hIcon)
            return FALSE;

        if (lpszTip)
            SaveNotifyIconTip(lpszTip);
        
        if (hIcon)
        {
            if (m_hIcon)
            {
                ::DestroyIcon(m_hIcon);
                m_hIcon = NULL;
            }
            m_hIcon = hIcon;
        }

        return ModifyNotifyIcon();
    }

    BOOL IsAddedNotifyIcon()
    {
        return m_bAdded;
    }
    
    static UINT GetDefaultNotifyIconMsg(void)
    {
        static const UINT sc_uDefaultMsg = ::RegisterWindowMessage(_T("CHideWindow_DefaultNotifyIconMsg"));
        return sc_uDefaultMsg;
    }

    static UINT GetTaskbarCreatedMsg(void)
    {
        static const UINT sc_uTaskbarCreatedMsg = ::RegisterWindowMessage(_T("TaskbarCreated"));
        return sc_uTaskbarCreatedMsg;
    }

    BEGIN_MSG_MAP(CSowCommonHideWindow)
        MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
        MESSAGE_HANDLER(WM_SIZE, OnSize)
        MESSAGE_HANDLER(GetTaskbarCreatedMsg(), OnTaskbarCreated)
        MESSAGE_HANDLER(m_uMessage, OnNotifyIcon)
    END_MSG_MAP()

    BOOL HideWindow()
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));

        if(!IsWindow(pT->m_hWnd))
            return FALSE;
    
        return pT->ShowWindow(SW_HIDE);
    }
    
    BOOL RestoreWindow()
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));

        if(!IsWindow(pT->m_hWnd))
            return FALSE;

        // if iconic, restore the main window
        if (pT->IsIconic())
            return pT->ShowWindow(SW_RESTORE);
        // if not visible, show main window
        else if (!pT->IsWindowVisible())
            return pT->ShowWindow(SW_SHOW);
        else
            return ForegroundWindow();
    }

    BOOL ForegroundWindow()
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));

        if(!IsWindow(pT->m_hWnd))
            return FALSE;

        // if so, does it have any popups?
        HWND hWndChild = pT->GetLastActivePopup();
        // bring the main window or its popup to the foreground
        return ::SetForegroundWindow(hWndChild);
    }

protected:

    LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
    {
        // destroy notify icon
        DestroyNotifyIcon();
        bHandled = FALSE;
        return 0;
    }

    LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
    {
        if (wParam == SIZE_MINIMIZED && IsAddedNotifyIcon())
        {
            HideWindow();
            return 1;
        }
        bHandled = FALSE;
        return 0;
    }

    LRESULT OnTaskbarCreated(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
    {
        if (IsAddedNotifyIcon())
            RestoreNotifyIcon();
        bHandled = FALSE;
        return 0;
    }

    LRESULT OnNotifyIcon(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        if (!IsAddedNotifyIcon())
            return 0;
        
        if (m_uID != wParam)
            return 0;

        POINT point;
        ::GetCursorPos(&point);
        
        switch(lParam)
        {
        case WM_MOUSEMOVE:
            break;
        case WM_LBUTTONDBLCLK:
            break;
        case WM_LBUTTONDOWN:
            RestoreWindow();
            ForegroundWindow();
            break;
        case WM_LBUTTONUP:
            break;
        case WM_RBUTTONDOWN:
            break;
        case WM_RBUTTONUP:
            OnNotifyIconContextMenu(point);
            break;
        case WM_RBUTTONDBLCLK:
            break;
        default:
            break;
        }

        bHandled = FALSE;
        return 0;
    }
    
    virtual void OnNotifyIconContextMenu(const POINT& point)
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));

        if(!IsWindow(pT->m_hWnd))
            return;

        HMENU hPopupMenu;
        HMENU hSubMenu;
        HINSTANCE hResource = _Module.GetResourceInstance();
        
        if(m_uIDMenu == 0)
            return;
        
        hPopupMenu = ::LoadMenu(hResource, MAKEINTRESOURCE(m_uIDMenu));
        
        if(hPopupMenu)
        {
            if (hSubMenu = ::GetSubMenu(hPopupMenu, 0))
            {
                if (!pT->SendMessage(WM_INITMENUPOPUP, (WPARAM)hSubMenu, 0))
                {
                    ForegroundWindow();
                    ::TrackPopupMenuEx(hSubMenu, TPM_LEFTALIGN, point.x, point.y, pT->m_hWnd, NULL);
                    pT->PostMessage(WM_NULL, 0, 0);
                }
            }
            ::DestroyMenu(hPopupMenu);
        }
    }

private:

    void SaveNotifyIconTip(LPCTSTR lpszTip)
    {
        if (lpszTip)
            lstrcpyn(m_szTip, lpszTip, _countof(m_szTip));
        else
            m_szTip[0] = '\0';
    }
    
    BOOL AddNotifyIcon()
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));

        if(!IsWindow(pT->m_hWnd))
            return FALSE;
        
        NOTIFYICONDATA nid;
        ZeroMemory(&nid, sizeof(NOTIFYICONDATA));
        nid.cbSize                 = sizeof(NOTIFYICONDATA);
        nid.hWnd                 = pT->m_hWnd;
        nid.uID                 = m_uID;
        nid.uFlags                 = NIF_MESSAGE | (m_hIcon ? NIF_ICON : 0);
        nid.uCallbackMessage    = m_uMessage;
        nid.hIcon                 = m_hIcon;
        
        if(lstrlen(m_szTip))
        {
            lstrcpyn(nid.szTip, m_szTip, _countof(nid.szTip));
            nid.uFlags |= NIF_TIP;
        }
        
        return (m_bAdded = ::Shell_NotifyIcon(NIM_ADD, &nid));
    }

    BOOL ModifyNotifyIcon()
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));

        if(!IsWindow(pT->m_hWnd))
            return FALSE;
        
        NOTIFYICONDATA nid;
        ZeroMemory(&nid, sizeof(NOTIFYICONDATA));
        nid.cbSize                 = sizeof(NOTIFYICONDATA);
        nid.hWnd                 = pT->m_hWnd;
        nid.uID                 = m_uID;
        nid.uFlags                 = NIF_MESSAGE | (m_hIcon ? NIF_ICON : 0);
        nid.uCallbackMessage    = m_uMessage;
        nid.hIcon                 = m_hIcon;
        
        if(lstrlen(m_szTip))
        {
            lstrcpyn(nid.szTip, m_szTip, _countof(nid.szTip));
            nid.uFlags |= NIF_TIP;
        }
        
        return ::Shell_NotifyIcon(NIM_MODIFY, &nid);
    }
    
    BOOL DeleteNotifyIcon(void)
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));

        if(!IsWindow(pT->m_hWnd))
            return FALSE;
        
        NOTIFYICONDATA nid;
        ZeroMemory(&nid, sizeof(NOTIFYICONDATA));
        nid.cbSize = sizeof(NOTIFYICONDATA);
        nid.hWnd   = pT->m_hWnd;
        nid.uID    = m_uID;
        
        return !(m_bAdded = !::Shell_NotifyIcon(NIM_DELETE, &nid));
    }
    
    BOOL RestoreNotifyIcon(void)
    {
        if(!m_hIcon)
            return FALSE;
        return AddNotifyIcon();
    }

    UINT        m_uID;            // the id
    UINT        m_uMessage;        // the message id

    HICON        m_hIcon;        // the handle of a current icon
    TCHAR        m_szTip[128];    // the tip string
    
    UINT        m_uIDMenu;        // the id of a popup menu
    BOOL        m_bAdded;

};
... << RSDN@Home 1.0 beta 5 >>
Re: Сварачивание окна в SystemTray (шаблон WTL)
От: vasketsov Россия http://ntprog.by.ru
Дата: 05.02.03 19:07
Оценка:
Здравствуйте, Splin, Вы писали:

[]

Мда....
Там ВЕСЬ API состоит из ОДНОЙ (!!!) функции.
И для нее это все городить?
Васкецов Сергей
http://registry.km.ru
Re[2]: Сварачивание окна в SystemTray (шаблон WTL)
От: Splin Беларусь  
Дата: 06.02.03 17:36
Оценка:
Здравствуйте, vasketsov, Вы писали:

V>Мда....

V>Там ВЕСЬ API состоит из ОДНОЙ (!!!) функции.
V>И для нее это все городить?
V>

Сколько строк кода надо написать для работы с этой одной функцией? А обработка сообщений?
А зечем нам WTL, ATL, MFC?
Мне было лень писать один и тот же код в нескольких проектах... Но это дело вкуса.
Re: Сварачивание окна в SystemTray (шаблон WTL)
От: aboo Россия  
Дата: 15.03.03 00:47
Оценка:
Здравствуйте, Splin, Вы писали:

S>Сразу прошу прощения за столь избитый сабж.


http://www.codeproject.com/wtl/wtltrayicon.asp

см. дату...
... << RSDN@Home 1.0 beta 6a >>
Re: Сварачивание окна в SystemTray (шаблон WTL)
От: Splin Беларусь  
Дата: 22.08.03 07:00
Оценка:
Привет всем!

Вот и настал момент, когда для меня WTL стал самой приемлемой библиотекой для новых проектов .
В связи с этим я слегка модернизировал данный шаблон (уже с новым пониманием принципов построения WTL).
Сразу скажу, что не претендую на 100%-е авторство кода (в основу легли публикации на RSDN).

Основное отличие от предыдущей версии:
1) Я попытался реализовать механизм переопределения реакций для NotifyIcon.
2) Изменил поведение по-умолчанию для NotifyIcon (сейчас работает в стиле FlashGet-a).
3) Ну имя шаблона поменял ;

Ниже код, прошу критиковать:

//////////////////////////////////////////////////////////////////////
// class CWtlExNotifyIcon

template <class T>
class CWtlExNotifyIcon
{
public:
    CWtlExNotifyIcon()
    {
        m_uID = 0;
        m_hIcon = NULL;
        m_szTip[0] = '\0';
        m_uMessage = WM_NULL;
        
        m_bAdded = FALSE;
        
        m_uIDMenu = 0;
    }

    ~CWtlExNotifyIcon()
    {
        DestroyNotifyIcon();

        if(m_hIcon)
        {
            ::DestroyIcon(m_hIcon);
            m_hIcon = NULL;
        }
    }

public:
    BOOL CreateNotifyIcon(UINT uID = 1, UINT nMessage = WM_NULL)
    {
        m_uID = uID;
        
        if (nMessage != WM_NULL)
            m_uMessage = nMessage;
        else
            m_uMessage = GetDefaultNotifyIconMsg();

        return UpdateNotifyIcon();
    }

    BOOL CreateNotifyIcon(UINT uIDIcon, UINT uIDTip, UINT uID = 1, UINT nMessage = WM_NULL)
    {
        HINSTANCE hResource = _Module.GetResourceInstance();
        HICON hIcon;
        TCHAR szTip[64];
        
        if (0 == ::LoadString(hResource, uIDTip, szTip, _countof(szTip)))
            return FALSE;
        
        // Load small icon first
        hIcon = (HICON)::LoadImage(hResource,
            MAKEINTRESOURCE(uIDIcon),
            IMAGE_ICON,
            ::GetSystemMetrics(SM_CXSMICON),
            ::GetSystemMetrics(SM_CYSMICON),
            LR_DEFAULTCOLOR);
        
        if(!hIcon)
            hIcon = (HICON)::LoadImage(hResource,
                MAKEINTRESOURCE(uIDIcon),
                IMAGE_ICON,
                ::GetSystemMetrics(SM_CXICON),
                ::GetSystemMetrics(SM_CYICON),
                LR_DEFAULTCOLOR);

        if(!hIcon)
            return FALSE;
        
        m_uID = uID;
        
        if (nMessage != WM_NULL)
            m_uMessage = nMessage;
        else
            m_uMessage = GetDefaultNotifyIconMsg();
        

        SaveNotifyIconTip(szTip);
        
        if (hIcon)
        {
            if (m_hIcon)
            {
                ::DestroyIcon(m_hIcon);
                m_hIcon = NULL;
            }
            m_hIcon = hIcon;
        }
        
        return AddNotifyIcon();
    }

    BOOL UpdateNotifyIcon()
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));

        if(!IsWindow(pT->m_hWnd))
            return FALSE;

        // get window icon
        HICON hIcon = (HICON)pT->SendMessage(WM_GETICON, ICON_SMALL, 0);
        if(!hIcon)
            hIcon    = (HICON)pT->SendMessage(WM_GETICON, ICON_BIG, 0);

        if (hIcon == NULL)
            return FALSE;

        // get window text
        TCHAR szTip[64];
        szTip[0] = _T('\0');
        int nTitle = pT->GetWindowText(szTip, _countof(szTip));
        if (nTitle > _countof(szTip))
        {
            szTip[_countof(szTip)-1] = _T('.');
            szTip[_countof(szTip)-2] = _T('.');
            szTip[_countof(szTip)-3] = _T('.');
            szTip[_countof(szTip)] = _T('\0');
        }

        SaveNotifyIconTip(szTip);
        
        if (hIcon)
        {
            if (m_hIcon)
            {
                ::DestroyIcon(m_hIcon);
                m_hIcon = NULL;
            }
            m_hIcon = hIcon;
        }

        if (IsAddedNotifyIcon())
            return ModifyNotifyIcon();
        else
            return AddNotifyIcon();
    }

    BOOL DestroyNotifyIcon()
    {
        if (IsAddedNotifyIcon())
            return DeleteNotifyIcon();
        else
            return TRUE;
    }

    void SetNotifyIconContextMenu(UINT uIDMenu)
    {
        m_uIDMenu = uIDMenu;
    }
    
    BOOL SetNotifyIconTip(LPCTSTR lpszTip)
    {
        SaveNotifyIconTip(lpszTip);
        return ModifyNotifyIcon();
    }
    
    BOOL ModifyNotifyIcon(HINSTANCE hInstRes, UINT uIDIcon, UINT uIDTip)
    {
        TCHAR lpszTip[64];
        
        if (0 == ::LoadString(hInstRes, uIDTip, lpszTip, _countof(lpszTip)))
            return FALSE;
        else
            return ModifyNotifyIcon(hInstRes, uIDIcon, lpszTip);
    }
    
    BOOL ModifyNotifyIcon(HINSTANCE hInstRes, UINT uIDIcon, LPCTSTR lpszTip = NULL)
    {
        HICON hIcon;
        
        hIcon = (HICON)::LoadImage(hInstRes, MAKEINTRESOURCE(uIDIcon), 
            IMAGE_ICON, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);

        if(!hIcon)
            return FALSE;

        if (lpszTip)
            SaveNotifyIconTip(lpszTip);
        
        if (hIcon)
        {
            if (m_hIcon)
            {
                ::DestroyIcon(m_hIcon);
                m_hIcon = NULL;
            }
            m_hIcon = hIcon;
        }

        return ModifyNotifyIcon();
    }

    BOOL IsAddedNotifyIcon()
    {
        return m_bAdded;
    }
    
    static UINT GetDefaultNotifyIconMsg(void)
    {
        static const UINT sc_uDefaultMsg = ::RegisterWindowMessage(_T("CWtlExNotifyIconDefaultNotifyIconMsg"));
        return sc_uDefaultMsg;
    }

    static UINT GetTaskbarCreatedMsg(void)
    {
        static const UINT sc_uTaskbarCreatedMsg = ::RegisterWindowMessage(_T("TaskbarCreated"));
        return sc_uTaskbarCreatedMsg;
    }

    BEGIN_MSG_MAP(CWtlExNotifyIcon)
        MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
        MESSAGE_HANDLER(WM_SIZE, OnSize)
        MESSAGE_HANDLER(GetTaskbarCreatedMsg(), OnTaskbarCreated)
        MESSAGE_HANDLER(m_uMessage, OnNotifyIcon)
    END_MSG_MAP()
    
    BOOL RestoreWindow(bool bForeground = true)
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));

        if(!IsWindow(pT->m_hWnd))
            return FALSE;

        // If not visible, show main window
        if (!pT->IsWindowVisible())
            pT->ShowWindow(SW_SHOW);
        // If iconic, restore the main window
        if (pT->IsIconic())
            pT->ShowWindow(SW_RESTORE);
        
        if (bForeground)
            ForegroundWindow();
        
        return TRUE;
    }

    BOOL ForegroundWindow()
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));

        if(!IsWindow(pT->m_hWnd))
            return FALSE;

        // If so, does it have any popups?
        HWND hWndChild = pT->GetLastActivePopup();
        // Bring the main window or its popup to the foreground
        return ::SetForegroundWindow(hWndChild);
    }

protected:

    LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
    {
        // destroy notify icon
        DestroyNotifyIcon();
        bHandled = FALSE;
        return 0;
    }

    LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));
    
        if (wParam == SIZE_MINIMIZED && IsAddedNotifyIcon())
            pT->ShowWindow(SW_HIDE);

        bHandled = FALSE;
        return 0;
    }

    LRESULT OnTaskbarCreated(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
    {
        if (IsAddedNotifyIcon())
            RestoreNotifyIcon();
        bHandled = FALSE;
        return 0;
    }

    LRESULT OnNotifyIcon(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        bHandled = FALSE;

        if (!IsAddedNotifyIcon())
            return 0;
        
        if (m_uID != wParam)
            return 0;

        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));

        if(!IsWindow(pT->m_hWnd))
            return 0;

        POINT point;
        ::GetCursorPos(&point);
        
        // M03082101
        switch(lParam)
        {
        case WM_MOUSEMOVE:
            pT->OnNotifyIconMouseMove(point);
            break;
        case WM_LBUTTONDBLCLK:
            pT->OnNotifyIconLButtonDblClk(point);
            break;
        case WM_LBUTTONDOWN:
            pT->OnNotifyIconLButtonDown(point);
            break;
        case WM_LBUTTONUP:
            pT->OnNotifyIconLButtonUp(point);
            break;
        case WM_RBUTTONDOWN:
            pT->OnNotifyIconRButtonDown(point);
            break;
        case WM_RBUTTONUP:
            pT->OnNotifyIconRButtonUp(point);
            pT->OnNotifyIconContextMenu(point);
            break;
        case WM_RBUTTONDBLCLK:
            pT->OnNotifyIconRButtonDblClk(point);
            break;
        default:
            break;
        }

        return 0;
    }
    
// Overridables
public:
    // M03082101
    void OnNotifyIconMouseMove(const POINT& /*point*/)
    {
    }
    void OnNotifyIconLButtonDblClk(const POINT& /*point*/)
    {
    }
    void OnNotifyIconLButtonDown(const POINT& point)
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));

        if(!IsWindow(pT->m_hWnd))
            return;

        // М03072201
        // If iconic or if not visible, restore the window
        if (pT->IsIconic() || !pT->IsWindowVisible())
            RestoreWindow();
        else
            pT->ShowWindow(SW_MINIMIZE);
    }
    void OnNotifyIconLButtonUp(const POINT& /*point*/)
    {
    }
    void OnNotifyIconRButtonDown(const POINT& /*point*/)
    {
    }
    void OnNotifyIconRButtonUp(const POINT& /*point*/)
    {
    }
    void OnNotifyIconContextMenu(const POINT& point)
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));

        if(!IsWindow(pT->m_hWnd))
            return;
        
        if(m_uIDMenu == 0)
            return;

        HMENU hPopupMenu;
        HMENU hSubMenu;
        HINSTANCE hResource = _Module.GetResourceInstance();
        
        hPopupMenu = ::LoadMenu(hResource, MAKEINTRESOURCE(m_uIDMenu));
        
        if(hPopupMenu)
        {
            if (hSubMenu = ::GetSubMenu(hPopupMenu, 0))
            {
                if (!pT->SendMessage(WM_INITMENUPOPUP, (WPARAM)hSubMenu, 0))
                {
                    ForegroundWindow();
                    ::TrackPopupMenuEx(hSubMenu, TPM_LEFTALIGN, point.x, point.y, pT->m_hWnd, NULL);
                    pT->PostMessage(WM_NULL, 0, 0);
                }
            }
            ::DestroyMenu(hPopupMenu);
        }
    }
    void OnNotifyIconRButtonDblClk(const POINT& /*point*/)
    {
    }

// Implementation
private:
    void SaveNotifyIconTip(LPCTSTR lpszTip)
    {
        if (lpszTip)
            lstrcpyn(m_szTip, lpszTip, _countof(m_szTip));
        else
            m_szTip[0] = '\0';
    }
    
    BOOL AddNotifyIcon()
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));

        if(!IsWindow(pT->m_hWnd))
            return FALSE;
        
        NOTIFYICONDATA nid;
        ZeroMemory(&nid, sizeof(NOTIFYICONDATA));
        nid.cbSize                 = sizeof(NOTIFYICONDATA);
        nid.hWnd                 = pT->m_hWnd;
        nid.uID                 = m_uID;
        nid.uFlags                 = NIF_MESSAGE | (m_hIcon ? NIF_ICON : 0);
        nid.uCallbackMessage    = m_uMessage;
        nid.hIcon                 = m_hIcon;
        
        if(lstrlen(m_szTip))
        {
            lstrcpyn(nid.szTip, m_szTip, _countof(nid.szTip));
            nid.uFlags |= NIF_TIP;
        }
        
        return (m_bAdded = ::Shell_NotifyIcon(NIM_ADD, &nid));
    }

    BOOL ModifyNotifyIcon()
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));

        if(!IsWindow(pT->m_hWnd))
            return FALSE;
        
        NOTIFYICONDATA nid;
        ZeroMemory(&nid, sizeof(NOTIFYICONDATA));
        nid.cbSize                 = sizeof(NOTIFYICONDATA);
        nid.hWnd                 = pT->m_hWnd;
        nid.uID                 = m_uID;
        nid.uFlags                 = NIF_MESSAGE | (m_hIcon ? NIF_ICON : 0);
        nid.uCallbackMessage    = m_uMessage;
        nid.hIcon                 = m_hIcon;
        
        if(lstrlen(m_szTip))
        {
            lstrcpyn(nid.szTip, m_szTip, _countof(nid.szTip));
            nid.uFlags |= NIF_TIP;
        }
        
        return ::Shell_NotifyIcon(NIM_MODIFY, &nid);
    }
    
    BOOL DeleteNotifyIcon(void)
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));

        if(!IsWindow(pT->m_hWnd))
            return FALSE;
        
        NOTIFYICONDATA nid;
        ZeroMemory(&nid, sizeof(NOTIFYICONDATA));
        nid.cbSize = sizeof(NOTIFYICONDATA);
        nid.hWnd   = pT->m_hWnd;
        nid.uID    = m_uID;
        
        return !(m_bAdded = !::Shell_NotifyIcon(NIM_DELETE, &nid));
    }
    
    BOOL RestoreNotifyIcon(void)
    {
        if(!m_hIcon)
            return FALSE;
        return AddNotifyIcon();
    }

    UINT        m_uID;            // the id
    UINT        m_uMessage;        // the message id

    HICON        m_hIcon;        // the handle of a current icon
    TCHAR        m_szTip[128];    // the tip string
    
    UINT        m_uIDMenu;        // the id of a popup menu
    BOOL        m_bAdded;

};


Ну вот и все. Желаю удачи. Для контактов : splin@tut.by

P.S. Интересно знать, нужны ли кому-нибудь подобные вещи.
Re[2]: Сварачивание окна в SystemTray (шаблон WTL)
От: Виталий Россия  
Дата: 22.08.03 07:25
Оценка:
Здравствуйте, Splin, Вы писали:

S>Основное отличие от предыдущей версии:

S>1) Я попытался реализовать механизм переопределения реакций для NotifyIcon.
Смотри ниже
S>2) Изменил поведение по-умолчанию для NotifyIcon (сейчас работает в стиле FlashGet-a).
А что это за стиль???
S>3) Ну имя шаблона поменял ;

S>Ниже код, прошу критиковать:

Во первых зачем
static UINT GetTaskbarCreatedMsg(void)
    {
        static const UINT sc_uTaskbarCreatedMsg = ::RegisterWindowMessage(_T("TaskbarCreated"));
        return sc_uTaskbarCreatedMsg;
    }

имхо гораздо приятнее объявить просто статическую переменную и инициализировать ее (а это будет гарантированно раньше создания объекта — статическая инициализация раньше, чем динамическая), ну да это так, мелочь, а вот что совсем не понравилось — так это
switch(lParam)
        {
        case WM_MOUSEMOVE:
            pT->OnNotifyIconMouseMove(point);
            break;
        case WM_LBUTTONDBLCLK:
            pT->OnNotifyIconLButtonDblClk(point);
            break;
        case WM_LBUTTONDOWN:
            pT->OnNotifyIconLButtonDown(point);
            break;
        case WM_LBUTTONUP:
            pT->OnNotifyIconLButtonUp(point);
            break;
        case WM_RBUTTONDOWN:
            pT->OnNotifyIconRButtonDown(point);
            break;
        case WM_RBUTTONUP:
            pT->OnNotifyIconRButtonUp(point);
            pT->OnNotifyIconContextMenu(point);
            break;
        case WM_RBUTTONDBLCLK:
            pT->OnNotifyIconRButtonDblClk(point);
            break;
        default:
            break;
        }

Это далеко не все сообщения, которые может потребоваться обрабатывать, лучше предусмотреть возможность вставки нужного обработчика в карту сообщений "хозяина", нечто вроде
BEGIN_MSG_MAP(CMyWindow)
        ...
        TASKBARICON_MESSAGE_HANDLER(WM_MOUSEMOVE, OnIconMouseMove)
END_MESSAGE_MAP()

S>P.S. Интересно знать, нужны ли кому-нибудь подобные вещи.
Угу, чтобы можно было посмотреть, оценить и, если что, подправить свою давно написанную реализацию
Re[3]: Сварачивание окна в SystemTray (шаблон WTL)
От: Splin Беларусь  
Дата: 22.08.03 14:33
Оценка:
Здравствуйте, Виталий, Вы писали:

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


S>>2) Изменил поведение по-умолчанию для NotifyIcon (сейчас работает в стиле FlashGet-a).

В>А что это за стиль???
Запусти FlashGet и посмотри .

S>>Ниже код, прошу критиковать:

В>Во первых зачем
В>
В>static UINT GetTaskbarCreatedMsg(void)
В>    {
В>        static const UINT sc_uTaskbarCreatedMsg = ::RegisterWindowMessage(_T("TaskbarCreated"));
В>        return sc_uTaskbarCreatedMsg;
В>    }
В>

В>имхо гораздо приятнее объявить просто статическую переменную и инициализировать ее (а это будет гарантированно раньше создания объекта — статическая инициализация раньше, чем динамическая), ну да это так, мелочь
Мелочь есть мелочь .
В>Это далеко не все сообщения, которые может потребоваться обрабатывать, лучше предусмотреть возможность вставки нужного обработчика в карту сообщений "хозяина", нечто вроде
В>
В>BEGIN_MSG_MAP(CMyWindow)
В>        ...
В>        TASKBARICON_MESSAGE_HANDLER(WM_MOUSEMOVE, OnIconMouseMove)
В>END_MESSAGE_MAP()
В>

А по поводу этого, я сделал так специально, т.к. лично мне удобнее и проще переопределить функцию не сопровождая карту .
Так проще:
class ....
{

// Overridables
    void OnNotifyIconContextMenu(const POINT& point)
    {
        ....
    }

}

По поводу не всех сообщений — это тоже поправимо... не сложно догадаться . Но вообще на досуге может поковыряю.
S>>P.S. Интересно знать, нужны ли кому-нибудь подобные вещи.
В>Угу, чтобы можно было посмотреть, оценить и, если что, подправить свою давно написанную реализацию
Ну так не жмись, покажи всем .

Удачи всем!
Re[3]: Сварачивание окна в SystemTray (шаблон WTL)
От: WolfHound  
Дата: 22.08.03 15:40
Оценка:
Здравствуйте, Виталий, Вы писали:

В>Во первых зачем

В>
В>static UINT GetTaskbarCreatedMsg(void)
В>    {
В>        static const UINT sc_uTaskbarCreatedMsg = ::RegisterWindowMessage(_T("TaskbarCreated"));
В>        return sc_uTaskbarCreatedMsg;
В>    }
В>

В>имхо гораздо приятнее объявить просто статическую переменную и инициализировать ее (а это будет гарантированно раньше создания объекта — статическая инициализация раньше, чем динамическая), ну да это так, мелочь, а вот что совсем не понравилось — так это
А потом какойнибудь бес решит создать окно в конструкторе статического объекта... А так как порядок инициализации статических обектов определен только в одной единице трансляции то можем легко получить трудноуловимый глюк. Короче правильно он делает ибо ТОЛЬКО ТАК можно гарантировать инициализацию до первого использования.
... << RSDN@Home 1.1 alpha 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Сварачивание окна в SystemTray (шаблон WTL)
От: 0xMeHi Украина  
Дата: 03.12.07 22:37
Оценка:
Здравствуйте, Splin, Вы писали:

S>Привет всем!


S>Вот и настал момент, когда для меня WTL стал самой приемлемой библиотекой для новых проектов .

S>В связи с этим я слегка модернизировал данный шаблон (уже с новым пониманием принципов построения WTL).
S>Сразу скажу, что не претендую на 100%-е авторство кода (в основу легли публикации на RSDN).
S>P.S. Интересно знать, нужны ли кому-нибудь подобные вещи.

Заюзал я этот код у себя, все работает чудненько, только есть один момент.
Мне нужно, чтобы окно в трее появлялось тогда, когда я прячу основное окно приложения. В этом случае я создаю иконку в трее.
Когда я делаю основное окно видимым — я убиваю "треевскую" иконку.
Проблема в том, что после этого я не могу ее заново создать.
Shell_NotifyIcon возвращает FALSE.
Кто-е. сталкивался с такой проблемой?
Или как правильно это делать? Может иконку можно как-н. прятать, а не убивать?
Re[3]: Сварачивание окна в SystemTray (шаблон WTL)
От: Splin Беларусь  
Дата: 04.12.07 11:21
Оценка: 2 (1)
Здравствуйте, 0xMeHi, Вы писали:

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


S>>Привет всем!


S>>Вот и настал момент, когда для меня WTL стал самой приемлемой библиотекой для новых проектов .

S>>В связи с этим я слегка модернизировал данный шаблон (уже с новым пониманием принципов построения WTL).
S>>Сразу скажу, что не претендую на 100%-е авторство кода (в основу легли публикации на RSDN).
S>>P.S. Интересно знать, нужны ли кому-нибудь подобные вещи.

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

MH>Мне нужно, чтобы окно в трее появлялось тогда, когда я прячу основное окно приложения. В этом случае я создаю иконку в трее.
MH>Когда я делаю основное окно видимым — я убиваю "треевскую" иконку.
MH>Проблема в том, что после этого я не могу ее заново создать.
MH>Shell_NotifyIcon возвращает FALSE.
MH>Кто-е. сталкивался с такой проблемой?
MH>Или как правильно это делать? Может иконку можно как-н. прятать, а не убивать?

надо написать свой WM_SIZE, что-то вроде:

LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
if (wParam == SIZE_MINIMIZED)
{
if (!IsAddedNotifyIcon())
CreateNotifyIcon(IDR_MAINFRAME, IDR_MAINFRAME, 1, WM_NULL);
if (IsAddedNotifyIcon())
ShowWindow(SW_HIDE);
}
else
{
if (IsAddedNotifyIcon())
DestroyNotifyIcon();
}
return 0;
}
... << RSDN@Home 1.2.0 alpha rev. 780>>
Re[4]: Сварачивание окна в SystemTray (шаблон WTL)
От: Splin Беларусь  
Дата: 05.12.07 11:30
Оценка:
Раз уж появился интерес, выкладываю более новую исправленную версию класса, совместимую с VS2005 (заодно поменял название).
Прошу высказывать предложения по улучшению.


//////////////////////////////////////////////////////////////////////////
// template <class T> class CNotifyIconWindow

template <class T>
class CNotifyIconWindow
{
public:
    enum
    {
        ToolTipStringLen = 128
    };

    CNotifyIconWindow() : m_uID(0), m_hIcon(NULL), m_uMessage(WM_NULL), m_uIDMenu(0)
    {
        memset(m_szTip, 0, sizeof(m_szTip));
    }

    ~CNotifyIconWindow()
    {
        DestroyNotifyIcon();
        if (m_hIcon)
        {
            ::DestroyIcon(m_hIcon);
            m_hIcon = NULL;
        }
    }

    BOOL CreateNotifyIcon(UINT uID = 1, UINT nMessage = WM_NULL)
    {
        m_uID = uID;
        if (nMessage != WM_NULL)
            m_uMessage = nMessage;
        else
            m_uMessage = GetDefaultNotifyIconMsg();
        return UpdateNotifyIcon();
    }

    BOOL CreateNotifyIcon(UINT uIDIcon, UINT uIDTip, UINT uID = 1, UINT nMessage = WM_NULL)
    {
#if (_ATL_VER >= 0x0700)
        HINSTANCE hResource = ATL::_AtlBaseModule.GetResourceInstance();
#else //!(_ATL_VER >= 0x0700)
        HINSTANCE hResource = _Module.GetResourceInstance();
#endif //!(_ATL_VER >= 0x0700)
        HICON hIcon;
        TCHAR szTip[ToolTipStringLen] = { 0 };
        if (0 == ::LoadString(hResource, uIDTip, szTip, _countof(szTip)))
            return FALSE;
        // Load small icon first
        hIcon = (HICON)::LoadImage(hResource, MAKEINTRESOURCE(uIDIcon), IMAGE_ICON,
            ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
        if (!hIcon)
            hIcon = (HICON)::LoadImage(hResource, MAKEINTRESOURCE(uIDIcon), IMAGE_ICON,
            ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);
        if (!hIcon)
            return FALSE;
        m_uID = uID;
        if (nMessage != WM_NULL)
            m_uMessage = nMessage;
        else
            m_uMessage = GetDefaultNotifyIconMsg();
        SaveNotifyIconTip(szTip);
        if (hIcon)
        {
            if (m_hIcon)
            {
                ::DestroyIcon(m_hIcon);
                m_hIcon = NULL;
            }
            m_hIcon = hIcon;
        }
        return AddNotifyIcon();
    }

    BOOL ModifyNotifyIcon(HINSTANCE hResource, UINT uIDIcon, UINT uIDTip)
    {
        TCHAR lpszTip[ToolTipStringLen] = { 0 };
        if (0 == ::LoadString(hResource, uIDTip, lpszTip, _countof(lpszTip)))
            return FALSE;
        else
            return ModifyNotifyIcon(hResource, uIDIcon, lpszTip);
    }

    BOOL ModifyNotifyIcon(HINSTANCE hResource, UINT uIDIcon, LPCTSTR lpszTip = NULL)
    {
        // Load small icon first
        HICON hIcon = (HICON)::LoadImage(hResource, MAKEINTRESOURCE(uIDIcon), IMAGE_ICON,
            ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
        if (!hIcon)
            hIcon = (HICON)::LoadImage(hResource, MAKEINTRESOURCE(uIDIcon), IMAGE_ICON,
                ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);
        if (!hIcon)
            return FALSE;
        if (lpszTip)
            SaveNotifyIconTip(lpszTip);
        if (hIcon)
        {
            if (m_hIcon)
            {
                ::DestroyIcon(m_hIcon);
                m_hIcon = NULL;
            }
            m_hIcon = hIcon;
        }
        return ModifyNotifyIcon();
    }

    BOOL UpdateNotifyIcon()
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));
        if (!IsWindow(pT->m_hWnd))
            return FALSE;
        // Get window icon
        HICON hIcon = (HICON)pT->SendMessage(WM_GETICON, ICON_SMALL, 0);
        if (!hIcon)
            hIcon    = (HICON)pT->SendMessage(WM_GETICON, ICON_BIG, 0);
        if (hIcon == NULL)
            return FALSE;
        // Get window text
        TCHAR szTip[ToolTipStringLen] = { 0 };
        int nTitle = pT->GetWindowText(szTip, _countof(szTip));
        if (nTitle > _countof(szTip))
        {
            szTip[_countof(szTip) - 4] = _T('.');
            szTip[_countof(szTip) - 3] = _T('.');
            szTip[_countof(szTip) - 2] = _T('.');
            szTip[_countof(szTip) - 1] = _T('\0');
        }
        SaveNotifyIconTip(szTip);
        if (hIcon)
        {
            if (m_hIcon)
            {
                ::DestroyIcon(m_hIcon);
                m_hIcon = NULL;
            }
            m_hIcon = hIcon;
        }
        if (IsAddedNotifyIcon())
            return ModifyNotifyIcon();
        else
            return AddNotifyIcon();
    }

    BOOL DestroyNotifyIcon()
    {
        if (IsAddedNotifyIcon())
            return DeleteNotifyIcon();
        else
            return TRUE;
    }

    void SetNotifyIconContextMenu(UINT uIDMenu)
    {
        m_uIDMenu = uIDMenu;
    }

    BOOL SetNotifyIconTip(LPCTSTR lpszTip)
    {
        SaveNotifyIconTip(lpszTip);
        return ModifyNotifyIcon();
    }

    BOOL IsAddedNotifyIcon()
    {
        return m_bAdded;
    }

    static UINT GetDefaultNotifyIconMsg(void)
    {
        static const UINT sc_uDefaultMsg = ::RegisterWindowMessage(_T("{407d42d2-30a8-4e30-a329-18bec2e35a9d}"));
        return sc_uDefaultMsg;
    }

    static UINT GetTaskbarCreatedMsg(void)
    {
        static const UINT sc_uTaskbarCreatedMsg = ::RegisterWindowMessage(_T("TaskbarCreated"));
        return sc_uTaskbarCreatedMsg;
    }

    BEGIN_MSG_MAP(CNotifyIconWindow)
        MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
        MESSAGE_HANDLER(WM_SIZE, OnSize)
        MESSAGE_HANDLER(GetTaskbarCreatedMsg(), OnTaskbarCreated)
        MESSAGE_HANDLER(m_uMessage, OnNotifyIcon)
    END_MSG_MAP()

    BOOL RestoreWindow(bool bForeground = true)
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));
        if (!IsWindow(pT->m_hWnd))
            return FALSE;
        // If not visible, show main window
        if (!pT->IsWindowVisible())
            pT->ShowWindow(SW_SHOW);
        // If iconic, restore the main window
        if (pT->IsIconic())
            pT->ShowWindow(SW_RESTORE);
        if (bForeground)
            ForegroundWindow();
        return TRUE;
    }

    BOOL ForegroundWindow()
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));
        if (!IsWindow(pT->m_hWnd))
            return FALSE;
        // If so, does it have any popups?
        HWND hWndChild = pT->GetLastActivePopup();
        // Bring the main window or its popup to the foreground
        return ::SetForegroundWindow(hWndChild);
    }

// Messages
protected:
    LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
    {
        DestroyNotifyIcon();
        bHandled = FALSE;
        return 0;
    }

    LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));
        if (wParam == SIZE_MINIMIZED && IsAddedNotifyIcon())
            pT->ShowWindow(SW_HIDE);
        bHandled = FALSE;
        return 0;
    }

    LRESULT OnTaskbarCreated(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
    {
        if (IsAddedNotifyIcon())
            RestoreNotifyIcon();
        bHandled = FALSE;
        return 0;
    }

    LRESULT OnNotifyIcon(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        bHandled = FALSE;
        if (!IsAddedNotifyIcon())
            return 0;
        if (m_uID != wParam)
            return 0;
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));
        if(!IsWindow(pT->m_hWnd))
            return 0;
        DWORD dwPos = ::GetMessagePos();
        POINT pt = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos) };
        switch(lParam)
        {
        case WM_MOUSEMOVE:
            pT->OnNotifyIconMouseMove(pt);
            break;
        case WM_LBUTTONDBLCLK:
            pT->OnNotifyIconLButtonDblClk(pt);
            break;
        case WM_LBUTTONDOWN:
            pT->OnNotifyIconLButtonDown(pt);
            break;
        case WM_LBUTTONUP:
            pT->OnNotifyIconLButtonUp(pt);
            break;
        case WM_RBUTTONDOWN:
            pT->OnNotifyIconRButtonDown(pt);
            break;
        case WM_RBUTTONUP:
            pT->OnNotifyIconRButtonUp(pt);
            pT->OnNotifyIconContextMenu(pt);
            break;
        case WM_RBUTTONDBLCLK:
            pT->OnNotifyIconRButtonDblClk(pt);
            break;
        default:
            break;
        }
        return 0;
    }
    
// Overridables
public:
    void OnNotifyIconMouseMove(const POINT& /*rpt*/)
    {
    }

    void OnNotifyIconLButtonDblClk(const POINT& /*rpt*/)
    {
    }

    void OnNotifyIconLButtonDown(const POINT& /*rpt*/)
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));
        if(!IsWindow(pT->m_hWnd))
            return;
        // If iconic or if not visible, restore the window
        if (pT->IsIconic() || !pT->IsWindowVisible())
            RestoreWindow();
        else
            pT->ShowWindow(SW_MINIMIZE);
    }

    void OnNotifyIconLButtonUp(const POINT& /*rpt*/)
    {
    }

    void OnNotifyIconRButtonDown(const POINT& /*rpt*/)
    {
    }

    void OnNotifyIconRButtonUp(const POINT& /*rpt*/)
    {
    }

    void OnNotifyIconContextMenu(const POINT& rpt)
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));
        if(!IsWindow(pT->m_hWnd))
            return;
        if(m_uIDMenu == 0)
            return;
#if (_ATL_VER >= 0x0700)
        HINSTANCE hResource = ATL::_AtlBaseModule.GetResourceInstance();
#else //!(_ATL_VER >= 0x0700)
        HINSTANCE hResource = _Module.GetResourceInstance();
#endif //!(_ATL_VER >= 0x0700)
        HMENU hPopupMenu = ::LoadMenu(hResource, MAKEINTRESOURCE(m_uIDMenu));
        if(hPopupMenu)
        {
            HMENU hSubMenu;
            if (hSubMenu = ::GetSubMenu(hPopupMenu, 0))
            {
                if (!pT->SendMessage(WM_INITMENUPOPUP, (WPARAM)hSubMenu, 0))
                {
                    ForegroundWindow();
                    ::TrackPopupMenuEx(hSubMenu, TPM_LEFTALIGN, rpt.x, rpt.y, pT->m_hWnd, NULL);
                    pT->PostMessage(WM_NULL, 0, 0);
                }
            }
            ::DestroyMenu(hPopupMenu);
        }
    }

    void OnNotifyIconRButtonDblClk(const POINT& /*rpt*/)
    {
    }

// Implementation
private:
    void SaveNotifyIconTip(LPCTSTR lpszTip)
    {
        if (lpszTip)
            lstrcpyn(m_szTip, lpszTip, _countof(m_szTip));
        else
            m_szTip[0] = _T('\0');
    }

    BOOL AddNotifyIcon()
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));
        if(!IsWindow(pT->m_hWnd))
            return FALSE;
        NOTIFYICONDATA nid = { 0 };
        nid.cbSize = sizeof(NOTIFYICONDATA);
        nid.hWnd = pT->m_hWnd;
        nid.uID = m_uID;
        nid.uFlags = NIF_MESSAGE | (m_hIcon ? NIF_ICON : 0);
        nid.uCallbackMessage = m_uMessage;
        nid.hIcon = m_hIcon;
        if(lstrlen(m_szTip))
        {
            lstrcpyn(nid.szTip, m_szTip, _countof(nid.szTip));
            nid.uFlags |= NIF_TIP;
        }
        return (m_bAdded = ::Shell_NotifyIcon(NIM_ADD, &nid));
    }

    BOOL ModifyNotifyIcon()
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));
        if(!IsWindow(pT->m_hWnd))
            return FALSE;
        NOTIFYICONDATA nid = { 0 };
        nid.cbSize = sizeof(NOTIFYICONDATA);
        nid.hWnd = pT->m_hWnd;
        nid.uID = m_uID;
        nid.uFlags = NIF_MESSAGE | (m_hIcon ? NIF_ICON : 0);
        nid.uCallbackMessage = m_uMessage;
        nid.hIcon = m_hIcon;
        if(lstrlen(m_szTip))
        {
            lstrcpyn(nid.szTip, m_szTip, _countof(nid.szTip));
            nid.uFlags |= NIF_TIP;
        }
        return ::Shell_NotifyIcon(NIM_MODIFY, &nid);
    }

    BOOL DeleteNotifyIcon(void)
    {
        T* pT = static_cast<T*>(this);
        ATLASSERT(::IsWindow(pT->m_hWnd));
        if(!IsWindow(pT->m_hWnd))
            return FALSE;
        NOTIFYICONDATA nid = { 0 };
        nid.cbSize = sizeof(NOTIFYICONDATA);
        nid.hWnd   = pT->m_hWnd;
        nid.uID = m_uID;
        m_bAdded = !::Shell_NotifyIcon(NIM_DELETE, &nid);
        return !m_bAdded;
    }

    BOOL RestoreNotifyIcon(void)
    {
        if(!m_hIcon)
            return FALSE;
        return AddNotifyIcon();
    }

private:
    UINT m_uID;
    UINT m_uMessage;
    HICON m_hIcon;
    TCHAR m_szTip[ToolTipStringLen];
    UINT m_uIDMenu;
    BOOL m_bAdded;
};
... << RSDN@Home 1.2.0 alpha rev. 780>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.