Silverfrost Forums

Welcome to our forums

Controlling %pv positioning of controls

13 Sep 2006 6:32 #1034

Hi,

I am trying to create a simple, resizeable dialog containing a main list view with three buttons in a row below it. I would like to have two of the buttons left-justified and one right-justified - this works for the first and last buttons, but the middle one, while being defined as left justified, moves with the right hand edge of the window (ie. it behaves as if its right justified). The example below demonstrates my problem. Is there any way of telling the dialog to attach the second button to the left edge, rather than the right edge ? (none of the %ap or %rp codes do the trick) Everything is okay with the dialog at its initial size, but as soon as resizing occurs the middle button moves.

program MainProgram use mswin integer i, hCtrl

i = winio@('%ww%ca[Resizing Test Dialog]%bg[BTNFACE]%fd&') i = winio@('Resize the dialog...%nl%dy&',0.25D0) i = winio@('%pv%uw[SysListView32]%ff%nl&', 500, 300, WS_VISIBLE+LVS_REPORT+WS_BORDER, 0, hCtrl)

! I would like the Add and Delete buttons to stay fixed to the left side of the dialog, ! with the Close button stuck to the right... i = winio@('%6bt[Add] %6bt[Delete] %rj%`10bt[Close]') ! Add on left, Delete 'sticks' to the right end program MainProgram

Thanks, Alan

13 Sep 2006 2:17 #1038

Alan

The only way I can think to do this at the moment is to do the positioning by hand. That is, do not use %pv but use winio@('%mg&', WM_SIZE, cb) instead. Use %lc to get the handles of the various controls and then, within the callback function cb, position and size the controls using move_window@ and resize_window@. It is tedious but you can get the result eventually.

%sz may also be useful in this context (to give you the size of the main window).

14 Sep 2006 1:20 #1040

In fact %mv is equivalent to %mg, WM_SIZE.

14 Sep 2006 1:28 #1041

Strange how these things get to you! The following is almost a solution...

WINAPP program MainProgram use mswin integer i, hCtrl, move_cb,hwnd,hwnd1 common hwnd,hwnd1 external move_cb i = winio@('%ww%ca[Resizing Test Dialog]%bg[BTNFACE]%fd&') i = winio@('Resize the dialog...%nl%dy&',0.25D0) i = winio@('%pv%uw[SysListView32]%ff%nl&', 500, 300, WS_VISIBLE+1+WS_BORDER, 0, hCtrl) ! I would like the Add and Delete buttons to stay fixed to the left side of the dialog, ! with the Close button stuck to the right... i = winio@('%6bt[Add]%lc %rj%`10bt[Close]&',hwnd1) ! Add on left, Delete 'sticks' to the right i = winio@('%nl%ap%6bt[Delete]%lc&',0,0,hwnd) i = winio@('%mg',WM_SIZE, move_cb) end program MainProgram

integer function move_cb() use mswin integer hwnd,hwnd1 common hwnd,hwnd1 call get_window_location@(hwnd1,ix,iy,iw,ih) call move_window@(hwnd, ix+60, iy-30) move_cb = 3 end

14 Sep 2006 2:38 #1045

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

14 Sep 2006 3:16 #1046

One downside to this is that preventing the default WM_SIZE processing means that the %sz variables are not updated as the window is resized, so you need to call get_window_location when the window dies to persist the size.

There isn't any way of getting the window to be resizeable without having a %pv is there ? That would be really useful as we might then be able to use the same 'manual' repositioning on %di windows as well.

14 Sep 2006 9:15 #1051

Alan

You probably need to use a return value of 3 in the %mg callback function. Check with the documentation. I think this causes the message to be passed on.

I cannot think of a way to avoid %pv. You need the main window to have the WS_THICKFRAME style but I do not know of another way to set this in ClearWin+. I have tried one or two things but they do not work. SET_WINDOW_STYLE@ does not do what it says on the tin. The documentation is incorrect. Basically we need a new %ww style. This is easy enough to add but it does not help you in the short term.

14 Sep 2006 10:21 #1052

Paul

The return of 2 is to explicitly prevent the standard ClearWin processing so the %pv has no effect other than to allow the window to be resized. If its 3 the controls that have been manually moved will be moved again automatically due to %pv, but I don't want to use %ap to prevent %pv positioning as the initial auto-positioning of the controls provides a template for the dialog. Anyway it all seems to work just as I want it now 😃

A 'resizeable' option would be useful in %ww - if it could also be added to %di it would be even better (mind you I haven't checked what happens if the %di dialog resource is set to thick frame it might work already).

14 Sep 2006 3:05 #1054

Alan

I will add the option to %ww. I think there is a good chance that WS_THICKFRAME will implemented by %di.

15 Sep 2006 6:45 #1058

An option on %ww would be great. Unfortunately setting a resizeable frame in the dialog resource doesn't make it through %di - an option there would be really nice 😉

19 Sep 2006 7:04 #1065

Paul,

If possible, adding the option to %sy would also be good to allow resizeable modal dialogs - I don't think there's a way of doing this at all at the moment.

Alan

20 Sep 2006 6:00 #1078

Alan

I have added [not_fixed_size] to %ww. %sy is more tricky and I have not attempted to change this.

When I get time I will take a look at %di.

Please login to reply.