diff --git a/src/cube/MainWindowController.cpp b/src/cube/MainWindowController.cpp index 07a697bfe..dbd45d605 100644 --- a/src/cube/MainWindowController.cpp +++ b/src/cube/MainWindowController.cpp @@ -52,7 +52,8 @@ #include #include #include - +#include + ////////////////////////////////////////////////////////////////////////////// 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; diff --git a/src/cube/MainWindowController.hpp b/src/cube/MainWindowController.hpp index c37b56287..eb0f88650 100644 --- a/src/cube/MainWindowController.hpp +++ b/src/cube/MainWindowController.hpp @@ -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; diff --git a/src/win32cpp/ApplicationThread.cpp b/src/win32cpp/ApplicationThread.cpp index 60a313a05..f67a2d800 100644 --- a/src/win32cpp/ApplicationThread.cpp +++ b/src/win32cpp/ApplicationThread.cpp @@ -41,7 +41,7 @@ using namespace win32cpp; -#define CALL_WAITING (WM_USER + 1) +#define CALL_WAITING (WM_USER + 1000) ////////////////////////////////////////// ///\brief diff --git a/src/win32cpp/Locale.cpp b/src/win32cpp/Locale.cpp index 1de142203..0064a939b 100644 --- a/src/win32cpp/Locale.cpp +++ b/src/win32cpp/Locale.cpp @@ -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")); } } diff --git a/src/win32cpp/SysTray.cpp b/src/win32cpp/SysTray.cpp new file mode 100644 index 000000000..c137a417b --- /dev/null +++ b/src/win32cpp/SysTray.cpp @@ -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 +#include + +////////////////////////////////////////////////////////////////////////////// +#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; +} \ No newline at end of file diff --git a/src/win32cpp/SysTray.hpp b/src/win32cpp/SysTray.hpp new file mode 100644 index 000000000..a90c9a868 --- /dev/null +++ b/src/win32cpp/SysTray.hpp @@ -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 +#include + +////////////////////////////////////////////////////////////////////////////// + +namespace win32cpp { + +////////////////////////////////////////////////////////////////////////////// +// SysTray +////////////////////////////////////////////////////////////////////////////// + +typedef std::map IconList; +typedef std::map 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(); +}; + +////////////////////////////////////////////////////////////////////////////// + +} \ No newline at end of file diff --git a/src/win32cpp/TopLevelWindow.cpp b/src/win32cpp/TopLevelWindow.cpp index e3c4f314f..37e96cb71 100644 --- a/src/win32cpp/TopLevelWindow.cpp +++ b/src/win32cpp/TopLevelWindow.cpp @@ -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); } diff --git a/src/win32cpp/TopLevelWindow.hpp b/src/win32cpp/TopLevelWindow.hpp index 1b6875bdd..893c645ba 100644 --- a/src/win32cpp/TopLevelWindow.hpp +++ b/src/win32cpp/TopLevelWindow.hpp @@ -41,6 +41,7 @@ ////////////////////////////////////////////////////////////////////////////// #include +#include 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; diff --git a/src/win32cpp/Win32Config.hpp b/src/win32cpp/Win32Config.hpp index a6ded0a30..f75fe5098 100644 --- a/src/win32cpp/Win32Config.hpp +++ b/src/win32cpp/Win32Config.hpp @@ -41,8 +41,11 @@ ////////////////////////////////////////////////////////////////////////////// #define _WIN32_WINNT 0x0501 +#define _WIN32_IE 0x0500 + #define WIN32_LEAN_AND_MEAN #include #include -#include \ No newline at end of file +#include +#include \ No newline at end of file diff --git a/src/win32cpp/pch.hpp b/src/win32cpp/pch.hpp index 1801b36c5..3849a4338 100644 --- a/src/win32cpp/pch.hpp +++ b/src/win32cpp/pch.hpp @@ -46,6 +46,7 @@ #include #include +#include #include #include #include diff --git a/src/win32cpp/win32cpp.vcproj b/src/win32cpp/win32cpp.vcproj index 55cb988bf..bf89785a3 100644 --- a/src/win32cpp/win32cpp.vcproj +++ b/src/win32cpp/win32cpp.vcproj @@ -185,6 +185,14 @@ RelativePath=".\Application.hpp" > + + + +