Genomgång: Anropa Windows-API:er (Visual Basic)

Windows-API:er är DLL:er (dynamic-link libraries) som ingår i Windows-operativsystemet. Du använder dem för att utföra uppgifter när det är svårt att skriva egna motsvarande procedurer. Windows tillhandahåller till exempel en funktion med namnet FlashWindowEx som gör att du kan göra namnlisten för ett program alternativ mellan ljusa och mörka nyanser.

Fördelen med att använda Windows-API:er i koden är att de kan spara utvecklingstid eftersom de innehåller dussintals användbara funktioner som redan är skrivna och väntar på att användas. Nackdelen är att Windows-API:er kan vara svåra att arbeta med och oförlåtande när saker går fel.

Windows-API:er representerar en särskild kategori av samverkan. Windows-API:er använder inte hanterad kod, har inte inbyggda typbibliotek och använder datatyper som skiljer sig från dem som används med Visual Studio. På grund av dessa skillnader, och eftersom Windows-API:er inte är COM-objekt, utförs samverkan med Windows-API:er och .NET Framework med hjälp av plattformsanrop eller PInvoke. Plattformsanrop är en tjänst som gör det möjligt för hanterad kod att anropa ohanterade funktioner som implementeras i DLL:er. Mer information finns i Använda ohanterade DLL-funktioner. Du kan använda PInvoke i Visual Basic genom att antingen använda -instruktionen Declare eller tillämpa attributet på DllImport en tom procedur.

Windows API-anrop var en viktig del av Visual Basic-programmering tidigare, men är sällan nödvändiga med Visual Basic .NET. När det är möjligt bör du använda hanterad kod från .NET Framework för att utföra uppgifter i stället för Windows API-anrop. Den här genomgången innehåller information om de situationer där det är nödvändigt att använda Windows-API:er.

Kommentar

Datorn kan visa olika namn eller platser för vissa av Visual Studio-användargränssnittselementen i följande instruktioner. Den Visual Studio-utgåva som du har och de inställningar som du använder avgör dessa element. Mer information finns i Anpassa IDE.

API-anrop med deklarera

Det vanligaste sättet att anropa Windows-API:er är att använda -instruktionen Declare .

Deklarera en DLL-procedur

  1. Fastställ namnet på den funktion som du vill anropa, plus dess argument, argumenttyper och returvärde, samt namnet och platsen för den DLL som innehåller den.

    Kommentar

    Fullständig information om Windows-API:er finns i Win32 SDK-dokumentationen i Platform SDK Windows API. Mer information om de konstanter som Windows-API:er använder finns i huvudfilerna, till exempel Windows.h som ingår i Platform SDK.

  2. Öppna ett nytt Windows-programprojekt genom att klicka på Nyttmenyn Arkiv och sedan på Projekt. Dialogrutan Nytt projekt visas.

  3. Välj Windows-program i listan över Visual Basic-projektmallar. Det nya projektet visas.

  4. Lägg till följande Declare funktion i klassen eller modulen där du vill använda DLL:en:

    Declare Auto Function MBox Lib "user32.dll" Alias "MessageBox" (
        ByVal hWnd As Integer,
        ByVal txt As String,
        ByVal caption As String,
        ByVal Typ As Integer) As Integer
    

Delar av deklarera-instruktionen

Instruktionen Declare innehåller följande element.

Automatisk modifierare

Modifieraren Auto instruerar körningen att konvertera strängen baserat på metodnamnet enligt vanliga språkkörningsregler (eller aliasnamn om det anges).

Nyckelord för Lib och Alias

Namnet som följer nyckelordet Function är det namn som programmet använder för att komma åt den importerade funktionen. Det kan vara samma som det verkliga namnet på den funktion som du anropar, eller så kan du använda valfritt giltigt procedurnamn och sedan använda nyckelordet Alias för att ange det verkliga namnet på den funktion som du anropar.

Ange nyckelordet Lib följt av namnet och platsen för den DLL som innehåller den funktion som du anropar. Du behöver inte ange sökvägen för filer som finns i Windows-systemkatalogerna.

Använd nyckelordet Alias om namnet på den funktion som du anropar inte är ett giltigt Visual Basic-procedurnamn eller står i konflikt med namnet på andra objekt i programmet. Alias anger det sanna namnet på funktionen som anropas.

Argument- och datatypsdeklarationer

Deklarera argumenten och deras datatyper. Den här delen kan vara utmanande eftersom de datatyper som Windows använder inte motsvarar Visual Studio-datatyper. Visual Basic utför mycket av arbetet åt dig genom att konvertera argument till kompatibla datatyper, en process som kallas marshaling. Du kan uttryckligen styra hur argument ordnas med hjälp av attributet MarshalAsAttribute som definierats i System.Runtime.InteropServices namnområdet.

Kommentar

Med tidigare versioner av Visual Basic kunde du deklarera parametrar As Any, vilket innebär att data av vilken datatyp som helst kan användas. Visual Basic kräver att du använder en specifik datatyp för alla Declare instruktioner.

Windows API-konstanter

Vissa argument är kombinationer av konstanter. Det API som visas i den här genomgången MessageBox accepterar till exempel ett heltalsargument med namnet Typ som styr hur meddelanderutan visas. Du kan fastställa det numeriska värdet för dessa konstanter genom att #define undersöka instruktionerna i filen WinUser.h. De numeriska värdena visas vanligtvis i hexadecimalt, så du kanske vill använda en kalkylator för att lägga till dem och konvertera till decimal. Om du till exempel vill kombinera konstanterna för utropsformatet MB_ICONEXCLAMATION 0x00000030 och formatmallen MB_YESNO Ja/Nej 0x00000004 kan du lägga till talen och få ett resultat av 0x00000034 eller 52 decimaler. Även om du kan använda decimalresultatet direkt är det bättre att deklarera dessa värden som konstanter i ditt program och kombinera dem med operatorn Or .

Deklarera konstanter för Windows API-anrop
  1. Läs dokumentationen för den Windows-funktion som du anropar. Fastställ namnet på de konstanter som används och namnet på .h-filen som innehåller de numeriska värdena för dessa konstanter.

  2. Använd en textredigerare, till exempel Anteckningar, för att visa innehållet i rubriken (.h) och hitta de värden som är associerade med de konstanter som du använder. API:et MessageBox använder till exempel konstanten MB_ICONQUESTION för att visa ett frågetecken i meddelanderutan. Definitionen för MB_ICONQUESTION finns i WinUser.h och visas på följande sätt:

    #define MB_ICONQUESTION 0x00000020L

  3. Lägg till motsvarande Const instruktioner i din klass eller modul för att göra dessa konstanter tillgängliga för ditt program. Till exempel:

    Const MB_ICONQUESTION As Integer = &H20
    Const MB_YESNO As Integer = &H4
    Const IDYES As Integer = 6
    Const IDNO As Integer = 7
    
Anropa DLL-proceduren
  1. Lägg till en knapp med namnet Button1 i startformuläret för projektet och dubbelklicka sedan på den för att visa koden. Händelsehanteraren för knappen visas.

  2. Lägg till kod i Click händelsehanteraren för knappen du lade till för att anropa proceduren och ange lämpliga argument:

    Private Sub Button1_Click(ByVal sender As System.Object,
        ByVal e As System.EventArgs) Handles Button1.Click
    
        ' Stores the return value.
        Dim RetVal As Integer
        RetVal = MBox(0, "Declare DLL Test", "Windows API MessageBox",
            MB_ICONQUESTION Or MB_YESNO)
    
        ' Check the return value.
        If RetVal = IDYES Then
            MsgBox("You chose Yes")
        Else
            MsgBox("You chose No")
        End If
    End Sub
    
  3. Kör projektet genom att trycka på F5. Meddelanderutan visas med knapparna Ja och Nej . Klicka på någon av dem.

Data Marshalling

Visual Basic konverterar automatiskt datatyperna för parametrar och returvärden för Windows API-anrop, men du kan använda MarshalAs attributet för att uttryckligen ange ohanterade datatyper som ett API förväntar sig. Mer information om interop marshalling finns i Interop Marshaling.

Så här använder du Deklarera och MarshalAs i ett API-anrop
  1. Fastställ namnet på den funktion som du vill anropa, plus dess argument, datatyper och returvärde.

  2. För att förenkla åtkomsten MarshalAs till attributet lägger du till en Imports -instruktion överst i koden för klassen eller modulen, som i följande exempel:

    Imports System.Runtime.InteropServices
    
  3. Lägg till en funktionsprototyp för den importerade funktionen i den klass eller modul som du använder och tillämpa MarshalAs attributet på parametrarna eller returvärdet. I följande exempel är ett API-anrop som förväntar sig att typen void* är marshalled som AsAny:

    Declare Sub SetData Lib "..\LIB\UnmgdLib.dll" (
        ByVal x As Short,
        <MarshalAsAttribute(UnmanagedType.AsAny)>
            ByVal o As Object)
    

API-anrop med DllImportera

Attributet DllImport ger ett andra sätt att anropa funktioner i DLL:er utan typbibliotek. DllImport är ungefär likvärdigt med att använda en Declare -instruktion men ger mer kontroll över hur funktioner anropas.

Du kan använda DllImport med de flesta Windows API-anrop så länge anropet refererar till en delad (kallas ibland statisk) metod. Du kan inte använda metoder som kräver en instans av en klass. Till skillnad från Declare -instruktioner DllImport kan anrop inte använda attributet MarshalAs .

Anropa ett Windows-API med hjälp av attributet DllImport

  1. Öppna ett nytt Windows-programprojekt genom att klicka på Nyttmenyn Arkiv och sedan på Projekt. Dialogrutan Nytt projekt visas.

  2. Välj Windows-program i listan över Visual Basic-projektmallar. Det nya projektet visas.

  3. Lägg till en knapp med namnet Button2 i startformuläret.

  4. Dubbelklicka Button2 för att öppna kodvyn för formuläret.

  5. För att förenkla åtkomsten till lägger du till DllImporten Imports -instruktion överst i koden för startformulärklassen:

    Imports System.Runtime.InteropServices
    
  6. Deklarera en tom funktion före instruktionen End Class för formuläret och ge funktionen MoveFilenamnet .

  7. Public Tillämpa modifierarna och Shared på funktionsdeklarationen och ange parametrar för MoveFile baserat på argumenten som Windows API-funktionen använder:

    Public Shared Function MoveFile(
        ByVal src As String,
        ByVal dst As String) As Boolean
        ' Leave the body of the function empty.
    End Function
    

    Funktionen kan ha valfritt giltigt procedurnamn. attributet DllImport anger namnet i DLL:en. Den hanterar även samverkansredering för parametrarna och returvärdena, så att du kan välja Visual Studio-datatyper som liknar de datatyper som API:et använder.

  8. DllImport Använd attributet för den tomma funktionen. Den första parametern är namnet och platsen för den DLL som innehåller den funktion som du anropar. Du behöver inte ange sökvägen för filer som finns i Windows-systemkatalogerna. Den andra parametern är ett namngivet argument som anger namnet på funktionen i Windows-API:et. I det här exemplet DllImport tvingar attributet anrop att MoveFile vidarebefordras till MoveFileW i KERNEL32.DLL. Metoden MoveFileW kopierar en fil från sökvägen src till sökvägen dst.

    <DllImport("KERNEL32.DLL", EntryPoint:="MoveFileW", SetLastError:=True,
        CharSet:=CharSet.Unicode, ExactSpelling:=True,
        CallingConvention:=CallingConvention.StdCall)>
    Public Shared Function MoveFile(
        ByVal src As String,
        ByVal dst As String) As Boolean
        ' Leave the body of the function empty.
    End Function
    
  9. Lägg till kod i Button2_Click händelsehanteraren för att anropa funktionen:

    Private Sub Button2_Click(ByVal sender As System.Object,
        ByVal e As System.EventArgs) Handles Button2.Click
    
        Dim RetVal As Boolean = MoveFile("c:\tmp\Test.txt", "c:\Test.txt")
        If RetVal = True Then
            MsgBox("The file was moved successfully.")
        Else
            MsgBox("The file could not be moved.")
        End If
    End Sub
    
  10. Skapa en fil med namnet Test.txt och placera den i katalogen C:\Tmp på hårddisken. Skapa Tmp-katalogen om det behövs.

  11. Starta programmet genom att trycka på F5. Huvudformuläret visas.

  12. Klicka på Knapp2. Meddelandet "Filen har flyttats" visas om filen kan flyttas.

Se även