ReactOS 0.4.16-dev-2104-gb84fa49
CIconWatcher Class Reference
Inheritance diagram for CIconWatcher:
Collaboration diagram for CIconWatcher:

Public Member Functions

 CIconWatcher ()
 
virtual ~CIconWatcher ()
 
bool Initialize (_In_ HWND hWndParent)
 
void Uninitialize ()
 
bool AddIconToWatcher (_In_ CONST NOTIFYICONDATA *iconData)
 
bool RemoveIconFromWatcher (_In_ CONST NOTIFYICONDATA *iconData)
 
IconWatcherDataGetListEntry (_In_opt_ CONST NOTIFYICONDATA *iconData, _In_opt_ HANDLE hProcess, _In_ bool Remove)
 

Static Private Member Functions

static UINT WINAPI WatcherThread (_In_opt_ LPVOID lpParam)
 

Private Attributes

CAtlList< IconWatcherData * > m_WatcherList
 
CRITICAL_SECTION m_ListLock
 
HANDLE m_hWatcherThread
 
HANDLE m_WakeUpEvent
 
HWND m_hwndSysTray
 
bool m_Loop
 

Detailed Description

Definition at line 56 of file syspager.cpp.

Constructor & Destructor Documentation

◆ CIconWatcher()

CIconWatcher::CIconWatcher ( )

Definition at line 274 of file syspager.cpp.

274 :
278 m_Loop(false)
279{
280}
HWND m_hwndSysTray
Definition: syspager.cpp:62
HANDLE m_WakeUpEvent
Definition: syspager.cpp:61
HANDLE m_hWatcherThread
Definition: syspager.cpp:60
#define NULL
Definition: types.h:112

◆ ~CIconWatcher()

CIconWatcher::~CIconWatcher ( )
virtual

Definition at line 282 of file syspager.cpp.

283{
284 Uninitialize();
286
287 if (m_WakeUpEvent)
291}
CRITICAL_SECTION m_ListLock
Definition: syspager.cpp:59
void Uninitialize()
Definition: syspager.cpp:314
#define CloseHandle
Definition: compat.h:739
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)

Member Function Documentation

◆ AddIconToWatcher()

bool CIconWatcher::AddIconToWatcher ( _In_ CONST NOTIFYICONDATA iconData)

Definition at line 338 of file syspager.cpp.

339{
341 (void)GetWindowThreadProcessId(iconData->hWnd, &ProcessId);
342
345 if (hProcess == NULL)
346 {
347 return false;
348 }
349
350 IconWatcherData *Icon = new IconWatcherData(iconData);
351 Icon->hProcess = hProcess;
352 Icon->ProcessId = ProcessId;
353
354 bool Added = false;
356
357 // The likelyhood of someone having more than 64 icons in their tray is
358 // pretty slim. We could spin up a new thread for each multiple of 64, but
359 // it's not worth the effort, so we just won't bother watching those icons
361 {
364 Added = true;
365 }
366
368
369 if (!Added)
370 {
371 delete Icon;
372 }
373
374 return Added;
375}
POSITION AddTail(INARGTYPE element)
Definition: atlcoll.h:629
size_t GetCount() const
Definition: atlcoll.h:542
CAtlList< IconWatcherData * > m_WatcherList
Definition: syspager.cpp:58
#define FALSE
Definition: types.h:117
HANDLE WINAPI OpenProcess(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwProcessId)
Definition: proc.c:1227
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2712
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
#define SYNCHRONIZE
Definition: nt_native.h:61
Definition: globals.h:96
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define MAXIMUM_WAIT_OBJECTS
Definition: winbase.h:381
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)

Referenced by CSysPagerWnd::NotifyIcon().

◆ GetListEntry()

IconWatcherData * CIconWatcher::GetListEntry ( _In_opt_ CONST NOTIFYICONDATA iconData,
_In_opt_ HANDLE  hProcess,
_In_ bool  Remove 
)

Definition at line 391 of file syspager.cpp.

392{
394 POSITION NextPosition = m_WatcherList.GetHeadPosition();
396 do
397 {
398 Position = NextPosition;
399
400 Entry = m_WatcherList.GetNext(NextPosition);
401 if (Entry)
402 {
403 if ((iconData && ((Entry->IconData.hWnd == iconData->hWnd) && (Entry->IconData.uID == iconData->uID))) ||
404 (hProcess && (Entry->hProcess == hProcess)))
405 {
406 if (Remove)
408 break;
409 }
410 }
411 Entry = NULL;
412
413 } while (NextPosition != NULL);
414
415 return Entry;
416}
POSITION GetHeadPosition() const
Definition: atlcoll.h:554
E & GetNext(_Inout_ POSITION &pos)
Definition: atlcoll.h:566
void RemoveAt(_In_ POSITION pos)
Definition: atlcoll.h:769
base of all file and directory entries
Definition: entries.h:83
static COORD Position
Definition: mouse.c:34
_In_ BOOLEAN Remove
Definition: psfuncs.h:111

◆ Initialize()

bool CIconWatcher::Initialize ( _In_ HWND  hWndParent)

Definition at line 293 of file syspager.cpp.

294{
296
299 if (m_WakeUpEvent == NULL)
300 return false;
301
303 0,
305 (LPVOID)this,
306 0,
307 NULL);
308 if (m_hWatcherThread == NULL)
309 return false;
310
311 return true;
312}
static UINT WINAPI WatcherThread(_In_opt_ LPVOID lpParam)
Definition: syspager.cpp:418
_ACRTIMP uintptr_t __cdecl _beginthreadex(void *, unsigned int, _beginthreadex_start_routine_t, void *, unsigned int, unsigned int *)
Definition: thread.c:207
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
PVOID HANDLE
Definition: typedefs.h:73

Referenced by CSysPagerWnd::OnCreate().

◆ RemoveIconFromWatcher()

bool CIconWatcher::RemoveIconFromWatcher ( _In_ CONST NOTIFYICONDATA iconData)

Definition at line 377 of file syspager.cpp.

378{
380
382 Icon = GetListEntry(iconData, NULL, true);
383
386
387 delete Icon;
388 return true;
389}
IconWatcherData * GetListEntry(_In_opt_ CONST NOTIFYICONDATA *iconData, _In_opt_ HANDLE hProcess, _In_ bool Remove)
Definition: syspager.cpp:391

Referenced by CSysPagerWnd::NotifyIcon().

◆ Uninitialize()

void CIconWatcher::Uninitialize ( )

Definition at line 314 of file syspager.cpp.

315{
316 m_Loop = false;
317 if (m_WakeUpEvent)
319
321
323 for (size_t i = 0; i < m_WatcherList.GetCount(); i++)
324 {
326 if (Pos)
327 {
330 delete Icon;
331 }
332 }
334
336}
E & GetAt(_In_ POSITION pos)
Definition: atlcoll.h:598
POSITION FindIndex(_In_ size_t iElement) const
Definition: atlcoll.h:818
void RemoveAll()
Definition: atlcoll.h:748
ush Pos
Definition: deflate.h:92
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248

Referenced by CSysPagerWnd::OnDestroy().

◆ WatcherThread()

UINT WINAPI CIconWatcher::WatcherThread ( _In_opt_ LPVOID  lpParam)
staticprivate

Definition at line 418 of file syspager.cpp.

419{
420 CIconWatcher* This = reinterpret_cast<CIconWatcher *>(lpParam);
421 HANDLE *WatchList = NULL;
422
423 This->m_Loop = true;
424 while (This->m_Loop)
425 {
426 EnterCriticalSection(&This->m_ListLock);
427
428 DWORD Size;
429 Size = This->m_WatcherList.GetCount() + 1;
431
432 if (WatchList)
433 delete[] WatchList;
434 WatchList = new HANDLE[Size];
435 WatchList[0] = This->m_WakeUpEvent;
436
438 for (size_t i = 0; i < This->m_WatcherList.GetCount(); i++)
439 {
440 Pos = This->m_WatcherList.FindIndex(i);
441 if (Pos)
442 {
444 Icon = This->m_WatcherList.GetAt(Pos);
445 WatchList[i + 1] = Icon->hProcess;
446 }
447 }
448
449 LeaveCriticalSection(&This->m_ListLock);
450
453 WatchList,
454 FALSE,
455 INFINITE);
456 if (Status == WAIT_OBJECT_0)
457 {
458 // We've been kicked, we have updates to our list (or we're exiting the thread)
459 if (This->m_Loop)
460 TRACE("Updating watched icon list\n");
461 }
462 else if ((Status >= WAIT_OBJECT_0 + 1) && (Status < Size))
463 {
465 Icon = This->GetListEntry(NULL, WatchList[Status], false);
466
467 TRACE("Pid %lu owns a notification icon and has stopped without deleting it. We'll cleanup on its behalf\n", Icon->ProcessId);
468
469 TRAYNOTIFYDATAW tnid = {0};
470 tnid.dwSignature = NI_NOTIFY_SIG;
471 tnid.dwMessage = NIM_DELETE;
472 CopyMemory(&tnid.nid, &Icon->IconData, Icon->IconData.cbSize);
473
475 data.dwData = 1;
476 data.cbData = sizeof(tnid);
477 data.lpData = &tnid;
478
479 BOOL Success = ::SendMessage(This->m_hwndSysTray, WM_COPYDATA,
480 (WPARAM)&Icon->IconData, (LPARAM)&data);
481 if (!Success)
482 {
483 // If we failed to handle the delete message, forcibly remove it
484 This->RemoveIconFromWatcher(&Icon->IconData);
485 }
486 }
487 else
488 {
489 if (Status == WAIT_FAILED)
490 {
492 }
493 ERR("Failed to wait on process handles : %lu\n", Status);
494 This->Uninitialize();
495 }
496 }
497
498 if (WatchList)
499 delete[] WatchList;
500
501 return 0;
502}
#define ERR(fmt,...)
Definition: precomp.h:57
#define INFINITE
Definition: serial.h:102
@ Success
Definition: eventcreate.c:712
unsigned int BOOL
Definition: ntddk_ex.h:94
Status
Definition: gdiplustypes.h:25
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define CopyMemory
Definition: minwinbase.h:29
LONG_PTR LPARAM
Definition: minwindef.h:175
UINT_PTR WPARAM
Definition: minwindef.h:174
#define ASSERT(a)
Definition: mode.c:44
#define NIM_DELETE
Definition: shellapi.h:96
#define TRACE(s)
Definition: solgame.cpp:4
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WAIT_OBJECT_0
Definition: winbase.h:383
#define WAIT_FAILED
Definition: winbase.h:390
#define WM_COPYDATA
Definition: winuser.h:1692
#define SendMessage
Definition: winuser.h:5954

Member Data Documentation

◆ m_hWatcherThread

HANDLE CIconWatcher::m_hWatcherThread
private

Definition at line 60 of file syspager.cpp.

◆ m_hwndSysTray

HWND CIconWatcher::m_hwndSysTray
private

Definition at line 62 of file syspager.cpp.

◆ m_ListLock

CRITICAL_SECTION CIconWatcher::m_ListLock
private

Definition at line 59 of file syspager.cpp.

◆ m_Loop

bool CIconWatcher::m_Loop
private

Definition at line 63 of file syspager.cpp.

◆ m_WakeUpEvent

HANDLE CIconWatcher::m_WakeUpEvent
private

Definition at line 61 of file syspager.cpp.

◆ m_WatcherList

CAtlList<IconWatcherData *> CIconWatcher::m_WatcherList
private

Definition at line 58 of file syspager.cpp.


The documentation for this class was generated from the following file: