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.
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:
- CMD: Set buffer height independently of window height
- How to change Screen buffer size in Windows Command Prompt from batch script
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.
Thank you for your valuable comment.