Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Changing WM_GETMINMAXINFO in system wide hook

562 views
Skip to first unread message

Steve Easley

unread,
Sep 16, 2002, 2:28:04 PM9/16/02
to
I am trying to write a system wide hook to alter the MINMAXINFO structure.
The code is below. My hook is being called as expected and the MINMAXINFO
structure in the code block is getting successfully changed. But when the
WM_GETMINMAXINFO message is passed on to WinProc, the MINMAXINFO has
reverted back to its default. So my new max size is not taking effect.

I did see on MSDN about CallWndProc: "The CallWndProc hook procedure can
examine the message, but it cannot modify it".

Is that the issue? If so, what other hook can I use to capture
WM_GETMINMAXINFO? GetMsgProc would seem like a good candidate, but it never
receives the WM_GETMINMAXINFO message.

Any ideas? Thanks.
Steve

--- Code ---

LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
CWPSTRUCT* pM = (CWPSTRUCT*)lParam ;
LPMINMAXINFO lpmmi;

if (nCode < 0)
return CallNextHookEx(hhook, nCode, wParam, lParam) ;

switch (nCode)
{
case HC_ACTION:
if(pM->message == WM_GETMINMAXINFO)
{
lpmmi = (LPMINMAXINFO)(pM->lParam) ;
lpmmi->ptMaxSize.x=400 ;
lpmmi->ptMaxSize.y=400;
}

default:
break ;
}

return CallNextHookEx(hhook, nCode, wParam, lParam) ;
}


Russ Freeman

unread,
Sep 16, 2002, 7:23:31 PM9/16/02
to
"Steve Easley" <n...@spam.com> wrote in message
news:Uoph9.45359$ip3.1...@twister.southeast.rr.com...

> I am trying to write a system wide hook to alter the MINMAXINFO structure.
> The code is below. My hook is being called as expected and the MINMAXINFO
> structure in the code block is getting successfully changed. But when the
> WM_GETMINMAXINFO message is passed on to WinProc, the MINMAXINFO has
> reverted back to its default. So my new max size is not taking effect.
>
> I did see on MSDN about CallWndProc: "The CallWndProc hook procedure can
> examine the message, but it cannot modify it".
>
> Is that the issue?

Of course it is. You are attempting to modify the structure even though the
docs say you can't ;-)


> If so, what other hook can I use to capture
> WM_GETMINMAXINFO? GetMsgProc would seem like a good candidate, but it
never
> receives the WM_GETMINMAXINFO message.
> Any ideas? Thanks

I think I'd be inclined to subclass the window when I see it (WM_NCCREATE)
in the hook and then handle the message modifications there...unless there
is a way to modify the message of course.

--
russ.
http://www.gipsysoft.com/articles/winspector/ - FREE Spy++ replacement.
http://www.gipsysoft.com/qhtm/ - FREE HTML display in a small and light DLL
http://www.gipsysoft.com/ZoomPlus/ - Programmers Zoom Utility on Steroids


Tim Robinson

unread,
Sep 16, 2002, 7:51:29 PM9/16/02
to
Russ Freeman <ru...@gipsysoft.com> wrote:
|| I did see on MSDN about CallWndProc: "The CallWndProc hook procedure
|| can examine the message, but it cannot modify it".
||
|| Is that the issue?
|
| Of course it is. You are attempting to modify the structure even
| though the docs say you can't ;-)

It seems to me that this statement refers to the actual uMsg, wParam and
lParam parameters -- I don't see why there should be a veto on modifying
memory that lParam points to.

However, I can guess why this isn't working:

1) Windows sends WM_GETMINMAXINFO to window, passing a buffer through lParam
2) CallWndProc gets called and modifies the buffer
3) Real WndProc gets called and passes WM_GETMINMAXINFO to DefWindowProc
4) DefWindowProc handles WM_GETMINMAXINFO by **filling in the buffer passed
through lParam**

What Steve probably needs to do is install a CallWndProcRet hook instead, to
overwrite what DefWindowProc puts in the WM_GETMINMAXINFO structure.

--
Tim Robinson
http://www.themobius.co.uk/


Steve Easley

unread,
Sep 16, 2002, 10:17:21 PM9/16/02
to
> What Steve probably needs to do is install a CallWndProcRet hook instead,
to
> overwrite what DefWindowProc puts in the WM_GETMINMAXINFO structure.

Nice thought Tim. I converted my hook to a CallWndProcRet, but no go. I
confirmed that my WM_GETMINMAXINFO hook was run AFTER WndProc and it was.
But the window was still able to be maximized all the way.

Any other ideas?

Steve


Steve Easley

unread,
Sep 16, 2002, 10:21:11 PM9/16/02
to
"Russ Freeman" <ru...@gipsysoft.com> wrote in message
news:uocpvlj...@corp.supernews.com...

> I think I'd be inclined to subclass the window when I see it (WM_NCCREATE)
> in the hook and then handle the message modifications there...unless there
> is a way to modify the message of course.

But this would only modify new windows wouldnt it? I want to intercept and
modify the max size of ALL windows, new AND current.

Steve


Steve Easley

unread,
Sep 16, 2002, 10:46:29 PM9/16/02
to
Well this is wierd. I just ran Spy++, and with my code converted to a
CallWndProcRet hook as Tim suggested, it shows a Send WM_GETMINMAXINFO
MINMAXINFO structure with the ordinary widths and heights and such. Then it
shows a Return WM_GETMINMAXINFO MINMAXINFO structure with the correct
values.

So to summerize:

1. WinProc receives the WM_GETMINMAXINFO message (with the default metrics
values) and passes it on (doing what it does by default)
2. My CallWndProcRet hook receives WM_GETMINMAXINFO and alters the
MINMAXINFO structure

Spy++ is confirming that it is occuring. But for some reason the window can
be sized above the max size I specified.

Just as a sanity check I moved my code to alter the MINMAXINFO structure
into WinProc. And it works fine, the window cant be maximized all the way
out. And oddly enough Spy++ reports just the same as with the hook. A send
message with the default MINMAXINFO structure, the a Receive with the
altered structure. So it looks like it should be working, but it's not.
Grrr....

Steve


Steve Easley

unread,
Sep 16, 2002, 11:15:20 PM9/16/02
to
Well I did some more experimenting. I change my code back to the way it was
in my first post. So I am now hooking CallWndProc again.

What REALLY wierd is that when monitoring the program with Spy++ it shows a
Send WM_GETMINMAXINFO message with a MINMAXINFO structure with the correct
values!! (Because my hook is successfully changing it). But then it shows a
Receive value with a structure that has been reset. Grr...

So I put in a debug line into WinProc like:

--snip--
case WM_GETMINMAXINFO:
lpmmi = (LPMINMAXINFO)(lParam) ;

swprintf(sDebug, L"WndProc: %d", lpmmi->ptMaxSize.x) ;
OutputDebugString(sDebug) ;
return 0;
--snip--

It writes: WndProc: 1032. Which should be a width of 400, not 1032. So even
though Spy++ shows the Window is receiving a structure with a width of 400,
WinProc is recieving something else.

Steve


Bob Moore

unread,
Sep 17, 2002, 3:40:53 AM9/17/02
to
On Mon, 16 Sep 2002 18:28:04 GMT, "Steve Easley" <n...@spam.com> wrote:

>But when the
>WM_GETMINMAXINFO message is passed on to WinProc, the MINMAXINFO has
>reverted back to its default. So my new max size is not taking effect.

I used to use just this technique many moons ago, and it worked fine.
the old (very old - spot the FARs still lying around !!) code is
appended below for comparison.

Just one thought occurs - the width and height values you're using -
they are stored in a shared segment, right ? and initialised ?

**************************
#pragma data_seg(".SHARDAT")
static HWND hWndMain = 0;
static HHOOK hWndHook = NULL ;
static int iLeft = 0;
static int iTop = 0;
static int iWidth = 0;
static int iHeight = 0;
#pragma data_seg()


BOOL DLL_CALL HOOKS32_InstallMinMaxHook (HWND hWnd,
int iLeftX,
int iTopY,
int ixSize,
int iySize)
{
hWndMain = hWnd ;

lpfnHookProc = (HOOKPROC) WndProcFunc ;

iLeft = iLeftX ;
iTop = iTopY ;
iWidth = ixSize ;
iHeight = iySize ;

hWndHook = SetWindowsHookEx (WH_CALLWNDPROC,lpfnHookProc,hInstance,NULL);

if (hWndHook)
return TRUE ;
else
return FALSE ;
}

//---------------------------------------------------------------------------
// FUNCTION : RemoveMinMaxHook
//
// PURPOSE : Removes the filter function from the WndProc hook chain.
//
// INPUTS : Standard Hook format.
//
// AUTHOR : R.M.Moore
//
// MOD HIST :
//---------------------------------------------------------------------------

void DLL_CALL HOOKS32_RemoveMinMaxHook (void)
{
if (hWndHook)
UnhookWindowsHookEx (hWndHook);
}

//---------------------------------------------------------------------------
// FUNCTION : WndProcFunc
//
// PURPOSE : Filter function for the WH_CALLWNDPROC hook. Traps any
// occurrence of WM_GETMINMAXINFO and limits the
maximisation
// size and position to match those requested at
installation.
//
// INPUTS : Standard Hook format.
// OUTPUTS : Standard Hook format.
//
// AUTHOR : R.M.Moore
//
// MOD HIST :
//---------------------------------------------------------------------------

