Silverfrost Forums

Welcome to our forums

dynamic scrollbars in a MDI frame

13 May 2009 8:21 (Edited: 13 May 2009 8:35) #4596

Hello, I've been working on building an MDI frame that has dynamic scrollbars for when a child window gets moved outside the frame. When no child is outside the frame edge then no scrollbars are visible. Everything is working great apart from when a child window is maximised when a scrollbar is present, then a strange edge is left where the scrollbar was originally. regards Albert Has anyone an idea how to work around this?

WINAPP  
 use funcs       
 implicit none 
  !!!!!!!!  MDI frame with dynamic scrollbars for when child  !!!!         
  !!!!!!!!  windows go out of the extremities of the frame    !!!!
  width_frame=500       
  height_frame=500     
  
  hmax_val=0               
  hstep=0    !set hstep == hmax_val to make scrollbar invisible         
  hcur_val=0             
  vmax_val=0                       
  vstep=0                   
  vcur_val=0    
  hlow=0          
  vlow=0        
                
  hhigh=width_frame         
  vhigh=height_frame            
  
  childnum=0  !counter for child windows     
    
  
  i=winio@('%ww[no_border]%hw&',frame_hnd)  
  
  !i=winio@('%^bt[test]%nl&',cback) !! toolbar         
  i=winio@('%^hx&',hstep, hmax_val, hcur_val, hmove_child_windows)        
  i=winio@('%^vx&',vstep, vmax_val, vcur_val, vmove_child_windows)   
  i=winio@('%pv%^`fr&',width_frame,height_frame,cur_child,scrollfunc)    
  i=winio@('%mn[&File[&Open]]&',open_func)   
  i=winio@('%mn[[&Cascade]]&','cascade') 
  i=winio@('%lw&',ctrl)    
  i=winio@('%`mv',resize_main_win) !!!! called if frame is resized   
end               


module funcs
implicit none
!!!!!!!  Global Variables   !!!!!!!!
integer ctrl,winio@, i, cur_child, frame_hnd
integer :: x,  child_width
integer :: y,  child_height
integer :: hlow, hhigh
integer :: vlow, vhigh
integer :: x_frame, y_frame, width_frame, height_frame
integer :: hstep, hmax_val, hcur_val, hcur_val_old
integer :: vstep, vmax_val, vcur_val, vcur_val_old
integer,allocatable :: childhnd(:,:), childhndtemp(:,:)
integer :: childnum

contains 

!!!!!  creates child window containing graphic region
integer function open_func()
  
  i=winio@('%aw&',ctrl)
  i=winio@('%hw&',cur_child)
  i=winio@('%pv%^gr[user_resize, grey]&',200,200,cback)
  i=winio@('%bd&',0.0d0,0.0d0,0.0d0,0.0d0)  !!!!set border for child windows
  i=winio@('%2.1ob[status,depressed]&') !!!!status bar
  i=winio@('%`rs%cb&','1.234')
  i=winio@('%`rs%cb&','sssssss') !!!! blah
  i=winio@('%mv&',scrollfunc)  !!!! called if child window moved
  i=winio@('%cc', exit_scrollfunc)  !!!! called if child closed
  childnum=childnum+1

!!!!!  make list of child window handles in array
!!!!!  if a child window is deleted the handle is set to zero
  
  if(childnum==1)then
    allocate(childhnd(childnum,3))
    childhnd(childnum,1)=cur_child
  else
    allocate(childhndtemp(size(childhnd,1),3))
    childhndtemp=childhnd
    deallocate(childhnd)
    allocate(childhnd(childnum,3))
    childhnd(1:childnum-1,:)=childhndtemp
    childhnd(childnum,1)=cur_child
    deallocate(childhndtemp)
  endif
  open_func=1
  
end function
  
!!!!!!!  function called when child window closed
integer function exit_scrollfunc()
integer :: i

  do i=1,size(childhnd,1)
    if(childhnd(i,1)==cur_child)then
      childhnd(i,1)=0
    endif  
  enddo
  
  exit_scrollfunc= -1
end function
13 May 2009 8:26 #4597

rest of module

integer function cback()
  cback = 1
end function

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

integer function scrollfunc()
use mswin
integer ::i, xoffset, yoffset
logical :: is, ist

!!!!! get size of frame
  call get_window_location@(frame_hnd, x_frame, y_frame, width_frame, height_frame)
  
  call window_update@(width_frame)
  call window_update@(height_frame)
  ist=.false.
  

!!!! yoffset bigger than xoffset because of menu   
  if(hstep/=hmax_val)then  !!!! scrollbar visible, acount for width of scrollbar
    yoffset=63             !!!! add 32 to this to include a toolbar
  else                     !!!! no scrollbar visible
    yoffset=47             !!!! add 32 to this to include a toolbar  
  endif

  if(vstep/=vmax_val)then
    xoffset=25
  else
    xoffset=9
  endif    

  hlow=0    !!!! 
  hhigh=width_frame-xoffset
  vlow=0
  vhigh=height_frame-yoffset

  do i=1,size(childhnd,1)      !!!! loop through child windows to find positions and sizes
  
  is=iszoomed(childhnd(i,1))   !!!! windows api call to check if child is maximized
  
   if(is)then
     ist=.true.
   endif   
  
    if(childhnd(i,1)/=0)then   !!!! child not already deleted
    call get_window_location@(childhnd(i,1), x, y, child_width, child_height)
    
    childhnd(i,2)=x   !!!! x position for each child
    childhnd(i,3)=y   
       !for horizontal
       if(x<hlow)then  !!!! left edge of child outside frame
         hlow=x        
       endif
       
       if(x+child_width>hhigh)then  !!!! right edge outside frame
         hhigh=x+child_width
       endif    
       !!! for vertical
       if(y<vlow)then
         vlow=y
       endif
       
       if(y+child_height>vhigh)then
         vhigh=y+child_height
       endif    
    endif
  enddo
!!!! for horizontal
  if(.not.(ist))then  !!!! no child maximised
  
    !!!!  calculate range of scrollbars
    if(hlow<0 .or. hhigh>width_frame-(xoffset-1))then  
      hmax_val=(hhigh-width_frame) + abs(hlow)+xoffset
      hcur_val= abs(hlow)
      hstep=hmax_val/2
    else  !!!! no child outside frame, no scrollbars
      hstep=0
      hmax_val=0
      hcur_val=0
    endif

  else  !!!! a child is maximized, no scrollbars
    hstep=0
    hmax_val=0
    hcur_val=0
  endif  

!!!! for vertical  
  if(.not.(ist))then
 
    if(vlow<0 .or. vhigh>(height_frame-(yoffset-1)))then
      vmax_val=(vhigh-height_frame) + abs(vlow)+yoffset 
      vcur_val= abs(vlow)
      vstep=vmax_val/2
    else
      vstep=0
      vmax_val=0
      vcur_val=0
    endif 
 
  else
    vstep=0
    vmax_val=0
    vcur_val=0
  endif  
  hcur_val_old = hcur_val
  vcur_val_old = vcur_val  

  call window_update@(hstep)
  call window_update@(hcur_val)
  call window_update@(hmax_val)
  call window_update@(vstep)
  call window_update@(vcur_val)
  call window_update@(vmax_val)
  !!!!  repaints frame background
  call update_window@(frame_hnd)
  scrollfunc = 1
end function

please see next post for rest of module

13 May 2009 8:29 #4598
subroutine hmove_child_windows
use mswin
integer :: i,intscr
  intscr=clearwin_info@('INTERMEDIATE_SCROLL')
  if(intscr==0)then  
    do i=1,size(childhnd,1)
      if(childhnd(i,1)/=0)then
        call move_window@(childhnd(i,1),childhnd(i,2)+(hcur_val_old - hcur_val) ,childhnd(i,3))
      endif
    enddo
  endif
endsubroutine

subroutine vmove_child_windows
use mswin
integer :: i,intscr
  intscr=clearwin_info@('INTERMEDIATE_SCROLL')
  if(intscr==0)then  
    do i=1,size(childhnd,1)
      if(childhnd(i,1)/=0)then
        call move_window@(childhnd(i,1),childhnd(i,2) ,childhnd(i,3)+(vcur_val_old - vcur_val))
      endif
    enddo
  endif
endsubroutine

integer function resize_main_win()
use mswin
integer :: i
  call get_window_location@(frame_hnd, x_frame, y_frame, width_frame, height_frame)
  call window_update@(width_frame)
  call window_update@(height_frame)

  if(childnum/=0)then  !!!! prevents calling scrollfunc if no child exists
    i =  scrollfunc()
  endif
resize_main_win=1
end function

endmodule funcs
14 May 2009 6:08 #4602

I have not had chance to look at your code but the first question I would ask is has the window size been changed and then not refreshed.

You can test for this by dragging another application over the window to force a refresh. If this is the case then you basically need to find a way to 'invalidate' the part that has not been refreshed.

On the other hand if the window is the wrong size then there are functions available to change the size. The main problem will be, when to do the resizing.

14 May 2009 6:57 #4606

Thanks Paul,

Your second suggestion works

changing the lines in the function scrollfunc() from

if(is)then
     ist=.true.
   endif   

to the following solves the problem

if(is)then
     ist=.true.
     call resize_window@(childhnd(i,1),width_frame,height_frame)
   endif   
Please login to reply.