Preventing a window to be resized smaller than wanted (PB6, 32bit, 26 jun 1998))

Back Up Next

Author: Eric Aling
Accessed:
Download: Download minmax.zip ( minmax.zip 6Kb )

Ever tried preventing a window to be resized smaller than a specific width and height? Of course, you can do this in the resize event: if the new widht or new height is smaller than a limit, resize the window again using these limits. This works fine, but the user can still see the 'resizeborder' when resizing. This is not a nice view and looks not professional at all ( better said: ugly ). To influence the resize event, you need information about the resizing just before the resize takes place. Luckily, Windows provides us an event that is called just before the resize event. It is called WM_GETMINMAXINFO, which is mapped to the pbm_getminmaxinfo event. So, map an userevent to that event and called it ue_getminmaxinfo. As you'll see, you'll get an argument, which is a pointer to the MINMAXINFO information. This is a structure with the following layout:

$PBExportHeader$str_minmaxinfo.srs
global type str_minmaxinfo from structure
    str_point        ptreserved
    str_point        ptmaxsize
    str_point        ptmaxposition
    str_point        ptmintracksize
    str_point        ptmaxtracksize
end type

The str_point datatype is also a structure:

$PBExportHeader$str_point.srs
global type str_point from structure
    long        lx
    long        ly
end type

 

So, this structure provides us all the information we need. Windows will use this information for resizing, so, if we can modify it, Windows will use our settings. We are especially interested in the ptMinTrackSize element. Setting this element with our minimal width and heigth values will do the trick, but how to get to the structure? Now, here comes a trick, which can only be used in the Win32 environment. It is called the CopyMemory() function. However, this function can not be found anywhere in any DLL Windows provide, but it does exists in all the Win32 API helpfiles. How come? The reason is that it is called differently, namely RtlMoveMemory(), and is located in the the Kernel32.dll. This function has 3 arguments: one pointer to the destination, one pointer to the source, and the number of bytes to copy. In order to use this function in PowerBuilder, we have to declare this function differently to be able to use our str_MinMaxInfo structure:

subroutine GetMinMaxInfo ( ref str_minmaxinfo d, long s, long l ) library 'kernel32.dll' alias for RtlMoveMemory 
subroutine SetMinMaxInfo ( long d, str_minmaxinfo s, long l ) library 'kernel32.dll' alias for RtlMoveMemory 

You see, we have now two different APIs: one for copying the data into our structure, and one for copying the data in our structure to a memory location. So, in the ue_GetMinMaxInfo userevent, we code the following:

str_MinMaxInfo lstr_MinMaxInfo

/* copy the data, pointed by the argument MinMaxInfo, to our lstr_MinMaxInfo structure */
GetMinMaxInfo(lstr_MinMaxInfo, MinMaxInfo, 40)

/* set the minimal size for our window */

lstr_MinMaxInfo.ptMinTrackSize.lx = long(sle_x.text)
lstr_MinMaxInfo.ptMinTrackSize.ly = long(sle_y.text)

/* copy the structure back into memory at the same place */

SetMinMaxInfo(MinMaxInfo,lstr_MinMaxInfo,40)

/* important, according to the MS API, we must return 0 */

return 0


That's all there is. You can also set the other element of the structure. Check out the sample PBL!

Enjoy!

 

 

Back Up Next