forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Terminating a print run without output

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> ClearWin+
View previous topic :: View next topic  
Author Message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Sat Jul 26, 2008 9:36 pm    Post subject: Terminating a print run without output Reply with quote

If I decide to do a graphics print, then I select a menu item that has a double-callback starting with 'GPRINTER_OPEN' and then going on to my routine that does all the graphics. In that routine, if I decide to abort the printing process, I can use:

Code:
CALL GET_CURRENT_DC@ (iHDC)
           CALL CLOSE_PRINTER_ONLY@(iHDC)


with GET_CURRENT_DC@ only necessary because it is a way to find the the gprinter handle.

By the same logic, I have elsewhere a choice to print tabulated results, where the menu item selects 'PRINTER_OPEN', then the fortran unit number, and then the routine that does the printing. However, if in the middle of this I decide I don't really want the print, what do I do to cancel it?

There's no point in calling CALL GET_CURRENT_DC@ (iHDC), because that returns the handle of the graphics area on the screen (in my case). It did occur to me that like CLOSE_PRINTER@, giving a handle of 0 to CLOSE_PRINTER_ONLY@ might terminate the printer without output, but it doesn't, and when the program exits, a blank sheet of paper is ejected.

I also tried STATUS='DELETE' on a Fortran CLOSE statement, but that had the effect of making the blank sheet eject immediately.

This is purely cosmetic, because in 99% of runs, no tabulated output is called for, and in 99% of the remaining 1%, the printing isn't aborted.

Does anyone know?

Eddie
Back to top
View user's profile Send private message
IanLambley



Joined: 17 Dec 2006
Posts: 490
Location: Sunderland

PostPosted: Sun Jul 27, 2008 9:13 am    Post subject: Reply with quote

Eddie,

I thought that the handle for opening printers was a user supplied handle, so why call get_current_dc@.

is it not just

itest = open_printer@(10)

.
.
.
.
call printer_close_only@(10)

for example?

Ian
Back to top
View user's profile Send private message Send e-mail
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Mon Jul 28, 2008 1:25 pm    Post subject: Reply with quote

Ian,

I don't think you are right. OPEN_PRINTER@ is for graphics output. Although the help file for FTN95 says:

The handle is supplied by the programmer and is used in conjunction with SELECT_GRAPHICS_OBJECT@.

I think this means that you declare a variable IHWND, and OPEN_PRINTER@ gives you back a value, not that you write it as you suggested. I find the FTN95.CHM sometimes confusing as to who provides what.

The problem lies with the structure of my code. If you have no data, and therefore can't print, the Windows way of handling things is to grey out the print menu/icon/button or whatever. You un-grey it when there is data that can be printed.

The particular program I am working on was my first serious effort with ClearWin, and it checks as to whether there is anything to print AFTER the user has said "Print it". I have two possible routes: firstly to print the image (which is a survey map), secondly to print the underlying readings.

What I ought to do is go back further up the chain and do the greying-out.

Having reflected on it, I think that CLOSE(UNIT=N, STATUS='DELETE') ought NOT to eject a sheet of paper, but since in the rest of my working life this is unlikely to waste more than half a ream of paper, all of which could go back into the printer, why am I bothered? Indeed, I can imagine situations where the existing behaviour is desirable, and changing it could cause inconvenience.

Eddie
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7924
Location: Salford, UK

PostPosted: Mon Jul 28, 2008 3:05 pm    Post subject: Reply with quote

OPEN_PRINTER@ takes a VAL and not a REF.
The programmer must supply an integer (any value will do, 42 has magical properties and is recommended by many programmers).
This integer value identifies the printer in the code.
Back to top
View user's profile Send private message AIM Address
IanLambley



Joined: 17 Dec 2006
Posts: 490
Location: Sunderland

PostPosted: Mon Jul 28, 2008 4:57 pm    Post subject: Reply with quote

Eddie,

I do agree with your statement:
Quote:

I find the FTN95.CHM sometimes confusing as to who provides what.

And I think we know who contributes to that - don't we (Paul)

I think that Paul is actually saying the same as me and a program would look like:


Code:

subroutine plotit
include <windows.ins>

itest=open_printer@(42)  ! the answer to life, the universe and everything

if(itest .eq. 1)then

  if(result .eq. rubbish)then
     CALL CLOSE_PRINTER_ONLY@(42)
  else
!carry on plotting  (Oooh Matron!)
.
.
.
.
     itest=close_printer@(42)
  endif

endif

end


Regards

Ian
Back to top
View user's profile Send private message Send e-mail
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Mon Jul 28, 2008 7:33 pm    Post subject: Reply with quote

Hi Paul & Ian,

I was in the throes of checking with FTN95.CHM, only to find that the latest Windows update had disabled HH.EXE because of a security vulnerability with it! Apparently the update is on the MS Website, but SP3 appears to fix it ....

Paul is right, that it is a VAL not a REF. Whatever it is, it misses the point of the post. Consider the following code:

Code:

       WINAPP
       OPTIONS (INTL)
       PROGRAM TESTPRINT
       include <windows.ins>
       EXTERNAL NPRINT, NEXIT
       IA=WINIO@('%ca[Test print]%ww&')
       IA=WINIO@('%6^bt[Print]  %6^bt[Exit]',NPRINT,NEXIT)
       END

       INTEGER FUNCTION NEXIT()
       NEXIT=0
       RETURN
       END

       INTEGER FUNCTION NPRINT()
       INCLUDE <WINDOWS.INS>
       EXTERNAL KILLIT, KPRINT
       itest=open_printer@(42) 
       IB=WINIO@('%ca[Second thoughts]%ww&')
       IB=WINIO@('%2nlDo you really want to print?%2nl&')
       IB=WINIO@('%6^bt[Yes]  %6^bt[No]', KPRINT, KILLIT)
       RETURN
       END

       INTEGER FUNCTION KILLIT()
       INCLUDE <WINDOWS.INS>
         CALL CLOSE_PRINTER_ONLY@(42)
         KILLIT = 0
       RETURN
       END

       INTEGER FUNCTION KPRINT()
         write(42,*) ' Eddie wrote this'
         itest=close_printer@(42)
         KPRINT = 0
       RETURN
       END


The problem is that 42 is simply an arbitrary number, and has nothing to do with a Fortran unit number. If we decide to abort the print (KILLIT) we don't get a page ejected, because Windows think that we have aborted a graphics print, and that works. So, here is version 2:

Code:

       WINAPP
       OPTIONS (INTL)
       PROGRAM TESTPRINT
       include <windows.ins>
       EXTERNAL NPRINT, NEXIT
       COMMON /DEVICE/ NDEV
       NDEV=42
       IA=WINIO@('%ca[Test print]%ww&')
       IA=WINIO@('%6^bt[Print]  %6^bt[Exit]','PRINTER_OPEN',
     &                      NDEV,NPRINT,NEXIT)
       END

       INTEGER FUNCTION NEXIT()
       NEXIT=0
       RETURN
       END

       INTEGER FUNCTION NPRINT()
       INCLUDE <WINDOWS.INS>
       EXTERNAL KILLIT, KPRINT
       COMMON /DEVICE/ NDEV
       IB=WINIO@('%ca[Second thoughts]%ww&')
       IB=WINIO@('%2nlDo you really want to print?%2nl&')
       IB=WINIO@('%6^bt[Yes]  %6^bt[No]', KPRINT, KILLIT)
       RETURN
       END

       INTEGER FUNCTION KILLIT()
       INCLUDE <WINDOWS.INS>
       COMMON /DEVICE/ NDEV
         CALL CLOSE_PRINTER_ONLY@(NDEV)
         KILLIT = 0
       RETURN
       END

       INTEGER FUNCTION KPRINT()
       INCLUDE <WINDOWS.INS>
       COMMON /DEVICE/ NDEV
         write(NDEV,*) ' Eddie wrote this'
         itest=close_printer@(NDEV)
         KPRINT = 0
       RETURN
       END


This works as it should, and if we really want the print - it prints. If we say "no, we don't want the print", we don't get a print. But when the program exits, out pops the blank sheet from the printer.

If in KILLIT I replace CALL CLOSE_PRINTER_ONLY@(NDEV) with CLOSE(NDEV,STATUS='DELETE') then I still get the ejected blank page, but immediately.

Eddie
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Mon Jul 28, 2008 7:36 pm    Post subject: Reply with quote

... and really, the whole OPEN_PRINTER@ family of subprograms are "OPEN_GPRINTER@" subprograms, as they are related to the callback 'GPRINTER_OPEN', not to 'PRINTER_OPEN'.

Eddie
Back to top
View user's profile Send private message
IanLambley



Joined: 17 Dec 2006
Posts: 490
Location: Sunderland

PostPosted: Mon Jul 28, 2008 8:24 pm    Post subject: Reply with quote

Ah!, The penny drops - You were doing Fortran writes to the printer.

I never even tried that and just printed everthing to a string, and output the string using draw_characters@.

Sometimes direct to a file, and then review on screen and then print using draw_characters@. Note, my files have a FF character at the top of each page.

Code:

      integer*4 function review()
      INCLUDE <WINDOWS.INS>
      character*256 print_file_name
      common/print_file/print_file_name
      external iprintout
      call set_clearwin_string@('printer_document','My List file')
      I=WINIO@('%ca[ List file viewer]&')
      I=WINIO@('%mn[E&xit,&Print]%es%sc&',
     &           'EXIT',
     &           iprintout,
     &           'edit_file',print_file_name)
      I=WINIO@('%ww[no_border]%pv%fn[Courier New]'//
     &         '%ts%126.30eb[vscrollbar,hscrollbar,read_only]'
     &         ,0.9d0,'*',0)
      review = 1
      END


      integer*4 function iprintout()
      include <windows.ins>
      integer*4 xres,yres
      real xwl,xwr,ywb,ywt
      character*155 lineout
      real xxx,yyy
      character*256 print_file_name
      common/print_file/print_file_name
      logical windows_printer
      lineout =  ' '
      ipage = 1
      ihandl = 2
      iblack = rgb@(0,0,0)
      call printer_dialog_options@(1,0,1,0,0,0,0,1,0)
      itest = open_printer@(ihandl)
      if(itest .ne. 0)then
        ipage_range = clearwin_info@("printer_pagenumbers")
        if(ipage_range .eq. 1)then
          istart_page = clearwin_info@("printer_first_page")
          ilast_page  = max(istart_page,
     &                      clearwin_info@("printer_last_page"))
        else
          istart_page = 1
          ilast_page  = 32768
        endif
        call set_text_offset(0,0)
        icurrent_page = 1
        ipage_count = 0
        if(istart_page .eq. 1)ipage_count = 1
        open(unit=27,file=print_file_name,status='unknown')
        call GET_GRAPHICAL_RESOLUTION@( ixxx, iyyy )
        ihsize = ixxx
        ivsize = iyyy
c
c set pixel paper size
        call set_paper_size(ixxx,iyyy)
c
c get the text size for the main body of the text
        nrow = 1
        if(ixxx .gt. iyyy)then
c
c landscape
          ncol = 155
        else
c
c portrait
          ncol = 140
        endif
        call get_text_scale(ncol,nrow,scale)
c
c set punching margin in pixels
        if(ixxx .gt. iyyy)then
c
c landscape
          ihoff = ixxx/297.0*6.0
          ivoff = int(ivsize*20.0/200.0)
        else
c
c portrait
          ihoff = int(ihsize*20.0/200.0)
          ivoff = ivsize/297.0*10.0
        endif
        call set_text_offset(ihoff,ivoff)
        irow = 1
c
c get the last text start position to set new offset for bulk of text
        call scale_font@(scale)
        call rotate_font@( 0d0 )
        do
          read(27,1000,end=9999)lineout
 1000     format(a)
! detect form feed character
          if(lineout(1:1) .eq. char(12))then
            icurrent_page = icurrent_page+1
            if(icurrent_page .ge. istart_page .and.
     &         icurrent_page .le. ilast_page)then
              if(ipage_count .gt. 0)then
                call new_page@
                call set_text_offset(ihoff,ivoff)
                lineout(1:1) = ' '
                irow = 1
              endif
              ipage_count = ipage_count + 1
            endif
          endif

Continued
Back to top
View user's profile Send private message Send e-mail
IanLambley



Joined: 17 Dec 2006
Posts: 490
Location: Sunderland

PostPosted: Mon Jul 28, 2008 8:26 pm    Post subject: Reply with quote

Code:

          if(icurrent_page .ge. istart_page .and.
     &       icurrent_page .le. ilast_page)then
            call DRAW_TEXT_CHAR(lineout,0,irow,scale,iblack)
            irow = irow + 1
          endif
        enddo
 9999   continue
        itest = close_printer@(ihandl)
        close(unit=27)
      endif
      iprintout = 2
      end

      subroutine set_text_offset(ixoff,iyoff)
      common/printer_text_offset/ixpoff,iypoff,ixmax,iymax,ixlast,iylast
      ixpoff = ixoff
      iypoff = iyoff
      end

      subroutine set_paper_size(ixxx,iyyy)
      common/printer_text_offset/ixpoff,iypoff,ixmax,iymax,ixlast,iylast
      ixmax = ixxx
      iymax = iyyy
      ixlast = 0
      iylast = 0
      end

      subroutine get_text_scale(ncol,nrow,scale)
      real*8 scale, scale1, scale2
