📄 tray.cpp
字号:
HWND hWndTrayWnd = FindTrayWnd(); if(hWndTrayWnd == NULL) return FALSE; GetWindowRect(hWndTrayWnd, rect); // Get the Rectangle of the Tray Icon owner window. // Check how many buttons there are - should be more than 0 int iButtonsCount = SendMessage(hWndTrayWnd, TB_BUTTONCOUNT, 0, 0); // Get an ID of the parent process for system tray DWORD dwTrayProcessID = -1; GetWindowThreadProcessId(hWndTrayWnd, &dwTrayProcessID); if(dwTrayProcessID <= 0) { return FALSE; } HANDLE hTrayProc = OpenProcess(PROCESS_ALL_ACCESS, 0, dwTrayProcessID); if(hTrayProc == NULL) { return FALSE; } LPVOID lpData = VirtualAllocEx(hTrayProc, NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE); if( lpData == NULL || iButtonsCount < 1 ) { CloseHandle(hTrayProc); return FALSE; } BOOL bIconFound = FALSE; for(int iButton=0; iButton<iButtonsCount; iButton++) { // Read TBUTTON information about each button in a task bar of tray DWORD dwBytesRead = -1; TBBUTTON buttonData; SendMessage(hWndTrayWnd, TB_GETBUTTON, iButton, (LPARAM)lpData); ReadProcessMemory(hTrayProc, lpData, &buttonData, sizeof(TBBUTTON), &dwBytesRead); if(dwBytesRead < sizeof(TBBUTTON)) { continue; } // Read extra data associated with each button: there will be a HWND of the window that created an icon and icon ID DWORD dwExtraData[2] = { 0,0 }; ReadProcessMemory(hTrayProc, (LPVOID)buttonData.dwData, dwExtraData, sizeof(dwExtraData), &dwBytesRead); if(dwBytesRead < sizeof(dwExtraData)) { continue; } HWND hWndOfIconOwner = (HWND) dwExtraData[0]; int iIconId = (int) dwExtraData[1]; if(hWndOfIconOwner != hWnd || iIconId != iconID) { continue; } // Found our icon - in WinXP it could be hidden - let's check it: if( buttonData.fsState & TBSTATE_HIDDEN ) { break; } // Convert the point from the owner window to screen. SendMessage(hWndTrayWnd, TB_GETITEMRECT, iButton, (LPARAM)lpData); ReadProcessMemory(hTrayProc, lpData, rect, sizeof(RECT), &dwBytesRead); if(dwBytesRead < sizeof(RECT)) { continue; } MapWindowPoints(hWndTrayWnd, NULL, (LPPOINT)rect, 2); bIconFound = TRUE; break; } VirtualFreeEx(hTrayProc, lpData, NULL, MEM_RELEASE); CloseHandle(hTrayProc); return TRUE;}DWORD GetDllVersion(LPCTSTR lpszDllName){ HINSTANCE hinstDll; DWORD dwVersion = 0; hinstDll = LoadLibrary(lpszDllName); if(hinstDll) { DLLGETVERSIONPROC pDllGetVersion; pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion"); /* Because some DLLs might not implement this function, you must test for it explicitly. Depending on the particular DLL, the lack of a DllGetVersion function can be a useful indicator of the version. */ if(pDllGetVersion) { DLLVERSIONINFO dvi; HRESULT hr; ZeroMemory(&dvi, sizeof(dvi)); dvi.cbSize = sizeof(dvi); hr = (*pDllGetVersion)(&dvi); if(SUCCEEDED(hr)) { dwVersion = dvi.dwMajorVersion; } } FreeLibrary(hinstDll); } return dwVersion;}/************************************************************************* WCustomCursor native methods*/JNIEXPORT jintArray JNICALL Java_org_jdesktop_jdic_tray_internal_impl_WinTrayIconService_getRectangleOnScreen(JNIEnv *env , jobject obj, jint id) { jintArray result = env->NewIntArray(4); RECT rect; GetTrayIconRect(messageWindow, id, &rect); jint rect_int[] = { rect.left, rect.top, rect.right, rect.bottom }; env->SetIntArrayRegion(result, 0, 4, rect_int); return result;}JNIEXPORT jlong JNICALL Java_org_jdesktop_jdic_tray_internal_impl_WinTrayIconService_createIconIndirect( JNIEnv *env, jobject self, jintArray intRasterData, jbyteArray andMask, jint nSS, jint nW, jint nH, jint xHotSpot, jint yHotSpot){ int length = env->GetArrayLength(andMask); jbyte *andMaskPtr = new jbyte[length]; env->GetByteArrayRegion(andMask, 0, length, andMaskPtr); HBITMAP hMask = ::CreateBitmap(nW, nH, 1, 1, (BYTE *)andMaskPtr); ::GdiFlush(); delete(andMaskPtr); jint *intRasterDataPtr = NULL; HBITMAP hColor = NULL; try { intRasterDataPtr = (jint *)env->GetPrimitiveArrayCritical(intRasterData, 0); hColor = create_BMP(NULL, (int *)intRasterDataPtr, nSS, nW, nH); } catch (...) { if (intRasterDataPtr != NULL) { env->ReleasePrimitiveArrayCritical(intRasterData, intRasterDataPtr, 0); } throw; } env->ReleasePrimitiveArrayCritical(intRasterData, intRasterDataPtr, 0); intRasterDataPtr = NULL; HICON hIcon = NULL; if (hMask && hColor) { ICONINFO icnInfo; memset(&icnInfo, 0, sizeof(ICONINFO)); icnInfo.hbmMask = hMask; icnInfo.hbmColor = hColor; icnInfo.fIcon = FALSE; icnInfo.xHotspot = xHotSpot; icnInfo.yHotspot = yHotSpot; hIcon = ::CreateIconIndirect(&icnInfo); destroy_BMP(hColor); destroy_BMP(hMask); } return (jlong) hIcon; }JNIEXPORT void JNICALL Java_org_jdesktop_jdic_tray_internal_impl_WinTrayIconService_deleteHIcon(JNIEnv *env , jobject obj, jlong icon){ DestroyIcon((HICON)icon);}char* ConvertJByteArray(JNIEnv *env, jbyteArray arr ){ int len = env->GetArrayLength(arr); if(len == 0) return NULL; char *temp = (char *)env->GetByteArrayElements(arr, 0); char *buffer = (char *)malloc(len+1); strncpy(buffer, temp, len); *(buffer+len)='\0'; env->ReleaseByteArrayElements(arr, (signed char*)temp, 0); return buffer;}JNIEXPORT void JNICALL Java_org_jdesktop_jdic_tray_internal_impl_WinTrayIconService_createIcon(JNIEnv *env , jobject obj, jlong icon, jint id, jbyteArray tooltip){ char *buffer = ConvertJByteArray(env, tooltip); TrayMessage(messageWindow,NIM_ADD,id,(HICON)icon, buffer); free(buffer);}JNIEXPORT void JNICALL Java_org_jdesktop_jdic_tray_internal_impl_WinTrayIconService_updateNativeIcon(JNIEnv *env , jobject obj, jlong icon, jint id, jbyteArray tooltip){ char *buffer = ConvertJByteArray(env, tooltip); TrayMessage(messageWindow,NIM_MODIFY,id,(HICON)icon,buffer); free(buffer);}JNIEXPORT void JNICALL Java_org_jdesktop_jdic_tray_internal_impl_WinTrayIconService_showBalloonMessage(JNIEnv *env , jobject obj, jlong icon, jint id, jbyteArray title, jbyteArray message, jint type){ NOTIFYICONDATA tnd; DWORD dll_version = GetDllVersion("Shell32.dll"); int tnd_size = dll_version >= 5 ? sizeof(tnd) : NOTIFYICONDATA_V1_SIZE; ::ZeroMemory(&tnd, tnd_size); tnd.cbSize = tnd_size; tnd.hWnd = messageWindow; tnd.uID = id; tnd.uFlags = NIF_INFO; switch (type) { case 0 : tnd.dwInfoFlags = NIIF_INFO; break; case 1 : tnd.dwInfoFlags = NIIF_ERROR; break; case 2 : tnd.dwInfoFlags = NIIF_WARNING; break; case 3 : tnd.dwInfoFlags = NIIF_NONE; } tnd.hIcon = (HICON)icon; char *buffer = ConvertJByteArray(env, title); if (buffer) { lstrcpyn(tnd.szInfoTitle, buffer, ARRAYSIZE(tnd.szInfoTitle)); } free(buffer); buffer = ConvertJByteArray(env, message); if (buffer) { lstrcpyn(tnd.szInfo, buffer, ARRAYSIZE(tnd.szInfo)); } free(buffer); Shell_NotifyIcon(NIM_MODIFY, &tnd);}JNIEXPORT void JNICALL Java_org_jdesktop_jdic_tray_internal_impl_WinTrayIconService_removeIcon(JNIEnv *env , jclass klass, jint id) { TrayMessage(messageWindow,NIM_DELETE,id,NULL,NULL);}JNIEXPORT void JNICALL Java_org_jdesktop_jdic_tray_internal_impl_DisplayThread_initTray(JNIEnv *env, jclass klass) { if (!inited) { if (!Initialize(env)) { return; } inited = 1; }}JNIEXPORT void JNICALL Java_org_jdesktop_jdic_tray_internal_impl_DisplayThread_eventLoop(JNIEnv *env, jclass klass) { MSG msg; while(GetMessage(&msg, NULL,0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -