Hi,

This concerns Microsoft Windows. I want to know when a window from other processes is made visible. Also, I want the handle of the window. I've tried to catch the message WM_SHOWWINDOW with SetWindowsHookEx(WH_GETMESSAGE, &MessageProc, g_hInstance, 0) but I receive no events ! The only events I receive is when I do a call to MessageBox after the call to SetWindowsHookEx. But the events only come from user32.dll. I call MessageBox to tell me that the call to SetWindowsHookEx is successful. Please, I need your help. Thank you.

Attachments
// HideMeHook.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "HideMeHook.h"

HINSTANCE g_hInstance = NULL;
HWND g_hHideMeWnd = NULL;
DWORD g_dwAppProcessId = 0;
UINT g_uiHideMeHookMsg = 0;
HHOOK g_hMessageHook = NULL;


BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	//case DLL_THREAD_ATTACH:
		g_hInstance = (HINSTANCE)hModule;
		break;
	//case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		UnsetHook();
		break;
	}
    return TRUE;
}

HIDEMEHOOK_API void SetHook(HWND hHideMeWnd, DWORD dwAppProcessId)
{
	g_hHideMeWnd = hHideMeWnd;
	g_dwAppProcessId = dwAppProcessId;
	g_uiHideMeHookMsg = RegisterWindowMessage("HideMeHook");
	if (g_hHideMeWnd && g_dwAppProcessId && g_uiHideMeHookMsg)
	{
		g_hMessageHook = SetWindowsHookEx(WH_GETMESSAGE, &MessageProc, g_hInstance, 0);
		//g_hMessageHook = SetWindowsHookEx(WH_CALLWNDPROCRET, &CallWndProc, g_hInstance, 0);
		//if (g_hMessageHook)
		//{
		//	MessageBox(NULL, "Hook installed", "Hook", MB_OK);
		//}
	}
}

HIDEMEHOOK_API void UnsetHook()
{
	g_hHideMeWnd = NULL;
	g_dwAppProcessId = 0;
	g_uiHideMeHookMsg = 0;
	if (g_hMessageHook)
	{
		UnhookWindowsHookEx(g_hMessageHook);
		g_hMessageHook = NULL;
	}
}

LRESULT CALLBACK MessageProc(int code, WPARAM wParam, LPARAM lParam)
{
	if (code == HC_ACTION)
	{
		DWORD dwWndProcessId = 0;
		GetWindowThreadProcessId(((MSG *)lParam)->hwnd, &dwWndProcessId);
		//HMODULE hModule = (HMODULE)GetWindowLong(((MSG *)lParam)->hwnd, GWL_HINSTANCE);
		//TCHAR tmp[300];
		//HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwWndProcessId);
		//GetModuleFileNameEx(hProcess, hModule, tmp, 299);
		//CloseHandle(hProcess);
		if (dwWndProcessId == g_dwAppProcessId)
		{
			if ((LOWORD(((MSG *)lParam)->message) == WM_SHOWWINDOW))
			{
				PostMessage(g_hHideMeWnd, g_uiHideMeHookMsg, wParam, lParam);
			}
		}
	}
	return CallNextHookEx(g_hMessageHook, code, wParam, lParam);
}

//LRESULT CALLBACK CallWndProc(int code, WPARAM wParam, LPARAM lParam)
//{
//	if (code == HC_ACTION)
//	{
//		DWORD dwWndProcessId = 0;
//		GetWindowThreadProcessId(((CWPSTRUCT *)lParam)->hwnd, &dwWndProcessId);
//		if (dwWndProcessId == g_dwAppProcessId)
//		{
//			if ((((CWPSTRUCT *)lParam)->message == WM_SHOWWINDOW))
//			{
////				MessageBox(NULL, "Post Message", "Hook", MB_OK);
//				PostMessage(g_hHideMeWnd, g_uiHideMeHookMsg, wParam, lParam);
//			}
//		}
//	}
//	return CallNextHookEx(g_hMessageHook, code, wParam, lParam);
//}

//// This is the constructor of a class that has been exported.
//// see HideMeHook.h for the class definition
//CHideMeHook::CHideMeHook()
//{ 
//	return; 
//}

You have to hook external objects using global hooks (those residing in a DLL). Process hooks can only be used with your own application's processes.

You have to hook external objects using global hooks (those residing in a DLL). Process hooks can only be used with your own application's processes.

Sorry, but I don't understand. My hook is already in a DLL, or do you mean that exists other hook functions that are more global to the system ? What I don't understand, is this is supposed to work according to Microsoft documentation :

SetWindowsHookEx
...
These events are associated either with a specific thread or with all threads in the same desktop as the calling thread.

I'm sorry, I mixed-up that last two arguments to SetWindowsHookEx() and thought you were installing a process hook.

The WM_SHOWWINDOW message is not a queued message --it is sent directly to the target window procedure. Hence, the WH_GETMESSAGE hook will never see it. You'll need to install a WH_CALLWNDPROC hook to catch it.

Annoying, isn't it?

(Sorry it took me this long to pay enough attention to answer your question...)

Thanks for your answer. Yes, I already tried WH_CALLWNDPROC with no luck. Please, see the file attachment to my first message.

Newsgroups are archived. For ever and ever. (But they are annoying to search.)

Yes, I already tried WH_CALLWNDPROC with no luck. Please, see the file attachment to my first message.

No, you tried WH_CALLWNDPROCRET, which is entirely different.

If you are still having problems I'll see if I can't compile your code myself and figure out what's wrong.

I also tried with WH_CALLWNDPROC and it doesn't work. Ok, I have no choice to send you the complete code, make what you want with it ;) It was supposed to be a simple program to practice and learn C/C++. It's developped under Visual Studio .NET 2002. I'll do cleanup when the hook will work.

This article has been dead for over six months. Start a new discussion instead.