WM_GETMINMAXINFO using WndProc and MINMAXINFO

Hi. I’m new to Xojo and I’m still getting to grips with things. I’ve got a problem below.

I have a working WndProc catching messages on my window. I’m trying to stop the window sizing too small by trapping WM_GETMINMAXINFO but I can’t figure out how to resolve lParam into a structure when its passed in as an Integer.

In other languages, I would cast lParam as MINMAXINFO pointer and access the structure that way, but I can’t seem to get it working in Xojo. I’ve tried all sorts of pointers and casting but I can’t get it right. Could someone please point me in the right direction? Many thanks

[code]Private Shared Function theNewWndProc(hWnd as Integer, msg as Integer, wParam as Integer, lParam as Integer) As Integer
Const WM_GETMINMAXINFO = &h0024

if msg = WM_GETMINMAXINFO then

// lParam is a pointer to a MINMAXINFO structure, how can I assign and use that here?
// I have corrently defined structure for MINMAXINFO as described on the
// MSDN page here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms632626(v=vs.85).aspx

end if

Declare Function CallWindowProcW Lib “User32” ( oldProc As Ptr, handle As Integer, msg As Integer, wParam As Integer, lParam As Integer ) As Integer
Return CallWindowProcW( theOldWndProc, hWnd, msg, wParam, lParam )
End Function
[/code]

Cast integer to Ptr and access values.

And instead of writing own wndproc filter I would use the plugin and only catch the messages I need:

See WinNotificationMBS class
http://www.monkeybreadsoftware.net/class-winnotificationmbs.shtml

Else this can slow down the windows app a lot.

If you have defined the structure in the IDE, then you can use the structure name and an offset (typically zero) to convert a Ptr into the structure.

The structures look like this:

Structure POINT
	X As Integer
	Y As Integer
	

Structure MINMAXINFO
	Reserved As POINT
	MaxSize As POINT
	MaxPosition As POINT
	MinTrackSize As POINT
	MaxTrackSize As POINT
Private Shared Function theNewWndProc(hWnd as Integer, msg as Integer, wParam as Integer, lParam as Integer) As Integer
  Const WM_GETMINMAXINFO = &h0024
  
  if msg = WM_GETMINMAXINFO then
    
    Dim p As Ptr = Ptr(lparam)
    Dim mystruct As MINMAXINFO = p.MINMAXINFO(0)
    
  end if

PS

Add this line to your Window procedure callback to avoid strange and hard to diagnose crashes:

#pragma X86CallingConvention StdCall

Thanks Chrstian, I’ll take a look at that if I can’t get this working.

Andrew, thank you very much for the code, it all looks great but I can’t for the life of me get the MinTrackSize to work, would you be able to sped some light on it? I must be doing something glaringly stupid? My structures are exactly the same as yours, private under the window. Thanks in advance.

[code]Private Shared Function theNewWndProc(hWnd as Integer, msg as Integer, wParam as Integer, lParam as Integer) As Integer
#pragma X86CallingConvention StdCall

Const WM_GETMINMAXINFO = &h0024

Select Case msg
Case WM_GETMINMAXINFO

Dim p as Ptr = Ptr(lParam)
Dim mystruct As MINMAXINFO = p.MINMAXINFO(0)

mystruct.MinTrackSize.X = 400
mystruct.MinTrackSize.Y = 400

// I can break here and the values have all been set correctly.

Return 0 //If an application processes this message, it should return zero.

Else
Declare Function CallWindowProcW Lib “User32” ( oldProc As Ptr, handle As Integer, msg As Integer, wParam As Integer, lParam As Integer ) As Integer
Return CallWindowProcW( theOldWndProc, hWnd, msg, wParam, lParam )
End Select

End Function
[/code]

You know the window class has a minimum width and height property you can just set in the IDE?

Yes I have tried that. The window doesn’t actually stop at the minimum size, it can be sized really small until you release the mouse button, then it snaps back to the minimum size which looks horrendous which is why I’m trying to do it the correct way as above. Unless I have a setting incorrect somewhere.

Just tried this on Windows 7, Xojo 2015R3, with a window set to 200 x 200 minimum
It resizes smoothly until it reaches 200 but won’t go smaller for me.
How does your setup differ?

Very odd, I’m running W10 64 with Xojo 2016 Release 1 on a blank project. See the video below if the link works:

https://www.dropbox.com/s/hpezkmbpwbwn4b0/2016-04-23_23-50-21.mp4

[quote=261871:@]Very odd, I’m running W10 64 with Xojo 2016 Release 1 on a blank project. See the video below if the link works:

https://www.dropbox.com/s/hpezkmbpwbwn4b0/2016-04-23_23-50-21.mp4[/quote]

In the IDE you can do that, but when you build (run) the app, the window can’t be resized smaller than the minimum values.

That is the running app that I’m resizing, I clicked the Run > button.

Are you saying that it will only work if I “build” the project?

Can anyone else replicate this behaviour in Windows 10 on Xojo 2016 R1 ?

