2010-07-19 118 views
7

是否可以在WPF窗口內嵌入控制檯窗口?在WPF窗口內嵌入控制檯窗口

作爲一個小小的背景,起初我試圖在WPF中從頭開始實現一個控制檯窗口,除了一個巨大的問題 - 它的速度非常慢之外,它是成功的。看到這裏的問題是:
VT100 Terminal Emulation in Windows WPF or Silverlight

因爲這似乎不是一種選擇,我不是看在我的WPF應用程序,我已經學會了如何在此描述做託管的實際控制檯窗口:

No output to console from a WPF application?

這是偉大的,由最好我想有一個控制檯窗口看起來像它是WPF應用程序的其它部分的一部分。我知道使用WinForms應用程序是可能的,因爲我已經看到它完成了,包括使用SetParent Win32 API。你可以看到一個例子.NET項目與嵌入一個控制檯窗口進入殼體這個命令欄項目做的:

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

所以我希望它可以用WPF做的很好,但我沒有想法你會怎麼做。非常感謝幫助(另外,如果你有任何明智的解決方案來解決我在WPF中從零開始創建終端窗口的原始問題,因爲這也解決了我的需求)。

UPDATE:

的幫助裏德·科普塞的幫助下,我能得到嵌入在控制檯窗口。然而,當然它需要被設計和移動,否則它看起來像一個WPF窗口內的常規控制檯窗口。我需要標題欄和大型邊框。做研究我想出瞭如何使用Win32 API來做這樣的事情:

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

但是有一個大問題。出於某種原因,控制檯窗口有一個渲染工件。就好像它不是在左下角和右上角重新繪畫一樣。工件的寬度與標題欄和厚邊框的寬度相似,事實上,如果我將工件大小的厚邊框留下,則會出現問題。但重新繪製它不會有幫助,因爲它重新出現。我可以,例如,移動窗口關閉屏幕並再次修復它,但它很快就重新出現在自己:

rendering artifact http://img837.imageshack.us/img837/6241/renderissue.png

更新2:即使我沒有影響情況將它父進入WindowsFormsHost控件。我需要做的就是啓動控制檯(使用AllocConsole()),然後使用SetWindowLong刪除它的標題欄。這是一臺win7機器。

UPDATE 3:它似乎'搞亂'與這樣的其他窗口不支持。控制檯窗口計算其textarea假設有一個標題,所以沒有辦法解決這個問題。我認爲我唯一的選擇在WPF中獲得類似控制檯的行爲將是編寫一個自定義的WinForms控件,然後將其嵌入到WPF中。

+0

你做到這一點成功? – 2012-06-24 03:24:01

+0

@ShawnMclean Nope ...更新代表整個故事:( – InfinitiesLoop 2012-06-24 04:22:58

+0

)您可能會看到Console2(後來分爲ConsoleZ)程序,它們成功地在標籤控件中託管了一系列命令提示符,但沒有標題/標題 – 2016-06-14 08:16:35

回答

4

您應該可以使用與通過重置爲HwndHost而顯示的Windows窗體應用程序相同的技術。您甚至可以調整Windows窗體代碼,並直接將其放入WindowsFormsHost控件中。

+0

It cann不是那麼容易,可以嗎?:)我這樣做了: SetParent(ConsoleManager.ConsoleWindowHandle,WindowsFormsHost.Handle); 但是控制檯窗口沒有顯示出來..只要它被重新設置,它就會消失。有任何想法嗎? – InfinitiesLoop 2010-07-19 21:47:30

+0

嘗試在WindowsFormsHost控件中放置(Windows窗體)面板,並將父窗口設置爲面板的句柄(而不是控件本身)。 – 2010-07-19 22:17:07

+0

你知道我認爲它正在工作,只是窗口有時在父視圖之外。我將需要弄清楚下一步如何將兩者的大小綁定在一起並隱藏標題欄等。您幫助了很多,謝謝:) – InfinitiesLoop 2010-07-19 22:20:52

5

除了Reed Copsey關於在WPF應用程序中嵌入控制檯窗口的優秀建議之外,另一種易於實現的替代策略是簡單地通過Process類發出命令,並將兩個流重定向到本地WPF的TextBlocks。下面是截圖...

enter image description here

這WPF應用程序(有線爲「EXE」文件中的Windows資源管理器上下文菜單)執行程序和管道,結果到相應的窗口。

它旨在幫助當您想要運行控制檯實用程序,並且當您單擊它時,該實用程序會在控制檯窗口中呼嘯而過,您永遠無法看到發生了什麼。它還連接到'csproj'文件以從資源管理器上運行MSBuild。

的一點是,有時更容易,更靈活的做自己,而不是嘗試舉辦一個控制檯窗口...

這個應用程序的內部使用這個類...

public class ProcessPiper 
{ 
    public string StdOut { get; private set; } 
    public string StdErr { get; private set; } 
    public string ExMessage { get; set; } 
    public void Start(FileInfo exe, string args, Action<ProcessPiper>onComplete) 
    { 
     ProcessStartInfo psi = new ProcessStartInfo(exe.FullName, args); 
     psi.RedirectStandardError = true; 
     psi.RedirectStandardOutput = true; 
     psi.UseShellExecute = false; 
     psi.WorkingDirectory = Path.GetDirectoryName(exe.FullName); 
     Task.Factory.StartNew(() => 
      { 
       try 
       { 
        ExMessage = string.Empty; 
        Process process = new Process(); 
        process.StartInfo = psi; 
        process.Start(); 
        process.WaitForExit(); 
        StdOut = process.StandardOutput.ReadToEnd(); 
        StdErr = process.StandardError.ReadToEnd(); 
        onComplete(this); 
       } 
       catch (Exception ex) 
       { 
        ExMessage = ex.Message; 
       } 
      }); 
    } 
} 

該類執行命名的'exe'文件並捕獲輸出,然後調用View Model。整個編碼鑽大約需要一個小時左右......在Process類

文檔是在這裏:http://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx