윈도우에서는 수많은 응용프로그램들이 실행 되어 있습니다. 사용자가 조작하는 프로그램 말고도, 백그라운드에서 작업하고 있는 프로세스들도 많이 있죠.
현재 실행 되어 있는 프로세스의 목록을, 작업 표시줄을 보면 알 수 있습니다.

위와 똑같이는 아니더라도 응용프로그램 목록을 얻어오려면 어떻게 해야할까요??
EnumWindows 함수를 사용하시면 됩니다.
BOOL EnumWindows(
WNDENUMPROC lpEnumFunc,
LPARAM lParam
);
EnumWindows 사용하기 전 Callback 함수를 선언합니다.
// 선언
static BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lparam );
// 정의
BOOL CALLBACK CEnumWindowDlg::EnumWindowsProc( HWND hWnd, LPARAM lparam )
{
return TRUE;
}
TRUE를 반환하면 그 다음 HWND를 검색하고, FALSE을 반환하면 Callback 함수 호출을 중단합니다.
원하는 HWND 값을 찾으면 FALSE를 반환하면 됩니다.
Callback 함수를 선언했다면, EnumWindows 사용은 아래와 같습니다.
::EnumWindows( EnumWindowsProc, (LPARAM)NULL );
코딩을 하고 실행을 시켜보면 상당히 많은 HWND가 얻어집니다. 백그라운드 프로세스까지 검색하다 보니 엄청나게 검색이 된거죠. 아래 프로그램은 샘플로 만든 프로그램입니다.

실제 사용자가 보고있는 프로세스 목록만 보고 싶다면 EnumWindowsProc에 아래와 같이 조건을 추가하면 됩니다.
BOOL CALLBACK CEnumWindowDlg::EnumWindowsProc( HWND hWnd, LPARAM lparam )
{
BOOL isVisible = ::IsWindowVisible( hWnd );
DWORD exStyle = GetWindowLong( hWnd, GWL_EXSTYLE );
BOOL isAppWindow = (exStyle & WS_EX_APPWINDOW);
BOOL isToolWindow = (exStyle & WS_EX_TOOLWINDOW);
BOOL isOwned = ::GetWindow( hWnd, GW_OWNER ) ? TRUE : FALSE;
if ( !isVisible )
return TRUE;
if ( !( isAppWindow || (!isToolWindow && !isOwned) ) )
return TRUE;
return TRUE;
}