📄 windowstrayicon.cpp
字号:
}
/*
* Class: jeans_trayicon_WindowsTrayIcon
* Method: setToolTip
* Signature: (ILjava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_setToolTip(JNIEnv *env, jclass, jint id_num, jstring tip) {
// Icon id valid?
if (tray_icons[id_num].used == FALSE) {
last_error = TRAY_WRONGICONID;
return;
}
// If already exists delete first..
if (tray_icons[id_num].tooltip != NULL) delete tray_icons[id_num].tooltip;
// Get java string for tooltip
int len = env->GetStringLength(tip);
const jchar *j_tip = env->GetStringChars(tip, 0);
if (bUseUnicode == 0) {
jchar* m_tip = new jchar[len+1];
convertUnicodeString(j_tip, m_tip, len);
tray_icons[id_num].tooltip = convertUnicodeANSI(m_tip);
delete m_tip;
} else {
tray_icons[id_num].tooltip = (char*)new jchar[len+1];
convertUnicodeString(j_tip, (jchar*)tray_icons[id_num].tooltip, len);
}
env->ReleaseStringChars(tip, j_tip);
updateIcon(id_num);
}
/*
* Class: com_jeans_trayicon_WindowsTrayIcon
* Method: showBalloon
* Signature: (ILjava/lang/String;Ljava/lang/String;II)V
*/
JNIEXPORT jint JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_showBalloon(JNIEnv* env, jclass, jint id_num, jstring msg, jstring title, jint time, jint flags) {
bool result = FALSE;
// Icon id valid?
if (tray_icons[id_num].used == FALSE) {
last_error = TRAY_WRONGICONID;
return 0;
}
if (my_hDlg != NULL && tray_icons[id_num].visible == TRUE && g_hinst != NULL) {
DWORD myflags = flags;
// Allocate buffers for Unicode version
int mlen = env->GetStringLength(msg);
int tlen = env->GetStringLength(title);
jchar* m_msg = new jchar[mlen+1];
jchar* m_title = new jchar[tlen+1];
// Get strings from Java side
const jchar *j_msg = env->GetStringChars(msg, 0);
const jchar *j_title = env->GetStringChars(title, 0);
// Convert strings (replace HTML codes)
convertUnicodeString(j_msg, m_msg, mlen);
convertUnicodeString(j_title, m_title, tlen);
// Release Java Strings
env->ReleaseStringChars(msg, j_msg);
env->ReleaseStringChars(title, j_title);
// Call method
if (bUseUnicode == 0 || g_UnicodeConversion[UNICODE_CONVERSION_BALLOON]) {
char *a_msg = convertUnicodeANSI(m_msg);
char *a_title = convertUnicodeANSI(m_title);
result = TrayBalloon(my_hDlg, id_num, a_msg, a_title, (UINT)time, myflags);
delete a_msg;
delete a_title;
} else {
result = TrayBalloonW(my_hDlg, id_num, m_msg, m_title, (UINT)time, myflags);
}
delete m_title;
delete m_msg;
}
if (!result) {
last_error = TRAY_ERRORBALLOON;
return 0;
}
return 1;
}
/*
* Class: WindowsTrayIcon
* Method: freeIcon
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_freeIcon(JNIEnv *env, jclass, jint id_num) {
freeIcon(env, id_num);
}
/*
* Class: com_jeans_trayicon_WindowsTrayIcon
* Method: initTrayIcon
* Signature: (Ljava/lang/String;Lcom/jeans/trayicon/WindowsTrayIcon;)V
*/
JNIEXPORT void JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_initTrayIcon(JNIEnv *env, jclass, jstring wndName, jobject obj) { // Store handle to Java VM
env->GetJavaVM(&hJavaVM);
#ifdef USE_GLOBAL_REF
hGlobalWinTrayClass = env->NewGlobalRef(obj);
#endif
// Store version of Shell32 DLL
hShell32Version = GetShell32Version();
// Store version of Windows
hWindowsVersion = TrayGetWindowsVersion();
// Initialize Unicode Functions
initUnicodeFunctions();
// Make dialog
if (my_hDlg == NULL) {
// Copy window name
const char *cWndName = env->GetStringUTFChars(wndName, 0);
strncpy(szWndName ,cWndName, WNDNAME_MAX);
szWndName[WNDNAME_MAX] = 0;
env->ReleaseStringUTFChars(wndName, cWndName);
// Initialize icon data struct
for (int ctr = 0; ctr < MY_MAX_ICONS; ctr++) tray_icons[ctr].used = FALSE;
// Popup invisible dummy window
if (g_hinst != NULL) {
wait_event = CreateEvent(NULL,FALSE,FALSE,NULL);
_beginthread(DialogThread, 0, NULL );
}
}
}
/*
* Class: com_jeans_trayicon_WindowsTrayIcon
* Method: initJAWT
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_initJAWT(JNIEnv *, jclass) {
GetJAWTHandle();
}
/*
* The Swing menu needs a message hook that tracks all mouse clicks
* if a user clicks outside the menu, it should dissapear
*/
extern "C" {
LRESULT CALLBACK WinTrayMouseClickHook(int nCode, WPARAM wParam, LPARAM lParam) {
if (hMouseClickEna == 1 && nCode == HC_ACTION) {
MOUSEHOOKSTRUCT* pStruct = (MOUSEHOOKSTRUCT*)lParam;
unsigned int isLButton = (unsigned int)GetAsyncKeyState(VK_LBUTTON);
if (isLButton > 1) {
SendMessage(hMouseClickWin, MYWM_APPMOUSE, pStruct->pt.x, pStruct->pt.y);
}
}
return CallNextHookEx(hMouseClickHook, nCode, wParam, lParam);
}
}
/*
* Class: com_jeans_trayicon_WindowsTrayIcon
* Method: initHook
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_initHook(JNIEnv *, jclass) {
hMouseClickEna = 0;
hMouseClickWin = my_hDlg;
if (hMouseClickHook == NULL) {
RemoveHook();
hMouseClickHook = SetWindowsHookEx(WH_MOUSE, (HOOKPROC)WinTrayMouseClickHook, g_hinst, 0);
if (hMouseClickHook == NULL) {
last_error = TRAY_ERRHOOK;
}
}
}
JNIEXPORT void JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_setMouseHookEnabled(JNIEnv *, jclass, jint enable) {
hMouseClickEna = enable;
}
/*
* Class: com_jeans_trayicon_WindowsTrayIcon
* Method: getWindowsVersionString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_getWindowsVersionString(JNIEnv *env, jclass) {
int version_int;
jstring result = NULL;
char version_string[300];
GetOSName(version_string, &version_int);
int len = strlen(version_string);
jchar* data = new jchar[len+1];
for (int i = 0; i < len; i++) {
data[i] = (jchar)version_string[i];
}
data[len] = 0;
if (data != NULL) {
result = env->NewString((const jchar*)data, (long int)len);
delete data;
}
return result;
}
/*
* Class: com_jeans_trayicon_WindowsTrayIcon
* Method: getWindowsVersion
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_getWindowsVersion(JNIEnv *, jclass) {
int version_int;
char version_string[300];
GetOSName(version_string, &version_int);
return (jint)version_int;
}
/*
* Class: jeans_trayicon_WindowsTrayIcon
* Method: isRunning
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT jboolean JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_isRunning(JNIEnv *env, jclass, jstring wndName) {
const char *cWndName = env->GetStringUTFChars(wndName, 0);
// Find out if there's a hidden window with the given title
HWND mHwnd = FindWindow(szAppName, cWndName);
env->ReleaseStringUTFChars(wndName, cWndName);
// If there is, another instance of our app is already running
return mHwnd != NULL;
}
/*
* Class: jeans_trayicon_WindowsTrayIcon
* Method: sendWindowsMessage
* Signature: (Ljava/lang/String;J)J
*/
JNIEXPORT jint JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_sendWindowsMessage
(JNIEnv *env, jclass, jstring wndName, jint lParam) {
const char *cWndName = env->GetStringUTFChars(wndName, 0);
// Find hidden window handle by name
HWND mHwnd = FindWindow(szAppName, cWndName);
env->ReleaseStringUTFChars(wndName, cWndName);
// If the window exists, send out our message and wait for return value
if (mHwnd == NULL) return -1;
else return SendMessage(mHwnd, MYWM_APPTALK, 0, lParam);
}
/*
* Class: jeans_trayicon_WindowsTrayIcon
* Method: termTrayIcon
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_termTrayIcon(JNIEnv *env, jclass) {
cleanUpExit(env);
}
/*
* Class: jeans_trayicon_WindowsTrayIcon
* Method: initPopup
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_initPopup
(JNIEnv *env, jclass, jint id_num, jint nbLevels) {
// Icon id valid?
if (tray_icons[id_num].used == FALSE) {
last_error = TRAY_WRONGICONID;
return;
}
// Free previous allocated menu
freeMenu(id_num);
if (nbLevels != -1) {
// Create new popup menu with given depth
tray_icons[id_num].popup = new PopupMenu(nbLevels);
}
}
/*
* Class: jeans_trayicon_WindowsTrayIcon
* Method: checkPopup
* Signature: (IIZ)V
*/
JNIEXPORT void JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_checkPopup
(JNIEnv *env, jclass, jint id_num, jint menuId, jboolean selected) {
// Get main popup menu handle of icon
PopupMenu *popup = tray_icons[id_num].popup;
if (popup != NULL) {
HMENU menu = popup->getMenu(0);
// Add check mark or remove check mark
UINT how = selected ?
MF_BYCOMMAND | MF_CHECKED :
MF_BYCOMMAND | MF_UNCHECKED;
// Check the menu item by command id (menuId)
CheckMenuItem(menu, menuId, how);
}
}
/*
* Class: jeans_trayicon_WindowsTrayIcon
* Method: enablePopup
* Signature: (IIZ)V
*/
JNIEXPORT void JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_enablePopup
(JNIEnv *env, jclass, jint id_num, jint menuId, jboolean enable) {
// Get main popup menu handle of icon
PopupMenu *popup = tray_icons[id_num].popup;
if (popup != NULL) {
HMENU menu = popup->getMenu(0);
// Enable or disable item
UINT how = enable ?
MF_BYCOMMAND | MF_ENABLED :
MF_BYCOMMAND | MF_GRAYED;
// Check the menu item by command id (menuId)
EnableMenuItem(menu, menuId, how);
}
}
/*
* Class: jeans_trayicon_WindowsTrayIcon
* Method: modifyPopup
* Signature: (IIIZ)V
*/
JNIEXPORT void JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_modifyPopup
(JNIEnv *env, jclass, jint id_num, jint menuId, jint what, jboolean state) {
// Get main popup menu handle of icon
PopupMenu *popup = tray_icons[id_num].popup;
if (popup != NULL) {
MENUITEMINFO info;
HMENU menu = popup->getMenu(0);
info.cbSize = sizeof(MENUITEMINFO);
info.fMask = MIIM_STATE;
GetMenuItemInfo(menu, menuId, FALSE, &info);
switch (what) {
case POPUP_MODE_ENABLE:
info.fState &= (MFS_DISABLED | MFS_ENABLED | MFS_GRAYED) ^ ((UINT)-1);
if (state) info.fState |= MFS_ENABLED; else info.fState |= MFS_GRAYED;
break;
case POPUP_MODE_CHECK:
info.fState &= (MFS_CHECKED | MFS_UNCHECKED) ^ ((UINT)-1);
if (state) info.fState |= MFS_CHECKED; else info.fState |= MFS_UNCHECKED;
break;
case POPUP_MODE_DEFAULT:
info.fState &= (MFS_DEFAULT) ^ ((UINT)-1);
if (state) info.fState |= MFS_DEFAULT;
break;
}
info.fMask = MIIM_STATE;
SetMenuItemInfo(menu, menuId, FALSE, &info);
}
}
/*
* Class: com_jeans_trayicon_WindowsTrayIcon
* Method: flashWindowImpl
* Signature: (Ljava/lang/String;III)Z
*/
JNIEXPORT jboolean JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_flashWindowImpl(JNIEnv *env, jclass, jstring windowTitle, jint flags, jint count, jint timeout) { HMODULE hShell = LoadLibrary("User32.dll");
if (hShell == NULL) {
return FALSE;
}
P_FLASHWINDOWEX proc = (P_FLASHWINDOWEX)GetProcAddress(hShell, "FlashWindowEx");
if (proc == NULL) {
FreeLibrary(hShell);
return FALSE;
}
const char* cWindowTitle = env->GetStringUTFChars(windowTitle, 0);
HWND hwnd = FindWindow(NULL, cWindowTitle);
env->ReleaseStringUTFChars(windowTitle, cWindowTitle);
MY_FLASHWINFO fi;
fi.cbSize = sizeof(fi);
fi.hwnd = hwnd;
fi.dwFlags = flags;
fi.uCount = count;
fi.dwTimeout = timeout;
proc(&fi);
FreeLibrary(hShell);
return TRUE;
}
void TrayAppendMenu(JNIEnv* env, HMENU hMenu, unsigned long type, UINT id, jstring mname) {
int len = env->GetStringLength(mname);
jchar* m_mname = new jchar[len+1];
const jchar* j_mname = env->GetStringChars(mname, 0);
convertUnicodeString(j_mname, m_mname, len);
env->ReleaseStringChars(mname, j_mname);
if (bUseUnicode == 0) {
char* a_mname = convertUnicodeANSI(m_mname);
AppendMenu(hMenu, type, id, a_mname);
delete a_mname;
} else {
AppendMenuW(hMenu, type, id, (const WCHAR*)m_mname);
}
delete m_mname;
}
/*
* Class: jeans_trayicon_WindowsTrayIcon
* Method: subPopup
* Signature: (IILjava/lang/String;I)I
*/
JNIEXPORT jint JNICALL Java_com_jeans_trayicon_WindowsTrayIcon_subPopup
(JNIEnv *env, jclass, jint id_num, jint level, jstring menuName, jint type, jint extra) {
// Return a menu id for the new submenu item
jint id = -1;
// Icon id valid?
if (tray_icons[id_num].used == FALSE) {
last_error = TRAY_WRONGICONID;
return -1;
}
// Popup valid? (use initPopup())
if (tray_icons[id_num].popup != NULL) {
PopupMenu *popup = tray_icons[id_num].popup;
if (type == POPUP_TYPE_INIT_LEVEL || type == POPUP_TYPE_DONE_LEVEL) {
// Add new level to the popup menu (= new submenu)
switch (type) {
case POPUP_TYPE_INIT_LEVEL:
// Marks the first item of the new level
popup->initMenu(level);
break;
case POPUP_TYPE_DONE_LEVEL:
// Marks the last item of the current level
if (level > 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -