📄 systraymanager.cpp
字号:
/*********************************************************************************
SysTrayManager.cpp
------------------
author : Tamas Bara
copyright : (C) 2002-2004 by SnoozeSoft
email : snoozesoft@compuserve.de
*********************************************************************************/
/*********************************************************************************
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
* *
*********************************************************************************/
#include "resource.h"
#include "StdAfx.h"
#include "systraymanager.h"
LPCWSTR SysTrayManager::s_jarVersion = 0;
// the id of our thread
DWORD SysTrayManager::s_threadId = 0;
// instance handle
HINSTANCE SysTrayManager::s_hInstance = 0;
// window handle
HWND SysTrayManager::s_hWnd = 0;
// handle to the default icon
HICON SysTrayManager::s_hDefIcon = 0;
// main menus container
// keys: menuId
// values: menus
map< UINT, SysTrayMenu* >* SysTrayManager::s_pMainMenuMap = 0;
// submenus container
// keys: menuId
// values: menus
map< UINT, SubMenu* >* SysTrayManager::s_pSubMenuMap = 0;
// icon handles container
// keys: file name
// values: icon handle
map< wstring, HICON >* SysTrayManager::s_pIconMap = 0;
// counter for main menu id assignment
UINT SysTrayManager::s_mainCounter = 1;
// minimum submenu id value
const UINT SysTrayManager::SUB_ID_BEGIN = 1001;
// counter for submenu id assignment
UINT SysTrayManager::s_subCounter = SUB_ID_BEGIN;
// virtual machine pointer
JavaVM* SysTrayManager::s_pVm = 0;
// native interface environment pointer
JNIEnv* SysTrayManager::s_pEnv = 0;
// id of method to call when the icon was clicked
jmethodID SysTrayManager::s_iconMethodIDMain = 0;
// id of method to call when an item in a main menu was selected
jmethodID SysTrayManager::s_itemMethodIDMain = 0;
// id of method to call when an item in a submenu was selected
jmethodID SysTrayManager::s_itemMethodIDSub = 0;
// start
void SysTrayManager::init( HINSTANCE hInstance, JNIEnv* pEnv, LPCWSTR jarVersion )
{
s_jarVersion = wcsdup( jarVersion );
s_hInstance = hInstance;
s_hDefIcon = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_ROCKET ) );
pEnv->GetJavaVM( &s_pVm );
s_pMainMenuMap = new map< UINT, SysTrayMenu* >;
s_pSubMenuMap = new map< UINT, SubMenu* >;
s_pIconMap = new map< wstring, HICON >;
// create our thread
CreateThread( 0, 0, threadProc, 0, 0, &s_threadId );
// yield the CPU to the new thread
Sleep( 0 );
}
// add a new main menu
int SysTrayManager::addMainMenu( jobject menuObj,
LPCWSTR iconFileName,
LPCWSTR toolTip )
{
if( !s_hWnd ) waitForWindow(); // if our window isn磘 yet ready
// extract the method ids, if this is the first time this function gets called
if( !s_iconMethodIDMain )
{
jclass clazz = s_pEnv->GetObjectClass( menuObj );
s_iconMethodIDMain = s_pEnv->GetMethodID( clazz, "iconLeftClicked", "(Z)V" );
s_itemMethodIDMain = s_pEnv->GetMethodID( clazz, "menuItemSelected", "(I)V" );
}
// extract the icon handle specified by the file name
HICON hIcon = getIcon( iconFileName );
// create the menu
SysTrayMenu* pstMenu = new SysTrayMenu(
s_mainCounter++, s_pEnv->NewGlobalRef( menuObj ), hIcon, toolTip );
// put the menu into the container
s_pMainMenuMap->insert( pair< UINT, SysTrayMenu* >( pstMenu->m_id, pstMenu ) );
// add the icon to the systray
pstMenu->m_niData.cbSize = sizeof( NOTIFYICONDATA );
pstMenu->m_niData.hWnd = s_hWnd;
pstMenu->m_niData.uID = pstMenu->m_id;
pstMenu->m_niData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
// assign the message that will be sent when the user clicks at the icon
pstMenu->m_niData.uCallbackMessage = WM_SYSTRAY;
Shell_NotifyIcon( NIM_ADD, &pstMenu->m_niData );
return pstMenu->m_id;
}
// add a new submenu
int SysTrayManager::addSubMenu( jobject menuObj )
{
if( !s_hWnd ) waitForWindow(); // if our window isn磘 yet ready
// extract the method id, if this is the first time this function gets called
if( !s_itemMethodIDSub )
{
jclass clazz = s_pEnv->GetObjectClass( menuObj );
s_itemMethodIDSub = s_pEnv->GetMethodID( clazz, "menuItemSelected", "(I)V" );
}
// create the menu
SubMenu* psMenu = new SubMenu( s_subCounter++, s_pEnv->NewGlobalRef( menuObj ) );
// put the menu into the container
s_pSubMenuMap->insert( pair< UINT, SubMenu* >( psMenu->m_id, psMenu ) );
return psMenu->m_id;
}
// change the tooltip displayed over the icon
void SysTrayManager::setToolTip( UINT menuId, LPCWSTR tip )
{
SysTrayMenu* pstMenu = findMainMenu( menuId );
pstMenu->m_niData.uFlags = NIF_TIP;
if( wcslen( tip ) > 63 )
{
fprintf( stderr, "systray4j: tooltip too long! maximum length is 63\n" );
}
wcsncpy( pstMenu->m_niData.szTip, tip, 63 );
pstMenu->m_niData.szTip[ 63 ] = 0;
if( pstMenu->m_isIconVisible )
Shell_NotifyIcon( NIM_MODIFY, &pstMenu->m_niData );
}
// show/hide the icon
void SysTrayManager::showIcon( UINT menuId, bool show )
{
DWORD dwMessage = show ? NIM_ADD : NIM_DELETE;
SysTrayMenu* pstMenu = findMainMenu( menuId );
if( show ) pstMenu->m_niData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
Shell_NotifyIcon( dwMessage, &pstMenu->m_niData );
pstMenu->m_isIconVisible = show;
}
// change the icon
void SysTrayManager::setIcon( UINT menuId, LPCWSTR fileName )
{
SysTrayMenu* pstMenu = findMainMenu( menuId );
pstMenu->m_niData.uFlags = NIF_ICON;
pstMenu->m_niData.hIcon = getIcon( fileName );
if( pstMenu->m_isIconVisible )
Shell_NotifyIcon( NIM_MODIFY, &pstMenu->m_niData );
}
// enable/disable the specified item
void SysTrayManager::enableItem( UINT menuId, int itemIndex, bool enable )
{
if( menuId < SUB_ID_BEGIN )
{
SysTrayMenu* pstMenu = findMainMenu( menuId );
pstMenu->enableItem( itemIndex, enable );
}
else
{
SubMenu* psMenu = findSubMenu( menuId );
psMenu->enableItem( itemIndex, enable );
}
}
// check/uncheck the specified item
void SysTrayManager::checkItem( UINT menuId, int itemIndex, bool check )
{
if( menuId < SUB_ID_BEGIN )
{
SysTrayMenu* pstMenu = findMainMenu( menuId );
pstMenu->checkItem( itemIndex, check );
}
else
{
SubMenu* psMenu = findSubMenu( menuId );
psMenu->checkItem( itemIndex, check );
}
}
// change the label of the specified item
void SysTrayManager::setItemLabel( UINT menuId, int itemIndex, LPCWSTR label )
{
if( menuId < SUB_ID_BEGIN )
{
SysTrayMenu* pstMenu = findMainMenu( menuId );
pstMenu->setItemLabel( itemIndex, label );
}
else
{
SubMenu* psMenu = findSubMenu( menuId );
psMenu->setItemLabel( itemIndex, label );
}
}
// insert an item to the menu at the specified position
void SysTrayManager::addItem( UINT menuId,
int itemIndex,
LPCWSTR label,
bool checkable,
bool checked,
bool enabled )
{
if( menuId < SUB_ID_BEGIN )
{
SysTrayMenu* pstMenu = findMainMenu( menuId );
pstMenu->addItem( itemIndex, label, checkable, checked, enabled );
}
else
{
SubMenu* psMenu = findSubMenu( menuId );
psMenu->addItem( itemIndex, label, checkable, checked, enabled );
}
}
// remove the specified item from the menu
void SysTrayManager::removeItem( UINT menuId, int itemIndex )
{
if( menuId < SUB_ID_BEGIN )
{
SysTrayMenu* pstMenu = findMainMenu( menuId );
pstMenu->removeItem( itemIndex );
}
else
{
SubMenu* psMenu = findSubMenu( menuId );
psMenu->removeItem( itemIndex );
}
}
// change the whole menu by replacing all items
void SysTrayManager::removeAll( UINT menuId )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -