ReactOS 0.4.16-dev-716-g2b2bdab
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 272 of file syspager.cpp.

272 :
276 m_Loop(false)
277{
278}
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 280 of file syspager.cpp.

281{
282 Uninitialize();
284
285 if (m_WakeUpEvent)
289}
CRITICAL_SECTION m_ListLock
Definition: syspager.cpp:59
void Uninitialize()
Definition: syspager.cpp:312
#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 336 of file syspager.cpp.

337{
339 (void)GetWindowThreadProcessId(iconData->hWnd, &ProcessId);
340
343 if (hProcess == NULL)
344 {
345 return false;
346 }
347
348 IconWatcherData *Icon = new IconWatcherData(iconData);
349 Icon->hProcess = hProcess;
350 Icon->ProcessId = ProcessId;
351
352 bool Added = false;
354
355 // The likelyhood of someone having more than 64 icons in their tray is
356 // pretty slim. We could spin up a new thread for each multiple of 64, but
357 // it's not worth the effort, so we just won't bother watching those icons
359 {
362 Added = true;
363 }
364
366
367 if (!Added)
368 {
369 delete Icon;
370 }
371
372 return Added;
373}
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:430
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 389 of file syspager.cpp.

390{
392 POSITION NextPosition = m_WatcherList.GetHeadPosition();
394 do
395 {
396 Position = NextPosition;
397
398 Entry = m_WatcherList.GetNext(NextPosition);
399 if (Entry)
400 {
401 if ((iconData && ((Entry->IconData.hWnd == iconData->hWnd) && (Entry->IconData.uID == iconData->uID))) ||
402 (hProcess && (Entry->hProcess == hProcess)))
403 {
404 if (Remove)
406 break;
407 }
408 }
409 Entry = NULL;
410
411 } while (NextPosition != NULL);
412
413 return Entry;
414}
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:110

◆ Initialize()

bool CIconWatcher::Initialize ( _In_ HWND  hWndParent)

Definition at line 291 of file syspager.cpp.

292{
294
297 if (m_WakeUpEvent == NULL)
298 return false;
299
301 0,
303 (LPVOID)this,
304 0,
305 NULL);
306 if (m_hWatcherThread == NULL)
307 return false;
308
309 return true;
310}
static UINT WINAPI WatcherThread(_In_opt_ LPVOID lpParam)
Definition: syspager.cpp:416
_CRTIMP uintptr_t __cdecl _beginthreadex(_In_opt_ void *_Security, _In_ unsigned _StackSize, _In_ unsigned(__stdcall *_StartAddress)(void *), _In_opt_ void *_ArgList, _In_ unsigned _InitFlag, _Out_opt_ unsigned *_ThrdAddr)
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 375 of file syspager.cpp.

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

Referenced by CSysPagerWnd::NotifyIcon().

◆ Uninitialize()

void CIconWatcher::Uninitialize ( )

Definition at line 312 of file syspager.cpp.

313{
314 m_Loop = false;
315 if (m_WakeUpEvent)
317
319
321 for (size_t i = 0; i < m_WatcherList.GetCount(); i++)
322 {
324 if (Pos)
325 {
328 delete Icon;
329 }
330 }
332
334}
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 416 of file syspager.cpp.

417{
418 CIconWatcher* This = reinterpret_cast<CIconWatcher *>(lpParam);
419 HANDLE *WatchList = NULL;
420
421 This->m_Loop = true;
422 while (This->m_Loop)
423 {
424 EnterCriticalSection(&This->m_ListLock);
425
426 DWORD Size;
427 Size = This->m_WatcherList.GetCount() + 1;
429
430 if (WatchList)
431 delete[] WatchList;
432 WatchList = new HANDLE[Size];
433 WatchList[0] = This->m_WakeUpEvent;
434
436 for (size_t i = 0; i < This->m_WatcherList.GetCount(); i++)
437 {
438 Pos = This->m_WatcherList.FindIndex(i);
439 if (Pos)
440 {
442 Icon = This->m_WatcherList.GetAt(Pos);
443 WatchList[i + 1] = Icon->hProcess;
444 }
445 }
446
447 LeaveCriticalSection(&This->m_ListLock);
448
451 WatchList,
452 FALSE,
453 INFINITE);
454 if (Status == WAIT_OBJECT_0)
455 {
456 // We've been kicked, we have updates to our list (or we're exiting the thread)
457 if (This->m_Loop)
458 TRACE("Updating watched icon list\n");
459 }
460 else if ((Status >= WAIT_OBJECT_0 + 1) && (Status < Size))
461 {
463 Icon = This->GetListEntry(NULL, WatchList[Status], false);
464
465 TRACE("Pid %lu owns a notification icon and has stopped without deleting it. We'll cleanup on its behalf\n", Icon->ProcessId);
466
467 TRAYNOTIFYDATAW tnid = {0};
468 tnid.dwSignature = NI_NOTIFY_SIG;
469 tnid.dwMessage = NIM_DELETE;
470 CopyMemory(&tnid.nid, &Icon->IconData, Icon->IconData.cbSize);
471
473 data.dwData = 1;
474 data.cbData = sizeof(tnid);
475 data.lpData = &tnid;
476
477 BOOL Success = ::SendMessage(This->m_hwndSysTray, WM_COPYDATA,
478 (WPARAM)&Icon->IconData, (LPARAM)&data);
479 if (!Success)
480 {
481 // If we failed to handle the delete message, forcibly remove it
482 This->RemoveIconFromWatcher(&Icon->IconData);
483 }
484 }
485 else
486 {
487 if (Status == WAIT_FAILED)
488 {
490 }
491 ERR("Failed to wait on process handles : %lu\n", Status);
492 This->Uninitialize();
493 }
494 }
495
496 if (WatchList)
497 delete[] WatchList;
498
499 return 0;
500}
#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 ASSERT(a)
Definition: mode.c:44
#define NIM_DELETE
Definition: shellapi.h:97
#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:4533
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CopyMemory
Definition: winbase.h:1735
#define WAIT_OBJECT_0
Definition: winbase.h:432
#define WAIT_FAILED
Definition: winbase.h:439
LONG_PTR LPARAM
Definition: windef.h:208
UINT_PTR WPARAM
Definition: windef.h:207
#define WM_COPYDATA
Definition: winuser.h:1667
#define SendMessage
Definition: winuser.h:5855

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: