SysTray component

- capabilities to show multiple tray icons with tooltips, popup menu and balloon tips
- added an example to the cube (MainWindowController)

small fixes:
- exchanged ansi by unicode functions for directory iteration in Locale-class
- changed message id in application thread
This commit is contained in:
andre@woesten.com 2008-09-03 00:37:01 +00:00
parent fb6b88104b
commit f4422e06f7
11 changed files with 320 additions and 12 deletions

View File

@ -52,7 +52,8 @@
#include <win32cpp/Splitter.hpp>
#include <win32cpp/TabView.hpp>
#include <win32cpp/RedrawLock.hpp>
#include <win32cpp/SysTray.hpp>
//////////////////////////////////////////////////////////////////////////////
using namespace musik::cube;
@ -77,6 +78,11 @@ MainWindowController::~MainWindowController()
delete this->transportController;
}
void MainWindowController::OnFileExit(MenuItemRef menuItem)
{
Application::Instance().Terminate();
}
void MainWindowController::OnMainWindowCreated(Window* window)
{
@ -88,7 +94,21 @@ void MainWindowController::OnMainWindowCreated(Window* window)
SendMessage( window->Handle(), WM_SETICON, WPARAM( ICON_BIG ), LPARAM( icon ) );
}
// Init Tray Icon
MenuRef myMenu = Menu::CreatePopup();
// Create Tray Menu
myMenu->Items().Append(MenuItem::Create(_T("Test 1")));
myMenu->Items().Append(MenuItem::Create(_T("Test 2")));
MenuItemRef trayExit = myMenu->Items().Append(MenuItem::Create(_T("E&xit")));
// Bind Exit to handler
trayExit->Activated.connect(this, &MainWindowController::OnFileExit);
UINT uidTrayIcon = this->mainWindow.SysTrayManager()->AddIcon(window, icon);
this->mainWindow.SysTrayManager()->SetTooltip(uidTrayIcon, _T("And another test..."));
this->mainWindow.SysTrayManager()->SetPopupMenu(uidTrayIcon, myMenu);
this->mainWindow.SysTrayManager()->ShowBalloon(uidTrayIcon, _T("musikCube 2"), _T("Welcome to musikCube!"), 2);
static const int TransportViewHeight = 54;

View File

@ -77,6 +77,7 @@ public: /*dtor*/ ~MainWindowController();
protected: void OnMainWindowCreated(Window* window);
protected: void OnResize(Window* window, Size size);
protected: void OnDestroyed(Window* window);
protected: void OnFileExit(MenuItemRef menuItem);
protected: TopLevelWindow& mainWindow;
protected: Splitter* clientView;

View File

@ -41,7 +41,7 @@
using namespace win32cpp;
#define CALL_WAITING (WM_USER + 1)
#define CALL_WAITING (WM_USER + 1000)
//////////////////////////////////////////
///\brief

View File

@ -180,22 +180,20 @@ LocaleList Locale::EnumLocales(void)
LocaleList localeList;
// convert directory to boost path
fs::path localePath(ShrinkString(path), fs::native);
fs::wpath localePath(path, fs::native);
// now iterate...
fs::directory_iterator iEnd;
for(fs::directory_iterator iDir(localePath); iDir != iEnd; ++iDir)
fs::wdirectory_iterator iEnd;
for(fs::wdirectory_iterator iDir(localePath); iDir != iEnd; ++iDir)
{
// lame conversion =(
std::string dirEntryA = iDir->path().leaf();
uistring dirEntryW = WidenString(dirEntryA.c_str());
uistring dirEntry = iDir->path().leaf();
// read name of config
Config entryConfig(path + _T("\\") + dirEntryW);
Config entryConfig(path + _T("\\") + dirEntry);
if(entryConfig.SectionExists(_T("config")))
{
entryConfig.SetSection(_T("config"));
localeList[dirEntryW.c_str()] = entryConfig.Value(_T("name"));
localeList[dirEntry] = entryConfig.Value(_T("name"));
}
}

181
src/win32cpp/SysTray.cpp Normal file
View File

