ReactOS 0.4.17-dev-806-gffa4164
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 61 of file syspager.cpp.

Constructor & Destructor Documentation

◆ CIconWatcher()

CIconWatcher::CIconWatcher ( )

Definition at line 282 of file syspager.cpp.

282 :
286 m_Loop(false)
287{
288}
HWND m_hwndSysTray
Definition: syspager.cpp:67
HANDLE m_WakeUpEvent
Definition: syspager.cpp:66
HANDLE m_hWatcherThread
Definition: syspager.cpp:65
#define NULL
Definition: types.h:112

◆ ~CIconWatcher()

CIconWatcher::~CIconWatcher ( )
virtual

Definition at line 290 of file syspager.cpp.

291{
292 Uninitialize();
294
295 if (m_WakeUpEvent)
299}
CRITICAL_SECTION m_ListLock
Definition: syspager.cpp:64
void Uninitialize()
Definition: syspager.cpp:322
#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 346 of file syspager.cpp.

347{
349 (void)GetWindowThreadProcessId(iconData->hWnd, &ProcessId);
350
353 if (hProcess == NULL)
354 {
355 return false;
356 }
357
358 IconWatcherData *Icon = new IconWatcherData(iconData);
359 Icon->hProcess = hProcess;
360 Icon->ProcessId = ProcessId;
361
362 bool Added = false;
364
365 // The likelyhood of someone having more than 64 icons in their tray is
366 // pretty slim. We could spin up a new thread for each multiple of 64, but
367 // it's not worth the effort, so we just won't bother watching those icons
369 {
372 Added = true;
373 }
374
376
377 if (!Added)
378 {
379 delete Icon;
380 }
381
382 return Added;
383}
POSITION AddTail(INARGTYPE element)
Definition: atlcoll.h:629
size_t GetCount() const
Definition: atlcoll.h:542
CAtlList< IconWatcherData * > m_WatcherList
Definition: syspager.cpp:63
#define FALSE
Definition: types.h:117
HANDLE WINAPI OpenProcess(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwProcessId)
Definition: proc.c:1274
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
HANDLE hProcess
Definition: syspager.cpp:39
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
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 399 of file syspager.cpp.

400{
402 for (POSITION NextPosition = m_WatcherList.GetHeadPosition(); NextPosition;)
403 {
404 POSITION Position = NextPosition;
405 Entry = m_WatcherList.GetNext(NextPosition); // Note: This will advance NextPosition
406 if (Entry)
407 {
408 if ((iconData && ((Entry->IconData.hWnd == iconData->hWnd) && (Entry->IconData.uID == iconData->uID))) ||
409 (hProcess && (Entry->hProcess == hProcess)))
410 {
411 if (Remove)
413 return Entry;
414 }
415 }
416 }
417 return NULL;
418}
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
Entry
Definition: section.c:5216
static COORD Position
Definition: mouse.c:34
_In_ BOOLEAN Remove
Definition: psfuncs.h:111

◆ Initialize()

bool CIconWatcher::Initialize ( _In_ HWND  hWndParent)

Definition at line 301 of file syspager.cpp.

302{
304
307 if (m_WakeUpEvent == NULL)
308 return false;
309
311 0,
313 (LPVOID)this,
314 0,
315 NULL);
316 if (m_hWatcherThread == NULL)
317 return false;
318
319 return true;
320}
static UINT WINAPI WatcherThread(_In_opt_ LPVOID lpParam)
Definition: syspager.cpp:420
_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:687
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:587
PVOID HANDLE
Definition: typedefs.h:73

Referenced by CSysPagerWnd::OnCreate().

◆ RemoveIconFromWatcher()

bool CIconWatcher::RemoveIconFromWatcher ( _In_ CONST NOTIFYICONDATA iconData)

Definition at line 385 of file syspager.cpp.

386{
388
389 IconWatcherData *Icon;
390 Icon = GetListEntry(iconData, NULL, true);
391
394
395 delete Icon;
396 return true;
397}
IconWatcherData * GetListEntry(_In_opt_ CONST NOTIFYICONDATA *iconData, _In_opt_ HANDLE hProcess, _In_ bool Remove)
Definition: syspager.cpp:399

Referenced by CSysPagerWnd::NotifyIcon().

◆ Uninitialize()

void CIconWatcher::Uninitialize ( )

Definition at line 322 of file syspager.cpp.

323{
324 m_Loop = false;
325 if (m_WakeUpEvent)
327
329
331 for (size_t i = 0; i < m_WatcherList.GetCount(); i++)
332 {
334 if (Pos)
335 {
336 IconWatcherData *Icon;
337 Icon = m_WatcherList.GetAt(Pos);
338 delete Icon;
339 }
340 }
342
344}
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 420 of file syspager.cpp.

421{
422 CIconWatcher* This = reinterpret_cast<CIconWatcher *>(lpParam);
423 HANDLE *WatchList = NULL;
424
425 This->m_Loop = true;
426 while (This->m_Loop)
427 {
428 EnterCriticalSection(&This->m_ListLock);
429
430 DWORD Size;
431 Size = This->m_WatcherList.GetCount() + 1;
433
434 if (WatchList)
435 delete[] WatchList;
436 WatchList = new HANDLE[Size];
437 WatchList[0] = This->m_WakeUpEvent;
438
440 for (size_t i = 0; i < This->m_WatcherList.GetCount(); i++)
441 {
442 Pos = This->m_WatcherList.FindIndex(i);
443 if (Pos)
444 {
445 IconWatcherData *Icon;
446 Icon = This->m_WatcherList.GetAt(Pos);
447 WatchList[i + 1] = Icon->hProcess;
448 }
449 }
450
451 LeaveCriticalSection(&This->m_ListLock);
452
455 WatchList,
456 FALSE,
457 INFINITE);
458 if (Status == WAIT_OBJECT_0)
459 {
460 // We've been kicked, we have updates to our list (or we're exiting the thread)
461 if (This->m_Loop)
462 TRACE("Updating watched icon list\n");
463 }
464 else if ((Status >= WAIT_OBJECT_0 + 1) && (Status < Size))
465 {
466 IconWatcherData *Icon;
467 Icon = This->GetListEntry(NULL, WatchList[Status], false);
468
469 TRACE("Pid %lu owns a notification icon and has stopped without deleting it. We'll cleanup on its behalf\n", Icon->ProcessId);
470
471 TRAYNOTIFYDATAW tnid = {0};
472 tnid.dwSignature = NI_NOTIFY_SIG;
473 tnid.dwMessage = NIM_DELETE;
474 CopyMemory(&tnid.nid, &Icon->IconData, Icon->IconData.cbSize);
475
477 data.dwData = 1;
478 data.cbData = sizeof(tnid);
479 data.lpData = &tnid;
480
481 BOOL Success = ::SendMessage(This->m_hwndSysTray, WM_COPYDATA,
482 (WPARAM)&Icon->IconData, (LPARAM)&data);
483 if (!Success)
484 {
485 // If we failed to handle the delete message, forcibly remove it
486 This->RemoveIconFromWatcher(&Icon->IconData);
487 }
488 }
489 else
490 {
491 if (Status == WAIT_FAILED)
492 {
494 }
495 ERR("Failed to wait on process handles : %lu\n", Status);
496 This->Uninitialize();
497 }
498 }
499
500 if (WatchList)
501 delete[] WatchList;
502
503 return 0;
504}
#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:24
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
NOTIFYICONDATA IconData
Definition: syspager.cpp:41
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:6009

Member Data Documentation

◆ m_hWatcherThread

HANDLE CIconWatcher::m_hWatcherThread
private

Definition at line 65 of file syspager.cpp.

◆ m_hwndSysTray

HWND CIconWatcher::m_hwndSysTray
private

Definition at line 67 of file syspager.cpp.

◆ m_ListLock

CRITICAL_SECTION CIconWatcher::m_ListLock
private

Definition at line 64 of file syspager.cpp.

◆ m_Loop

bool CIconWatcher::m_Loop
private

Definition at line 68 of file syspager.cpp.

◆ m_WakeUpEvent

HANDLE CIconWatcher::m_WakeUpEvent
private

Definition at line 66 of file syspager.cpp.

◆ m_WatcherList

CAtlList<IconWatcherData *> CIconWatcher::m_WatcherList
private

Definition at line 63 of file syspager.cpp.


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