ReactOS 0.4.15-dev-8390-g075894b
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 269 of file syspager.cpp.

269 :
273 m_Loop(false)
274{
275}
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 277 of file syspager.cpp.

278{
279 Uninitialize();
281
282 if (m_WakeUpEvent)
286}
CRITICAL_SECTION m_ListLock
Definition: syspager.cpp:59
void Uninitialize()
Definition: syspager.cpp:309
#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 333 of file syspager.cpp.

334{
336 (void)GetWindowThreadProcessId(iconData->hWnd, &ProcessId);
337
340 if (hProcess == NULL)
341 {
342 return false;
343 }
344
345 IconWatcherData *Icon = new IconWatcherData(iconData);
346 Icon->hProcess = hProcess;
347 Icon->ProcessId = ProcessId;
348
349 bool Added = false;
351
352 // The likelyhood of someone having more than 64 icons in their tray is
353 // pretty slim. We could spin up a new thread for each multiple of 64, but
354 // it's not worth the effort, so we just won't bother watching those icons
356 {
359 Added = true;
360 }
361
363
364 if (!Added)
365 {
366 delete Icon;
367 }
368
369 return Added;
370}
POSITION AddTail(INARGTYPE element)
Definition: atlcoll.h:626
size_t GetCount() const
Definition: atlcoll.h:539
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:2711
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:404
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 386 of file syspager.cpp.

387{
389 POSITION NextPosition = m_WatcherList.GetHeadPosition();
391 do
392 {
393 Position = NextPosition;
394
395 Entry = m_WatcherList.GetNext(NextPosition);
396 if (Entry)
397 {
398 if ((iconData && ((Entry->IconData.hWnd == iconData->hWnd) && (Entry->IconData.uID == iconData->uID))) ||
399 (hProcess && (Entry->hProcess == hProcess)))
400 {
401 if (Remove)
403 break;
404 }
405 }
406 Entry = NULL;
407
408 } while (NextPosition != NULL);
409
410 return Entry;
411}
POSITION GetHeadPosition() const
Definition: atlcoll.h:551
E & GetNext(_Inout_ POSITION &pos)
Definition: atlcoll.h:563
void RemoveAt(_In_ POSITION pos)
Definition: atlcoll.h:748
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 288 of file syspager.cpp.

289{
291
294 if (m_WakeUpEvent == NULL)
295 return false;
296
298 0,
300 (LPVOID)this,
301 0,
302 NULL);
303 if (m_hWatcherThread == NULL)
304 return false;
305
306 return true;
307}
static UINT WINAPI WatcherThread(_In_opt_ LPVOID lpParam)
Definition: syspager.cpp:413
_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 372 of file syspager.cpp.

373{
375
377 Icon = GetListEntry(iconData, NULL, true);
378
381
382 delete Icon;
383 return true;
384}
IconWatcherData * GetListEntry(_In_opt_ CONST NOTIFYICONDATA *iconData, _In_opt_ HANDLE hProcess, _In_ bool Remove)
Definition: syspager.cpp:386

Referenced by CSysPagerWnd::NotifyIcon().

◆ Uninitialize()

void CIconWatcher::Uninitialize ( )

Definition at line 309 of file syspager.cpp.

310{
311 m_Loop = false;
312 if (m_WakeUpEvent)
314
316
318 for (size_t i = 0; i < m_WatcherList.GetCount(); i++)
319 {
321 if (Pos)
322 {
325 delete Icon;
326 }
327 }
329
331}
E & GetAt(_In_ POSITION pos)
Definition: atlcoll.h:595
POSITION FindIndex(_In_ size_t iElement) const
Definition: atlcoll.h:797
void RemoveAll()
Definition: atlcoll.h:727
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 413 of file syspager.cpp.

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

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: