🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.nativeapi
4 messages
4 total messages Started by Patryk B. Thu, 12 Jun 2008 06:33
Problem with global hook?
#128
Author: Patryk B.
Date: Thu, 12 Jun 2008 06:33
73 lines
3086 bytes
Hello,

I've wrote code that make inactive window transparent.
It's works but not to good :) I've used global hook to detect when window
is going to be active/inactive. Here is my code (from dll):

HINSTANCE hDLL;
HHOOK hWin;
HWND hWindow;
extern "C" __declspec(dllexport) void _stdcall SetHook(void);
extern "C" __declspec(dllexport) void _stdcall RemoveHook(void);
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	if(nCode <0)
	{
		return CallNextHookEx(hWin, nCode, wParam, lParam);
	}

	if(nCode==HC_ACTION)
	{
		CWPSTRUCT* msg=(CWPSTRUCT*)lParam;
		hWindow=msg->hwnd;
		if(msg->message==WM_ACTIVATE)
		{
			if(IsWindowVisible(hWindow) && (GetWindow(hWindow, GW_OWNER) == NULL)
&&((GetWindowLong(hWindow, GWL_EXSTYLE) & WS_EX_TOOLWINDOW) == 0))
			{
				if(LOWORD(msg->wParam==WA_INACTIVE))
				{
					SetWindowLong(hWindow, GWL_EXSTYLE,GetWindowLong(hWindow, GWL_EXSTYLE)
| WS_EX_LAYERED);
					::SetLayeredWindowAttributes(hWindow, 0, 180, LWA_ALPHA);

				}
				if(LOWORD(msg->wParam==WA_ACTIVE) ||
LOWORD(msg->wParam==WA_CLICKACTIVE))
				{
					::SetLayeredWindowAttributes(msg->hwnd, 0, 255, LWA_ALPHA);
				}
			}
		}
	}

	return CallNextHookEx(hWin, nCode, wParam, lParam);
}
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*
lpReserved)
{
	hDLL=hinst;
	return 1;
}
//---------------------------------------------------------------------------
void _stdcall SetHook(void)
{
	hWin=SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, hDLL, NULL);
}
//---------------------------------------------------------------------------
void _stdcall RemoveHook(void)
{
	UnhookWindowsHookEx(hWin);
}
//---------------------------------------------------------------------------


Ok, code work like it should, inactive windows are transparent, active
window not. But when im traying to move window it's move veeeery slow.
It's laging and I dont know why...
When I put for example Beep() instead of setting transparency, pc beeping
when window changing state but it not laging. When I set transparency for
window from normal program (exe) it works ok. So why it dont work when im
trying to set transparency from that dll?

Patryk. 
Re: Problem with global hook?
#129
Author: Bob Gonder
Date: Thu, 12 Jun 2008 15:17
44 lines
2429 bytes
Patryk B. wrote:

>Ok, code work like it should, inactive windows are transparent, active
>window not. But when im traying to move window it's move veeeery slow.
>It's laging and I dont know why...
>When I put for example Beep() instead of setting transparency, pc beeping
>when window changing state but it not laging.

The following code is all that is executed during drag,
so that shouldn't be the problem:

>LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
>{
>	if(nCode <0)
>	{	return CallNextHookEx(hWin, nCode, wParam, lParam);
>	}
>	if(nCode==HC_ACTION)
>	{	CWPSTRUCT* msg=(CWPSTRUCT*)lParam;
>		hWindow=msg->hwnd;	<-- not significant,
			but you might move this after if(WM_ACTIVATE)
>		if(msg->message==WM_ACTIVATE)
>		{
			// not executed during drag.
>		}
>	}
>	return CallNextHookEx(hWin, nCode, wParam, lParam);
>}

>When I set transparency for window from normal program (exe) it
>works ok. So why it dont work when im trying to set transparency
>from that dll?

When setting from program, only program is affected.
When setting from DLL, _all_ windows affected.

Just a guess, but from the following link, you should be clearing
the WS_EX_LAYERED bit instead of changing the alpha to 255.

Using Layered Windows (bottom of page)
http://msdn.microsoft.com/en-us/library/ms632598(VS.85).aspx

See also Layered Windows at
http://msdn.microsoft.com/en-us/library/ms632599(VS.85).aspx
where it suggests using UpdateLayeredWindow for position changes.
Re: Problem with global hook?
#130
Author: Remy Lebeau (TeamB)
Date: Thu, 12 Jun 2008 16:31
53 lines
2944 bytes
"Patryk B." <no.spam@spam.pl> wrote in message 
news:bhxmq2m9ts12.1p5w7pvxgm2as.dlg@40tude.net...

> HHOOK hWin;

That handle needs to be stored in a block of shared memory so that every 
instance of the DLL has access to it.  Use CreateFileMapping() and 
MapViewOfFile() to create such a memory block.

> extern "C" __declspec(dllexport) void _stdcall SetHook(void);
> extern "C" __declspec(dllexport) void _stdcall RemoveHook(void);
> LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)

You need to export your hook procedure as well:

    extern "C" __declspec(dllexport) LRESULT CALLBACK CallWndProc(int nCode, 
WPARAM wParam, LPARAM lParam);

> SetWindowLong(hWindow, GWL_EXSTYLE,GetWindowLong(hWindow, GWL_EXSTYLE)
> | WS_EX_LAYERED);

You should check if WS_EX_LAYERED is already applied before re-applying it:

    long exstyle = GetWindowLong(hWindow, GWL_EXSTYLE);
    if( (exstyle & WS_EX_LAYERED) == 0 )
        SetWindowLong(hWindow, GWL_EXSTYLE, exstyle | WS_EX_LAYERED);

> if(LOWORD(msg->wParam==WA_ACTIVE) ||
> LOWORD(msg->wParam==WA_CLICKACTIVE))
> {
> ::SetLayeredWindowAttributes(msg->hwnd, 0, 255, LWA_ALPHA);
> }

Likewise, you should check for WS_EX_LAYERED before calling 
SetLayeredWindowAttributes().

> Ok, code work like it should, inactive windows are transparent,
> active window not. But when im traying to move window it's
> move veeeery slow.

That is because your hook is getting called on every message that every 
window receives.  That is very inefficient.  You might consider using a 
WH_CBT hook instead, checking for the HCBT_ACTIVATE notification.

> When I put for example Beep() instead of setting transparency,
> pc beeping when window changing state but it not laging.

Applying and removing alpha blending is not a trivial task for the OS to 
perform.  So there is going to be some overhead to it.


Gambit 
Re: Problem with global hook?
#131
Author: Remy Lebeau (TeamB)
Date: Thu, 12 Jun 2008 16:34
16 lines
1730 bytes
"Bob Gonder" <none@nowhere.invalid> wrote in message 
news:8ce2545biafpgdrnirg8be2bto3cragih3@4ax.com...

> Just a guess, but from the following link, you should be clearing
> the WS_EX_LAYERED bit instead of changing the alpha to 255.

Although I would typically agree with that, you do have to take into account 
that an app may already be using WS_EX_LAYERED for its own purposes, so 
messing with that style manually might have undesirable effects. It may be 
better for the DLL to keep track of which windows did not already have 
WS_EX_LAYERED applied so that it knows which windows it can safely remove 
WS_EX_LAYERED from.


Gambit 
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads