2016-03-04 75 views
1

我想在C#中使用COM调用中使用IFileDialogCustomize接口。我有呼叫定义为GetEditBoxText(ID,缓冲剂):如何从C#中的IFileDialogCustomize GetEditBoxText()获取字符串#

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

这是我从https://msdn.microsoft.com/en-us/library/windows/desktop/bb775908(v=vs.85).aspx

我写的代码得到的是:

 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; 

字符串总是返回奇怪的字符如벰∔。

我是新来的使用COM接口,并没有做过C++编程,所以我有点迷路了。为什么我没有从文本框中获取实际的字符串?

+1

你不需要串分配内存。这样的调用: IntPtr缓冲区; string textboxString; ... textboxString = Marshal.PtrToStringUni(buffer); Marshal.FreeCoTaskMem(buffer); –

+0

Um,'MethodImplOptions.InternalCall' [记录为](https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.methodimploptions(v = vs.110).aspx)“The call是内部的,也就是说,它调用了在公共语言运行库中实现的方法。“公共语言运行库中未实现“IFileDialogCustomize :: GetEditBoxText”。 –

+0

如果我没有分配内存,那么我会得到一个ArgumentException“值不在预期范围内”。 –

回答

1

我想通了。这是雅各布所说的和改变Com电话签名的组合。取而代之的

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

我需要做签名:

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

里面居然正确传递的IntPtr的了,我能得到使用

Marshal.PtrToStringUni(buffer); 
相关问题