Привет всем!
Сразу прошу прощения за столь избитый сабж.
Начну с использования:
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 >>