Search code examples
c#c++shellcom

How to get string from IFileDialogCustomize GetEditBoxText() in C#


I am trying to use the IFileDialogCustomize interface in C# using COM calls. I have the call to GetEditBoxText(id, buffer) defined as:

    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
    HRESULT GetEditBoxText([In] int dwIDCtl, [Out] IntPtr ppszText);

Which I got from https://msdn.microsoft.com/en-us/library/windows/desktop/bb775908(v=vs.85).aspx

The code I have written is:

        IntPtr buffer = Marshal.AllocCoTaskMem(sizeof(int));
        string textboxString;
        var customizeDialog = GetFileDialog() as IFileDialogCustomize;
        if (customizeDialog != null)
        {
         HRESULT result = customizeDialog.GetEditBoxText(id, buffer);
            if (result != HRESULT.S_OK)
            {
                throw new Exception("Couldn't parse string from textbox");
            }
        }
        textboxString = Marshal.PtrToStringUni(buffer);
        Marshal.FreeCoTaskMem(buffer);
        return textboxString;

The string always returns odd characters such as 벰∔.

I'm new to using Com interfaces and haven't ever done C++ programming, so I'm a bit lost here. Why am I not getting the actual string from the textbox here?


Solution

  • I figured it out. It was a combination of what Jacob said and changing the signature of the Com call. Instead of

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void GetEditBoxText([In] int dwIDCtl, [Out] IntPtr ppszText);
    

    I needed to make the signature:

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        HRESULT GetEditBoxText([In] int dwIDCtl, out IntPtr ppszText);
    

    Which actually passed the IntPtr out correctly and I was able to get the string using

        Marshal.PtrToStringUni(buffer);