Hello,
We are redoing a C Application in WPF/C# framework.
This C application uses another one in C++/MFC we do not have time to catch for the moment. We seek to integrate it in our WPF Application.
We can use .exe or .dll for the c++ application.
To do so, we use "hwndHost" methods.
We have been able to begin integration ".exe", but steals some difficulties :
1/ open each time we want to use the c++ application is to time consuming
2/ we lost "focus" on C++ textbox (I don't if it is really focus, but it could be possible to double-click on textbox, but no more to click at some text position but it is possible to move mouse pointer with arrows keyboard...)
In a perfect world, we'd like to communicate with this application. I have no idea about how to achieve this goal...
I precise that it is a MDI appli with a ribbon.
Here's the current code.
public class EurekaHwndHost : HwndHost
{
int hostHeight, hostWidth;
EurekaEnvironment oContext;
public EurekaHwndHost(double height, double width, EurekaEnvironment oenv)
{
hostHeight = (int)height;
hostWidth = (int)width;
oContext = oenv;
}
public IntPtr hwndHost;
private IntPtr hookId = new IntPtr(3);
private NativeMethods.HookProc hookProc;
Process procEureka = null;
protected override HandleRef BuildWindowCore(HandleRef hwndParent)
{
if (procEureka == null)
{
string sCommand = System.IO.Path.Combine(MyTools.GetEurekaDirectoryPath(), "eurekav6.exe");
procEureka = new Process();
procEureka.StartInfo = new ProcessStartInfo(sCommand, oContext.EurParams.GetExeCommandArgs());
procEureka.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
procEureka.EnableRaisingEvents = true;
procEureka.Exited += new EventHandler(procEureka_Exited);
procEureka.Start();
try
{
hwndHost = procEureka.MainWindowHandle;
}
catch (Exception)
{
return new HandleRef(this, IntPtr.Zero);
}
int iTry = 0;
while (hwndHost.Equals(IntPtr.Zero) && iTry < 5)
{
System.Threading.Thread.Sleep(2000);
Process[] processes = Process.GetProcessesByName("EurekaV6");
foreach (Process pnn in processes)
{
hwndHost = pnn.MainWindowHandle;
}
iTry++;
}
if (hwndHost.Equals(IntPtr.Zero))
{
return new HandleRef(this, IntPtr.Zero);
}
uint newStyle = NativeMethods.WS_VISIBLE + NativeMethods.WS_MAXIMIZE + NativeMethods.WS_DLGFRAME + NativeMethods.WS_CHILD + NativeMethods.WS_SYSMENU;
NativeMethods.SetWindowLong(hwndHost, NativeMethods.GWL_STYLE, newStyle);
NativeMethods.SetParent(hwndHost, hwndParent.Handle);
IntPtr hMenu = NativeMethods.GetSystemMenu(hwndHost, false);
NativeMethods.RemoveMenu(hMenu, NativeMethods.SC_MOVE, NativeMethods.MF_BYCOMMAND);
NativeMethods.RemoveMenu(hMenu, NativeMethods.SC_SIZE, NativeMethods.MF_BYCOMMAND);
NativeMethods.RemoveMenu(hMenu, NativeMethods.SC_MAXIMIZE, NativeMethods.MF_BYCOMMAND);
NativeMethods.RemoveMenu(hMenu, NativeMethods.SC_MINIMIZE, NativeMethods.MF_BYCOMMAND);
NativeMethods.RemoveMenu(hMenu, NativeMethods.SC_RESTORE, NativeMethods.MF_BYCOMMAND);
NativeMethods.DrawMenuBar(hwndHost);
hookProc = new NativeMethods.HookProc(MyHookHandler);
NativeMethods.SetWindowsHookEx(hookId.ToInt32(), hookProc, IntPtr.Zero,
System.Threading.Thread.CurrentThread.ManagedThreadId);
}
return new HandleRef(this, hwndHost);
}
delegate void dlgProcEurekaExited(object sender, EventArgs e);
void procEureka_Exited(object sender, EventArgs e)
{
oContext.procEureka_Exited(sender,e);
}
private int MyHookHandler(int nCode, IntPtr wParam, IntPtr lParam)
{
return NativeMethods.CallNextHookEx(hookId.ToInt32(), nCode, wParam, lParam);
}
protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
handled = false;
return IntPtr.Zero;
}
protected override void DestroyWindowCore(HandleRef hwnd)
{
procEureka.Exited -= new EventHandler(procEureka_Exited);
NativeMethods.DestroyWindow(hwnd.Handle);
procEureka.Kill();
}
}
If it is more simple we can use the dll,
but if i do such code :
protected override HandleRef BuildWindowCore(HandleRef hwndParent)
{
hwndHost = EurekaDll.GetWindow();
[Modif style fenêtre...]
return new HandleRef(this, hwndHost);
}
where GetWindow() calls dll function :
__declspec(dllexport) HWND Sphinx2EurekaGetWindow()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return *framewnd;
}
and framewnd = new FrameWnd();
We can't acheive because we obtain an error on new handelref:
Et la ca plante sur le new HandleRef.
Échec de BuildWindowCore lors du renvoi du handle de fenêtre enfant hébergé.
à System.Windows.Interop.HwndHost.BuildWindow(HandleRef hwndParent)
à System.Windows.Interop.HwndHost.BuildOrReparentWindow()
à System.Windows.Interop.HwndHost.OnSourceChanged(Object sender, SourceChangedEventArgs e)
à System.Windows.SourceChangedEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
à System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
Finally, i hope help to decide if i must use .dll, or .exe and ideas to communicate. The only idea for the moment is written in a file....
Thanks
Aurore