Just create a new project with a single window, set its min width and min height to 300, run the project and drag the window as small as possible. Does it stop at 300 300 or does it resize all the way down and start flickering as per my video above?

Thanks in advance.

I dont have 2016 myself… all I have read on the forum since it came out suggests that its a bit unstable yet.

Here’s a random theorum: are you using the HDi functionality?
Maybe you can resize it down to 300 pixels, then scaling kicks in and it gets made up to 300 (bigger) points ?

[quote=261926:@Jeff Tullin]I dont have 2016 myself… all I have read on the forum since it came out suggests that its a bit unstable yet.

Here’s a random theorum: are you using the HDi functionality?
Maybe you can resize it down to 300 pixels, then scaling kicks in and it gets made up to 300 (bigger) points ?[/quote]

Nope, I’m running native rez, no scaling.

I’ve had a look around the site and I can’t find a link for version 2015, I guess I’d need to purchase? I’d try that in a second and it would rule out a few things if it did/didn’t work. I can’t really put a bug report in until someone can replicate it as I guess it could be something wrong with my system.

I just ran a quick test with 2016R1 under Windows 10, it works as expected : I cannot make the window any smaller than the minimum width and height.

[quote=261835:@]Thanks Chrstian, I’ll take a look at that if I can’t get this working.

Andrew, thank you very much for the code, it all looks great but I can’t for the life of me get the MinTrackSize to work, would you be able to sped some light on it? I must be doing something glaringly stupid? My structures are exactly the same as yours, private under the window. Thanks in advance.

[code]Private Shared Function theNewWndProc(hWnd as Integer, msg as Integer, wParam as Integer, lParam as Integer) As Integer
#pragma X86CallingConvention StdCall

Const WM_GETMINMAXINFO = &h0024

Select Case msg
Case WM_GETMINMAXINFO

Dim p as Ptr = Ptr(lParam)
Dim mystruct As MINMAXINFO = p.MINMAXINFO(0)

mystruct.MinTrackSize.X = 400
mystruct.MinTrackSize.Y = 400

// I can break here and the values have all been set correctly.

Return 0 //If an application processes this message, it should return zero.

Else
Declare Function CallWindowProcW Lib “User32” ( oldProc As Ptr, handle As Integer, msg As Integer, wParam As Integer, lParam As Integer ) As Integer
Return CallWindowProcW( theOldWndProc, hWnd, msg, wParam, lParam )
End Select

End Function
[/code][/quote]

In this code mystruct is a copy of the structure Windows pass by reference to your function.
When this function returns mystruct gets lost and, as a copy, you are not passing the new values back to Windows itself.
Modify the code linke this:

Dim p as Ptr = Ptr(lParam) p.MINMAXINFO.MinTrackSize.X = 400 p.MINMAXINFO.MinTrackSize.Y = 400

In any case Windows does not resize your program windows smaller than the minimum value you defined in the IDE.

Regards.

[quote=261934:@Maurizio Rossi]In this code mystruct is a copy of the structure Windows pass by reference to your function.
When this function returns mystruct gets lost and, as a copy, you are not passing the new values back to Windows itself.
Modify the code linke this:

Dim p as Ptr = Ptr(lParam) p.MINMAXINFO.MinTrackSize.X = 400 p.MINMAXINFO.MinTrackSize.Y = 400

In any case Windows does not resize your program windows smaller than the minimum value you defined in the IDE.

Regards.[/quote]

Thank you Murizio! It’s working perfectly now!!

Thanks Michel for testing it and letting me know. I’ll have to do some more testing to see why it doesn’t work without this code. I’ll try it on a fresh install of W10 in a VM first, I’ll let you know what I find.

Well that didnt take me long to find the problem now I know its working on someone else’s 2016R1.

I run a program called Sizer by Brian Apps which allows me to set the size of any window which I use to set windows internal size to 1920x1200 for video recording. If I quit the program and try a fresh xojo app with min window size and no other code it works as expected and limits the min size.

It would seem that the Xojo’s default method of setting window min size conflicts with Sizer allowing the window to crush right down. But when I code in my own size restriction as above it works fine and limits the min size. That would lead me to believe that there is something wrong with Xojo’s method of setting the windows min size so its breaking somewhere as I have never had a window go past its min size in the way shown in my video above.

Thanks to everyone for their help, I’ll raise this as a bug and see where it goes.

It seems rather paradoxical to accuse Xojo of not managing minwidth and minheight correctly when obviously the issue comes from a third party class. If Sizer messes up, the blame should not be placed anywhere else.

Sizer doesnt “mess up” other apps. This is the first and only time I’ve ever seen a problem with minwidth minheight and it comes from a xojo app I’d rather start looking there first to discount that possibility. I can write a 10 line program in another language that works flawlessly with Sizer running, and I can trap the correct windows message in Xojo to make my app work with Sizer, so I can only assume the library that Xojo default apps use is at fault until I find otherwise?

If 100 cars pass over a road with no vibration and one car passes over a road and vibrates, you’d check the car, not the road right?

Every single other app I have works with Sizer, I make one app with Xojo and it doesn’t behave as expected, why would I check Sizer first?