Partilhar via


Exemplo de OpenFileDlg

Este exemplo demonstra como chamar uma função não gerenciada que espera um ponteiro para uma estrutura que contém uma seqüência de caracteres.Além disso, ele demonstra como usar um gerenciado classe para representar um un gerenciado estruturar como aplicar o InAttribute e OutAttribute atributos para a classe de realizar marshaling de volta para o chamador e como declarar e inicializar campos diferentes da classe para produzir un correto gerenciado representação.

O exemplo OpenFileDlg utiliza a seguinte função não gerenciada, mostrada com sua declaração de função original:

  • GetOpenFileName exportados de Comdlg32.dll.

    BOOL GetOpenFileName(LPOPENFILENAME lpofn);
    

The LPOPENFILENAME a estrutura do API do Win32, que é passado para a função anterior, contém os seguintes elementos:

typedef struct tagOFN { 
  DWORD         lStructSize; 
  //…
  LPCTSTR       lpstrFilter; 
  //…
  LPTSTR        lpstrFile; 
  DWORD         nMaxFile; 
  LPTSTR        lpstrFileTitle; 
  DWORD         nMaxFileTitle; 
  LPCTSTR       lpstrInitialDir; 
  LPCTSTR       lpstrTitle; 
  //… 
  LPCTSTR       lpstrDefExt; 
  //…
} OPENFILENAME, *LPOPENFILENAME; 

Neste exemplo, a OpenFileName classe contém sistema autônomo elementos da estrutura original sistema autônomo membros de classe. Estrutura não gerenciada é declarada sistema autônomo uma classe, em vez de sistema autônomo uma estrutura gerenciada para mostrar sistema autônomo uma classe pode ser usada quando a função não gerenciada espera um ponteiro para uma estrutura.Como uma classe gerenciada é um tipo de referência, quando ele é passado por valor, um ponteiro para a classe é passado para código não gerenciado.Isso é exatamente o que espera a função não gerenciada.

The StructLayoutAttribute atributo é aplicado à classe para garantir que os membros são dispostos em memória seqüencialmente, na ordem em que aparecem. The Conjunto de caracteres campo é definido para invocação de plataforma que pode escolher entre ANSI e Unicode formatos em time de execução, com base em plataforma de destino.

The LibWrap classe contém o protótipo do gerenciado de GetOpenFileName método, que passa a OpenFileName classe sistema autônomo um parâmetro de entrada/saída. Aplicando InAttribute and OutAttribute explicitamente, o exemplo garante que OpenFileName é empacotado sistema autônomo um parâmetro de entrada/saída e o chamador podem ver sistema autônomo alterações novamente empacotadas. (Para desempenho, o padrão de atributo direcional para uma classe é, que impede que o chamador vendo as alterações empacotadas novamente.) The App classe cria uma nova instância das OpenFileName classe e usa o Marshal.SizeOf método para determinar o dimensionar em bytes, da estrutura não gerenciada.

O código-fonte para os exemplos de código a seguir é fornecido pelo.NET estrutura Invocação de plataforma Tecnologia Exemplo.

Declaração de protótipos

' Declare a class member for each structure element.
< StructLayout( LayoutKind.Sequential, CharSet:=CharSet.Auto )> _
Public Class OpenFileName

   Public structSize As Integer = 0
   '…
   Public filter As String = Nothing
   '…
   Public file As String = Nothing
   Public maxFile As Integer = 0
   Public fileTitle As String = Nothing
   Public maxFileTitle As Integer = 0
   Public initialDir As String = Nothing
   Public title As String = Nothing
   '…
   Public defExt As String = Nothing
   '…
End Class 'OpenFileName

Public Class LibWrap
   ' Declare managed prototype for the unmanaged function.
   Declare Auto Function GetOpenFileName Lib "Comdlg32.dll" ( _
      <[In], Out> ByVal ofn As OpenFileName ) As Boolean
End Class 'LibWrap
// Declare a class member for each structure element.
[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Auto )]  
public class OpenFileName 
{
    public int       structSize = 0;
    //…
    public String    filter = null;
    //…
    public String    file = null;
    public int       maxFile = 0;
    public String    fileTitle = null;
    public int       maxFileTitle = 0;
    public String    initialDir = null;
    public String    title = null;   
    //…
    public String    defExt = null; 
    //…
}

public class LibWrap
{
   // Declare a managed prototype for the unmanaged function.
   [ DllImport( "Comdlg32.dll", CharSet=CharSet.Auto )]
   public static extern bool GetOpenFileName([ In, Out ] 
OpenFileName ofn );  
}

Chamando funções

Public Class App
   Public Shared Sub Main()
   
      Dim ofn As New OpenFileName()
      ofn.structSize = Marshal.SizeOf( ofn )
      ofn.filter = "Log files" & ChrW(0) & "*.log" & ChrW(0) & _
         "Batch files" & ChrW(0) & "*.bat" & ChrW(0)
      ofn.file = New String( New Char( 256 ) {})
      ofn.maxFile = ofn.file.Length
      ofn.fileTitle = New String( New Char( 64 ) {})
      ofn.maxFileTitle = ofn.fileTitle.Length
      ofn.initialDir = "C:\"
      ofn.title = "Open file called using platform invoke..."
      ofn.defExt = "txt"
      
      If LibWrap.GetOpenFileName( ofn ) Then
         Console.WriteLine( "Selected file with full path: {0}", _
         ofn.file )
      End If
   End Sub 'Main
End Class 'OpenFileDlgSample
public class App
{
   public static void Main()
   {
      OpenFileName ofn = new OpenFileName();
      ofn.structSize = Marshal.SizeOf( ofn );
      ofn.filter = "Log files\0*.log\0Batch files\0*.bat\0";
      ofn.file = new String( new char[ 256 ]);
      ofn.maxFile = ofn.file.Length;
      ofn.fileTitle = new String( new char[ 64 ]);
      ofn.maxFileTitle = ofn.fileTitle.Length;
      ofn.initialDir = "C:\\";
      ofn.title = "Open file called using platform invoke...";
      ofn.defExt = "txt";
      
      if( LibWrap.GetOpenFileName( ofn ))
      {
         Console.WriteLine( "Selected file with full path: {0}", 
            ofn.file );
      }
   }
}

Consulte também

Tarefas

Invocação de plataforma Tecnologia Exemplo

Conceitos

marshaling de strings

Tipos de dados de invocação de plataforma

Padrão de marshaling de strings

Criando protótipos em código gerenciado