// GlobalWindows.cpp
#include <windows.h>
#include <list>
struct SHwnd
{
bool lDeleted;
bool lChanged;
bool lNew;
bool lDisplayed;
union
{
HWND hwnd;
int _hwnd;
};
};
std::list<SHwnd*> hwnds;
bool iiLookupHwnd(HWND hwnd)
{
SHwnd* h;
std::list<SHwnd*>::iterator hi;
// Iterate through the list
for (hi = hwnds.begin(); hi != hwnds.end(); ++hi)
{
// Grab the structure
h = *hi;
if (h->hwnd == hwnd)
{
// This one matches
h->lChanged = false;
return true;
}
}
// If we get here, not found
return false;
}
void iiAppendHwnd(HWND hwnd)
{
SHwnd* h;
// Create it
h = new SHwnd;
h->hwnd = hwnd;
h->lChanged = true;
h->lNew = true;
h->lDeleted = false;
h->lDisplayed = false;
// Add to the list
hwnds.push_back(h);
}
BOOL CALLBACK EnumChildWindowsProc(HWND hwnd, LPARAM l)
{
// Store the window
if (!iiLookupHwnd(hwnd))
iiAppendHwnd(hwnd);
EnumChildWindows(hwnd, EnumChildWindowsProc, NULL);
return TRUE;
}
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM l)
{
// Store the window
if (!iiLookupHwnd(hwnd))
iiAppendHwnd(hwnd);
EnumChildWindows(hwnd, EnumChildWindowsProc, NULL);
return TRUE;
}
int main()
{
bool llFirst;
RECT lrc;
wchar_t title[1024];
WNDCLASSW wc;
SHwnd* h;
std::list<SHwnd*>::iterator hi;
union
{
HWND hwndP;
int _hwndP;
};
// Enter a loop to repeatedly show differences
llFirst = true;
while (true)
{
// Mark everything changed, which means if it exists now and it's still marked changed at the end, then it's been deleted
for (hi = hwnds.begin(); hi != hwnds.end(); ++hi)
(*hi)->lChanged = true;
// Get all windows, and child windows, and child-of-child windows...
EnumWindows(EnumWindowsProc, NULL);
// Report differences
if (!llFirst)
{
// Display any changes
for (hi = hwnds.begin(); hi != hwnds.end(); ++hi)
{
h = *hi;
if (h->lChanged && (IsWindowVisible(h->hwnd) || h->lDisplayed))
{
// Get the window title/caption
h->lDisplayed = true;
GetWindowText(h->hwnd, title, sizeof(title) / sizeof(title[0]));
// Display the event
h->lDeleted = (!h->lNew && h->lChanged);
if (h->lDeleted)
{
// Window has been deleted
wprintf(L"%s %08x %s\n", L"\nDel", h->_hwnd, ((title[0] == 0) ? L"<no title>" : title));
} else {
// New window
wprintf(L"%s %08x %s\n", L"\nAdd", h->_hwnd, ((title[0] == 0) ? L"<no title>" : title));
GetWindowRect(h->hwnd, &lrc);
wprintf(L"X=%d, Y=%d, W=%d, H=%d\n", lrc.left, lrc.top, lrc.right - lrc.left, lrc.bottom - lrc.top);
GetWindowLong(h->hwnd, GWL_HINSTANCE);
GetClassName(h->hwnd, title, sizeof(title) / sizeof(title[0]));
GetClassInfo((HINSTANCE)GetWindowLong(h->hwnd, GWL_HINSTANCE), title, &wc);
wprintf(L"Class = %s\n", title);
if (wc.style & WS_CAPTION) wprintf(L"[caption]");
if (wc.style == WS_OVERLAPPED) wprintf(L"[overlapped]");
if (wc.style & WS_POPUP) wprintf(L"[popup]");
if (wc.style & WS_CHILD) wprintf(L"[child]");
if (wc.style & WS_MINIMIZE) wprintf(L"[minimize]");
if (wc.style & WS_VISIBLE) wprintf(L"[visible]");
if (wc.style & WS_DISABLED) wprintf(L"[disabled]");
if (wc.style & WS_CLIPSIBLINGS) wprintf(L"[clipsiblings]");
if (wc.style & WS_CLIPCHILDREN) wprintf(L"[clipchildren]");
if (wc.style & WS_MAXIMIZE) wprintf(L"[maximize]");
if (wc.style & WS_CAPTION) wprintf(L"[caption]");
if (wc.style & WS_BORDER) wprintf(L"[border]");
if (wc.style & WS_DLGFRAME) wprintf(L"[dlgframe]");
if (wc.style & WS_VSCROLL) wprintf(L"[vscroll]");
if (wc.style & WS_HSCROLL) wprintf(L"[hscroll]");
if (wc.style & WS_SYSMENU) wprintf(L"[sysmenu]");
if (wc.style & WS_THICKFRAME) wprintf(L"[thickframe]");
if (wc.style & WS_MINIMIZEBOX) wprintf(L"[minimizebox]");
if (wc.style & WS_MAXIMIZEBOX) wprintf(L"[maximizebox]");
if (wc.style & WS_TILED) wprintf(L"[tiled]");
if (wc.style & WS_ICONIC) wprintf(L"[iconic]");
if (wc.style & WS_SIZEBOX) wprintf(L"[sizebox]");
if (wc.style & WS_TILEDWINDOW) wprintf(L"[tiledwindow]");
wprintf(L"\n");
hwndP = (HWND)GetWindowLong(h->hwnd, GWL_HWNDPARENT);
while (hwndP != NULL)
{
GetWindowText(hwndP, title, sizeof(title) / sizeof(title[0]));
wprintf(L" Parent = %08x %s\n", _hwndP, ((title[0] == 0) ? L"<no title>" : title));
hwndP = (HWND)GetWindowLong(hwndP, GWL_HWNDPARENT);
}
}
// Lower the new flag
h->lNew = false;
}
}
}
llFirst = false;
// Remove all the deleted ones
std::list<SHwnd*>::reverse_iterator hir;
for (hir = hwnds.rbegin(); hir != hwnds.rend(); ++hir)
{
h = *hir;
if (h->lDeleted)
{
hwnds.remove(h);
free(h);
}
}
}
}