1  /* EnumText 1.1 - 2011-10-15
 2  
 3  Update:
 4    http://myc01.free.fr/enumtext/
 5  
 6  License:
 7    Public Domain Dedication (CC0 1.0)
 8    http://creativecommons.org/publicdomain/zero/1.0/
 9  
10  Usage:
11    enumtext.exe
12  */
13  
14  #include <windows.h>
15  #include <psapi.h>  //link: MinGW\lib\libpsapi.a (psapi.dll) (or psapi.lib for Visual Studio)
16  #include <stdlib.h>
17  #include <stdio.h>
18  
19  #define MAX_STR  1024
20  
21  typedef DWORD (WINAPI *QUERYFULLPROCESSIMAGENAME) (HANDLE, DWORD, LPTSTR, PDWORD);
22  
23  DWORD GetWindowPath (HWND hWnd, char *szEXEName, DWORD nExeName)
24  {
25      if (!szEXEName || !nExeName)
26          return 0;
27  
28      DWORD     dwProcessID = 0;
29      HANDLE    hProcess    = NULL;
30      HINSTANCE hKernel32   = NULL;
31      QUERYFULLPROCESSIMAGENAME pQueryFullProcessImageName = NULL;
32  
33      GetWindowThreadProcessId (hWnd, &dwProcessID);  // Convert from Window to Process ID
34  
35      // Get a handle to the process from the Process ID
36      if (!(hProcess = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessID)))
37          return 0;
38  
39      if ((hKernel32 = LoadLibrary ("kernel32.dll")))  // Get the process name for Windows Vista/Seven
40      {
41          if ((pQueryFullProcessImageName = (QUERYFULLPROCESSIMAGENAME) GetProcAddress (hKernel32, "QueryFullProcessImageNameA")))
42              pQueryFullProcessImageName (hProcess, 0, szEXEName, &nExeName);
43          else  // Get the process name for Windows 2000/XP
44              GetModuleFileNameEx (hProcess, NULL, szEXEName, nExeName);
45          FreeLibrary (hKernel32);
46      }
47      CloseHandle (hProcess);
48      return dwProcessID;
49  }
50  
51  BOOL CALLBACK EnumChildWindowsProc (HWND hWnd, long lParam)
52  {
53      long len = SendMessage (hWnd, WM_GETTEXTLENGTH, 0, 0);
54      char classname[MAX_STR+1], visible = 'v', *text = calloc (len+2, 1);
55  
56      if (len != 0)
57      {
58          SendMessage (hWnd, WM_GETTEXT, (WPARAM)len+2, (LPARAM)text);
59          CharToOemBuff (text, text, len+2);
60      }
61      GetClassName (hWnd, classname, MAX_STR);
62      if (!IsWindowVisible (hWnd))
63          visible = 'h';
64      printf ("   %c %08lX \"%s\"  (%s)\n", visible, (DWORD)hWnd, text, classname);
65      free (text);
66  
67      return TRUE;
68  }
69  
70  BOOL CALLBACK EnumWindowsProc (HWND hWnd, long lParam)
71  {
72      char buff[MAX_STR+1], path[MAX_STR+1];
73  
74      if (IsWindowVisible (hWnd))
75      {
76          SendMessage (hWnd, WM_GETTEXT, (WPARAM)MAX_STR, (LPARAM)buff);
77          if (buff[0])
78          {
79              DWORD PID = GetWindowPath (hWnd, path, MAX_STR);
80              CharToOemBuff (buff, buff, MAX_STR);
81              CharToOemBuff (path, path, MAX_STR);
82              printf ("\"%s\"\n  PID:%ld \"%s\"\n", buff, PID, path);
83          }
84          EnumChildWindows (hWnd, EnumChildWindowsProc, lParam);
85          puts ("");
86      }
87      return TRUE;
88  }
89  
90  int main (void)
91  {
92      EnumWindows (EnumWindowsProc, 0);
93      return 0;
94  }