2017-10-21 79 views
3

我正在嘗試更改控制檯和其緩衝區的大小和80/25。下面是我試過的代碼:操縱.NET System.Console窗口大小導致ArgumentOutOfBoundsException

//ConsoleUtils u = new ConsoleUtils(); <- dummy class 
while (true) { 
    Console.SetBufferSize(Console.WindowLeft + 80, Console.WindowTop + 25); 
    Console.SetWindowSize(80, 25); 
    System.Threading.Thread.Sleep(1); //To minimize processor ussage %. 
} 

一切看起來不錯,但後,我嘗試調整控制檯,出現約ArgumentOutOfBounds野生錯誤(這取決於我縮放控制檯的方式)。 如何使控制檯大小永久?例如我希望它是80x25,並禁止用戶調整它的大小。

+0

嗨Krzysztof,你有沒有嘗試過的解決方案? –

+0

是的,我試過了。 –

回答

2

您的代碼有一個錯誤,可能會影響結果,也可能不會影響結果: Console.SetBufferSize(Console.WindowLeft + 80, Console.WindowTop + 25); 根據控制檯窗口左上角座標設置緩衝區大小。

Console.WindowLeftConsole.WindowTop屬性允許獲取或設置控制檯窗口的左上角位置。

第二個錯誤是在更改大小之前缺少檢查控制檯窗口和緩衝區大小以調整操作順序以使窗口大小始終小於緩衝區大小的要求。調整控制檯緩衝區和控制檯窗口大小的順序取決於目標大小和原始大小之間的關係。要更好地理解它,有必要了解控制檯窗口大小和控制檯緩衝區大小之間的關係。控制檯窗口是一個可以顯示控制檯緩衝區內容的滑動窗口。因此,如果控制檯窗口高度或寬度大於緩衝區高度或寬度ArgumentOutOfRangeException被拋出(在.NET中沒有ArgumentOutOfBounds異常類型)

爲了避免緩衝區的大小和窗口大小變化很重要的順序,並且必須在每個維度上處理它。爲了更好地理解問題,我創建了一個示例程序,它只是做你想做的事情,並允許更好地理解控制檯大小更改機制 - 它不是生產代碼!!!在實踐中,使用Console.SetBufferSize和Console.SetWindowSize方法執行此操作會更簡單。

using System; 
using System.Threading; 
using static System.Console; 

namespace ResizeConsoleWindow 
{ 
    class Program 
    { 

     static void Main(string[] args) 
     { 
      int targetWindowWidth = 80; 
      int targetWindowHeight = 25; 

      Timer timer = new Timer(
       (object state) => 
       { 
        int originalWindowWidth = WindowWidth; 
        int originalWindowHeight = WindowHeight; 
        int originalBufferWidth = BufferWidth; 
        int originalBufferHeight = BufferHeight; 

        if (targetWindowWidth <= originalWindowWidth) 
        { 
         WindowWidth = targetWindowWidth; 
         BufferWidth = targetWindowWidth; 
         if (targetWindowHeight <= originalWindowHeight) 
         { 
          WindowHeight = targetWindowHeight; 
          BufferHeight = targetWindowHeight; 
         } 
         else 
         { 
          BufferHeight = targetWindowHeight; 
          WindowWidth = targetWindowWidth; 
          WindowHeight = targetWindowHeight; 
         } 
        } 
        else 
        { 
         BufferWidth = targetWindowWidth; 
         WindowWidth = targetWindowWidth; 
         if (targetWindowHeight <= originalWindowHeight) 
         { 
          WindowHeight = targetWindowHeight; 
          BufferHeight = targetWindowHeight; 
         } 
         else 
         { 
          BufferHeight = targetWindowHeight; 
          WindowHeight = targetWindowHeight; 
         } 
        } 

        WindowWidth = targetWindowWidth; 
        WindowHeight = targetWindowHeight; 

       }, state: null, dueTime: 0, period: 200); 

      while (true) 
      { 
       WriteLine("Press Enter to exit ... "); 
       ReadLine(); 
       break; 
      } 
     } 
    } 
} 

玩弄啓動程序,並試圖改變控制檯窗口大小比目標大於或小於目標,看看會發生什麼(使它更容易觀察計時器增加刻度持續時間)或者調試程序而改變控制檯窗口大小並設置斷點以檢查更改是如何完成的。比改變順序,並檢查是否引發異常和何時。

+0

因此,即使不使用計時器,也無法設置最小/最大尺寸? –

+0

不,您可以在Main方法中更改大小而不需要定時器。定時器對於控制檯窗口大小的輪詢是必要的,以將其大小保持在預定義的目標 - 否則用戶可以隨意更改它。這是您的代碼功能要求之一。使用單獨的線程進行輪詢的效率較低,因爲一個線程(主要是睡眠)會因非常短的任務而被阻塞。 –