#include "common.h" #include "mywindowlist.h" class WindowList { public: struct ListNode { HWND hwnd; ListNode *next; }; WindowList(): head(0), count(0) {} ~WindowList() {clear();} void clear() { ListNode *n; while(head) { n = head; head = head->next; delete n; } } void AddWindow(HWND hwnd) { if(HasWindow(hwnd)) return; ListNode *n = new ListNode; n->hwnd = hwnd; n->next = head; head = n; count++; } void RemoveWindow(HWND hwnd) { ListNode *n = head, *prev = 0; while(n) { if(n->hwnd == hwnd) { if(prev) prev->next = n->next; else head = n->next; delete n; count--; break; } prev = n; n = n->next; } } void PostListMessage(UINT msg, WPARAM wParam, LPARAM lParam) { ListNode *n = head; while(n) { PostMessage(n->hwnd, msg, wParam, lParam); n = n->next; } } bool HasWindow(HWND hwnd) { ListNode *n = head; while(n) { if(n->hwnd == hwnd) return true; n = n->next; } return false; } int GetCount() { return count; } protected: ListNode *head; int count; }; class WindowMap { public: struct ListNode { HANDLE hContact; WindowList list; ListNode *next; }; WindowMap(): head(0) {} ~WindowMap() {clear();} void clear() { ListNode *n = head; while(head) { n = head; head = head->next; delete n; } } WindowList *FindList(HANDLE hContact) { ListNode *n = head; while(n) { if(n->hContact == hContact) return &n->list; n = n->next; } return 0; } void Add(HANDLE hContact, HWND hWnd) { WindowList *l = FindList(hContact); if(l) l->AddWindow(hWnd); else { ListNode *n = new ListNode; n->hContact = hContact; n->list.AddWindow(hWnd); n->next = head; head = n; } } void Remove(HANDLE hContact, HWND hWnd) { ListNode *n = head, *prev = 0; while(n) { if(n->hContact == hContact) { n->list.RemoveWindow(hWnd); if(n->list.GetCount() == 0) { if(prev) prev->next = n->next; else head = n->next; delete n; } break; } prev = n; n = n->next; } } void PostMapMessage(UINT msg, WPARAM wParam, LPARAM lParam) { ListNode *n = head; while(n) { n->list.PostListMessage(msg, wParam, lParam); n = n->next; } } protected: ListNode *head; }; WindowMap window_map; CRITICAL_SECTION list_cs; void AddToWindowList(HANDLE hContact, HWND hWnd) { EnterCriticalSection(&list_cs); window_map.Add(hContact, hWnd); LeaveCriticalSection(&list_cs); } void RemoveFromWindowList(HANDLE hContact, HWND hWnd) { EnterCriticalSection(&list_cs); window_map.Remove(hContact, hWnd); LeaveCriticalSection(&list_cs); } void PostMessageWindowList(UINT msg, WPARAM wParam, LPARAM lParam) { EnterCriticalSection(&list_cs); window_map.PostMapMessage(msg, wParam, lParam); LeaveCriticalSection(&list_cs); } void PostMessageWindowListContact(HANDLE hContact, UINT msg, WPARAM wParam, LPARAM lParam) { EnterCriticalSection(&list_cs); WindowList *l = window_map.FindList(hContact); if(l) l->PostListMessage(msg, wParam, lParam); LeaveCriticalSection(&list_cs); } bool InList(HANDLE hContact, HWND hWnd) { bool ret = false; EnterCriticalSection(&list_cs); WindowList *l = window_map.FindList(hContact); if(l) ret = l->HasWindow(hWnd); LeaveCriticalSection(&list_cs); return ret; } int CountList(HANDLE hContact) { int count = 0; EnterCriticalSection(&list_cs); WindowList *l = window_map.FindList(hContact); if(l) count = l->GetCount(); LeaveCriticalSection(&list_cs); return count; } bool EmptyList(HANDLE hContact) { EnterCriticalSection(&list_cs); bool ret = (window_map.FindList(hContact) == 0); LeaveCriticalSection(&list_cs); return ret; } void InitWindowList() { InitializeCriticalSection(&list_cs); } void DeinitWindowList() { DeleteCriticalSection(&list_cs); }