Here's an example that uses the technique: ------------------------------------------ // Win32App.cpp : Defines the entry point for the application. // #include "stdafx.h" #include #include #include #include typedef std::vector HWNDS; namespace { struct EnumInfo { DWORD dwProcessID; HWNDS *pHWNDS; }; BOOL CALLBACK EnumWindowsProc( HWND hWnd, LPARAM lParam ) { const EnumInfo *pInfo = reinterpret_cast(lParam); DWORD dwProcessID; GetWindowThreadProcessId(hWnd, &dwProcessID); if ( dwProcessID == pInfo->dwProcessID ) { pInfo->pHWNDS->push_back(hWnd); } return TRUE; } } BOOL GetProcessTopLevelWindows( DWORD dwProcessId, HWNDS *pOut ) { assert(pOut); EnumInfo ei = {dwProcessId, pOut}; return EnumWindows(&EnumWindowsProc, reinterpret_cast(&ei)); } struct ShowWindowTitle { bool operator()(HWND hWnd) const { int Len = GetWindowTextLength(hWnd); if ( Len>0 ) { char *pText = reinterpret_cast(_alloca(Len+1)); GetWindowText(hWnd, pText, Len+1); MessageBox(NULL, pText, "Window title", MB_OK); return true; } return false; } }; int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWNDS wins; if ( GetProcessTopLevelWindows(2216, &wins) ) // PID HARDCODED! { std::for_each(wins.begin(), wins.end(), ShowWindowTitle()); } return 0; } Steve