Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
40 Views

How to change console window size programmatically

Jump to solution

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

Accepted Solutions
Highlighted
Black Belt
40 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
Highlighted
Black Belt
40 Views

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

0 Kudos
Highlighted
Beginner
40 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
Highlighted
Valued Contributor III
40 Views
        bret = SetWindowPos(GetConsoleWindow(),int(HWND_TOP,handle), wrect2%left, wrect2%top, &
                            wrect2%right-wrect2%left, wrect2%bottom -wrect2%top ,SWP_SHOWWINDOW)

 

0 Kudos
Highlighted
Valued Contributor III
40 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
Highlighted
Black Belt
41 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
Highlighted
Beginner
40 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