Vertical scroll bar

Using Gfortran: I would please like to know how to get rid of the vertical scroll bar on the compiler output frame using Windows OS.

gfortran does not have a scroll bar, but the terminal emulator or IDE you are using to run gfortran probably does. The best place to check is the terminal/IDE application preferences.

2 Likes

It is Windows that takes the decisions re the frame in which the compiler output is presented. In C you can change most aspects re the compiler output window, from within your program. So it should also be possible from within a Fortran application.

There is no background, nor intent of the computation shared. Hence the speculation it might be a lengthy loop iteration. If this were the case and you are fine to compile from the CLI, can a) a redirect

gfortran my_file.f90 -o executable
./executable > permanent_record.txt

be an option for you? (Or an append to an existing file, which uses >> instead of a single >?)

Or b) use write with an unit associated with a record file, and store the data right there. The learning materials offers a section dedicated to file I/O with snippets one can use to build something greater. What about e.g.

program test
implicit none
integer :: io, i

open(newunit=io, file="log.txt", status="new", action="write")
  do i = 1, 20
    write(io, '(I2)') i
  end do
close(io)

end program test

I have no idea of what you are trying to do. “test.f90” didn’t do a thing. Thank you anyway. Patrick

Instead of reporting the iteration to the screen, results are stored in a permanent record, the newly generated / overwritten file log.txt. It isn’t of particular use except for the provision of a minimal working example.

Am I to understand that your code will remove a unwanted vertical scroll bar?

I don’t recognise your response as a solution to my query, viz getting rid of the vertical slide on the compiler output screen, using Windows (which is the cause of the slide, not Fortran, or the compiler). It can be done in C, so it should be doable in Fortran equally well.

The only way I am able to interpret your query is you’d like the console window height (in lines) to match the console buffer size, similar to what is shown at the following link:

It looks like it is possible to modify the console settings from the command line or via the Console API. More information can be found at the links below:

In particular, the following code snippet, adapted from this answer, appears to do what you are asking about:

/* SetWindow.c */

#include <windows.h> 

// SetWindow(Width,Height,WidthBuffer,HeightBuffer) 
//    -- set console size and buffer dimensions
//
void SetWindow(int Width, int Height, int WidthBuffer, int HeightBuffer) { 
    _COORD coord; 
    coord.X = WidthBuffer; 
    coord.Y = HeightBuffer; 

    _SMALL_RECT Rect; 
    Rect.Top = 0; 
    Rect.Left = 0; 
    Rect.Bottom = Height - 1; 
    Rect.Right = Width - 1; 

    HANDLE Handle = GetStdHandle(STD_OUTPUT_HANDLE);      // Get Handle 
    SetConsoleScreenBufferSize(Handle, coord);            // Set Buffer Size 
    SetConsoleWindowInfo(Handle, TRUE, &Rect);            // Set Window Size 
}  // SetWindow

You can try calling this function from Fortran by adding the following interface to your program:

interface 
   subroutine SetWindow(w,h,wb,hb) bind(c,name="SetWindow")
      use, intrinsic :: iso_c_binding, only: c_int
      implicit none
      integer(c_int), intent(in), value :: w, h, wb, hb
   end subroutine
end interface

and then calling it somewhere in your program:

call SetWindow(w=120,h=40,wb=110,hb=40)  ! Assumes c_int == kind(0)

Since I am not a Windows user, I can’t test this, nor do I know how to link the Windows runtime library.

I understand from what you say that I can set the size of the compiler output window, and remove the vertical slide from within Fortran code. That was precisely my query and what I wish to do. (I never said I wanted to do same from the command line.) I will test your code example - with many thanks!! Patrick de Ridder,

Removed - sorry

Testing your program:

program x
call SetWindow(w=120,h=40,wb=110,hb=40) ! Assumes c_int == kind(0)
end program x

interface
subroutine SetWindow(w,h,wb,hb) bind(c,name=“SetWindow”)
use, intrinsic :: iso_c_binding, only: c_int
implicit none
integer(c_int), intent(in), value :: w, h, wb, hb
end subroutine
end interface

I get following result
D:>gfortran x.f90
x.f90:1:9:

1 | program x
  |         1

…
5 | interface
| 2
Error: Two main PROGRAMs at (1) and (2)

In order to remove the scollbar in your console application you need to make the console buffer the same size as the console display window. The following program illustrates this. The interfaces to the Windows API functions and the constants and type definitions used in subroutine RemoveConsoleScrollBar need to be provided - they may be included with GFortran, I don’t know, I don’t use it - you can determine them yourself from Microsoft documentation or, as here, you can use the Intel modules. If you don’t want to install ifort you can extract the relevent files from the installer or copy them from the include folder of an ifort installation. You will need to link with kernel32.lib which you will have to find if you don’t want to install the Windows SDK or VSbuild tools or VS itself. The other option as illustrated above is to write a function in C, an interface to it in fortran and link the C object file when you build your application. I imagine you’ll still need kernel32.lib and the relevent C header files.

  program Main
  
  implicit none

  integer :: i_line
  character(1) :: str1

  do  i_line = 1,10
      write(*,*) 'Line ',i_line
  end do
  write(*,'(a)',advance = 'no') 'Press enter to continue... '
  read(*,'(a)') str1
  
  call RemoveConsoleScollBar

  write(*,'(a)')
  write(*,'(a)',advance = 'no') 'Press enter to continue... '
  read(*,'(a)') str1
  
  
  contains


  subroutine RemoveConsoleScollBar
  
  use ifwinty, only:SHORT,T_CONSOLE_SCREEN_BUFFER_INFO,T_COORD,BOOL,DWORD,HANDLE
  use ifwinty, only:STD_OUTPUT_HANDLE,FALSE
  use kernel32, only:GetStdHandle,GetConsoleScreenBufferInfo,SetConsoleScreenBufferSize,GetLastError
  
  type(T_CONSOLE_SCREEN_BUFFER_INFO) :: console_screen_buffer_info 
  type(T_COORD) :: coord
  
  integer(BOOL) :: bret
  integer(DWORD) :: dret
  integer(HANDLE) :: h_console_output
  
  h_console_output = GetStdHandle(STD_OUTPUT_HANDLE)
  bret = GetConsoleScreenBufferInfo(h_console_output,console_screen_buffer_info)
  if (bret /= FALSE) then
      associate(small_rect => console_screen_buffer_info%srWindow)
          coord%X = small_rect%Right - small_rect%Left + 1_SHORT
          coord%Y = small_rect%Bottom - small_rect%Top + 1_SHORT
      end associate
      bret = SetConsoleScreenBufferSize(h_console_output,coord)
      if (bret == FALSE) dret = GetLastError()
  else
      dret = GetLastError()
  end if

  end subroutine RemoveConsoleScollBar

  
  end program

Re: “Testing your program” :

@Patrick, I am afraid that you have taken bits of Fortran code from separate posts and assembled them in haphazard fashion. The resulting source file does not contain a valid Fortran program unit, which is why the compiler rejected it. The error message from the compiler is quite specific, and you may use it to guide you on how to fix the program. There are rules that specify where an interface block is to be placed, and your pastiche does not satisfy them.

removed

I did it more simple

#include <windows.h>
void removeScrollBars();

int main()
{
removeScrollBars();
}
void removeScrollBars()
{
HANDLE handle;
handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO info;GetConsoleScreenBufferInfo(handle, &info);
COORD new_size =
{
info.srWindow.Right - info.srWindow.Left + 1,
info.srWindow.Bottom - info.srWindow.Top + 1
};
SetConsoleScreenBufferSize(handle, new_size);
}
. . . and call it from the command line

You could have posted your latest “results” here instead of opening a new thread (Execute_command_line - #5 by Patrick). As stated by our community guidelines:

Make the effort to put things in the right place, so that we can spend more time discussing and less cleaning up. So:

  • […]
  • Don’t cross-post the same thing in multiple topics.

Concerning your program – calling a program via execute_command_line may appear like the simpler solution, but is prone to fail if the executable is not in the path or for any other arcane reason. Linking the routine directly into your executable would be preferable.

As I’ve suggested before, you can begin to study Fortran with the freely available chapters on Modern Fortran from Manning: Exploring Modern Fortran Basics. In case helpful, you can consider buying the full book (Modern Fortran), which also contains a chapter on interoperability with C.

Both @mecej4 and @Nocaster60 have also given good advice.

1 Like

Thank you for your valuable comment.