まずは練習として。
トップレベルのウインドウを列挙して、
- クラス名
- タイトル
- モジュール名
を取得するサンプルを書く。これは
- 指定されたモジュール名のウインドウを検索
- それぞれについて、クラス名を取得して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