mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
246 lines
6.4 KiB
246 lines
6.4 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// TaskMan - NT TaskManager
|
|
// Copyright (C) Microsoft
|
|
//
|
|
// File: trayicon.CPP
|
|
//
|
|
// History: Jan-27-96 DavePl Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "precomp.h"
|
|
|
|
// Queue for messages to be processed by the worker thread
|
|
|
|
#define MSG_QUEUE_SIZE 5
|
|
CTrayNotification * g_apQueue[MSG_QUEUE_SIZE] = { NULL };
|
|
CRITICAL_SECTION g_CSTrayThread;
|
|
UINT g_cQueueSize = 0;
|
|
|
|
/*++ DeliverTrayNotification (MAIN THREAD CODE)
|
|
|
|
Routine Description:
|
|
|
|
Adds a tray notification block to the list of things to be done
|
|
by the tray notify worker thread
|
|
|
|
Arguments:
|
|
|
|
pNot - The CTrayNotification object to be queued
|
|
|
|
Returns:
|
|
|
|
TRUE - Message added to queue
|
|
FALSE - Queue full
|
|
|
|
Revision History:
|
|
|
|
Mar-27-95 Davepl Created
|
|
*/
|
|
|
|
BOOL DeliverTrayNotification(CTrayNotification * pNot)
|
|
{
|
|
EnterCriticalSection(&g_CSTrayThread);
|
|
|
|
// If no worker thread is running, or queue is full, fail
|
|
|
|
if (0 == g_idTrayThread || g_cQueueSize == MSG_QUEUE_SIZE)
|
|
{
|
|
LeaveCriticalSection(&g_CSTrayThread);
|
|
return FALSE;
|
|
}
|
|
|
|
// Add notification to the queue and post a message to the
|
|
// worker thread
|
|
|
|
g_apQueue[g_cQueueSize++] = pNot;
|
|
PostThreadMessage(g_idTrayThread, PM_NOTIFYWAITING, 0, 0);
|
|
|
|
LeaveCriticalSection(&g_CSTrayThread);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*++ TrayThreadMessageLoop (WORKER THREAD CODE)
|
|
|
|
Routine Description:
|
|
|
|
Waits for messages telling it a notification packet is ready
|
|
in the queue, then dispatches it to the tray
|
|
|
|
Mar-27-95 Davepl Created
|
|
|
|
--*/
|
|
|
|
DWORD TrayThreadMessageLoop(LPVOID)
|
|
{
|
|
MSG msg;
|
|
|
|
while(GetMessage(&msg, NULL, 0, 0))
|
|
{
|
|
switch(msg.message)
|
|
{
|
|
case PM_NOTIFYWAITING:
|
|
{
|
|
// Take a message out of the queue
|
|
|
|
EnterCriticalSection(&g_CSTrayThread);
|
|
|
|
ASSERT(g_cQueueSize);
|
|
CTrayNotification * pNot = g_apQueue[0];
|
|
for (UINT i = 0; i < g_cQueueSize; i++)
|
|
{
|
|
g_apQueue[i] = g_apQueue[i+1];
|
|
}
|
|
g_cQueueSize--;
|
|
|
|
LeaveCriticalSection(&g_CSTrayThread);
|
|
|
|
// Give it to the tray to process. If it blocks, our queue
|
|
// will fill, but taskman itself won't hang
|
|
|
|
Tray_NotifyIcon(pNot->m_hWnd,
|
|
pNot->m_uCallbackMessage,
|
|
pNot->m_Message,
|
|
pNot->m_hIcon,
|
|
pNot->m_szTip);
|
|
|
|
delete pNot;
|
|
|
|
break;
|
|
}
|
|
|
|
case PM_QUITTRAYTHREAD:
|
|
{
|
|
// Delete all messages pending
|
|
|
|
EnterCriticalSection(&g_CSTrayThread);
|
|
|
|
while (g_cQueueSize)
|
|
{
|
|
delete g_apQueue[g_cQueueSize - 1];
|
|
g_cQueueSize--;
|
|
}
|
|
|
|
g_idTrayThread = 0;
|
|
LeaveCriticalSection(&g_CSTrayThread);
|
|
DeleteCriticalSection(&g_CSTrayThread);
|
|
|
|
PostQuitMessage(0);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
ASSERT(0 && "Taskman tray worker got unexpected message");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*++ Tray_NotifyIcon (WORKER THREAD CODE)
|
|
|
|
Routine Description:
|
|
|
|
Handles adding, updating, etc., of icon on the tray
|
|
|
|
Arguments:
|
|
|
|
hWnd - icon owner
|
|
uCallbackMessage - message ID to be used for callback
|
|
Message - argument to Shell_NotifyIcon (NIM_ADD, NIM_DELETE, etc)
|
|
hIcon - Handle to the icon
|
|
lpTip - tooltip text for the icon
|
|
|
|
Revision History:
|
|
|
|
Jan-27-95 Davepl Created
|
|
|
|
--*/
|
|
|
|
void Tray_NotifyIcon(HWND hWnd,
|
|
UINT uCallbackMessage,
|
|
DWORD Message,
|
|
HICON hIcon,
|
|
LPCTSTR lpTip)
|
|
{
|
|
NOTIFYICONDATA NotifyIconData;
|
|
|
|
NotifyIconData.cbSize = sizeof(NOTIFYICONDATA);
|
|
NotifyIconData.uID = uCallbackMessage;
|
|
NotifyIconData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
|
|
NotifyIconData.uCallbackMessage = uCallbackMessage;
|
|
|
|
NotifyIconData.hWnd = hWnd;
|
|
NotifyIconData.hIcon = hIcon;
|
|
|
|
if (lpTip)
|
|
{
|
|
lstrcpyn(NotifyIconData.szTip, lpTip, ARRAYSIZE(NotifyIconData.szTip));
|
|
}
|
|
else
|
|
{
|
|
NotifyIconData.szTip[0] = 0;
|
|
}
|
|
|
|
Shell_NotifyIcon(Message, &NotifyIconData);
|
|
}
|
|
|
|
/*++ Tray_Notify (MAIN THREAD CODE)
|
|
|
|
Routine Description:
|
|
|
|
Handles notifications sent by the tray
|
|
|
|
Revision History:
|
|
|
|
Jan-27-95 Davepl Created
|
|
|
|
--*/
|
|
|
|
void Tray_Notify(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (lParam)
|
|
{
|
|
case WM_LBUTTONDBLCLK:
|
|
ShowRunningInstance();
|
|
break;
|
|
|
|
case WM_RBUTTONDOWN:
|
|
{
|
|
HMENU hPopup = LoadPopupMenu(g_hInstance, IDR_TRAYMENU);
|
|
|
|
// Display the tray icons context menu at the current cursor location
|
|
|
|
if (hPopup)
|
|
{
|
|
POINT pt;
|
|
GetCursorPos(&pt);
|
|
|
|
if (IsWindowVisible(g_hMainWnd))
|
|
{
|
|
DeleteMenu(hPopup, IDM_RESTORETASKMAN, MF_BYCOMMAND);
|
|
}
|
|
else
|
|
{
|
|
SetMenuDefaultItem(hPopup, IDM_RESTORETASKMAN, FALSE);
|
|
}
|
|
|
|
CheckMenuItem(hPopup, IDM_ALWAYSONTOP,
|
|
MF_BYCOMMAND | (g_Options.m_fAlwaysOnTop ? MF_CHECKED : MF_UNCHECKED));
|
|
|
|
SetForegroundWindow(hWnd);
|
|
g_fInPopup = TRUE;
|
|
TrackPopupMenuEx(hPopup, 0, pt.x, pt.y, hWnd, NULL);
|
|
g_fInPopup = FALSE;
|
|
DestroyMenu(hPopup);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|