opensc-notify: add Exit button to tray icon

This commit is contained in:
Frank Morgner 2018-07-26 14:44:20 +02:00
parent 4a3a3e5df2
commit 0f1fdb7872
4 changed files with 79 additions and 22 deletions

View File

@ -167,6 +167,9 @@ WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nShowC
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessage(&msg); DispatchMessage(&msg);
} }
if (msg.message == WM_COMMAND && LOWORD(msg.wParam) == WMAPP_EXIT) {
break;
}
} }
CloseHandle(hThread); CloseHandle(hThread);

View File

@ -75,30 +75,55 @@ void sc_notify_close(void)
// {83C35893-99C6-4600-BFDB-45925C53BDD9} // {83C35893-99C6-4600-BFDB-45925C53BDD9}
static const GUID myGUID = { 0x83c35893, 0x99c6, 0x4600, { 0xbf, 0xdb, 0x45, 0x92, 0x5c, 0x53, 0xbd, 0xd9 } }; static const GUID myGUID = { 0x83c35893, 0x99c6, 0x4600, { 0xbf, 0xdb, 0x45, 0x92, 0x5c, 0x53, 0xbd, 0xd9 } };
HINSTANCE sc_notify_instance = NULL; HINSTANCE sc_notify_instance = NULL;
HWND hwndNotification = NULL; HWND sc_notify_hwnd = NULL;
BOOL delete_icon = TRUE; BOOL delete_icon = TRUE;
#define IDI_SMARTCARD 102 #define IDI_SMARTCARD 102
UINT const WMAPP_NOTIFYCALLBACK = WM_APP + 1; #define WMAPP_NOTIFYCALLBACK (WM_APP + 1)
static BOOL RestoreTooltip(); static BOOL RestoreTooltip();
void ShowContextMenu(HWND hwnd, POINT pt);
// we need commctrl v6 for LoadIconMetric() // we need commctrl v6 for LoadIconMetric()
#include <commctrl.h> #include <commctrl.h>
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{ {
if ((message == WM_DESTROY) switch (message) {
|| (message == WMAPP_NOTIFYCALLBACK case WM_COMMAND:
&& (LOWORD(lParam) == NIN_BALLOONTIMEOUT {
|| LOWORD(lParam) == NIN_BALLOONUSERCLICK))) { int const wmId = LOWORD(wParam);
#if 0 // Parse the menu selection:
DeleteNotificationIcon(); switch (wmId)
#else {
case WMAPP_EXIT:
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
break;
case WMAPP_NOTIFYCALLBACK:
switch (LOWORD(lParam)) {
case NIN_BALLOONTIMEOUT:
case NIN_BALLOONUSERCLICK:
RestoreTooltip(); RestoreTooltip();
#endif break;
return TRUE;
case WM_CONTEXTMENU:
{
POINT const pt = { LOWORD(wParam), HIWORD(wParam) };
ShowContextMenu(hwnd, pt);
}
break;
}
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
} }
return DefWindowProc(hwnd, message, wParam, lParam); return 0;
} }
static const char* lpszClassName = "NOTIFY_CLASS"; static const char* lpszClassName = "NOTIFY_CLASS";
@ -109,13 +134,14 @@ static BOOL AddNotificationIcon(void)
TCHAR path[MAX_PATH]={0}; TCHAR path[MAX_PATH]={0};
BOOL r; BOOL r;
hwndNotification = create_invisible_window(lpszClassName, WndProc, sc_notify_instance); sc_notify_hwnd = create_invisible_window(lpszClassName, WndProc,
if (!hwndNotification) { sc_notify_instance);
if (!sc_notify_hwnd) {
return FALSE; return FALSE;
} }
nid.cbSize = sizeof(NOTIFYICONDATA); nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hwndNotification; nid.hWnd = sc_notify_hwnd;
// add the icon, setting the icon, tooltip, and callback message. // add the icon, setting the icon, tooltip, and callback message.
// the icon will be identified with the GUID // the icon will be identified with the GUID
nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE | NIF_SHOWTIP | NIF_GUID; nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE | NIF_SHOWTIP | NIF_GUID;
@ -140,9 +166,10 @@ static BOOL AddNotificationIcon(void)
} }
r = Shell_NotifyIcon(NIM_ADD, &nid); r = Shell_NotifyIcon(NIM_ADD, &nid);
if (TRUE == r) {
nid.uVersion = NOTIFYICON_VERSION_4; nid.uVersion = NOTIFYICON_VERSION_4;
r &= Shell_NotifyIcon(NIM_SETVERSION, &nid); r = Shell_NotifyIcon(NIM_SETVERSION, &nid);
}
return r; return r;
} }
@ -162,8 +189,9 @@ static BOOL DeleteNotificationIcon(void)
r = Shell_NotifyIcon(NIM_DELETE, &nid); r = Shell_NotifyIcon(NIM_DELETE, &nid);
r &= delete_invisible_window(hwndNotification, lpszClassName, r &= delete_invisible_window(sc_notify_hwnd, lpszClassName,
sc_notify_instance); sc_notify_instance);
sc_notify_hwnd = NULL;
return r; return r;
} }
@ -180,6 +208,30 @@ static BOOL RestoreTooltip()
return Shell_NotifyIcon(NIM_MODIFY, &nid); return Shell_NotifyIcon(NIM_MODIFY, &nid);
} }
void ShowContextMenu(HWND hwnd, POINT pt)
{
HMENU hMenu;
hMenu=CreatePopupMenu();
if (hMenu) {
AppendMenu(hMenu, MF_STRING, WMAPP_EXIT, "E&xit");
// our window must be foreground before calling TrackPopupMenu or the menu will not disappear when the user clicks away
SetForegroundWindow(hwnd);
// respect menu drop alignment
UINT uFlags = TPM_RIGHTBUTTON;
if (GetSystemMetrics(SM_MENUDROPALIGNMENT) != 0) {
uFlags |= TPM_RIGHTALIGN;
} else {
uFlags |= TPM_LEFTALIGN;
}
TrackPopupMenuEx(hMenu, uFlags, pt.x, pt.y, hwnd, NULL);
}
}
static void notify_shell(struct sc_context *ctx, static void notify_shell(struct sc_context *ctx,
const char *title, const char *text, LPCTSTR icon_path, int icon_index) const char *title, const char *text, LPCTSTR icon_path, int icon_index)
{ {

View File

@ -39,6 +39,8 @@ void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr,
* initialized before calling `sc_notify_init()`. If not initialized, we're * initialized before calling `sc_notify_init()`. If not initialized, we're
* using the HINSTANCE of the EXE */ * using the HINSTANCE of the EXE */
extern HINSTANCE sc_notify_instance; extern HINSTANCE sc_notify_instance;
/* This is the message created when the user clicks on "exit". */
#define WMAPP_EXIT (WM_APP + 2)
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus