调整控制台的事件大小

本文关键字:事件 控制台 调整 | 更新日期: 2023-09-27 18:03:13

所以我认为窗口调整事件将通过winproc,我可能是错误的,希望得到通知控制台调整事件。

我想在调整大小时最大化控制台缓冲区,一旦它完成后基本上将其缩小到窗口大小,从而防止由于缓冲区小于窗口而导致的溢出错误。

调整控制台的事件大小

不幸的是,答案是你不能钩住控制台的windowproc,因为它在一个单独的、安全控制的进程中。spy++可以钩住其他进程的WndProcs来读取窗口消息,而spy++甚至不能读取控制台窗口消息。即使你可以解决安全问题,c#也不能用来挂钩另一个进程。

我有完全相同的竞争条件在调整大小。在Windows 10中情况更糟,因为调整窗口大小会使文本重新流动,并改变缓冲区宽度和窗口宽度。Console.BufferWidth, Console.BufferHeight和family是非原子的,如果您在调整窗口大小时使用它们,将抛出托管和非托管错误。

你绝对可以在之后通过读取输入缓冲区事件来了解的大小,但这并不能解决你的问题。您仍然会遇到并发性问题。因为这不是一个钩子,你不能让调整大小等待你完成Console类的非原子缓冲区/窗口大小操作。

我认为处理竞争条件的唯一选择是重试循环,这就是我将使用的。

while (true) try
{
    // Read and write the buffer size/location and window size/location and cursor position,
    // but be aware it will be rudely interrupted if the console is resized by the user.
}
catch (IOException) { }
catch (ArgumentOutOfRangeException) { }

1#您需要获得控制台窗口的引用,有多种方法可以做到这一点:https://support.microsoft.com/en-us/kb/124103

2#你需要使用setwindowshookex来hook你的windowproc

3#在WndProc中处理WM_SIZE消息https://msdn.microsoft.com/en-us/library/windows/desktop/ms632646(v=vs.85).aspx

值得注意的是,在SetWindowHookEx的例子中,调用CallNextHookEx的家伙,那是因为钩子是链式的。

另一个完整的示例http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx,他获取键盘消息,但是您可以做同样的事情来捕获大小事件。

一个捕获所有Windows消息

您可以使用线程侦听和捕获Resize事件:

class Program
{
    private static bool _listnerOn;
    static void Main(string[] args)
    {
        Thread listner = new Thread(EventListnerWork);
        listner.Start();
        Console.WriteLine("Press a key to exit...");
        Console.ReadKey(true);
        _listnerOn = false;
        listner.Join();
    }
    static void ConsoleResizeEvent(int height, int width)
    {
        Console.WriteLine("Console Resize Event");
    }
    static void EventListnerWork()
    {
        Console.WriteLine("Listner is on");
        _listnerOn = true;
        int height = Console.WindowHeight;
        int width = Console.WindowWidth;
        while (_listnerOn)
        {
            if (height != Console.WindowHeight || width != Console.WindowWidth)
            {
                height = Console.WindowHeight;
                width = Console.WindowWidth;
                ConsoleResizeEvent(height,width);
            }
            Thread.Sleep(10); 
        }
        Console.WriteLine("Listner is off");
    }
}