Buchempfehlung
Windows System Programming
Windows System Programming
Das Kompendium liefert viele interessante Informationen zur Windows-Programmierung auf Englisch. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Tutorial

Windows Drag und Drop Tutorial

von MitgliedstephanbrunkerSeite 7 von 12

IEnumFormatEtc

Das nächste Interface ist also der Enumerator für die FORMATETC Strukturen, der zu Beginn jedes Drags von Windows aufgerufen wird. Das Interface hat diese Struktur:

Type IEnumFORMATETC EXTENDS IUnknown    'custom IEnumFormatEtc Interface

    Declare Constructor(ByVal pfmtetc As FORMATETC Ptr, ByVal nNumFormats As integer)
    Declare Destructor()

    'Methods:
    'IUnknown Interface:
    Declare Virtual Function QueryInterface ( byval iid As REFIID, byval ppvObject As Any Ptr Ptr) as HRESULT

    'IEnumFormatEtc Interface:
    Declare Virtual Function Nexxt Alias "Next" ( ByVal celt As ULong, ByVal pfmtetc As FORMATETC Ptr,ByVal pceltFetched As ULong Ptr) As HRESULT
    Declare Virtual Function Skip ( ByVal celt As ULong) As HRESULT
    Declare Virtual Function Reset () As HRESULT
    Declare Virtual Function Clone ( ByVal ppEnumFormatetc As IEnumFORMATETC Ptr Ptr) As HRESULT

    'helper Function:
    Declare Static Function DeepCopyFormatEtc(ByVal dest As FORMATETC ptr, ByVal source As FORMATETC Ptr) As HRESULT

    'member variables:
    As ULong            m_nIndex
    As ULong            m_nNumFormats
    As FORMATETC ptr    m_pFormatetc

End Type

Der Constructor erhält das Array der FORMATETC Strukturen und die Größe des Arrays als nNumFormats und wir speichern das innerhalb des Types genauso wie im IDataObject. Die Hilfsfunktion DeepCopyFormatEtc kopiert dabei die komplette Struktur, denn rein prinzipiell könnte das ptd Member wiederum eine DVTARGETDEVICE Struktur enthalten, auch wenn wir sie nicht verwenden. Der Destructor löscht wieder alles:

Constructor IEnumFormatEtc(ByVal pfmtetc As FORMATETC Ptr, ByVal nNumFormats As integer)

    'initalize member variables
    m_nIndex = 0
    m_nNumFormats = nNumFormats

    'copy FORMATETC data
    m_pFormatEtc = New FORMATETC[nNumFormats]
    Dim i As Integer
    For i = 0 To nNumFormats - 1
        DeepCopyFormatEtc(@m_pFormatEtc[i],@pfmtetc[i])
    Next i
    Print "IEnumFormatEtc::Constructor [ "; m_nNumFormats;" Formats]"
End Constructor

Destructor IEnumFormatEtc()
    Print "IEnumFormatEtc::Destructor"

    If m_pFormatEtc Then
        Dim i As Integer
        For i = 0 To m_nNumFormats -1
            If m_pFormatEtc[i].ptd Then CoTaskMemFree(m_pFormatEtc[i].ptd)
        Next i
        Delete [] m_pFormatetc
    EndIf
End Destructor

'helper function
Function IEnumFormatEtc.DeepCopyFormatEtc(ByVal dest As FORMATETC ptr, ByVal source As FORMATETC Ptr) As HRESULT
    *dest = *source
    If source->ptd Then
        dest->ptd = CoTaskMemAlloc(SizeOf(DVTARGETDEVICE))
        *(dest->ptd) = *(source->ptd)
    EndIf
    Return S_OK
End Function

Die vier Methoden des Interfaces sind recht einfach erklärt: Next (weil das Schlüsselwort von Freebasic bereits verwendet wird, müssen wir mit Alias arbeiten) gibt ein Array der Größe celt mit den nächsten Strukturen zurück. Skip überspringt die Anzahl von celt Strukturen, Reset beginnt wieder von vorn und Clone kopiert das komplette Interface.

Function IEnumFormatEtc.Nexxt ( ByVal celt As ULong, ByVal pfmtetc As FORMATETC ptr,ByVal pceltFetched As ULong Ptr) As HRESULT

    If celt = 0 Or pfmtetc = 0 Then Return E_INVALIDARG

    'copy celt formats to pfmtetc, begin at m_nIndex
    Dim copied As Integer
    While(m_nIndex < m_nNumFormats) And (copied < celt)
        IEnumFormatEtc.DeepCopyFormatEtc(@pfmtetc[copied],@m_pFormatEtc[m_nIndex])
        copied += 1
        m_nIndex += 1
    Wend

    Print "IEnumFormatEtc::Next [copied: ";copied;" ]"

    If pceltFetched <> 0 Then *pceltFetched = copied
    If copied = celt Then
        Return S_OK
    Else
        Return S_FALSE
    EndIF
End Function

'IEnumFormatEtc::Skip
Function IEnumFormatEtc.Skip ( ByVal celt As ULong) As HRESULT

    'increase the index -> skip formats
    m_nIndex += celt
    If m_nIndex <= m_nNumFormats Then
        Return S_OK
    Else
        Return S_FALSE
    EndIf

End Function

'IEnumFormatEtc::Reset
Function IEnumFormatEtc.Reset ( ) As HRESULT

    'reset the index to 0
    m_nIndex = 0
    Return S_OK
End Function

'IEnumFormatEtc::Clone
Function IEnumFormatEtc.Clone ( ByVal ppEnumFormatetc As IEnumFORMATETC Ptr Ptr) As HRESULT

    'make a clone of this interface
    *ppEnumFormatetc = New IEnumFormatEtc(m_pFormatetc,m_nNumFormats)
    (*ppEnumFormatetc)->m_nIndex = m_nIndex
    Return S_OK
End Function

Damit hätten wir die benötigten Interfaces alle beisammen und wir können das ganze in unser Programm einbauen.

 

Gehe zu Seite Gehe zu Seite  1  2  3  4  5  6  7  8  9  10  11  12  
Zusätzliche Informationen und Funktionen
  Bearbeiten Bearbeiten  

  Versionen Versionen