Silverfrost Forums

Welcome to our forums

Create image of window built up with multiple regions

14 Jul 2015 10:49 #16580

I have created a small program to do some calculations and present the results, displayed in two separate %gr regions.

http://tr5mx.co.uk/seq_cal.jpg

The whole 'page' is surrounded by an invisible %ob. Is it possible to select the whole of the contents of that %ob and create a bitmap of the contents? I know that I can select the individual %gr regions, but I cannot work out how to select the whole box. Could somebody point me in the right direction?

Thanks

Ken

14 Jul 2015 12:50 #16582

Kenneth,

Looks great. But I don't think Clearwin+ has a function that you describe.

  1. You could get the user (you?) to copy the whole application window to the clipboard using Alt+PrtSc. Once the image is safely in the clipboard, if you want to paste it into a different application, like Paint, that's fine. Doing it in an FTN95 / Clearwin+ application requires using CLIPBOARD_TO_SCREEN_BLOCK@. The screen block is a device independent bitmap that you can then mess around with DIB_PAINT@ to put it into (say) a %gr area. You can clip off the extraneous parts of the image using the offsets (top and left) and the other edges by sizing the %gr area appropriately.

To find out how big those extraneous bits are you could use trial-and-error, but I would use an onscreen pixel ruler like 'Ruler By George!' (you can find it using Google).

  1. In Windows 8 there is a snipping tool to just select the area you want.

  2. If you want it printed and not manipulatable in another program, then there are other combinations of PrtSc. You could also simply redraw the objects on a printer having selected the printer with OPEN_PRINTER@ or the appropriate standard callback. The values in the input boxes would have to be drawn some other way, but you have obviously mastered the graphics. If you drew the two graphics areas using fixed sizes, then of course they will come out very small on a print, so they would been to be scaled up. I'm assuming that your application redraws them as the input values on the left are changed, and this is done by dedicated subroutines, so it would not seem difficult to simply redraw having changed the graphics handle appropriately. There are plenty of posts on this forum about getting the dot resolution of printers.

I use:

	ixdpi = GetDeviceCaps(jHDC, LOGPIXELSX)
	iydpi = GetDeviceCaps(jHDC, LOGPIXELSY)
       jXRES = GetDeviceCaps(jHDC, HORZRES)
       jYRES = GetDeviceCaps(jHDC, VERTRES) 

There are lots of niceties about doing hard copy that would probably mean more after you had a go, if you follow that path.

Eddie

14 Jul 2015 1:07 #16583

Kenneth, is it really necessary to have two %gr regions? Why not use a single one of double width, then simply display the right graphics with a constant offset for all x values?

Wilfried

14 Jul 2015 1:21 #16584

Wilfried,

That was my first reaction. However, on re-reading the post I came to the conclusion he wanted the whole of the contents of the client area, including the input parameters.

Eddie

14 Jul 2015 1:49 #16585

Eddie, Thanks for your prompt reply – which confirms what I through to be the case i.e. you cannot select these multiple regions. I do have a Plan B which is broadly along the lines of your third suggestion.

The new “anti-aliasing” and set opacity features makes these graphics look so much better, I was never happy with my previous attempts to draw these vector/phasor diagrams.

I’m not sure I’ve mastered the graphics, yet! The routine below stopped me pulling my hair out with the coordinate system, and thereafter it all becomes a lot easier (posting it here just in case anybody else is struggling with this).

!--------------------------------------------------------------------------------------------------
! #079 function map_range_dp (a1, a2, b1, b2, s)
!      Given two ranges [a1,a2] and [b1,b2]; then a value s in range [a1,a2] is linearly mapped to 
!      a value in the range [b1,b2]
!--------------------------------------------------------------------------------------------------
    function map_range_dp(a1, a2, b1, b2, s)
    real(kind = dp)  map_range_dp
    real(kind = dp), intent(in) :: a1, a2, b1, b2, s
    
      if ( abs(a1 - a2) .gt. zero_sp .eqv. .false. ) then
        call abort_run ('ERROR in MAP_RANGE_DP, range [a1,a2] is zero')
      end if
      map_range_dp = (s - a1) * (b2 - b1) / (a2 - a1) + b1 
 
    end function map_range_dp

Cheers

Ken

14 Jul 2015 1:54 #16586

The missing code in the above example

!--------------------------------------------------------------------------------------------------
! #110 subroutine abort_run (text)
!      Displays text and stops run
!--------------------------------------------------------------------------------------------------
    subroutine abort_run (text)
    character(len=*), intent(in) :: text
    integer i
    include <windows.ins>  ! required to access clearwin+
    
      i = winio@('%ca[Fatal error message]&')
      i = winio@('%mi[{C:\ftn\code_0002\icons\gear.ico}]&')
      i = winio@('%bg&',RGB@(250,250,250))
      i = winio@('%tc&', RGB@(255,0,0))
      i = winio@('%2.1ob[no_border]&')
      i = winio@('%si#&')
      i = winio@('%cb&')
      i = winio@('%ws&',text)
      i = winio@('%cb&')
      i = winio@('%ff%nl%cn%`tt[Continue]')
      stop
    
    end subroutine abort_run
14 Jul 2015 5:18 #16588

Hi Kenneth,

Some suggestions from me. Firstly, dialog boxes like your popup error message aren't supposed to be minimised, and so shouldn't have a mimimise icon (%mi). This took me by surprise, as how do you know which of a multiplicity of running apps has thrown the error? That's where the caption and dialog box text come in. In any case, you are better off putting icons in the RESOURCES section of your program as it is one less file to install on a different computer. I can also recommend using the line 1 24 default.manifest in your resources section.

I see that you use %tt - I do sometimes, as the standard %bt button is too high for contemporary window designs. If you read the MS User Experience guidelines you will see that 'Continue' is not an ideal label, as a fatal error message cannot be continued, and it should be 'Quit' - unless your user can override the error condition, but then it isn't fatal, is it?

I manage all my scaling and positioning with two statement functions:

   IPOSX(XX) = (XX-P2X)/SCRN_SCALE+IXRES/2
   IPOSY(YY) = IYRES/2-(YY-P2Y)/SCRN_SCALE 

In this, IXRES and IYRES are the graphics area extents, XX and YY the coordinates I have in real world units, P2X and P2Y are offsets, and SCRN_SCALE is a scale factor in real world units per pixel. Then I can draw my objects anywhere just by changing the parameters and redrawing. My objects in the real world operate in an upper right quadrant coordinate system, and the graphics areas in a lower right one: this gives pixel coordinates for IPOSX and IPOSY that have the correct sign. If P2X and P2Y are the centre of the object then the object is centred in the graphics region.

A pair of inverse functions get me real world coordinates from pixels. Drawing something on a hard copy is just a function of changing the scaling and extents and running the graphics subroutine again once the target has changed.

Eddie

Please login to reply.