c
c determines the scale factor for text to fit the printer
c base on a default 8x14 font
      common/printer_text_offset/ixpoff,iypoff,ixmax,iymax,ixlast,iylast
      scale1 = float(ixmax-ixpoff)/8.0/float(ncol)
      scale2 = float(iymax-iypoff)/14.0/float(nrow)
      scale  = min(scale1,scale2)
      end

      subroutine DRAW_TEXT_CHAR(text,ix,iy,scale,icol)
!ix & iy are column and row number
      real*8 scale
      character*(*) text
      common/printer_text_offset/ixpoff,iypoff,ixmax,iymax,ixlast,iylast
      iy2 = iy*14*scale+iypoff
      ilen = max(1,leng(text))
      do i=1,ilen
        ix2 = (ix+i-1)*7*scale+ixpoff
        call DRAW_characters@(text(i:i),ix2,iy2,icol)
      enddo
      ixlast = ix2
      iylast = iy2
      end



I hope this helps

Ian
Back to top
View user's profile Send private message Send e-mail
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Mon Jul 28, 2008 10:38 pm    Post subject: Reply with quote

Ian,

Wow,

I thought of using DRAW_CHARACTERS@ and gave up ....

This is basically what I'm doing:

Code:

      SUBROUTINE DISPLAY_AND_MAYBE_PRINT
      COMMON/TEXTWINDOW/IHWND, KONTROL
      EXTERNAL IQUIT, IHARD_COPY, MINIM_FUNCTION
      INCLUDE <WINDOWS.INS>

      IA=WINIO@('%ca[Program output]%2nl&')
      IA=WINIO@('%hw&',IHWND)
      IA=WINIO@('%pv%70.40cw[vscroll,hscroll]&',99)
      IA=WINIO@('%mi[ICON_2]&')
      IA=WINIO@('%ww%ff%nl%cn&')
      IA=WINIO@('%6^bt[Clear]%6^bt[Print]%6^bt[Shrink]%lw',
     &            IQUIT,
     &           'PRINTER_OPEN', 99, IHARD_COPY,
     &            MINIM_FUNCTION,
     &            KONTROL)
      CALL PRINTER_OUTPUT_TO_99
      CLOSE (99)
      RETURN
      END

      INTEGER FUNCTION IHARD_COPY()
      COMMON/TEXTWINDOW/IHWND, KONTROL
      KONTROL = 1
      CALL WINDOW_UPDATE@(KONTROL)
      INCLUDE <WINDOWS.INS>
      CALL PRINTER_OUTPUT_TO_99
      CLOSE (99)
      IHARD_COPY = 0  ! or use KONTROL ...
      RETURN
      END

      INTEGER FUNCTION IQUIT()
      IQUIT = 0
      RETURN
      END

      INTEGER FUNCTION MINIM_FUNCTION()
      COMMON/TEXTWINDOW/IHWND
      INCLUDE <WINDOWS.INS>   
      LOGICAL Q
      Q=SHOWWINDOW (IHWND, SW_MINIMIZE)
      MINIM_FUNCTION=1
      RETURN
      END

      SUBROUTINE PRINTER_OUTPUT_TO_99
C     loads of formatted WRITE statements to UNIT=99
      RETURN
      END


Basically, I created a window with a scalable ClearWin window in it (%cw - this takes a pivot). I associated UNIT=99 with this inner %cw area, so I can just do formatted Fortran WRITEs to it. The window is left visible (%lw). Pressing the SHRINK button minimises it (although it has a minimise box top-right because of %ww), CLEAR wipes out the window containing the %cw area. PRINT wipes out the text window, allocates UNIT=99 now to a printer, and does the print, finishing off by releasing UNIT=99.

All the WRITE(99 ... statements are in SUBROUTINE PRINTER_OUTPUT_TO_99, whether for use in the %cw or hard copy. My outputs are all short, so I did not need to tinker with the size of buffer for %cw, and I haven't bothered with the ability to cut sections from the results - the top level window could have menus, including an edit menu.

It wouldn't be difficult to add a "save to file" button to it.

Eddie
Back to top
View user's profile Send private message
IanLambley



Joined: 17 Dec 2006
Posts: 490
Location: Sunderland

PostPosted: Sun Aug 10, 2008 9:48 am    Post subject: Reply with quote

Eddie,

There were a few bugs and omisions in my post above, please see my reply to Little-Acorn's question on edit boxes in the "support" forum section.

Ian
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> ClearWin+ All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group