📄 trayicon.cpp
字号:
#include <windows.h>
#include <process.h>
#include <jni.h>
#include "TrayIconUtil.h"
// Message ID for Tray icons
#define MYWM_NOTIFYICON (WM_APP+100)
#define WNDNAME_MAX 20
// the ICON ID
#define MY_ICON_ID 333
// Class for the icon bitmap
class IconData {
private:
HBITMAP hBitmapXOR; // Colors
HBITMAP hBitmapAND; // Transparancy info
int wd, hi;
public:
IconData();
~IconData();
int setData(unsigned long *data, int wd, int hi);
HICON makeIcon(HINSTANCE hInst);
};
// Information for each tray icon
typedef struct {
BOOL visible; // Icon visible on screen or hidden?
IconData *icon; // Icon bitmap data
char *tooltip; // Icon tooltip
jobject globalClass; // Pointer to Java class for callbacks
} TrayIconData;
#define MOUSE_BTN_UP 1
#define MOUSE_BTN_DOUBLE 2
// Current instance of the TrayIcon DLL
HINSTANCE g_hinst = NULL;
// Handle to the hidden window used to receive the tray icon messages
HWND my_hDlg = NULL;
// App name for the hidden window's registered class
CHAR szAppName[] = "QSJavaTray";
// Title for the hidden window
CHAR szWndName[WNDNAME_MAX+1];
// Record for each icon
TrayIconData tray_icon;
// Wait while creating the hidden window
HANDLE wait_event = NULL;
// Wait while destroying hidden window
HANDLE exit_event = NULL;
// Handle to Java VM
JavaVM *hJavaVM = NULL;
// Taskbar restart id
UINT g_TaskbarRestart = 0;
// Add/Remove/Modify tray icon to system tray
BOOL TrayMessage(HWND hDlg, DWORD dwMessage, HICON hIcon, PSTR pszTip);
// Create the hidden window to receive the icon's mouse messages
HWND MakeHWND(HINSTANCE hInst);
void showTrayIcon();
// Remove the hidden window (on app closing)
void RemoveHWND();
// The thread proc that creates the hidden window an listens for messages
void DialogThread( void *dummy );
// Free an icon's other resources
void freeIcon(JNIEnv *env);
// Clean up @ exit of app
void cleanUpExit(JNIEnv *env);
// Call TrayMessage for the specified icon id
void updateIcon();
// Make an icon dissapear from the system tray
void makeInvisible();
//call back;
void doMouseEvent(JNIEnv * env,jobject jThis,int button,int x,int y);
JNIEnv *jniEnv_current;
jobject jobject_current;
class ThreadJavaCallback {
public:
virtual int execute(JNIEnv* env) = 0;
};
class MouseJavaCallback : public ThreadJavaCallback {
protected:
int m_Button;
int m_X;
int m_Y;
public:
MouseJavaCallback(int button,int x,int y);
virtual int execute(JNIEnv* env);
};
// Main proc of DLL, called on initialisation, termination
BOOL WINAPI DllMain(HANDLE hInst, ULONG fdwReason, LPVOID lpReserved) {
switch(fdwReason) {
case DLL_PROCESS_ATTACH:
g_hinst = (HINSTANCE)hInst;
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
MouseJavaCallback::MouseJavaCallback(int button, int x,int y) {
m_Button = button;
m_X = x;
m_Y = y;
}
int MouseJavaCallback::execute(JNIEnv* env) {
jobject obj = tray_icon.globalClass;
if (obj == 0) return -1;
jclass winTrayClass = env->GetObjectClass(obj);
if (winTrayClass == 0) return -1;
// Get callback method id
jmethodID mid = env->GetMethodID(winTrayClass, "processTrayIconMouseEvent", "(III)V");
if (mid == 0) return -1;
env->CallVoidMethod(obj, mid, m_Button, m_X, m_Y);
return 0;
}
void CallJavaVM(JavaVM* vm, ThreadJavaCallback* call) {
JNIEnv* env;
if (vm->AttachCurrentThread((void**) &env, NULL) < 0) return ;
call->execute(env);
if (env->ExceptionOccurred()) env->ExceptionDescribe();
vm->DetachCurrentThread();
}
void CallJavaThread(void *arg) {
ThreadJavaCallback *tjc = (ThreadJavaCallback*)arg;
CallJavaVM(hJavaVM, tjc);
delete tjc;
}
void CallJavaVMSThread(ThreadJavaCallback* tjc) {
if (_beginthread(CallJavaThread, 0, tjc) == -1) delete tjc;
}
void cleanUpExit(JNIEnv *env) {
freeIcon(env);
RemoveHWND();
}
// Free all icon resources for given id
// Make invisible, destroy icon, destroy tooltip, destroy global reference, free menu,..
void freeIcon(JNIEnv *env) {
if (tray_icon.visible == TRUE) {
makeInvisible();
}
tray_icon.visible = FALSE;
//Free icon
if (tray_icon.icon != NULL) {
delete tray_icon.icon;
tray_icon.icon = NULL;
}
// Free tooltip
if (tray_icon.tooltip != NULL) {
delete tray_icon.tooltip;
tray_icon.tooltip = NULL;
}
// Free global ref to callback class for mouse/menu events
if (tray_icon.globalClass != 0) {
if (env != NULL) {
env->DeleteGlobalRef(tray_icon.globalClass);
} else {
}
tray_icon.globalClass = 0;
}
}
// Update icon with given id in system tray
// Show or Hide and add tooltip,..
void updateIcon() {
// Valid hidden window handle, icon id an visible?
if (my_hDlg != NULL && tray_icon.visible == TRUE) {
if (g_hinst != NULL && tray_icon.icon != NULL) {
HICON icon = tray_icon.icon->makeIcon(g_hinst);
if (icon != NULL) {
// Modify icon status
TrayMessage(my_hDlg, NIM_MODIFY, icon, tray_icon.tooltip);
}/*else {
printf("TRAY_NOTENOUGHMEM\n");
} */
} else {
makeInvisible();
}
}
}
// Hide icon
void makeInvisible() {
if (tray_icon.visible == TRUE) {
if (my_hDlg != NULL) TrayMessage(my_hDlg, NIM_DELETE, NULL, NULL);
tray_icon.visible = FALSE;
}
}
BOOL TrayMessage(HWND hDlg, DWORD dwMessage, HICON hIcon, PSTR pszTip) {
BOOL res;
// Fill data struct for tray icon
NOTIFYICONDATA tnd;
tnd.cbSize = sizeof(NOTIFYICONDATA);
tnd.hWnd = hDlg;
tnd.uID = MY_ICON_ID;
tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
tnd.uCallbackMessage = MYWM_NOTIFYICON;
tnd.hIcon = hIcon;
// Include tooltip?
if (pszTip) {
lstrcpyn(tnd.szTip, pszTip, sizeof(tnd.szTip));
} else {
tnd.szTip[0] = '\0';
}
// Call tray icon windows API function
res = Shell_NotifyIcon(dwMessage, &tnd);
// Destroy the icon's handle (icon data is copied by Windows function)
if (hIcon) DestroyIcon(hIcon);
return res;
}
// Handle icon mouse event (left/right button)
void HandleNotifyIcon(WPARAM id_num, LPARAM lParam) {
POINT mouse_pos;
GetCursorPos(&mouse_pos);
int button = -1;
switch (lParam) {
case WM_RBUTTONDOWN:
button = 0; break;
case WM_LBUTTONDOWN:
button = 1; break;
case WM_MBUTTONDOWN:
button = 2; break;
case WM_LBUTTONUP:
button = 3; break;
case WM_MBUTTONUP:
button = 4; break;
case WM_RBUTTONUP:
button = 5; break;
case WM_LBUTTONDBLCLK:
button = 6; break;
case WM_RBUTTONDBLCLK:
button = 7; break;
case WM_MBUTTONDBLCLK:
button = 8; break;
}
MouseJavaCallback* call = new MouseJavaCallback(button,mouse_pos.x,mouse_pos.y);
CallJavaVMSThread(call);
}
// Windows message proc for hidden window
// Receives mouse/menu events for the apps tray icons
LONG APIENTRY WndProc(HWND hWnd, UINT iMessage, UINT wParam, LONG lParam) {
switch (iMessage) {
case WM_DESTROY:
PostQuitMessage(0) ;
break;
case MYWM_NOTIFYICON:
HandleNotifyIcon(wParam, lParam);
break;
case WM_CREATE:
g_TaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
break;
case WM_GETMINMAXINFO:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -