本文介绍了如何在C#winform中托管VB6 EXE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我通过C#在.net中编写了一个WinForm来打开TabControl中的VB6 exe, 现在所有的Windows exe文件如Notpad.exe或...在TabControl中打开成功但VB6无法打开正确地在WinForm中,它不遵守父母/子女的法律。 现在请帮助我,这对我来说非常重要和绝对。 在Addation中: 1-in本程序使用Procces类启动程序,并使用SetParent()定义父/子合法。 2-我使用Telerik PageView在单独的标签中打开窗户。 代码: // Global Var --------------- public string TabName; public const int GWL_STYLE = -16; public const uint WS_VISIBLE = 0x10000000; // -------------------- ------- private void radButtonElement3_Click ( object sender,EventArgs e) { // 在Telerik PageView中Creeate New Tab TabName = radButtonElement3.Text; Telerik.WinControls.UI.RadPageViewPage Tab = new Telerik.WinControls.UI.RadPageViewPage(TabName); radPageView1.Pages.Add(Tab); radPageView1.SelectedPage = Tab; IntPtr appWin; appWin = IntPtr .Zero; string exeName = Application.StartupPath + \\ + VB6.exe; 流程p = null ; 尝试 { // 启动流程 p = System.Diagnostics.Process.Start(exeName); // 等待创建进程并进入空闲状态 p.WaitForInputIdle(); // 获取主句柄 appWin = p。 MainWindowHandle; } catch (例外情况) { MessageBox.Show( this ,ex.Message, 错误); } // 设置新的亨德尔 IntPtr _newHandler = radPageView1.Pages [(radPageView1.Pages.Count) - 1 ]。处理; SetParent(p.MainWindowHandle,_newHandler); SetWindowLong(_newHandler,GWL_STYLE,WS_VISIBLE); MoveWindow(_newHandler, 0 , 0 ,radPageView1.Pages [ 0 ]。Size.Width,radPageView1.Pages [ 0 ]。Size.Height,真); } // define user32。 dll --------------------------------------- [DllImport ( user32.dll,EntryPoint = GetWindowThreadProcessId,SetLastError = true , CharSet = CharSet.Unicode,ExactSpelling = true , CallingConvention = CallingConvention.StdCall)] private static extern long GetWindowThreadProcessId( long hWnd, long lpdwProcessId); [DllImport( user32.dll,SetLastError = true )] private static extern IntPtr FindWindow( string lpClassName, string lpWindowName); [DllImport( User32.dll)] public static extern int GetClassLong( IntPtr hWnd, int index); [DllImport( user32.dll,SetLastError = true )] private static extern long SetParent( IntPtr hWndChild, IntPtr hWndNewParent); [DllImport( user32.dll,EntryPoint = GetWindowLongA,SetLastError = true )] 私有 静态 extern long GetWindowLong( IntPtr hwnd, int nIndex); [DllImport( user32.dll,EntryPoint = SetWindowLongA,SetLastError = true )] 私有 静态 extern long SetWindowLong( IntPtr hwnd, int nIndex, long dwNewLong); [DllImport( user32.dll,SetLastError = true )] private static extern long SetWindowPos( IntPtr hwnd, long hWndInsertAfter, long x, long y, long cx, long cy, long wFlags); [DllImport( user32.dll,SetLastError = true )] private static extern bool MoveWindow( IntPtr hwnd, int x, int y, int cx, int cy, bool repaint); [DllImport( user32.dll,EntryPoint = PostMessageA,SetLastError = true )] 私有 静态 extern bool PostMessage( IntPtr hwnd, uint 消息, long wParam, long lParam); 解决方案 在不同的应用程序之间建立父/子关系并没有多大意义。显然,Windows并不是为处理这种情况而设计的。由于每种技术都有处理和调度事件的方式,因此混合使用VB或.NET可能会更糟糕...... 你可能想要转换你VB代码创建Active / X(COM)控件,然后可以嵌入到窗体或用户控件中。 或者更好的是,将转换VB6代码无论是VB.NET还是C#代码,还是用一些为.NET设计的更现代的控件替换那些控件。 如果你负担不起,那么我认为你应该仍然使用独立窗口。也许,您可以简单地调整VB6主窗口的位置,使其显示在适当的区域,并在VB6应用程序处于活动状态时将您的应用程序显示为已激活。 然后,您需要自定义代码来处理移动和激活,以便两个应用程序看起来就像是一个应用程序。即使这样,如果其中一个应用程序停止响应或崩溃,也可能会出现问题... 更好的选择可能是重用VB6 EXE中的代码但重做使用.NET的UI。 I programmed a WinForm in .net by C# to opens VB6 exe in TabControl,now all of Windows exe file like Notpad.exe or ... opens success in TabControl but VB6 does not open correctly in WinForm, it does not obey Parent/Child legal.Now please help me, it is very important and neseccery for me.In Addation:1-in The Program used Procces class to start program and also used SetParent() for define Parent/Child legal.2- I Used Telerik PageView to open windows in separated tabs.code:// Global Var ---------------public string TabName;public const int GWL_STYLE = -16;public const uint WS_VISIBLE = 0x10000000;// ---------------------------private void radButtonElement3_Click(object sender, EventArgs e) { //Creeate New Tab in Telerik PageView TabName = radButtonElement3.Text; Telerik.WinControls.UI.RadPageViewPage Tab = new Telerik.WinControls.UI.RadPageViewPage(TabName); radPageView1.Pages.Add(Tab); radPageView1.SelectedPage = Tab; IntPtr appWin; appWin = IntPtr.Zero; string exeName = Application.StartupPath + "\\" + "VB6.exe"; Process p = null; try { // Start the process p = System.Diagnostics.Process.Start(exeName); // Wait for process to be created and enter idle condition p.WaitForInputIdle(); // Get the main handle appWin = p.MainWindowHandle; } catch (Exception ex) { MessageBox.Show(this, ex.Message, "Error"); } //set new Handel IntPtr _newHandler = radPageView1.Pages[(radPageView1.Pages.Count) - 1].Handle; SetParent(p.MainWindowHandle, _newHandler); SetWindowLong(_newHandler, GWL_STYLE, WS_VISIBLE); MoveWindow(_newHandler, 0, 0, radPageView1.Pages[0].Size.Width, radPageView1.Pages[0].Size.Height, true); }// define user32.dll ---------------------------------------[DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern long GetWindowThreadProcessId(long hWnd, long lpdwProcessId); [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("User32.dll")] public static extern int GetClassLong(IntPtr hWnd, int index); [DllImport("user32.dll", SetLastError = true)] private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent); [DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)] private static extern long GetWindowLong(IntPtr hwnd, int nIndex); [DllImport("user32.dll", EntryPoint = "SetWindowLongA", SetLastError = true)] private static extern long SetWindowLong(IntPtr hwnd, int nIndex, long dwNewLong); [DllImport("user32.dll", SetLastError = true)] private static extern long SetWindowPos(IntPtr hwnd, long hWndInsertAfter, long x, long y, long cx, long cy, long wFlags); [DllImport("user32.dll", SetLastError = true)] private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint); [DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)] private static extern bool PostMessage(IntPtr hwnd, uint Msg, long wParam, long lParam); 解决方案 It does not really make sense to have parent/child relationship between distinct applications. And obviously, Windows is not designed to handle such scenarios. And it might be even worst with VB or .NET in the mix as each technology has its way of handling and dispatching events...You might want to convert you VB code to create Active/X (COM) controls that can then be embedded inside a form or user control.Or better yet, would be to convert the VB6 code to either VB.NET or C# code or replace those controls by some more modern controls designed for .NET.If you cannot afford to do that, then I think you should still use standalone windows. Maybe, you could simply adjust the position of the VB6 main windows so that it appears at the appropriate area and display your application as activated when the VB6 application is active.You would then need custom code to handle move and activation so that both applications appears as if they were one application. Even then, it might be problematic if one of the application stop responding or crashes...A better alternative might be to reuse code from the VB6 EXE but redo the UI using .NET. 这篇关于如何在C#winform中托管VB6 EXE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-16 05:13