Click here to Skip to main content
15,917,177 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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; // oldStyle & ~NativeMethods.WS_BORDER & ~NativeMethods.WS_SIZEBOX | NativeMethods.WS_CHILD & ~NativeMethods.WS_DISABLED;
                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
Posted
Comments
KarstenK 19-Jul-11 3:11am    
i dont understand france, but HWND from MFC is a bad idea. Access the hwnd-Member.

Cant you cahnge so call your code in a dll. I do stuff in C# to call a C-dll. Starting with init(), and than DoStuff(...) it works .-O
AuroreC 19-Jul-11 4:34am    
Could you explain more "hwnd-Member" ?

I can change code in dll and code in C#.
I start with "initlibrary" then call C++ function.
But the handle given by my dll seems not corrspond with type wanted for HandleRef.

I suppose that (*FrameWnd) could not be casted to Hwnd... I missed a marshalization somewhere ?

I'm not so fool ;=)

I call other dll functions which open windows and all is ok.

My particular problem here, is that i want a complete C++ application window integration in my wpf control.

It's why i use HwndHost ! And why i need a C++ application Handle !

Thanks for the second link, i will study it.
 
Share this answer
 
Hello,

We have solved our problem. It was not a C++dll problem, but "only" when the HwndHost was create.

We created it after render, it should be create on the loaded wpf ctrl event.

All is ok now.
 
Share this answer
 
dont cast a object to a hwmd!!! You are a fool (to be honest)

Thats nearly the same way as i have done it:
Dynamic Invoke C++ DLL function in C#[^]

this is more complex, but it looks like you want it that way.
Using Window Messages to Implement Global System Hooks in C#[^]

read this articles and try to understand. I would prefer the first way because it is cleaner and direct and you'll avoid the HWND hazzle stuff.

(I have search with "c++ dll c#")
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900