Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28455 Discussions

How to change console window size programmatically

jirina
New Contributor I
754 Views

Is there a way how I can change the size of my application's console window programmatically? I know I can change the console window size (and other properties like font, color, or screen buffer size) manually, but I would like to automatically change the size to the desired one once the application starts running.

0 Kudos
1 Solution
IanH
Honored Contributor II
754 Views

Yes - the error is due to a clash between use associated symbols.  You can use the ONLY feature of USE, or the rename feature, on ifport perhaps, to avoid the clash.

Here is an example using SetConsoleWindowInfo.  Unlike Andrew's example, this cannot control the location of the window, just its size. 

Note that a BOOL value is best considered a kind of integer (some API's even return BOOL values that are different from the TRUE or FALSE named constants (which are not necessarily same things as .TRUE. and .FALSE. logical literal constants)), and that 120 rows of console display requires quite a tall display monitor or a rather squished font.

program set_window
  use ifwin
  implicit none
  
  integer(HANDLE) :: output_handle
  integer(BOOL) :: bool_result
  
  type(T_CONSOLE_SCREEN_BUFFER_INFO) :: cBufInfoLoc
  type(T_SMALL_RECT) :: srWindowLoc
  
  output_handle = GetStdHandle(STD_OUTPUT_HANDLE)
  bool_result = GetConsoleScreenBufferInfo(output_handle, cBufInfoLoc)
  if (bool_result == 0) then
    print "(i0)", GetLastError()
    error stop 'GetConsoleScreenBufferInfo failed'
  end if
  
  srWindowLoc%left = 0
  srWindowLoc%top = 0
  srWindowLoc%right = min(79, cBufInfoLoc%dwMaximumWindowSize%X - 1)
  srWindowLoc%bottom = min(120, cBufInfoLoc%dwMaximumWindowSize%Y - 1)
  bool_result = SetConsoleWindowInfo(output_handle, TRUE, srWindowLoc)
  if (bool_result == 0) then
    print "(i0)", GetLastError()
    error stop 'SetConsoleWindowInfo failed'
  end if
end program set_window

 

View solution in original post

0 Kudos
6 Replies
IanH
Honored Contributor II
754 Views

Have a look at the console support API, in particular SetConsoleWindowInfo.

0 Kudos
jirina
New Contributor I
754 Views

Thank you for pointing me in the right direction. I am trying following to set console window icon (this works well) and to change the console window size (this does not work):

use ifport
use ifwin

        interface
          function SetConsoleIcon ( hIcon )
          use ifwinty
          integer(BOOL) :: SetConsoleIcon
          integer(DWORD) :: hIcon
          !dec$ attributes default, stdcall :: SetConsoleIcon
          end function
        end interface

        integer,parameter :: IDI_ICON_MYAPP=101
        integer(kind=HANDLE) hModule, hLib
        integer hMainIcon, lRet
        pointer ( SetConsoleF1, SetConsoleIcon )

        type(T_CONSOLE_SCREEN_BUFFER_INFO) cBufInfoLoc
        type(T_SMALL_RECT) :: srWindowLoc
        logical*4 :: lStatLoc
        integer(DWORD) :: lastError

        hLib = LoadLibrary ( 'Kernel32.dll'C )
        SetConsoleF1 = GetProcAddress ( hLib, 'SetConsoleIcon'C )
        hModule = GetModuleHandle(0)
        hMainIcon = LoadIcon ( hModule, MAKEINTRESOURCE(IDI_ICON_MYAPP) )
        lRet = SetConsoleIcon ( hMainIcon )
        lRet = FreeLibrary ( hLib )

        hModule = GetStdHandle(STD_OUTPUT_HANDLE)
        lStatLoc =  GetConsoleScreenBufferInfo ( hModule, cBufInfoLoc )
        if ( lStatLoc ) then
          srWindowLoc.top = 0
          srWindowLoc.left = 0
          srWindowLoc.right = 79
          srWindowLoc.bottom = 120
          lStatLoc = SetConsoleWindowInfo ( hModule, .TRUE., srWindowLoc )
          if ( .NOT.lStatLoc ) then
            lastError = GetLastError ( )
          endif
        endif

GetConsoleScreenBufferInfo works well and cBufInfoLoc contain correct information about the console window size. However, SetConsoleWindowInfo returns false and I am not able to use the GetLastError function, because I get compiler error #6405: The same named entity from different modules and/or program units cannot be referenced. Is this because I use both ifport and ifwin? Is there any documentation with a list of what both of them contain?

0 Kudos
andrew_4619
Honored Contributor II
754 Views
        bret = SetWindowPos(GetConsoleWindow(),int(HWND_TOP,handle), wrect2%left, wrect2%top, &
                            wrect2%right-wrect2%left, wrect2%bottom -wrect2%top ,SWP_SHOWWINDOW)

 

0 Kudos
andrew_4619
Honored Contributor II
754 Views

The one above works for me. You don't need to loadlibrary for kernel32 it will resolve as you use it by default with all windowing apps.

0 Kudos
IanH
Honored Contributor II
755 Views

Yes - the error is due to a clash between use associated symbols.  You can use the ONLY feature of USE, or the rename feature, on ifport perhaps, to avoid the clash.

Here is an example using SetConsoleWindowInfo.  Unlike Andrew's example, this cannot control the location of the window, just its size. 

Note that a BOOL value is best considered a kind of integer (some API's even return BOOL values that are different from the TRUE or FALSE named constants (which are not necessarily same things as .TRUE. and .FALSE. logical literal constants)), and that 120 rows of console display requires quite a tall display monitor or a rather squished font.

program set_window
  use ifwin
  implicit none
  
  integer(HANDLE) :: output_handle
  integer(BOOL) :: bool_result
  
  type(T_CONSOLE_SCREEN_BUFFER_INFO) :: cBufInfoLoc
  type(T_SMALL_RECT) :: srWindowLoc
  
  output_handle = GetStdHandle(STD_OUTPUT_HANDLE)
  bool_result = GetConsoleScreenBufferInfo(output_handle, cBufInfoLoc)
  if (bool_result == 0) then
    print "(i0)", GetLastError()
    error stop 'GetConsoleScreenBufferInfo failed'
  end if
  
  srWindowLoc%left = 0
  srWindowLoc%top = 0
  srWindowLoc%right = min(79, cBufInfoLoc%dwMaximumWindowSize%X - 1)
  srWindowLoc%bottom = min(120, cBufInfoLoc%dwMaximumWindowSize%Y - 1)
  bool_result = SetConsoleWindowInfo(output_handle, TRUE, srWindowLoc)
  if (bool_result == 0) then
    print "(i0)", GetLastError()
    error stop 'SetConsoleWindowInfo failed'
  end if
end program set_window

 

0 Kudos
jirina
New Contributor I
754 Views

Thank you, Andrew and Ian, for your valuable inputs. It is sufficient for me now to be able to change the console window size, without changing its position. I adjusted my code based on Ian's kind example and it works now; the problem was that I did not use

cBufInfoLoc%dwMaximumWindowSize

in my code. So, if my console window was positioned in such a way that it would not fit the screen after resizing, SetConsoleWindowInfo returned 0 and I concluded it does not work. After adding the maximum window size, everything works flawlessly.

Also, GetLastError can be used after I reviewed and optimized using ifport and ifwin by applying the ONLY feature of USE.

Thanks a lot once more!

0 Kudos
Reply