Tutorial
Windows Drag und Drop Tutorial
von stephanbrunker | Seite 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.
Zusätzliche Informationen und Funktionen | |||||||
---|---|---|---|---|---|---|---|
|
|