📄 systraymanager.cpp
字号:
if( menuId < SUB_ID_BEGIN )
{
SysTrayMenu* pstMenu = findMainMenu( menuId );
pstMenu->removeAll();
}
else
{
SubMenu* psMenu = findSubMenu( menuId );
psMenu->removeAll();
}
}
// tell our thread to detach himself from the JVM
void SysTrayManager::dispose()
{
PostMessage( s_hWnd, WM_DISPOSE, 0, 0 );
}
// clean up
void SysTrayManager::destroy()
{
// maybe someone just called available, without ever creating
// a menu - than there is no message thread
if( s_threadId )
{
// delete all main menus
SysTrayMenu* pstMenu;
map< UINT, SysTrayMenu* >::iterator i = s_pMainMenuMap->begin();
while( i != s_pMainMenuMap->end() )
{
pstMenu = i->second;
Shell_NotifyIcon( NIM_DELETE, &pstMenu->m_niData );
delete pstMenu;
i++;
}
// delete all submenus
SubMenu* psMenu;
map< UINT, SubMenu* >::iterator j = s_pSubMenuMap->begin();
while( j != s_pSubMenuMap->end() )
{
psMenu = j->second;
delete psMenu;
j++;
}
// destroy all icons
HICON hIcon;
map< wstring, HICON >::iterator k = s_pIconMap->begin();
while( k != s_pIconMap->end() )
{
hIcon = k->second;
DestroyIcon( hIcon );
k++;
}
UnregisterHotKey( s_hWnd, 0xc000 );
UnregisterHotKey( s_hWnd, 0xc001 );
}
}
// the loop of our window
LRESULT CALLBACK SysTrayManager::wndProc( HWND hWnd,
UINT message,
WPARAM wParam, // item index
LPARAM lParam ) // mouse button
{
POINT pCursor; // mouse position
static SysTrayMenu* pstMenu = 0;
switch( message )
{
case WM_COMMAND : // an item was selected
{
// ---------------------------------------------------------------------
//
// how to interpet wParam:
//
// - if it is smaller than SUB_ID_BEGIN the selected item is in a main
// menu and the value of wParam is the id of the item.
//
// - otherwise the selected item is in a submenu, and wParam consists of
// the item id and the submenu id:
// wParam = <submenuId> * ( SUB_ID_BEGIN - 1 ) + <itemId>
//
// example:
// SUB_ID_BEGIN := 1001, submenuId := 2, itemId := 3
// then wParam = 2003
//
// ---------------------------------------------------------------------
//
// why this is necessary:
//
// When an item is selected, the id of the menu the selected item is
// part of needs to be acquired in order to make the necessary JNI
// method call. For main menus this is simple, because the menu id is
// passed along in wParam when the icon in the system tray is clicked.
// For submenus the only way to access the submenu id of the selected
// item, is to pass it along in wParam together with the id of the
// item.
//
// ---------------------------------------------------------------------
if( wParam < SUB_ID_BEGIN ) // item is in the main menu
{
// since the menu pointer is declared static it is still valid
pstMenu->toggleCheckForItem( wParam );
s_pEnv->CallVoidMethod( pstMenu->m_jobject, s_itemMethodIDMain, wParam );
}
else // item is in a submenu
{
int menuId = wParam / ( SUB_ID_BEGIN - 1 );
int itemId = wParam - menuId * ( SUB_ID_BEGIN - 1 );
SubMenu* psMenu = findSubMenu( menuId );
psMenu->toggleCheckForItem( itemId );
s_pEnv->CallVoidMethod( psMenu->m_jobject, s_itemMethodIDSub, itemId );
}
break;
}
case WM_SYSTRAY : // the icon was clicked
{
GetCursorPos( &pCursor );
pstMenu = findMainMenu( ( UINT ) wParam );
if( lParam == WM_LBUTTONDOWN ) // left mose button click
{
s_pEnv->CallVoidMethod( pstMenu->m_jobject, s_iconMethodIDMain, false );
}
else if( lParam == WM_LBUTTONDBLCLK ) // left mose button double-click
{
s_pEnv->CallVoidMethod( pstMenu->m_jobject, s_iconMethodIDMain, true );
}
else if( lParam == WM_RBUTTONDOWN ) // right mouse button
{
// show the menu
GetCursorPos( &pCursor );
SetForegroundWindow( s_hWnd );
TrackPopupMenu( pstMenu->m_hMenu,
TPM_RIGHTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON,
pCursor.x, pCursor.y, 0, s_hWnd, NULL );
}
break;
}
case WM_HOTKEY :
{
if( wParam == 0xc000 ) ShowWindow( s_hWnd, SW_SHOW );
else ShowWindow( s_hWnd, SW_HIDE );
break;
}
case WM_DISPOSE :
{
destroy();
s_pVm->DetachCurrentThread();
break;
}
case WM_CLOSE :
{
ShowWindow( s_hWnd, SW_HIDE );
break;
}
default : return DefWindowProc( hWnd, message, wParam, lParam );
}
}
DWORD WINAPI SysTrayManager::threadProc( LPVOID lpParameter )
{
// attach this thread to the virtual machine in order to get
// a valid environment pointer
JDK1_1AttachArgs thread_args;
s_pVm->AttachCurrentThread( ( void** ) &s_pEnv, &thread_args );
// create an invisible window to receive messages
WNDCLASS wc;
LPCWSTR szMainWndClass = L"SysTray4JavaDispatcher";
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = wndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = s_hInstance;
wc.hIcon = s_hDefIcon;
wc.hCursor = 0;
wc.hbrBackground = ( HBRUSH ) 1;
wc.lpszMenuName = L"MAINMENU";
wc.lpszClassName = szMainWndClass;
if( !RegisterClass( &wc ) )
{
MessageBox( NULL, L"Main-window couldn't be created",
L"Error", MB_TASKMODAL | MB_OK | MB_ICONEXCLAMATION );
return 0;
}
int screen_width = GetSystemMetrics( SM_CXSCREEN );
int screen_height = GetSystemMetrics( SM_CYSCREEN );
s_hWnd = CreateWindow( szMainWndClass, L"Info", WS_SYSMENU, screen_width - 230,
screen_height - 150, 210, 106, HWND_DESKTOP, 0, s_hInstance, 0 );
if ( !s_hWnd )
{
MessageBox( NULL, L"Main-window couldn't be created",
L"Error", MB_ICONEXCLAMATION | MB_OK );
return 0;
}
TCHAR buffer[ 256 ];
TCHAR txtInfo[ 256 ];
LoadString( s_hInstance, IDS_INFO, buffer, 255 );
wsprintf( txtInfo, buffer, s_jarVersion, ST4J_VERSION );
CreateWindow( L"STATIC", txtInfo, WS_CHILD | WS_VISIBLE, 1, 1, 210, 80,
s_hWnd, 0, s_hInstance, 0 );
RegisterHotKey( s_hWnd, 0xc000, MOD_ALT, 33 );
RegisterHotKey( s_hWnd, 0xc001, MOD_ALT, 34 );
// enter the message loop
MSG msg;
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return 0;
}
// wait until our window is ready
void SysTrayManager::waitForWindow()
{
while( !s_hWnd ) Sleep( 10 );
}
// extract the icon specified by the given file name
HICON SysTrayManager::getIcon( LPCWSTR iconFileName )
{
// instead of calling ExtractIcon each time an icon in the system
// tray is changed, extracted icons are cached in a map
HICON hIcon;
map< wstring, HICON >::iterator i;
i = s_pIconMap->find( iconFileName );
if( i != s_pIconMap->end() ) hIcon = i->second;
else
{
// the icon was not found in our map
hIcon = ExtractIcon( s_hInstance, iconFileName, 0 );
if( !hIcon ) hIcon = s_hDefIcon;
else
{
wstring* key = new wstring( iconFileName );
s_pIconMap->insert( pair< wstring, HICON >( *key, hIcon ) );
}
}
return hIcon;
}
// retrieve the main menu specified by id
SysTrayMenu* SysTrayManager::findMainMenu( UINT id )
{
map< UINT, SysTrayMenu* >::iterator i;
i = s_pMainMenuMap->find( id );
if( i != s_pMainMenuMap->end() ) return i->second;
else return 0;
}
// retrieve the submenu specified by id
SubMenu* SysTrayManager::findSubMenu( UINT id )
{
map< UINT, SubMenu* >::iterator i;
i = s_pSubMenuMap->find( id );
if( i != s_pSubMenuMap->end() ) return i->second;
else return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -