hi, all!
Помогите, дедлайн на носу, а на VC++ перешел недавно.
есть задача — отследить создание определенного окна. Пытаюсь сделать через глобальный хук WH_SHELL, ссобщение HSHELL_WINDOWCREATED. Но по пути наступаю на грабли: хук действеннен только для окна приложения. При компилировании и отладке проблем не наблюдается. Вроде бы с обеспечением глобальности переменных все правильно — делается через mapped file (см. фрагмент исходника ниже):
typedef struct
{
UINT MsgCode;
HWND MsgTarget;
HHOOK hkShell;
int nCount;
int fhandle;
} MAPPED_AREA;
typedef MAPPED_AREA* PMAPPED_AREA;
PMAPPED_AREA lpvMem;
#define SHARED_NAME "SHARED_MEM_AREA6"
LRESULT CALLBACK TheShellProc(int nCode,WPARAM wParam, LPARAM lParam);
// предполагается инициализация при каждом аттаче
static HANDLE hMapObject = NULL;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
BOOL fInit, fIgnore;
switch (ul_reason_for_call)
{
// The DLL is loading due to process
// initialization or a call to LoadLibrary.
case DLL_PROCESS_ATTACH:
// Ниже создается отображение MMF. Полет нормальный.
// Create a named file mapping object.
hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,PAGE_READWRITE,0,sizeof(MAPPED_AREA),SHARED_NAME);
if (hMapObject == NULL)
return FALSE;
// The first process to attach initializes memory.
fInit = (GetLastError() != ERROR_ALREADY_EXISTS);
// Get a pointer to the file-mapped shared memory.
lpvMem = (PMAPPED_AREA)MapViewOfFile(MapObject,FILE_MAP_WRITE,0,0,0);
if (lpvMem == NULL)
return FALSE;
// Действия при инициализации
if(fInit)
{
memset((void*)lpvMem,0,sizeof(MAPPED_AREA));
SetLastError(0);
lpvMem->hkShell=SetWindowsHookEx(WH_SHELL,(HOOKPROC)TheShellProc,(HINSTANCE)hModule,0);
// И так далее...
}
break;
case DLL_THREAD_DETACH:
break;
// The DLL is unloading from a process due to
// process termination or a call to FreeLibrary.
case DLL_PROCESS_DETACH:
// Действия при детаче экземпялра длл
UnhookWindowsHookEx(lpvMem->hkShell);
// Unmap shared memory from the process's address space.
fIgnore = UnmapViewOfFile(lpvMem);
// Close the process's handle to the file-mapping object.
fIgnore = CloseHandle(hMapObject);
//...
break;
default:
break;
}
return TRUE;
}
LRESULT CALLBACK TheShellProc(int nCode,WPARAM wParam, LPARAM lParam)
{
if(nCode>=0)
{
lpvMem->nCount++;
if(nCode==HSHELL_WINDOWCREATED)
{ // Здесь узнается caption окна и проводятся дальнейшие действия
char stWindowName[128];
GetWindowText((HWND)wParam,(LPSTR)&stWindowName,sizeof(stWindowName));
}
}
return CallNextHookEx(lpvMem->hkShell,nCode,wParam,lParam);
}