-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathenum_format.d
148 lines (128 loc) · 3.53 KB
/
enum_format.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/++
Win32 Drag and Drop demo
enum_format.d
++/
module enum_format;
import core.atomic;
import core.memory;
import win32.objidl;
import win32.ole2;
import win32.winbase;
import win32.windef;
import win32.winuser;
import win32.wtypes;
import utils;
import debugLog;
class EnumFormatEtc : ComObject, IEnumFORMATETC
{
private:
uint _index;
FORMATETC[] _formatEtc;
public:
//
this(FORMATETC[] fmt)
{
outLog("EnumFormatEtc:this");
_index = 0;
foreach (v ; fmt)
_formatEtc ~= deepDupFormatEtc(v);
}
~this()
{
outLog("EnumFormatEtc:~this");
}
//
extern (Windows)
override HRESULT QueryInterface(GUID* riid, void** ppv)
{
outLog("EnumFormatEtc:QueryInterface");
if (*riid == IID_IEnumFORMATETC)
{
*ppv = cast(void*)cast(IUnknown)this;
AddRef();
return S_OK;
}
return super.QueryInterface(riid, ppv);
}
/**
MSDN: If the returned FORMATETC structure contains a non-null
ptd member, then the caller must free this using CoTaskMemFree.
itemCount で指定された数だけFORMATETC構造体を pf にコピーします。
**/
extern (Windows)
HRESULT Next(ULONG itemCount, FORMATETC* pf, ULONG* itemsCopied)
{
outLog("ClassEnumFormatEtc:Next");
if (itemCount <= 0 || pf is null || _index >= _formatEtc.length)
return S_FALSE;
// itemCount が1 の時だけitemsCopied はNULLに出来る?
if (itemCount != 1 && itemsCopied is null )
return S_FALSE;
if (itemsCopied != null)
*itemsCopied = 0;
ULONG copyCount = 0;
while (_index < _formatEtc.length && copyCount < itemCount)
{
pf[copyCount] = deepDupFormatEtc(_formatEtc[_index]);
copyCount++;
_index++;
}
if (itemsCopied != null)
*itemsCopied = copyCount;
// did we copy all that was requested?
return copyCount == itemCount ? S_OK : S_FALSE;
}
/++
extern (Windows)
HRESULT Skip(ULONG itemCount)
{
outLog("ClassEnumFormatEtc:Skip");
_index += itemCount;
return _index <= _formatEtc.length ? S_OK : S_FALSE;
}
++/
// 読みとり位置(_index)をitemCount分スキップします
extern (Windows)
HRESULT Skip(ULONG itemCount)
{
outLog("ClassEnumFormatEtc:Skip");
while(_index < _formatEtc.length && itemCount > 0) {
_index++;
itemCount--;
}
return (itemCount == 0)? S_OK : S_FALSE;
}
// 読みとり位置(_index)を先頭に戻します
extern (Windows)
HRESULT Reset()
{
outLog("ClassEnumFormatEtc:Reset");
_index = 0;
return S_OK;
}
// Clone this enumerator.
// ppEnumFormatEtc を複製します
extern (Windows)
HRESULT Clone(IEnumFORMATETC* ppEnumFormatEtc)
{
outLog("ClassEnumFormatEtc:Clone");
if (_formatEtc.length == 0 || ppEnumFormatEtc is null)
return E_INVALIDARG;
auto obj = new EnumFormatEtc(_formatEtc);
if (obj is null)
return E_OUTOFMEMORY;
obj.AddRef();
*ppEnumFormatEtc = obj;
return S_OK;
}
private:
private void releaseMemory()
{
outLog("releaseMemory");
foreach (v ; _formatEtc) {
if (v.ptd)
CoTaskMemFree(v.ptd);
}
}
}
// eof