LRESULT DLL_CALL WndProcFunc (int nCode,
WPARAM wParam,
LPARAM lParam)
{
static MyMsg FAR * pMsg ;
static MINMAXINFO FAR * pMinMax ;

pMsg = (MyMsg FAR*) lParam ;

switch (pMsg -> uMsg)
{
case WM_GETMINMAXINFO :

if ((pMsg -> hWnd) != hWndMain)
{
pMinMax = (MINMAXINFO FAR *) pMsg -> lParam ;
pMinMax -> ptMaxSize.x = iWidth ;
pMinMax -> ptMaxSize.y = iHeight ;
pMinMax -> ptMaxPosition.x = iLeft ;
pMinMax -> ptMaxPosition.y = iTop ;
}
break ;

default:
break;
}

return (CallNextHookEx (hWndHook, nCode, wParam, lParam));
}

Jugoslav Dujic

unread,
Sep 17, 2002, 5:15:25 AM9/17/02
to
"Steve Easley" <n...@spam.com> wrote in message
news:c7xh9.46310$ip3.2...@twister.southeast.rr.com...

Well, I wouldn't call it THAT weird. You know, to spy sent & received
messages Spy++ uses... global CallWndProc and CallWndProcRet hooks.
At the moment the only thing I can think of is that there's another
hook in the chain that overwrites *your* data (and the data seen
by Spy++). Can't tell you where that hook comes from -- maybe it's
a system one (well, maybe it doesn't exist at all and my presumptions
are false).

What happens if you apply solution (b) (CallWndProcRet) but NOT call
CallNextHookEx?

--
Jugoslav
___________
www.geocities.com/jdujic


Steve Easley

unread,
Sep 17, 2002, 1:51:20 PM9/17/02
to
Ok, I have more info about my problem. I am currently using the
CallWndRetProc hook. So my hook get processed AFTER WinProc. Using Spy++ and
some debugging output, I have been able to track the memory address of the
MINMAXINFO structure through the system. My theory was that something was
altering before it went back to the system. Here is what I found:

The order is:
1. Spy++ shows a send WM_GETMINMAXINFO message with the MINMAXINFO structure
at memory address A. It contains the default x y etc. size values .
2. WinProc receives the message with MINMAXINFO at the same memory address
A, with the default values.
3. My CallWinProx hook receives the message with MINMAXINFO at the same
memory address A, and it changes the values.
4. Spy++ shows a return message with the MINMAXINFO structure at memory
address B (a completly different address!!!), and the values are the correct
values that my hook set.

So it appears that after, or during, my hook procedure, the pointer is
getting changed. And Windows continues to use the default values (from the
original pointer).

Steve


Russ Freeman

unread,
Sep 17, 2002, 5:52:14 PM9/17/02
to
"Steve Easley" <n...@spam.com> wrote in message
news:rkwh9.46301$ip3.2...@twister.southeast.rr.com...

Okay, then in your global hook keep a map of windows and the first time you
see them subclass.

Russ Freeman

unread,
Sep 17, 2002, 5:53:30 PM9/17/02
to
> Well, I wouldn't call it THAT weird. You know, to spy sent & received
> messages Spy++ uses... global CallWndProc and CallWndProcRet hooks.
> At the moment the only thing I can think of is that there's another
> hook in the chain that overwrites *your* data (and the data seen
> by Spy++). Can't tell you where that hook comes from -- maybe it's
> a system one (well, maybe it doesn't exist at all and my presumptions
> are false).

Or windows copies the message for the hook and then uses the original.

Russ Freeman

unread,
Sep 17, 2002, 5:57:54 PM9/17/02
to
"Steve Easley" <n...@spam.com> wrote in message
news:Uoph9.45359$ip3.1...@twister.southeast.rr.com...

> I am trying to write a system wide hook to alter the MINMAXINFO structure.
> The code is below. My hook is being called as expected and the MINMAXINFO
> structure in the code block is getting successfully changed. But when the
> WM_GETMINMAXINFO message is passed on to WinProc, the MINMAXINFO has
> reverted back to its default. So my new max size is not taking effect.
>
> I did see on MSDN about CallWndProc: "The CallWndProc hook procedure can
> examine the message, but it cannot modify it".
>
> Is that the issue? If so, what other hook can I use to capture
> WM_GETMINMAXINFO? GetMsgProc would seem like a good candidate, but it
never
> receives the WM_GETMINMAXINFO message.

I've recently looked at this again and I think you should use the WH_SHELL
hook (not tried it but the docs suggest it could be useful).

In particular HSHELL_GETMINRECT says "A window is being minimized or
maximized. The system needs the coordinates of the minimized rectangle for
the window.". I'm sure a quick hook will tell you whether it's for minimised
only or minimized *and* maximized. It's got to be worth a shot ;-)

0 new messages