Thanks Paul. I see that you are still relying on %pv to do the other resizing - on my system here the delete button 'wibbles' (!) up and down by a pixel as resizing occurs, but it looks promising. Actually I had started to work on your previous suggestion which has produced exactly what I want, albeit with more complexity. I get the initial window and control sizes & positions on startup (in the first WM_SIZE rather than using %sc so that it gets the default dialog size, rather than any initial size set by %sz). Then on WM_SIZE, use the initial positions as a template and move and resize as required.
WINAPP
module SizeDlgMod
! Windows rectangle structure
type RECT
sequence
integer:: left = 0
integer:: top = 0
integer:: right = 0
integer:: bottom = 0
end type RECT
integer:: hDlg,hList,hAdd,hDel,hClose
logical:: started
type(RECT):: dlgRect, listRect, addRect, delRect, closeRect
integer:: dlgWidth, dlgHeight
end module SizeDlgMod
! Return child window rectangle in dialog co-ords
subroutine GetChildRect(hCtrl, crect)
use mswin
use SizeDlgMod
integer:: hCtrl
type(RECT):: crect
logical:: apiok
apiok = GetWindowRect(hCtrl, crect)
apiok = ScreenToClient(hDlg, crect%left) ! converts left & right to dlg co-ords
apiok = ScreenToClient(hDlg, crect%right)
end subroutine GetChildRect
program MainProgram
use mswin
use SizeDlgMod
external start_cb, move_cb
hdlg = 0
started = .false.
dlgWidth = 700 ! non-default initial dialog size
dlgHeight = 600
i = winio@('%ww%ca[Resizing Test Dialog]%bg[BTNFACE]%fd%hw&',hdlg)
!i = winio@('%sc&', start_cb)
i = winio@('%sz&', dlgWidth, dlgHeight)
i = winio@('Resize the dialog...%nl%dy&',0.25D0)
i = winio@('%pv%uw[SysListView32]%ff%nl&', 500, 300, WS_VISIBLE+1+WS_BORDER, 0, hList)
i = winio@('%6bt[Add]%lc %6bt[Delete]%lc %rj%`10bt[Close]%lc&',hAdd,hDel,hClose) i = winio@('%mg',WM_SIZE, move_cb)
end program MainProgram
integer function move_cb()
use mswin
use SizeDlgMod
logical:: apiok
type(RECT):: drect
integer:: dx, dy
! If this is the first size, get dialog and control template, thereafter just
! adjust control positions/sizes
if (.not.started) then
! Get initial size and positions af moveable items
apiok = GetClientRect(hdlg, dlgRect)
if (apiok .and. dlgRect%right>0) then ! in case we get WM_SIZE before dialog really exists
call GetChildRect(hList, listRect)
call GetChildRect(hAdd, addRect)
call GetChildRect(hDel, delRect)
call GetChildRect(hClose, closeRect)
started = .true.
end if
else
if (GetClientRect(hDlg, drect)) then
dx = drect%right - dlgRect%right ! calc change in size from initial size
dy = drect%bottom - dlgRect%bottom
call RESIZE_WINDOW@(hList, listRect%right-listRect%left+dx, listRect%bottom-listRect%top+dy)
call MOVE_WINDOW@(hList, listRect%left, listRect%top) ! stick top top/left
call MOVE_WINDOW@(hAdd, addRect%left, addRect%top+dy) ! stick to left/bottom
call MOVE_WINDOW@(hDel, delRect%left, delRect%top+dy)
call MOVE_WINDOW@(hClose, closeRect%left+dx, closeRect%top+dy) ! stick to right/bottom
end if
end if
! Return 'message handled' so %pv doesn't get to change things
move_cb = 2
end