在WPF窗口内嵌入控制台窗口 [英] Embed a Console Window inside a WPF Window

查看:2095
本文介绍了在WPF窗口内嵌入控制台窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有可能在WPF窗口中嵌入控制台窗口吗?



作为一个小背景,我开始尝试在WPF中从头开始实现一个控制台窗口,这是成功除了一个巨大的问题 - 它非常缓慢。在此处查看问题:

。你甚至可以只适应Windows窗体代码,并将其直接放入 WindowsFormsHost 控制。


Is it possible to embed a console window inside a WPF window?

As a little background, at first I tried to implement a console window from scratch in WPF, which was successful except for one huge problem -- its extremely slow. See the question here:
VT100 Terminal Emulation in Windows WPF or Silverlight

Since that does not seem to be an option I am instead looking at hosting an actual console window in my WPF application, which I've learned how to do as described here:

No output to console from a WPF application?

And that's great, by ideally I'd like to have that console window look like it is a part of the rest of the WPF application. I know it is possible with a WinForms app as I've seen it done, involving using the SetParent Win32 API. You can see an example .NET project that does it with this CommandBar project that embeds a console window into the shell:

http://www.codeproject.com/KB/cs/commandbar.aspx

So I am hopeful it can be done with WPF as well, but I have no idea how you'd do that. Help is much appreciated (also, if you have any brilliant solutions to my original problem of creating a terminal window from scratch in WPF since that would solve my needs too).

UPDATE:

With help Reed Copsey's help I was able to get the Console Window embedded. However, of course it needed to be styled and moved or else it just looked like a regular console window inside a WPF window. I need the title bar and large borders removed. Doing research I figured out how to use the Win32 APIs to do that like this:

uint style = GetWindowLong(ConsoleManager.ConsoleWindowHandle, GWL_STYLE);
style &= ~(uint)WindowStyles.WS_CAPTION;
style &= ~(uint)WindowStyles.WS_THICKFRAME;
style &= ~(uint)WindowStyles.WS_DLGFRAME;
style &= ~(uint)WindowStyles.WS_POPUP;
SetWindowLong(ConsoleManager.ConsoleWindowHandle, GWL_STYLE, style);
MoveWindow(ConsoleManager.ConsoleWindowHandle, 0, 0, (int)WindowsFormsHost.ActualWidth, (int)WindowsFormsHost.ActualHeight, true);

However there's one big problem. For some reason, the console window has a rendering artifact. It's as if it is not repainting itself on the bottom left and top right sides. The width of the artifact is similar to the width of the title bar and the thick border, and in fact if I leave the thick border in the size of the artifact goes down. But simply repainting it won't help since it reappears. I can, for example, move the window off the screen and back again to fix it, but it soon reappears on its own:

UPDATE 2: The effect happens even if I don't parent it into the WindowsFormsHost control. All I need to do to reproduce it is launch the console (using AllocConsole()) and then remove it's title bar with SetWindowLong. This is a win7 machine.

UPDATE 3: It seems 'messing' with other windows like this isn't supported. The console window calculates its textarea assuming there is a caption, so there's no way around this. I think my only option to get console-like behavior in WPF is going to be to write a custom WinForms control and then embed that into WPF.

解决方案

You should be able to use the same technique as the Windows Forms application you showed by reparenting into an HwndHost. You could even just adapt the Windows Forms code, and put this directly into WindowsFormsHost control.

这篇关于在WPF窗口内嵌入控制台窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