Čtení schránky - metafile   zodpovězená otázka

VB.NET

Zdravím,

Zkouším číst obsah schránky a nemůžu přijít kde dělám chybu. Ve schránce je kus textu z Wordu a potřebuji jej jako Obrázek - Metafile. Do PPT lze bez problému jako metafile zkopírovat.

Dim myObject As DataObject
Dim Formats() As String


myObject = Clipboard.GetDataObject
Formats = myObject.GetFormats

If Not Formats.Contains("MetaFilePict") Then Exit Sub

Dim myMeta As Drawing.Image
Dim myStream As IO.MemoryStream

myStream = myObject.GetData("MetaFilePict", True)
myMeta = New Imaging.Metafile(myStream)

Na posledním příkazu to hází chybu - Generic error in GDI+.

Nemohu bohužel použít myObject.getimage, protože se to tváří, že tam obrázek není a proto to zkouším přes memorystream.

Máte s tím někdo nějaké zkušenosti prosím?

Moc dík. P.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Formát grafiky, který ukládá Microsoft Word do schránky prostě není kompatibilní s grafickými objekty z .NET Frameworku. Jestli je možné použít to co je ve schránce v kombinaci s grafickými objekty z Frameworku zjistíte pomocí metody DataObject.ContainsImage.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Moc děkuji - bohužel jste mi potrvdil toho čeho jsem se obával.

DataObject.ContainsImage je false a právě proto GetImage také nemá smysl používat.

(když použiju např. Inkscape, tak vše funguje jak má a je to plně kompatibilní s IMAGE objektem.)

Takže to chce vyšpionit jak na formát používaný wordem:(

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Třeba bude někoho zajímat řešení, které jsem našel na netu. nejsem autor, jen jsem to upravil aby to bylo funkcni. Z diskuzí jsem pochopil, že s kompatabilitou metafilu WIN vs .NET clipboard je problém a tak se musí použít win API pro jeho čtení.

Takže stačí zavolat následující funkci, která vrátí objekt typu metafile nebo nic, pokud schránka neobsahuje metafile.


If Clipboard.GetDataObject.GetFormats.Contains("MetaFilePict") Then Mymetafile = MetafileClipboard.GetMetafile()

Tady je kompletní kód:

Imports System.Runtime.InteropServices

Class MetafileClipboard
    Shared Function GetMetafile() As Imaging.Metafile
        Const CF_ENHMETAFILE As Integer = 14

        Dim ip As IntPtr
        Dim metaFile As System.Drawing.Imaging.Metafile
        Dim bRet As Boolean

        bRet = ClipboardAPI.OpenClipboard(My.Application.OpenForms(0).Handle)
        If bRet = True Then
            'Verify the clipboard contains data available
            'as an enhanced metafile.
            bRet = ClipboardAPI.IsClipboardFormatAvailable(CF_ENHMETAFILE) <> 0
        End If

        If bRet = True Then
            'Store the clipboard's contents in the IntPtr.
            ip = ClipboardAPI.GetClipboardData(CF_ENHMETAFILE)
        End If

        'Verify the IntPrt contains data before proceeding. Passing
        'an empty IntPtr to System.Drawing.Imaging.Metafile results
        'in an exception.
        If Not IntPtr.Zero.Equals(ip) Then
            metaFile = New System.Drawing.Imaging.Metafile(ip, True)
            ClipboardAPI.CloseClipboard()
            
            Return metaFile
        Else
            Return Nothing
        End If
    End Function
End Class

Class ClipboardAPI
    <DllImport("user32.dll", EntryPoint:="OpenClipboard", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
    Public Shared Function OpenClipboard(ByVal hWnd As IntPtr) As Boolean
    End Function

    <DllImport("user32.dll", EntryPoint:="EmptyClipboard", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
    Public Shared Function EmptyClipboard() As Boolean
    End Function

    <DllImport("user32.dll", EntryPoint:="SetClipboardData", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
     Public Shared Function SetClipboardData(ByVal uFormat As Integer, ByVal ByValhWnd As IntPtr) As IntPtr()
    End Function

    <DllImport("user32.dll", EntryPoint:="CloseClipboard", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
    Public Shared Function CloseClipboard() As Boolean
    End Function

    <DllImport("user32.dll", EntryPoint:="GetClipboardData", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
    Public Shared Function GetClipboardData(ByVal uFormat As Integer) As IntPtr
    End Function

    <DllImport("user32.dll", EntryPoint:="IsClipboardFormatAvailable", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
    Public Shared Function IsClipboardFormatAvailable(ByVal uFormat As Integer) As Short
    End Function
End Class

nahlásit spamnahlásit spam 3 / 3 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback