リストビューの表示を定期的にファイルに出したい(2)

まずは練習として。

トップレベルのウインドウを列挙して、

  • クラス名
  • タイトル
  • モジュール名

を取得するサンプルを書く。これは

  1. 指定されたモジュール名のウインドウを検索
  2. それぞれについて、クラス名を取得してListviewかどうか判定する

という最終目的の叩き台にするため。モジュール名の取得は、psapi.dllを使うのでちとめんどいかなあ。前に作ったものがあるので、基本コピペするだけだから楽といえば楽だけどね。

#include <stdio.h>
#include <windows.h>
#define BUFSIZE 128

BOOL CALLBACK EnumWindowsProc(HWND, LPARAM);

int main(int argc, char **argv){
  HINSTANCE hInstpsapi;
  void *fp;
  
  if((hInstpsapi = LoadLibrary("psapi.dll")) == NULL){
    return -1;
  }
  if((fp = GetProcAddress(hInstpsapi, "GetModuleBaseNameA")) == NULL){
    return -1;
  }
  EnumWindows(EnumWindowsProc , (LPARAM)fp);
  FreeLibrary(hInstpsapi);

  return 0;
}
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
  char title[BUFSIZE], classname[BUFSIZE], modulename[BUFSIZE];
  DWORD pid;
  HANDLE hProc;
  DWORD (WINAPI *fpGetModuleBaseName)(HANDLE, HMODULE, LPTSTR, DWORD) = (DWORD (WINAPI *)(HANDLE, HMODULE, LPTSTR, DWORD))lParam;
  
  GetWindowText(hWnd, title, BUFSIZE);
  GetClassName(hWnd, classname, BUFSIZE);
  GetWindowThreadProcessId(hWnd, &pid);
  if(!(hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid))){
    return 2;
  }
  fpGetModuleBaseName(hProc, NULL, modulename, BUFSIZE);
  printf("%08X, %s, %s, %s\n", (unsigned)hWnd, classname, modulename, title);
  return 1;
}

EnumWindowsは、第一引数にコールバック関数のポインター、第二引数にapplication specificな値(コールバック関数で使える)を設定する。で、コールバック関数は第一引数にEnumWindowsで見つかったウインドウハンドル、第二引数はEnumWindowsの第二引数が入る。
コンパイルして実行。ちなみにCygwin環境です。

$ gcc -Wall -mno-cygwin -mwindows -o list list.c