📄 trayicon.cpp
字号:
case WM_PAINT:
case WM_MOUSEMOVE:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MOVE:
case WM_SIZE:
case WM_LBUTTONDOWN:
case WM_KEYDOWN:
break;
default:
if (iMessage == g_TaskbarRestart) {
if (tray_icon.visible == TRUE) {
showTrayIcon();
}
}
else return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
}
return 0L ;
}
// Create the hidden window to receive the icon's mouse messages
HWND MakeHWND(HINSTANCE hInst) {
HWND hWnd;
// Create window class
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = (WNDPROC) WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInst;
wndclass.hIcon = LoadIcon(hInst, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass)) return NULL;
// Create window
hWnd = CreateWindow(szAppName, szWndName, WS_OVERLAPPEDWINDOW,
0,0,100,100,
NULL, NULL, hInst, NULL);
return hWnd;
}
// Remove the hidden window (on app closing)
void RemoveHWND() {
// Close dial
if (my_hDlg != NULL) {
// Create wait event
exit_event = CreateEvent(NULL,FALSE,FALSE,NULL);
// Send destroy messages
PostMessage(my_hDlg, WM_NCDESTROY, 0, 0);
PostMessage(my_hDlg, WM_DESTROY, 0, 0);
// Wait for window to destroy
WaitForSingleObject(exit_event,10000);
CloseHandle(exit_event);
exit_event = NULL;
}
// Free handle
if (wait_event != NULL) {
CloseHandle(wait_event);
wait_event = NULL;
}
}
// The thread proc that creates the hidden window an listens for messages
void DialogThread(void *dummy) {
MSG msg;
// Create window
my_hDlg = MakeHWND(g_hinst);
// Signal wait event
if (wait_event != NULL) SetEvent(wait_event);
// Hide window
ShowWindow(my_hDlg, SW_HIDE);
UpdateWindow(my_hDlg);
// Process messages
while (GetMessage(&msg, NULL, 0, 0)){
TranslateMessage(&msg) ;
DispatchMessage(&msg) ;
}
// Unregister window class
UnregisterClass(szAppName, g_hinst);
// Signal exit event (so app knows hidden window is destroyed)
if (exit_event != NULL) SetEvent(exit_event);
}
// New icon resource with no bitmap and zero size
IconData::IconData() {
wd = hi = 0;
hBitmapAND = hBitmapXOR = NULL;
}
// Destroy icon resources (and and xor bitmap)
IconData::~IconData() {
if (hBitmapAND != NULL) DeleteObject(hBitmapAND);
if (hBitmapXOR != NULL) DeleteObject(hBitmapXOR);
}
// Make icon using and and xor bitmaps (returns handle to new icon)
HICON IconData::makeIcon(HINSTANCE hInst) {
ICONINFO ii;
ii.fIcon = TRUE;
ii.xHotspot = 0;
ii.yHotspot = 0;
ii.hbmMask = hBitmapAND;
ii.hbmColor = hBitmapXOR;
return CreateIconIndirect(&ii);
}
// Set icon's image data (pixel array, width, height)
int IconData::setData(unsigned long *data, int wd, int hi) {
int res = -1;
// Set size
this->wd = wd;
this->hi = hi;
// Clean up if setData was called before
if (hBitmapAND != NULL) DeleteObject(hBitmapAND);
if (hBitmapXOR != NULL) DeleteObject(hBitmapXOR);
// To protect against java sending a dud image
if (wd > 0 && hi > 0) {
// Set up the header for creating our 24 bit colour bitmap
BITMAPINFOHEADER bih;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = wd;
bih.biHeight = hi;
bih.biPlanes = 1;
bih.biBitCount = 24;
bih.biCompression = BI_RGB;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
// Create memory DC
HDC hdc = CreateCompatibleDC(NULL);
// Make the 24-bit DIB
hBitmapXOR = CreateDIBSection(hdc, (LPBITMAPINFO)&bih, DIB_RGB_COLORS, (LPVOID *)NULL, NULL, 0);
// Select it into the DC so we can draw onto it
SelectObject(hdc, hBitmapXOR);
// Calloc memory to be used to create a monochrome bitmask
long size = (wd*hi/8)+1;
unsigned char *andMask = new unsigned char[size];
if (andMask != NULL) {
for (int i = 0; i < size; i++) andMask[i] = 0;
// Loop through the given pixels and draw onto the colour and mono bitmaps
unsigned long pixel;
unsigned char red, green, blue, alpha;
for (int row = 0; row < hi; row++) {
for (int col = 0; col < wd; col++) {
pixel = data[(row*wd)+col];
alpha = (unsigned char)((pixel >> 24) & 0x000000ff);
red = (unsigned char)((pixel >> 16) & 0x000000ff);
green = (unsigned char)((pixel >> 8) & 0x000000ff);
blue = (unsigned char)( pixel & 0x000000ff);
if (alpha == 0xFF) {
// Pixel is not transparent - update xor bitmap
SetPixel(hdc, col, row, RGB(red, green, blue));
} else {
// Pixel is transparent - update and mask
int p = (row*wd) + col;
andMask[p/8] |= 1 << (7-(p%8));
SetPixel(hdc, col, row, RGB(0, 0, 0));
}
}
}
// Create the monochrome bitmask with transparency info
hBitmapAND = CreateBitmap(wd, hi, 1, 1, andMask);
// Free memory
delete andMask;
// Return code
res = 0;
}
// Release the memory DC
DeleteDC(hdc);
}
// Error on zero size icons
return res;
}
///////////////--------------JNI Method-----------//////////////////////////////////////////////////////////
JNIEXPORT void JNICALL Java_TrayIconUtil_initTrayIcon
(JNIEnv * env, jobject jThis, jobject ic_cls,jstring wndName, jint){
jniEnv_current = env;
jobject_current = jThis;
jobject globalWinTrayClass = env->NewGlobalRef(ic_cls);
if (globalWinTrayClass != 0) {
if (tray_icon.globalClass != 0)
env->DeleteGlobalRef(tray_icon.globalClass);
tray_icon.globalClass = globalWinTrayClass;
}
env->GetJavaVM(&hJavaVM);
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);
// Popup invisible dummy window
if (g_hinst != NULL) {
wait_event = CreateEvent(NULL,FALSE,FALSE,NULL);
_beginthread(DialogThread, 0, NULL );
}
}
}
JNIEXPORT void JNICALL Java_TrayIconUtil_setTrayIconTip
(JNIEnv *env, jobject, jstring tip){
const char *tooltip = env->GetStringUTFChars(tip, 0);
int len = strlen(tooltip);
if (tray_icon.tooltip != NULL)
delete tray_icon.tooltip;
tray_icon.tooltip = new char[len+1];
strcpy(tray_icon.tooltip, tooltip);
env->ReleaseStringUTFChars(tip, tooltip);
updateIcon();
}
JNIEXPORT void JNICALL Java_TrayIconUtil_setTrayIconData
(JNIEnv *env, jobject, jint wd, jint hi, jintArray array){
if (g_hinst == NULL) {
return;
}
// Get array length and elements
jsize len = env->GetArrayLength(array);
jint *body = env->GetIntArrayElements(array, 0);
// Allocate data for icon bitmap and store the given pixel array
IconData *data = new IconData();
if (data != NULL && data->setData((unsigned long *)body, wd, hi) != -1) {
IconData *olddata = tray_icon.icon;
tray_icon.icon = data;
updateIcon();
if (olddata != NULL) delete olddata;
} else {
delete data;
}
// Release java array
env->ReleaseIntArrayElements(array, body, 0);
}
JNIEXPORT void JNICALL Java_TrayIconUtil_showTrayIcon
(JNIEnv * env, jobject){
showTrayIcon();
}
JNIEXPORT void JNICALL Java_TrayIconUtil_closeTrayIcon
(JNIEnv * env, jobject){
makeInvisible();
}
void showTrayIcon() {
if (tray_icon.visible == FALSE) {
if (tray_icon.icon != NULL) {
HICON icon = tray_icon.icon->makeIcon(g_hinst);
if (icon != NULL) {
TrayMessage(my_hDlg, NIM_ADD,icon, tray_icon.tooltip);
tray_icon.visible = TRUE;
}/* else {
printf("TRAY_NOTENOUGHMEM\n");
} */
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -