Resize Event for Console

我的梦境 提交于 2019-12-11 03:08:03

问题


So I thought the window resize event would come through winproc, I might be mistaken, looking to get notified for a Console resize event.

I want to maximize the console buffer on resize, and once it's finished essentially shrink it back down to the window size, thus preventing an overflow error due to the buffer being smaller than the window.


回答1:


Unfortunately, the answer is you can't hook the console's WndProc because it's in a separate, security-controlled process. Spy++ can hook other processes' WndProcs to read window messages, and Spy++ can't even read console window messages. Even if you could work around the security issue, C# cannot be used to hook another process.

I'm having the exact same race condition on resize. It's worse on Windows 10 because resizing the window reflows the text and changes the buffer width as well as the window width. Console.BufferWidth, Console.BufferHeight and family are non-atomic and will throw both managed and unmanaged errors if you use them while the window is being resized.

You can definitely find out about resizes after the fact by Reading Input Buffer Events but that won't solve your problem. You'll still have concurrency issues. Since that's not a hook, you can't make the resize wait for you to finish the Console class's non-atomic buffer/window size operations.

I think the only option to deal with the race condition is a retry loop, and that is what I will use.

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) { }



回答2:


1# You'll need to get a reference to the console window, there's various ways of doing that: https://support.microsoft.com/en-us/kb/124103

2# You'll need to hook your WndProc using setwindowshookex SetWindowsHookEx in C#

3# Handle the WM_SIZE message inside your WndProc https://msdn.microsoft.com/en-us/library/windows/desktop/ms632646(v=vs.85).aspx

Its important to note that in the SetWindowHookEx example, the guy called CallNextHookEx, thats because hooks are chained.

Another full example http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx where he gets keyboard messages, but you can do the same to catch the size events.

One more Capture all Windows Messages




回答3:


You can listen and capture the Resize event with a thread :

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");

    }

}


来源:https://stackoverflow.com/questions/31467941/resize-event-for-console

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!