@ -0,0 +1,181 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2008, André Wösten
//
// Sources and Binaries of: mC2, win32cpp
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#include <pch.hpp>
#include <win32cpp/SysTray.hpp>
//////////////////////////////////////////////////////////////////////////////
#define WM_MC2_SYSTRAY (WM_USER + 100)
using namespace win32cpp;
IconList SysTray::iconList;
MenuList SysTray::menuList;
int SysTray::uidCounter = 100;
SysTray::SysTray()
{
::InitCommonControls();
}
SysTray::~SysTray()
{
// iterate through list and delete icons
for(IconList::iterator i = SysTray::iconList.begin(); i != SysTray::iconList.end(); ++i) {
this->DeleteIcon(i->second.uID);
}
}
bool SysTray::DeleteIcon(UINT uid)
{
if(SysTray::iconList.find(uid) != SysTray::iconList.end()) {
return (::Shell_NotifyIcon(NIM_DELETE, &SysTray::iconList[uid]) != 0);
}
return false;
}
bool SysTray::ShowBalloon(UINT uid, const uistring& title, const uistring& text, UINT timeout, UINT icon)
{
if(SysTray::iconList.find(uid) != SysTray::iconList.end()) {
SysTray::iconList[uid].uFlags |= NIF_INFO;
SysTray::iconList[uid].uTimeout = timeout * 1000;
SysTray::iconList[uid].dwInfoFlags = icon;
::wcsncpy_s(SysTray::iconList[uid].szInfoTitle, 64, title.c_str(), 64);
::wcsncpy_s(SysTray::iconList[uid].szInfo, 256, text.c_str(), 256);
return (::Shell_NotifyIcon(NIM_MODIFY, &SysTray::iconList[uid]) != 0);
}
return false;
}
bool SysTray::SetIcon(UINT uid, HICON icon)
{
if(SysTray::iconList.find(uid) != SysTray::iconList.end()) {
SysTray::iconList[uid].hIcon = icon;
return (::Shell_NotifyIcon(NIM_MODIFY, &SysTray::iconList[uid]) != 0);
}
return false;
}
bool SysTray::SetTooltip(UINT uid, const uistring& tooltip)
{
if(SysTray::iconList.find(uid) != SysTray::iconList.end()) {
SysTray::iconList[uid].uFlags |= NIF_TIP;
::wcsncpy_s(SysTray::iconList[uid].szTip, 128, tooltip.c_str(), 128);
return (::Shell_NotifyIcon(NIM_MODIFY, &SysTray::iconList[uid]) != 0);
}
return false;
}
bool SysTray::SetPopupMenu(UINT uid, MenuRef menu)
{
if(menu) {
SysTray::menuList[uid] = menu;
return true;
}
return false;
}
LRESULT SysTray::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(SysTray::menuList.find(message - WM_MC2_SYSTRAY) != SysTray::menuList.end()) {
switch(LOWORD(lParam)) {
case WM_RBUTTONDOWN:
{
UINT uid = message - WM_MC2_SYSTRAY;
if(SysTray::menuList.find(uid) != SysTray::menuList.end()) {
POINT mousePos = { 0 };
::GetCursorPos(&mousePos);
TrackPopupMenu(
SysTray::menuList[uid]->Handle(),
TPM_LEFTBUTTON,
mousePos.x,
mousePos.y,
NULL,
SysTray::iconList[uid].hWnd,
NULL);
}
}
return 0;
}
}
return 0;
}
int SysTray::AddIcon(Window* window, HICON icon, const uistring& tooltip)
{
UINT uid = SysTray::uidCounter++;
NOTIFYICONDATA nid;
// setup notifyicondata structure
::ZeroMemory(&nid, sizeof(nid));
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = window->Handle();
nid.uID = uid;
nid.uFlags = NIF_MESSAGE | NIF_ICON;
if(tooltip != _T("")) {
nid.uFlags |= NIF_TIP;
::wcsncpy_s(nid.szTip, 64, tooltip.c_str(), 64);
}
nid.hIcon = icon;
nid.uCallbackMessage = WM_MC2_SYSTRAY + uid;
// create icon
if(!::Shell_NotifyIcon(NIM_ADD, &nid)) {
return -1;
}
nid.uVersion = NOTIFYICON_VERSION;
if(!::Shell_NotifyIcon(NIM_SETVERSION, &nid)) {
return -1;
}
// add to icon list
SysTray::iconList[uid] = nid;
return uid;
}

82
src/win32cpp/SysTray.hpp Normal file
View File

@ -0,0 +1,82 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2008, André Wösten
//
// Sources and Binaries of: win32cpp
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
#include <map>
#include <win32cpp/Menu.hpp>
//////////////////////////////////////////////////////////////////////////////
namespace win32cpp {
//////////////////////////////////////////////////////////////////////////////
// SysTray
//////////////////////////////////////////////////////////////////////////////
typedef std::map<UINT, NOTIFYICONDATA> IconList;
typedef std::map<UINT, MenuRef> MenuList;
class SysTray {
private:
// Contains the list of notify icons
static IconList iconList;
// Contains a list of menus for each icon
static MenuList menuList;
// Each notify icon has its own UID. This counter increments
// when an icon is created.
static int uidCounter;
public:
LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
bool DeleteIcon(UINT uid);
int AddIcon(Window* window, HICON icon, const uistring& tooltip = _T(""));
bool SetIcon(UINT uid, HICON icon);
bool SetTooltip(UINT uid, const uistring& tooltip);
bool SetPopupMenu(UINT uid, MenuRef menu);
bool ShowBalloon(UINT uid, const uistring& title, const uistring& text, UINT timeout, UINT icon = NIIF_INFO);
/* ctor */ SysTray();
/* dtor */ ~SysTray();
};
//////////////////////////////////////////////////////////////////////////////
}

View File

@ -63,10 +63,12 @@ using namespace win32cpp;
, closed(false)
, modalChild(NULL)
{
this->sysTray = new SysTray;
}
/*dtor*/ TopLevelWindow::~TopLevelWindow()
{
delete this->sysTray;
}
bool TopLevelWindow::RegisterWindowClass()
@ -147,6 +149,12 @@ Size TopLevelWindow::MinimumSize() const
return this->minSize;
}
///\brief Returns the systray manager
SysTray* TopLevelWindow::SysTrayManager()
{
return this->sysTray;
}
///\brief Closes the TopLevelWindow
void TopLevelWindow::Close()
{
@ -190,6 +198,8 @@ LRESULT TopLevelWindow::WindowProc(UINT message, WPARAM wParam, LPARAM lPara
return 0;
}
this->SysTrayManager()->WindowProc(message, wParam, lParam);
return base::WindowProc(message, wParam, lParam);
}

View File

@ -41,6 +41,7 @@
//////////////////////////////////////////////////////////////////////////////
#include <win32cpp/Container.hpp>
#include <win32cpp/SysTray.hpp>
namespace win32cpp {
@ -70,6 +71,8 @@ public: // methods
void ShowModal(TopLevelWindow* parent);
void Close();
SysTray* SysTrayManager();
static TopLevelWindow* FindFromAncestor(Window* window);
protected: // methods
@ -85,6 +88,7 @@ protected: // methods
static bool RegisterWindowClass();
private: // instance data
SysTray* sysTray;
uistring windowTitle;
bool closed;
Size minSize;

View File

@ -41,8 +41,11 @@
//////////////////////////////////////////////////////////////////////////////
#define _WIN32_WINNT 0x0501
#define _WIN32_IE 0x0500
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <commctrl.h>
#include <shellapi.h>

View File

@ -46,6 +46,7 @@
#include <win32cpp/Win32Config.hpp>
#include <win32cpp/Application.hpp>
#include <win32cpp/SysTray.hpp>
#include <win32cpp/TopLevelWindow.hpp>
#include <win32cpp/Container.hpp>
#include <win32cpp/Menu.hpp>

View File

@ -185,6 +185,14 @@
RelativePath=".\Application.hpp"
>
</File>
<File
RelativePath=".\SysTray.cpp"
>
</File>
<File
RelativePath=".\SysTray.hpp"
>
</File>
<File
RelativePath=".\win32cpp.hpp"
>