Bay Six Software Forum Index Bay Six Software
Beyond the Basics
 
 FAQFAQ   SearchSearch   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Limit a window's minimum size

 
Post new topic   Reply to topic    Bay Six Software Forum Index -> WMLiberty DLL
View previous topic :: View next topic  
Author Message
Mattestion
New Member


Joined: 29 Feb 2012
Posts: 4

PostPosted: May 12th, 2012, 12:18pm    Post subject: Limit a window's minimum size Reply with quote

I've been trying to use the VB code at this Microsoft article support.microsoft.com/kb/185733. I get the protection violation error and I know it's because I'm not calling the RtlMoveMemory function correctly. But I can't figure out how to do it. In the VB code, it uses type long for the parameters but the MSDN article says to use pointers.

Here is my code:
Code:

    struct MINMAXINFO,_
        ptReserved.x as long,_
        ptReserved.y as long,_
        ptMaxSize.x as long,_
        ptMaxSize.y as long,_
        ptMaxPosition.x as long,_
        ptMaxPosition.y as long,_
        ptMinTrackSize.x as long,_
        ptMinTrackSize.y as long,_
        ptMaxTrackSize.x as long,_
        ptMaxTrackSize.y as long

    open "WMLiberty" for dll as #wmlib

    nomainwin

    WindowWidth = 800
    WindowHeight = 600

    UpperLeftX=int((DisplayWidth-WindowWidth)/2)
    UpperLeftY=int((DisplayHeight-WindowHeight)/2)

    open "Limited Min" for window as #min
    #min "trapclose [QUIT]"

    callback lpfn, OnGetMinMaxInfo(ulong, ulong, ulong, ulong), long

    hwndMin = hwnd(#min)

    calldll #wmlib, "SetWMHandler", _
        hwndMin as ulong, _
        _WM_GETMINMAXINFO as ulong, _
        lpfn as ulong, _
        0 as long, _
        ret as long


[LOOP]
    scan
    calldll #kernel32, "Sleep", _ 'Minimize CPU usage
        50 as long, _
        ret as void
    goto [LOOP]


[QUIT]
    close #min
    close #wmlib
    end


function OnGetMinMaxInfo(hwnd, uMsg, wParam, lParam)
    length = len(MINMAXINFO.struct)
    calldll #kernel32, "RtlMoveMemory", MINMAXINFO as struct, lParam as ulong, length as long

    ptMinTrackSize.x.struct = 400
    ptMinTrackSize.y.struct = 300

    length = len(MINMAXINFO.struct)
    calldll #kernel32, "RtlMoveMemory", lParam as ulong, MINMAXINFO as struct, length as long
end function

_________________
Just BASIC v1.01 / Liberty BASIC Pro v4.04 / Run BASIC v1.01 / Vista Home Premium SP2 - AMD Athlon 64 X2 Dual Core Processor 5000+ 2.60 GHz - 2GB RAM
Back to top
View user's profile Send private message
STPendl
Full Member


Joined: 20 Aug 2007
Posts: 161
Location: Austria

PostPosted: May 12th, 2012, 1:24pm    Post subject: Re: Limit a window's minimum size Reply with quote

VB is bad since they use LONG for anything and convert it to the correct data-type behind the scene.
It is always best to translate from an ANSI C code source to LB, since they do have more in common in regard to data-types.

In addition you are missing an argument of the function, which must be present.

See RtlMoveMemory at MSDN for the correct declaration.

Code:

calldll #kernel32, "RtlMoveMemory", _
    Destination  as struct,_
    Source       as ulong, _
    SourceLength as ulong, _
    Result       as void


Depending on the type of the source and destination, you use ULONG (Windows memory location address) or STRUCT (LB structure).

_________________
Stefan

Any code I post can be freely used, just give credit.
Back to top
View user's profile Send private message
Mattestion
New Member


Joined: 29 Feb 2012
Posts: 4

PostPosted: May 13th, 2012, 12:20am    Post subject: Re: Limit a window's minimum size Reply with quote

Quote:
It is always best to translate from an ANSI C code source to LB

That's my feeling as well but I couldn't find any code in C. All the forums kept saying to respond to the WM_GETMINMAXINFO message and fill in the MINMAXINFO struct but they never gave any code.

Quote:
In addition you are missing an argument of the function

Doh! I can't believe I forgot the Result argument. I also forgot that you can't fill in the struct like this:
Code:

ptMinTrackSize.x.struct = 400
ptMinTrackSize.y.struct = 300

It needs the name of the struct like this:
Code:

MINMAXINFO.ptMinTrackSize.x.struct = 400
MINMAXINFO.ptMinTrackSize.y.struct = 300


Thanks Stefan for your help with the data types. It works great now. Here is the corrected code:
Code:

    struct MINMAXINFO,_
        ptReserved.x as long,_
        ptReserved.y as long,_
        ptMaxSize.x as long,_
        ptMaxSize.y as long,_
        ptMaxPosition.x as long,_
        ptMaxPosition.y as long,_
        ptMinTrackSize.x as long,_
        ptMinTrackSize.y as long,_
        ptMaxTrackSize.x as long,_
        ptMaxTrackSize.y as long

    open "WMLiberty" for dll as #wmlib

    nomainwin

    WindowWidth = 800
    WindowHeight = 600

    UpperLeftX=int((DisplayWidth-WindowWidth)/2)
    UpperLeftY=int((DisplayHeight-WindowHeight)/2)

    open "Limited Min" for window as #min
    #min "trapclose [QUIT]"

    callback lpfn, OnGetMinMaxInfo(ulong, ulong, ulong, ulong), long

    hwndMin = hwnd(#min)

    calldll #wmlib, "SetWMHandler", _
        hwndMin as ulong, _
        _WM_GETMINMAXINFO as ulong, _
        lpfn as ulong, _
        0 as long, _
        ret as long


[LOOP]
    scan
    calldll #kernel32, "Sleep", _ 'Minimize CPU usage
        50 as long, _
        ret as void
    goto [LOOP]


[QUIT]
    close #min
    close #wmlib
    end


function OnGetMinMaxInfo(hwnd, uMsg, wParam, lParam)
    length = len(MINMAXINFO.struct)
    calldll #kernel32, "RtlMoveMemory", MINMAXINFO as struct, lParam as ulong, length as ulong, result as void

    MINMAXINFO.ptMinTrackSize.x.struct = 400
    MINMAXINFO.ptMinTrackSize.y.struct = 300

    length = len(MINMAXINFO.struct)
    calldll #kernel32, "RtlMoveMemory", lParam as ulong, MINMAXINFO as struct, length as ulong, result as void
end function

_________________
Just BASIC v1.01 / Liberty BASIC Pro v4.04 / Run BASIC v1.01 / Vista Home Premium SP2 - AMD Athlon 64 X2 Dual Core Processor 5000+ 2.60 GHz - 2GB RAM
Back to top
View user's profile Send private message
STPendl
Full Member


Joined: 20 Aug 2007
Posts: 161
Location: Austria

PostPosted: May 13th, 2012, 9:08am    Post subject: Re: Limit a window's minimum size Reply with quote

Another way would be using the RESIZEHANDLER, but that only works for windows of type window.

For dialog type windows you could use the approach I used for my LB 4.04 help search entry.

_________________
Stefan

Any code I post can be freely used, just give credit.
Back to top
View user's profile Send private message
RichardRussell
Full Member


Joined: 28 Jan 2012
Posts: 57
Location: Downham Market, UK

PostPosted: May 13th, 2012, 2:38pm    Post subject: Re: Limit a window's minimum size Reply with quote

STPendl wrote:
VB is bad since they use LONG for anything and convert it to the correct data-type behind the scene.
It is always best to translate from an ANSI C code source to LB, since they do have more in common in regard to data-types.

It makes not the slightest difference whether you specify LONG or ULONG in a STRUCT declaration or a CALLDLL statement, so long as the actual value is valid for both (which means it is in the range 0 to +2147483647). Only if the value is negative (in which case you must use LONG) or greater than +2147483647 (in which case you must use ULONG) does it matter.

So for example in the case of the RtlMoveMemory API you can be absolutely certain that the length parameter is valid for both LONG and ULONG, and it makes no difference which you use.

Richard.
Back to top
View user's profile Send private message Visit poster's website
Alyce
Full Member


Joined: 04 Jul 2005
Posts: 91

PostPosted: May 14th, 2012, 12:32pm    Post subject: Re: Limit a window's minimum size Reply with quote

RichardRussell wrote:

It makes not the slightest difference whether you specify LONG or ULONG in a STRUCT declaration or a CALLDLL statement, so long as the actual value is valid for both
Richard.


That is not correct for Liberty BASIC. You may not know the "actual value" returned from the HWND statement, for instance. If you pass it as a long into an API call it might be misinterpreted. This has happened to folks and caused errors that are hard to nail down.

Stefan is correct when he cautions folks to use C rather than VB for documentation on API functions.

_________________
- Alyce
Back to top
View user's profile Send private message Visit poster's website
RichardRussell
Full Member


Joined: 28 Jan 2012
Posts: 57
Location: Downham Market, UK

PostPosted: May 14th, 2012, 1:29pm    Post subject: Re: Limit a window's minimum size Reply with quote

Alyce wrote:
That is not correct for Liberty BASIC. You may not know the "actual value" returned from the HWND statement, for instance.

It is always correct; the language makes no difference. There are basically three situations that you can encounter in Liberty BASIC:

1. The value that you are storing in a STRUCT, or passing in a CALLDLL statement, is known (for example it may be a constant that you set in your program). In that case you can easily determine what type to use: if it's negative you must declare it as LONG, if it's greater than +2147483647 you must declare it as a ULONG. Otherwise it makes no difference, you can use LONG or ULONG.

2. The value that you are storing in a STRUCT, or passing in a CALLDLL, was itself returned from a previous API call. In that case what matters is that the type you specified for the value returned from the original API is the same as the type you specify in the STRUCT or CALLDLL. It doesn't matter whether it's LONG or ULONG, but they must agree. So for example both these code snippets are perfectly correct:

Code:
calldll #user32, "GetDesktopWindow", hdesk as LONG
calldll #user32, "GetWindowDC", hdesk as LONG, hdc as LONG

calldll #user32, "GetDesktopWindow", hdesk as ULONG
calldll #user32, "GetWindowDC", hdesk as ULONG, hdc as ULONG

A myth has developed at some stage that you must always use ULONG for handles, but that is not true. In a case such as the code above all that matters is that the type specified when the handle is retrieved is the same as that when it is subsequently used.

3. The value is a handle returned from HWND(). When passing the handle to CALLDLL or storing it in a STRUCT you must use whatever type is returned from HWND(). The trouble is that the LB docs don't tell you what that is! I assume that it's a ULONG, in which case that's the type you should specify in the STRUCT or CALLDLL. But it would be a lot more helpful it that was stated somewhere. Wink

What's important to realise is that the type specified in (say) the Microsoft documentation for an API is never important in LB. When LB calls an API it simply passes numbers, there is no way that Windows can tell or care what type was assigned to that number in LB. I read Stefan's comment as implying the contrary - that somehow it can be important to specify in your LB program the type that MSDN specifies rather than the type the VB docs specify. That is not correct and it can lead to a misunderstanding about how the interface between an application and the Windows API works.

Richard.
Back to top
View user's profile Send private message Visit poster's website
Alyce
Full Member


Joined: 04 Jul 2005
Posts: 91

PostPosted: May 14th, 2012, 2:16pm    Post subject: Re: Limit a window's minimum size Reply with quote

RichardRussell wrote:

A myth has developed at some stage that you must always use ULONG for handles, but that is not true.


The "myth" developed because Carl stated it to be so. Since he is the author of the language, I trust he knows how types are handled behind the scenes.

Quote:
3. The value is a handle returned from HWND(). When passing the handle to CALLDLL or storing it in a STRUCT you must use whatever type is returned from HWND(). The trouble is that the LB docs don't tell you what that is! I assume that it's a ULONG, in which case that's the type you should specify in the STRUCT or CALLDLL. But it would be a lot more helpful it that was stated somewhere. Wink


As I wrote above, it is type ulong. It should be stated in the docs. Considering the fact that Carl must make a living at a full-time job and must develop LB by himself in whatever spare time he can find, I think he does an excellent job. He did a better job when he could devote 100% of his working hours to LB. That has not been the case for years, though.

I don't disagree that you can pass a number as either ulong or long as long as it fits within the values of the type specified. Liberty BASIC is meant to be beginner-friendly, hobbiest-friendly. Since Carl tells us that handles are always to be of type ulong, it is much easier to pass them as ulong than to put in conditional statements to check if they are within a certain range of numbers so that they can be passed as longs.

_________________
- Alyce
Back to top
View user's profile Send private message Visit poster's website
RichardRussell
Full Member


Joined: 28 Jan 2012
Posts: 57
Location: Downham Market, UK

PostPosted: May 14th, 2012, 5:16pm    Post subject: Re: Limit a window's minimum size Reply with quote

Alyce wrote:
The "myth" developed because Carl stated it to be so. Since he is the author of the language, I trust he knows how types are handled behind the scenes.

I don't know the context in which he stated that, but I expect he was referring to the type returned by HWND(), which may well be a ULONG.

Given that being the case, I have no objection to advising users of LB always to use ULONG for handles, because it's a nice easy-to-remember rule, and as you rightly say LB is intended to be simple for beginners.

However I still think it is important to appreciate that it's only essential to use ULONG when the handle was returned from HWND(). When it is returned from an API function all that matters is that the same type (LONG or ULONG) is used consistently for that handle.

I'm not trying to second-guess how LB is implemented, and certainly not suggesting that Carl is mistaken, but simply stating a fundamental fact which follows from the way all applications interface with the Windows API.

Quote:
Considering the fact that Carl must make a living at a full-time job and must develop LB by himself in whatever spare time he can find, I think he does an excellent job.

No criticism of Carl was intended or implied. I would prefer the docs to be more comprehensive and more accurate, but I can understand Carl wishing to concentrate his time on coding rather than writing documentation. The user community can go a long way to address the deficiencies in the docs.

I'm fortunate in having now retired so I don't have to divide my time between paid employment and 'hobby' programming. However for about 25 years I was in exactly the same position as Carl: working full-time for an employer and developing/documenting/marketing BBC BASIC in my spare time. So I know what the pressures are.

Richard.
Back to top
View user's profile Send private message Visit poster's website
STPendl
Full Member


Joined: 20 Aug 2007
Posts: 161
Location: Austria

PostPosted: May 14th, 2012, 5:57pm    Post subject: Re: Limit a window's minimum size Reply with quote

The whole thing started out with Windows XP, when more handles were used by the system and they got beyond the positive range of LONG.
This has caused some real trouble, since stable API functions started crashing unexpectedly.

The conclusion was to use ULONG instead of LONG for handles, which resulted in more stable code.

In general a handle can never be a negative number, since it ranges from 0 to 2^32.

One can argue that the binary representation is the same, but we want to develop on the save side.

And if anyone is turning this into a bug of LB and an advantage of any other tool, he should turn his face into the next corner and think about what he has done wrong.

_________________
Stefan

Any code I post can be freely used, just give credit.
Back to top
View user's profile Send private message
RichardRussell
Full Member


Joined: 28 Jan 2012
Posts: 57
Location: Downham Market, UK

PostPosted: May 14th, 2012, 9:26pm    Post subject: Re: Limit a window's minimum size Reply with quote

STPendl wrote:
In general a handle can never be a negative number, since it ranges from 0 to 2^32.

A handle is a 32-bit number. As far as Windows and the processor is concerned there is no concept of it being positive or negative.

In the Windows header files HANDLE is defined as void*, i.e. as a pointer to void. It is neither signed nor unsigned, indeed strictly it's not even an integer! That may be why LB supports the undocumented type HANDLE:

Code:
calldll #user32, "GetDesktopWindow", hdesk as HANDLE
calldll #user32, "GetWindowDC", hdesk as HANDLE, hdc as HANDLE

Richard.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Bay Six Software Forum Index -> WMLiberty DLL All times are GMT
Page 1 of 1
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum



Lo-Fi Version
Powered by phpBB © 2001, 2005 phpBB Group