Search code examples
c#mfcc++-clicommand-line-interface

Convert HWND to IntPtr (CLI)


I have a HWND in my C++ MFC code, and I want to pass this HWND to a C# control and get it as IntPtr.

What Is wrong in my code, and how can I do it correctly? (I think it's something with wrong using of the CLI pointers, because I get an error that it cannot convert from System::IntPtr^ to System::IntPtr. But I don't know how exactly to make it all to work properly...)

My C++ MFC code:

HWND myHandle= this->GetSafeHwnd();
m_CLIDialog->UpdateHandle(myHandle);

My C# code:

public void UpdateHandle(IntPtr mHandle)
{
   ......
}

My CLI code:

void CLIDialog::UpdateHandle(HWND hWnd)
{
   System::IntPtr^ managedhWnd = gcnew System::IntPtr();
   HWND phWnd; // object on the native heap

   try
   {

       phWnd = (HWND)managedhWnd->ToPointer();
        *phWnd = *hWnd; //Deep-Copy the Native input object to Managed wrapper.

       m_pManagedData->CSharpControl->UpdateHandle(managedhWnd);
    }

Error (cannot convert from IntPtr^ to IntPtr) currently occurs on m_pManagedData->CSharpControl->UpdateHandle(managedhWnd);

if I change the CLI code to:

void CLIDialog::UpdateHandle(HWND hWnd)
{
   System::IntPtr managedhWnd;
   HWND phWnd; // object on the native heap

   try
   {

       phWnd = (HWND)managedhWnd.ToPointer();
        *phWnd = *hWnd; //Deep-Copy the Native input object to Managed wrapper.

       m_pManagedData->CSharpControl->UpdateHandle(managedhWnd);
    }

So in this case the value gotten in C# is 0.

How can I make it work properly?


Solution

  • To convert from HWND (which is just a pointer) to IntPtr you have to invoke its constructor, and you do not need gcnew as it's a value type. So this should work to pass a HWND from native to managed:

    void CLIDialog::UpdateHandle( HWND hWnd )
    {
      IntPtr managedHWND( hwnd );
      m_pManagedData->CSharpControl->UpdateHandle( managedHWND );
    }
    

    And this is a function you can invoke from managed code and get a native HWND from in native code:

    void SomeManagedFunction( IntPtr hWnd )
    {
      HWND nativeHWND = (HWND) hWnd.ToPointer();
      //...
    }