いろいろと調べたのですが、ほとんど理解できなかったので質問させていただきます。
この記事のおかげでD&Dのドロップ(ファイルの受け取り)の部分は実現できましたが、ドラッグ(ファイルの受け渡し)の部分がさっぱりできません。
まず、イグトランスさんがどうやってIDropTargetを実装しているのかコードをみても何をやっているのかまったく分からなかったのですが、無理やり自分なりにIDropSourceを実装してみました。次に、このページを参考に実際に書いてみましたがアクセス違反が起こってしまいます。
なぜアクセス違反になってしまうのでしょうか?それともうひとつ質問ですが、前記のCでの実装のページで使われている、実際にドラッグを開始すると思われるDoDrugDropですが、これは一体何者ですか?
以下にコード(ほぼ前述の記事のパクリですが…)を載せます。
なにか分かる方がいらっしゃればアドバイスよろしくお願いします。
OleDragDropImpl.sbp
[ここをクリックすると内容が表示されます]
OleDragDropInterface.sbp
Class DropTargetImpl
Inherits DropTargetImplThunk
Public
Sub DropTargetImpl(hwndTarget As HWND)
refCount = 0
hwnd = hwndTarget
End Sub
Function QueryInterface(ByRef iid As IID, ppvObj As *VoidPtr) As HRESULT
QueryInterface = S_OK
If IsEqualIID(iid, IID_IUnknown) <> FALSE Then
ppvObj[0] = VarPtr (This) As *IUnknown
AddRef()
ElseIf IsEqualIID(iid, IID_IDropTarget) <> FALSE Then
ppvObj[0] = VarPtr (This) As *IDropTarget
AddRef()
Else
ppvObj[0] = 0
QueryInterface = E_NOINTERFACE
End If
End Function
Function AddRef() As ULONG
refCount++
AddRef = refCount
End Function
Function Release() As ULONG
refCount--
Release = refCount
If refCount = 0 Then
Delete VarPtr(This)
End If
End Function
Function DragEnter(
/* [unique][in] */ ByVal pDataObj As *IDataObject,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
DragEnter = S_OK
End Function
Function DragOver(
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
DragOver = S_OK
End Function
Function DragLeave() As HRESULT
DragLeave = S_OK
End Function
Function Drop(
/* [unique][in] */ ByVal pDataObj As *IDataObject,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord _
) As HRESULT
Dim fData As Long
fData = FALSE
Dim fe As FORMATETC
Dim medium As STGMEDIUM
Dim hglMem As HGLOBAL
With fe
.cfFormat = CF_HDROP
.ptd = 0
.dwAspect = DVASPECT_CONTENT
.lindex = -1
.tymed = TYMED_HGLOBAL
End With
'ファイルドロップ
If( pDataObj->GetData(fe, medium) = S_OK )Then
hglMem = medium.data As HGLOBAL
Dim file[MAX_PATH] As Byte
DragQueryFile( GlobalLock(hglMem), 0, file, MAX_PATH )
GlobalUnlock(medium.data)
ReleaseStgMedium(medium)
MessageBox( hMainWnd, file, "",MB_OK)
effect = DROPEFFECT_COPY
fData = TRUE
End If
'それ以外
If( fData=FALSE )Then
effect = DROPEFFECT_NONE
End If
Drop = S_OK
End Function
Private
refCount As ULONG
hwnd As HWND
End Class
Class DropSourceImpl
Inherits DropSourceImplThunk
Public
Sub DropSourceImpl(hwndSource As HWND)
refCount = 0
hwnd = hwndSource
End Sub
Function QueryInterface(ByRef iid As IID, ppvObj As *VoidPtr) As HRESULT
QueryInterface = S_OK
If IsEqualIID(iid, IID_IUnknown) <> FALSE Then
ppvObj[0] = VarPtr (This) As *IUnknown
AddRef()
ElseIf IsEqualIID(iid, IID_IDropTarget) <> FALSE Then
ppvObj[0] = VarPtr (This) As *IDropTarget
AddRef()
Else
ppvObj[0] = 0
QueryInterface = E_NOINTERFACE
End If
End Function
Function AddRef() As ULONG
refCount++
AddRef = refCount
End Function
Function Release() As ULONG
refCount--
Release = refCount
If refCount = 0 Then
Delete VarPtr(This)
End If
End Function
Function QueryContinueDrag(
ByVal fEscapePressed As DWord,
ByVal grfKeyState As DWord) As HRESULT
QueryContinueDrag = S_OK
/* ESCキーが押されたらD&Dキャンセル */
If fEscapePressed Then
MessageBox(0, "キャンセル", "", MB_OK)
QueryContinueDrag = DRAGDROP_S_CANCEL
/* マウスボタンが離されたらD&D完了 */
Elseif (grfKeyState And (MK_LBUTTON or MK_RBUTTON)) Then
MessageBox(0, "完了", "", MB_OK)
QueryContinueDrag = S_OK
Endif
EndFunction
Function GiveFeedback(
ByVal dwEffect As DWord) As HRESULT
GiveFeedback = DRAGDROP_S_USEDEFAULTCURSORS
EndFunction
Private
refCount As ULONG
hwnd As HWND
End Class
Inherits DropTargetImplThunk
Public
Sub DropTargetImpl(hwndTarget As HWND)
refCount = 0
hwnd = hwndTarget
End Sub
Function QueryInterface(ByRef iid As IID, ppvObj As *VoidPtr) As HRESULT
QueryInterface = S_OK
If IsEqualIID(iid, IID_IUnknown) <> FALSE Then
ppvObj[0] = VarPtr (This) As *IUnknown
AddRef()
ElseIf IsEqualIID(iid, IID_IDropTarget) <> FALSE Then
ppvObj[0] = VarPtr (This) As *IDropTarget
AddRef()
Else
ppvObj[0] = 0
QueryInterface = E_NOINTERFACE
End If
End Function
Function AddRef() As ULONG
refCount++
AddRef = refCount
End Function
Function Release() As ULONG
refCount--
Release = refCount
If refCount = 0 Then
Delete VarPtr(This)
End If
End Function
Function DragEnter(
/* [unique][in] */ ByVal pDataObj As *IDataObject,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
DragEnter = S_OK
End Function
Function DragOver(
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
DragOver = S_OK
End Function
Function DragLeave() As HRESULT
DragLeave = S_OK
End Function
Function Drop(
/* [unique][in] */ ByVal pDataObj As *IDataObject,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord _
) As HRESULT
Dim fData As Long
fData = FALSE
Dim fe As FORMATETC
Dim medium As STGMEDIUM
Dim hglMem As HGLOBAL
With fe
.cfFormat = CF_HDROP
.ptd = 0
.dwAspect = DVASPECT_CONTENT
.lindex = -1
.tymed = TYMED_HGLOBAL
End With
'ファイルドロップ
If( pDataObj->GetData(fe, medium) = S_OK )Then
hglMem = medium.data As HGLOBAL
Dim file[MAX_PATH] As Byte
DragQueryFile( GlobalLock(hglMem), 0, file, MAX_PATH )
GlobalUnlock(medium.data)
ReleaseStgMedium(medium)
MessageBox( hMainWnd, file, "",MB_OK)
effect = DROPEFFECT_COPY
fData = TRUE
End If
'それ以外
If( fData=FALSE )Then
effect = DROPEFFECT_NONE
End If
Drop = S_OK
End Function
Private
refCount As ULONG
hwnd As HWND
End Class
Class DropSourceImpl
Inherits DropSourceImplThunk
Public
Sub DropSourceImpl(hwndSource As HWND)
refCount = 0
hwnd = hwndSource
End Sub
Function QueryInterface(ByRef iid As IID, ppvObj As *VoidPtr) As HRESULT
QueryInterface = S_OK
If IsEqualIID(iid, IID_IUnknown) <> FALSE Then
ppvObj[0] = VarPtr (This) As *IUnknown
AddRef()
ElseIf IsEqualIID(iid, IID_IDropTarget) <> FALSE Then
ppvObj[0] = VarPtr (This) As *IDropTarget
AddRef()
Else
ppvObj[0] = 0
QueryInterface = E_NOINTERFACE
End If
End Function
Function AddRef() As ULONG
refCount++
AddRef = refCount
End Function
Function Release() As ULONG
refCount--
Release = refCount
If refCount = 0 Then
Delete VarPtr(This)
End If
End Function
Function QueryContinueDrag(
ByVal fEscapePressed As DWord,
ByVal grfKeyState As DWord) As HRESULT
QueryContinueDrag = S_OK
/* ESCキーが押されたらD&Dキャンセル */
If fEscapePressed Then
MessageBox(0, "キャンセル", "", MB_OK)
QueryContinueDrag = DRAGDROP_S_CANCEL
/* マウスボタンが離されたらD&D完了 */
Elseif (grfKeyState And (MK_LBUTTON or MK_RBUTTON)) Then
MessageBox(0, "完了", "", MB_OK)
QueryContinueDrag = S_OK
Endif
EndFunction
Function GiveFeedback(
ByVal dwEffect As DWord) As HRESULT
GiveFeedback = DRAGDROP_S_USEDEFAULTCURSORS
EndFunction
Private
refCount As ULONG
hwnd As HWND
End Class
[ここをクリックすると内容が表示されます]
OleDragDropThunk.sbp
TypeDef BOOL = Long
TypeDef HRESULT = Long
TypeDef ULONG = DWord
TypeDef IID = GUID
TypeDef CLSID = GUID
TypeDef CLIPFORMAT = Word
Type DROPFILES
pFiles As DWord
pt As POINTAPI
fNC As BOOL
fWid As BOOL
End Type
Dim IID_IUnknown = [0, 0, 0, [&hC0, 0, 0, 0, 0, 0, 0, &h46]] As IID
Dim IID_IDataObject = [&h0000010e, 0, 0, [&hC0, 0, 0, 0, 0, 0, 0, &h46]] As IID
Dim IID_IDropTarget = [&h00000122, 0, 0, [&hC0, 0, 0, 0, 0, 0, 0, &h46]] As IID
Dim IID_IDropSource = [&h00000121, 0, 0, [&hC0, 0, 0, 0, 0, 0, 0, &h46]] As IID
Const DRAGDROP_S_CANCEL = &h00040101L
Const DRAGDROP_S_USEDEFAULTCURSORS = &h00040102L
Declare Function OleInitialize Lib "Ole32" (reserved As VoidPtr) As HRESULT
Declare Sub OleUninitialize Lib "Ole32" ()
Declare Function IsEqualGUID Lib "Ole32" (ByRef guid1 As GUID, ByRef guid2 As GUID) As BOOL
Declare Function IsEqualCLSID Lib "Ole32" Alias "IsEqualGUID" (ByRef clsid1 As CLSID, ByRef clsid2 As CLSID) As BOOL
Declare Function IsEqualIID Lib "Ole32" Alias "IsEqualGUID" (ByRef iid1 As IID, ByRef iid2 As IID) As BOOL
Function egtraOleInitialize() HRESULT
OleInitialize(0)
End Function
Declare Function RegisterDragDrop Lib "Ole32" (
hwnd As HWND,
pDropTarget As *IDropTarget _
) As HRESULT
Declare Function RevokeDragDrop Lib "Ole32" (
hwnd As HWND _
) As HRESULT
Declare Sub ReleaseStgMedium Lib "OLE32" (ByRef rmedium As STGMEDIUM)
Type FORMATETC
cfFormat As CLIPFORMAT
ptd As *DVTARGETDEVICE
dwAspect As DWord
lindex As Long
tymed As DWord
End Type
Type STGMEDIUM
tymed As DWord
data As VoidPtr
hGlobal As HGLOBAL
' C/C++では次のような共用体
/* [switch_type(DWORD), switch_is((DWORD) tymed)]
union {
[case(TYMED_GDI)] HBITMAP hBitmap;
[case(TYMED_MFPICT)] HMETAFILEPICT hMetaFilePict;
[case(TYMED_ENHMF)] HENHMETAFILE hEnhMetaFile;
[case(TYMED_HGLOBAL)] HGLOBAL hGlobal;
[case(TYMED_FILE)] LPWSTR lpszFileName;
[case(TYMED_ISTREAM)] IStream *pstm;
[case(TYMED_ISTORAGE)] IStorage *pstg;
[default] ;
};
*/
/*[unique]*/ pUnkForRelease As *IUnknown
End Type
Type DVTARGETDEVICE
tdSize As DWord
tdDriverNameOffset As Word
tdDeviceNameOffset As Word
tdPortNameOffset As Word
tdExtDevmodeOffset As Word
tdData[ELM(1)] As Byte
End Type
Class IDataObject
Inherits IUnknown
Public
Virtual Function /* [local] */ GetData(
/* [unique][in] */ ByRef rformatetcIn As FORMATETC,
/* [out] */ ByRef rmedium As STGMEDIUM _
) As HRESULT
Virtual Function /* [local] */ GetDataHere(
/* [unique][in] */ ByRef rformatetcIn As FORMATETC,
/* [out] */ ByRef pmedium As STGMEDIUM _
) As HRESULT
Virtual Function QueryGetData(
/* [unique][in] */ ByRef pformatetc As FORMATETC _
) As HRESULT
Virtual Function GetCanonicalFormatEtc(
/* [unique][in] */ ByRef pformatetcIn As FORMATETC,
/* [out] */ ByRef pmedium As STGMEDIUM _
) As HRESULT
Virtual Function /* [local] */ SetData(
/* [unique][in] */ByRef pformatetcIn As FORMATETC,
/* [out] */ByRef pmedium As STGMEDIUM,
/* [in] */ fRelease As BOOL _
) As HRESULT
Virtual Function EnumFormatEtc(
/* [in] */ ByVal dwDirection As DWord,
/* [out] */ ByRef rpenumFormatEtc As *IEnumFORMATETC _
) As HRESULT
Virtual Function DAdvise(
/* [in] */ ByRef pformatetc As FORMATETC,
/* [in] */ ByVal advf As DWORD,
/* [unique][in] */ ByVal pAdvSink As *IAdviseSink,
/* [out] */ ByVal pdwConnection As *DWord _
) As HRESULT
Virtual Function DUnadvise(
/* [in] */ ByVal dwConnection As DWord _
) As HRESULT
Virtual Function EnumDAdvise(
/* [out] */ ByRef rpenumAdvise As *IEnumSTATDATA _
) As HRESULT
End Class
Class IDropTarget
Inherits IUnknown
Public
Virtual Function DragEnter(
/* [unique][in] */ ByVal pDataObj As *IDataObject,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
Virtual Function DragOver(
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
Virtual Function DragLeave() As HRESULT
Virtual Function Drop(
/* [unique][in] */ ByVal pDataObj As *IDataObject,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
End Class
Class IDropSource
Inherits IUnknown
Public
Virtual Function QueryContinueDrag(
ByVal fEscapePressed As DWord,
ByVal grfKeyState As DWord) As HRESULT
Virtual Function GiveFeedback(
ByVal dwEffect As DWord) As HRESULT
End Class
Class IAdviseSink
Inherits IUnknown
End Class
Class IEnumSTATDATA
Inherits IUnknown
End Class
Class IEnumFORMATETC
Inherits IUnknown
End Class
Enum DROPEFFECT
DROPEFFECT_NONE = 0
DROPEFFECT_COPY = 1
DROPEFFECT_MOVE = 2
DROPEFFECT_LINK = 4
DROPEFFECT_SCROLL = &h80000000
End Enum
Enum /*[transmit_as(long)]*/ TYMED
TYMED_HGLOBAL = 1
TYMED_FILE = 2
TYMED_ISTREAM = 4
TYMED_ISTORAGE = 8
TYMED_GDI = 16
TYMED_MFPICT = 32
TYMED_ENHMF = 64
TYMED_NULL = 0
End Enum
Enum DVASPECT
DVASPECT_CONTENT = 1
DVASPECT_THUMBNAIL = 2
DVASPECT_ICON = 4
DVASPECT_DOCPRINT = 8
End Enum
TypeDef HRESULT = Long
TypeDef ULONG = DWord
TypeDef IID = GUID
TypeDef CLSID = GUID
TypeDef CLIPFORMAT = Word
Type DROPFILES
pFiles As DWord
pt As POINTAPI
fNC As BOOL
fWid As BOOL
End Type
Dim IID_IUnknown = [0, 0, 0, [&hC0, 0, 0, 0, 0, 0, 0, &h46]] As IID
Dim IID_IDataObject = [&h0000010e, 0, 0, [&hC0, 0, 0, 0, 0, 0, 0, &h46]] As IID
Dim IID_IDropTarget = [&h00000122, 0, 0, [&hC0, 0, 0, 0, 0, 0, 0, &h46]] As IID
Dim IID_IDropSource = [&h00000121, 0, 0, [&hC0, 0, 0, 0, 0, 0, 0, &h46]] As IID
Const DRAGDROP_S_CANCEL = &h00040101L
Const DRAGDROP_S_USEDEFAULTCURSORS = &h00040102L
Declare Function OleInitialize Lib "Ole32" (reserved As VoidPtr) As HRESULT
Declare Sub OleUninitialize Lib "Ole32" ()
Declare Function IsEqualGUID Lib "Ole32" (ByRef guid1 As GUID, ByRef guid2 As GUID) As BOOL
Declare Function IsEqualCLSID Lib "Ole32" Alias "IsEqualGUID" (ByRef clsid1 As CLSID, ByRef clsid2 As CLSID) As BOOL
Declare Function IsEqualIID Lib "Ole32" Alias "IsEqualGUID" (ByRef iid1 As IID, ByRef iid2 As IID) As BOOL
Function egtraOleInitialize() HRESULT
OleInitialize(0)
End Function
Declare Function RegisterDragDrop Lib "Ole32" (
hwnd As HWND,
pDropTarget As *IDropTarget _
) As HRESULT
Declare Function RevokeDragDrop Lib "Ole32" (
hwnd As HWND _
) As HRESULT
Declare Sub ReleaseStgMedium Lib "OLE32" (ByRef rmedium As STGMEDIUM)
Type FORMATETC
cfFormat As CLIPFORMAT
ptd As *DVTARGETDEVICE
dwAspect As DWord
lindex As Long
tymed As DWord
End Type
Type STGMEDIUM
tymed As DWord
data As VoidPtr
hGlobal As HGLOBAL
' C/C++では次のような共用体
/* [switch_type(DWORD), switch_is((DWORD) tymed)]
union {
[case(TYMED_GDI)] HBITMAP hBitmap;
[case(TYMED_MFPICT)] HMETAFILEPICT hMetaFilePict;
[case(TYMED_ENHMF)] HENHMETAFILE hEnhMetaFile;
[case(TYMED_HGLOBAL)] HGLOBAL hGlobal;
[case(TYMED_FILE)] LPWSTR lpszFileName;
[case(TYMED_ISTREAM)] IStream *pstm;
[case(TYMED_ISTORAGE)] IStorage *pstg;
[default] ;
};
*/
/*[unique]*/ pUnkForRelease As *IUnknown
End Type
Type DVTARGETDEVICE
tdSize As DWord
tdDriverNameOffset As Word
tdDeviceNameOffset As Word
tdPortNameOffset As Word
tdExtDevmodeOffset As Word
tdData[ELM(1)] As Byte
End Type
Class IDataObject
Inherits IUnknown
Public
Virtual Function /* [local] */ GetData(
/* [unique][in] */ ByRef rformatetcIn As FORMATETC,
/* [out] */ ByRef rmedium As STGMEDIUM _
) As HRESULT
Virtual Function /* [local] */ GetDataHere(
/* [unique][in] */ ByRef rformatetcIn As FORMATETC,
/* [out] */ ByRef pmedium As STGMEDIUM _
) As HRESULT
Virtual Function QueryGetData(
/* [unique][in] */ ByRef pformatetc As FORMATETC _
) As HRESULT
Virtual Function GetCanonicalFormatEtc(
/* [unique][in] */ ByRef pformatetcIn As FORMATETC,
/* [out] */ ByRef pmedium As STGMEDIUM _
) As HRESULT
Virtual Function /* [local] */ SetData(
/* [unique][in] */ByRef pformatetcIn As FORMATETC,
/* [out] */ByRef pmedium As STGMEDIUM,
/* [in] */ fRelease As BOOL _
) As HRESULT
Virtual Function EnumFormatEtc(
/* [in] */ ByVal dwDirection As DWord,
/* [out] */ ByRef rpenumFormatEtc As *IEnumFORMATETC _
) As HRESULT
Virtual Function DAdvise(
/* [in] */ ByRef pformatetc As FORMATETC,
/* [in] */ ByVal advf As DWORD,
/* [unique][in] */ ByVal pAdvSink As *IAdviseSink,
/* [out] */ ByVal pdwConnection As *DWord _
) As HRESULT
Virtual Function DUnadvise(
/* [in] */ ByVal dwConnection As DWord _
) As HRESULT
Virtual Function EnumDAdvise(
/* [out] */ ByRef rpenumAdvise As *IEnumSTATDATA _
) As HRESULT
End Class
Class IDropTarget
Inherits IUnknown
Public
Virtual Function DragEnter(
/* [unique][in] */ ByVal pDataObj As *IDataObject,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
Virtual Function DragOver(
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
Virtual Function DragLeave() As HRESULT
Virtual Function Drop(
/* [unique][in] */ ByVal pDataObj As *IDataObject,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
End Class
Class IDropSource
Inherits IUnknown
Public
Virtual Function QueryContinueDrag(
ByVal fEscapePressed As DWord,
ByVal grfKeyState As DWord) As HRESULT
Virtual Function GiveFeedback(
ByVal dwEffect As DWord) As HRESULT
End Class
Class IAdviseSink
Inherits IUnknown
End Class
Class IEnumSTATDATA
Inherits IUnknown
End Class
Class IEnumFORMATETC
Inherits IUnknown
End Class
Enum DROPEFFECT
DROPEFFECT_NONE = 0
DROPEFFECT_COPY = 1
DROPEFFECT_MOVE = 2
DROPEFFECT_LINK = 4
DROPEFFECT_SCROLL = &h80000000
End Enum
Enum /*[transmit_as(long)]*/ TYMED
TYMED_HGLOBAL = 1
TYMED_FILE = 2
TYMED_ISTREAM = 4
TYMED_ISTORAGE = 8
TYMED_GDI = 16
TYMED_MFPICT = 32
TYMED_ENHMF = 64
TYMED_NULL = 0
End Enum
Enum DVASPECT
DVASPECT_CONTENT = 1
DVASPECT_THUMBNAIL = 2
DVASPECT_ICON = 4
DVASPECT_DOCPRINT = 8
End Enum
[ここをクリックすると内容が表示されます]
MainWnd.sbp内
Class IUnknownVTable
Public
QueryInterface As *Function(ByRef thunk As IUnknown, ByRef iid As IID, ppvObj As *VoidPtr) As HRESULT
AddRef As *Function(ByRef thunk As IUnknown) As ULONG
Release As *Function(ByRef thunk As IUnknown) As ULONG
End Class
Class IDropTargetVTable
Inherits IUnknownVTable
Public
DragEnter As *Function(
ByRef thunk As DropTargetImpl,
/* [unique][in] */ ByVal pDataObj As *IDataObject,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
DragOver As *Function(
ByRef thunk As DropTargetImpl,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
DragLeave As *Function(ByRef thunk As DropTargetImpl) As HRESULT
Drop As *Function(
ByRef thunk As DropTargetImpl,
/* [unique][in] */ ByVal pDataObj As *IDataObject,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
End Class
Class DropTargetImplThunk
Public
vtable As *IDropTargetVTable
End Class
Function IUnknownThunk_QueryInterface(ByRef unk As DropTargetImpl, ByRef iid As IID, ppvObj As *VoidPtr) As HRESULT
IUnknownThunk_QueryInterface = unk.QueryInterface(iid, ppvObj)
End Function
Function IUnknownThunk_AddRef(ByRef unk As DropTargetImpl) As ULONG
IUnknownThunk_AddRef = unk.AddRef()
End Function
Function IUnknownThunk_Release(ByRef unk As DropTargetImpl) As ULONG
Dim vtable As *IDropTargetVTable
vtable = unk.vtable
IUnknownThunk_Release = unk.Release()
If IUnknownThunk_Release = 0 Then
Delete vtable
End If
End Function
Function IDropTargetThunk_DragEnter(
ByRef thunk As DropTargetImpl,
/* [unique][in] */ ByVal pDataObj As *IDataObject,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
IDropTargetThunk_DragEnter = thunk.DragEnter(pDataObj, grfKeyState, x, y, effect)
End Function
Function IDropTargetThunk_DragOver(
ByRef thunk As DropTargetImpl,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
IDropTargetThunk_DragOver = thunk.DragOver(grfKeyState, x, y, effect)
End Function
Function IDropTargetThunk_DragLeave(ByRef thunk As DropTargetImpl) As HRESULT
IDropTargetThunk_DragLeave = thunk.DragLeave()
End Function
Function IDropTargetThunk_Drop(
ByRef thunk As DropTargetImpl,
/* [unique][in] */ ByVal pDataObj As *IDataObject,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
IDropTargetThunk_Drop = thunk.Drop(pDataObj, grfKeyState, x, y, effect)
End Function
Function CreateDropTargetImpl(hwnd As HWND, ByRef iid As IID, ByVal ppv As *VoidPtr) As HRESULT
CreateDropTargetImpl = E_OUTOFMEMORY
Dim punk As *DropTargetImpl
punk = New DropTargetImpl(hwnd)
If punk = 0 Then Exit Function
punk->vtable = New IDropTargetVTable
If punk->vtable = 0 Then Exit Function
With punk->vtable[0]
.QueryInterface = AddressOf (IUnknownThunk_QueryInterface)
.AddRef = AddressOf (IUnknownThunk_AddRef)
.Release = AddressOf (IUnknownThunk_Release)
.DragEnter = AddressOf (IDropTargetThunk_DragEnter)
.DragOver = AddressOf (IDropTargetThunk_DragOver)
.DragLeave = AddressOf (IDropTargetThunk_DragLeave)
.Drop = AddressOf (IDropTargetThunk_Drop)
End With
CreateDropTargetImpl = punk->QueryInterface(iid, ppv)
If CreateDropTargetImpl <> S_OK Then
CreateDropTargetImpl = 0
Delete punk
End If
End Function
Class IDropSourceVTable
Inherits IUnknownVTable
Public
QueryContinueDrag As *Function(
ByRef thunk As DropSourceImpl,
ByVal fEscapePressed As DWord,
ByVal grfKeyState As DWord) As HRESULT
GiveFeedback As *Function(
ByRef thunk As DropSourceImpl,
ByVal dwEffect As DWord) As HRESULT
End Class
Class DropSourceImplThunk
Public
vtable As *IDropSourceVTable
End Class
Function IDropSourceThunk_QueryContinueDrag(
ByRef thunk As DropSourceImpl,
ByVal fEscapePressed As DWord,
ByVal grfKeyState As DWord) As HRESULT
IDropSourceThunk_QueryContinueDrag = thunk.QueryContinueDrag(fEscapePressed, grfKeyState)
End Function
Function IDropSourceThunk_GiveFeedback(
ByRef thunk As DropSourceImpl,
ByVal dwEffect As DWord) As HRESULT
IDropSourceThunk_GiveFeedback = thunk.GiveFeedback(dwEffect)
EndFunction
Function CreateDropSourceImpl(hwnd As HWND, ByRef iid As IID, ByVal ppv As *VoidPtr) As HRESULT
CreateDropSourceImpl = E_OUTOFMEMORY
Dim punk As *DropSourceImpl
punk = New DropSourceImpl(hwnd)
If punk = 0 Then Exit Function
punk->vtable = New IDropSourceVTable
If punk->vtable = 0 Then Exit Function
With punk->vtable[0]
.QueryInterface = AddressOf (IUnknownThunk_QueryInterface)
.AddRef = AddressOf (IUnknownThunk_AddRef)
.Release = AddressOf (IUnknownThunk_Release)
.QueryContinueDrag = AddressOf (IDropSourceThunk_QueryContinueDrag)
.GiveFeedback = AddressOf (IDropSourceThunk_GiveFeedback)
End With
CreateDropSourceImpl = punk->QueryInterface(iid, ppv)
If CreateDropSourceImpl <> S_OK Then
CreateDropSourceImpl = 0
Delete punk
End If
End Function
Public
QueryInterface As *Function(ByRef thunk As IUnknown, ByRef iid As IID, ppvObj As *VoidPtr) As HRESULT
AddRef As *Function(ByRef thunk As IUnknown) As ULONG
Release As *Function(ByRef thunk As IUnknown) As ULONG
End Class
Class IDropTargetVTable
Inherits IUnknownVTable
Public
DragEnter As *Function(
ByRef thunk As DropTargetImpl,
/* [unique][in] */ ByVal pDataObj As *IDataObject,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
DragOver As *Function(
ByRef thunk As DropTargetImpl,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
DragLeave As *Function(ByRef thunk As DropTargetImpl) As HRESULT
Drop As *Function(
ByRef thunk As DropTargetImpl,
/* [unique][in] */ ByVal pDataObj As *IDataObject,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
End Class
Class DropTargetImplThunk
Public
vtable As *IDropTargetVTable
End Class
Function IUnknownThunk_QueryInterface(ByRef unk As DropTargetImpl, ByRef iid As IID, ppvObj As *VoidPtr) As HRESULT
IUnknownThunk_QueryInterface = unk.QueryInterface(iid, ppvObj)
End Function
Function IUnknownThunk_AddRef(ByRef unk As DropTargetImpl) As ULONG
IUnknownThunk_AddRef = unk.AddRef()
End Function
Function IUnknownThunk_Release(ByRef unk As DropTargetImpl) As ULONG
Dim vtable As *IDropTargetVTable
vtable = unk.vtable
IUnknownThunk_Release = unk.Release()
If IUnknownThunk_Release = 0 Then
Delete vtable
End If
End Function
Function IDropTargetThunk_DragEnter(
ByRef thunk As DropTargetImpl,
/* [unique][in] */ ByVal pDataObj As *IDataObject,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
IDropTargetThunk_DragEnter = thunk.DragEnter(pDataObj, grfKeyState, x, y, effect)
End Function
Function IDropTargetThunk_DragOver(
ByRef thunk As DropTargetImpl,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
IDropTargetThunk_DragOver = thunk.DragOver(grfKeyState, x, y, effect)
End Function
Function IDropTargetThunk_DragLeave(ByRef thunk As DropTargetImpl) As HRESULT
IDropTargetThunk_DragLeave = thunk.DragLeave()
End Function
Function IDropTargetThunk_Drop(
ByRef thunk As DropTargetImpl,
/* [unique][in] */ ByVal pDataObj As *IDataObject,
/* [in] */ ByVal grfKeyState As DWord,
/* [in] */ ByVal x As Long, ByVal y As Long,
/* [out][in] */ ByRef effect As DWord) As HRESULT
IDropTargetThunk_Drop = thunk.Drop(pDataObj, grfKeyState, x, y, effect)
End Function
Function CreateDropTargetImpl(hwnd As HWND, ByRef iid As IID, ByVal ppv As *VoidPtr) As HRESULT
CreateDropTargetImpl = E_OUTOFMEMORY
Dim punk As *DropTargetImpl
punk = New DropTargetImpl(hwnd)
If punk = 0 Then Exit Function
punk->vtable = New IDropTargetVTable
If punk->vtable = 0 Then Exit Function
With punk->vtable[0]
.QueryInterface = AddressOf (IUnknownThunk_QueryInterface)
.AddRef = AddressOf (IUnknownThunk_AddRef)
.Release = AddressOf (IUnknownThunk_Release)
.DragEnter = AddressOf (IDropTargetThunk_DragEnter)
.DragOver = AddressOf (IDropTargetThunk_DragOver)
.DragLeave = AddressOf (IDropTargetThunk_DragLeave)
.Drop = AddressOf (IDropTargetThunk_Drop)
End With
CreateDropTargetImpl = punk->QueryInterface(iid, ppv)
If CreateDropTargetImpl <> S_OK Then
CreateDropTargetImpl = 0
Delete punk
End If
End Function
Class IDropSourceVTable
Inherits IUnknownVTable
Public
QueryContinueDrag As *Function(
ByRef thunk As DropSourceImpl,
ByVal fEscapePressed As DWord,
ByVal grfKeyState As DWord) As HRESULT
GiveFeedback As *Function(
ByRef thunk As DropSourceImpl,
ByVal dwEffect As DWord) As HRESULT
End Class
Class DropSourceImplThunk
Public
vtable As *IDropSourceVTable
End Class
Function IDropSourceThunk_QueryContinueDrag(
ByRef thunk As DropSourceImpl,
ByVal fEscapePressed As DWord,
ByVal grfKeyState As DWord) As HRESULT
IDropSourceThunk_QueryContinueDrag = thunk.QueryContinueDrag(fEscapePressed, grfKeyState)
End Function
Function IDropSourceThunk_GiveFeedback(
ByRef thunk As DropSourceImpl,
ByVal dwEffect As DWord) As HRESULT
IDropSourceThunk_GiveFeedback = thunk.GiveFeedback(dwEffect)
EndFunction
Function CreateDropSourceImpl(hwnd As HWND, ByRef iid As IID, ByVal ppv As *VoidPtr) As HRESULT
CreateDropSourceImpl = E_OUTOFMEMORY
Dim punk As *DropSourceImpl
punk = New DropSourceImpl(hwnd)
If punk = 0 Then Exit Function
punk->vtable = New IDropSourceVTable
If punk->vtable = 0 Then Exit Function
With punk->vtable[0]
.QueryInterface = AddressOf (IUnknownThunk_QueryInterface)
.AddRef = AddressOf (IUnknownThunk_AddRef)
.Release = AddressOf (IUnknownThunk_Release)
.QueryContinueDrag = AddressOf (IDropSourceThunk_QueryContinueDrag)
.GiveFeedback = AddressOf (IDropSourceThunk_GiveFeedback)
End With
CreateDropSourceImpl = punk->QueryInterface(iid, ppv)
If CreateDropSourceImpl <> S_OK Then
CreateDropSourceImpl = 0
Delete punk
End If
End Function
[ここをクリックすると内容が表示されます]
[/hide]Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
If egtraOleInitialize() <> S_OK Then Debug
Dim pDropTarget As *IDropTarget
Dim hr As HRESULT
hr = CreateDropTargetImpl(hMainWnd, IID_IDropTarget, VarPtr(pDropTarget))
hr = RegisterDragDrop(hMainWnd, pDropTarget)
End Sub
Sub MainWnd_LButtonDown(flags As Long, x As Integer, y As Integer)
Dim lpDropSource As *IDropSource
Dim lpDataObj As *IDataObject
Dim hr As HRESULT
Dim effect As DWord
hr = CreateDropSourceImpl(hMainWnd, IID_IDropSource, VarPtr(lpDropSource) )
Dim files[MAX_PATH] As Byte
lstrcpy(files, "C:/test.txt")
Dim fmtetc As FORMATETC
' /* FORMATETC構造体をセット
fmtetc.cfFormat = CF_HDROP
fmtetc.ptd = NULL
fmtetc.dwAspect = DVASPECT_CONTENT
fmtetc.lindex = -1
fmtetc.tymed = TYMED_HGLOBAL
Dim medium As STGMEDIUM
Dim p As LPSTR
Dim df As *DROPFILES
' /* STGMEDIUM構造体をセット */
' medium.tymed = TYMED_HGLOBAL
medium.hGlobal = GlobalAlloc(
GMEM_MOVEABLE,
sizeof(DROPFILES) + lstrlen(files)
)
medium.pUnkForRelease = NULL
p = GlobalLock(medium.hGlobal)
df=p As *DROPFILES
df->pFiles = sizeof(DROPFILES)
df->fWid = FALSE
p+=SizeOf(DROPFILES)
lstrcpy(p,files)
p+=lstrlen(p)+1
lstrcpy(p,Chr$(0))
GlobalUnlock(medium.hGlobal)
/* IDataObjectをセット */
lpDataObj->SetData(fmtetc, medium, FALSE)
/* OLE Drag & Drop開始 */
' hr = DoDragDrop(lpDataObj, lpDropSource, DROPEFFECT_MOVE or DROPEFFECT_COPY or DROPEFFECT_LINK, effect)
/* リソースを開放 */
lpDataObj->Release()
lpDropSource->Release()
End Sub
If egtraOleInitialize() <> S_OK Then Debug
Dim pDropTarget As *IDropTarget
Dim hr As HRESULT
hr = CreateDropTargetImpl(hMainWnd, IID_IDropTarget, VarPtr(pDropTarget))
hr = RegisterDragDrop(hMainWnd, pDropTarget)
End Sub
Sub MainWnd_LButtonDown(flags As Long, x As Integer, y As Integer)
Dim lpDropSource As *IDropSource
Dim lpDataObj As *IDataObject
Dim hr As HRESULT
Dim effect As DWord
hr = CreateDropSourceImpl(hMainWnd, IID_IDropSource, VarPtr(lpDropSource) )
Dim files[MAX_PATH] As Byte
lstrcpy(files, "C:/test.txt")
Dim fmtetc As FORMATETC
' /* FORMATETC構造体をセット
fmtetc.cfFormat = CF_HDROP
fmtetc.ptd = NULL
fmtetc.dwAspect = DVASPECT_CONTENT
fmtetc.lindex = -1
fmtetc.tymed = TYMED_HGLOBAL
Dim medium As STGMEDIUM
Dim p As LPSTR
Dim df As *DROPFILES
' /* STGMEDIUM構造体をセット */
' medium.tymed = TYMED_HGLOBAL
medium.hGlobal = GlobalAlloc(
GMEM_MOVEABLE,
sizeof(DROPFILES) + lstrlen(files)
)
medium.pUnkForRelease = NULL
p = GlobalLock(medium.hGlobal)
df=p As *DROPFILES
df->pFiles = sizeof(DROPFILES)
df->fWid = FALSE
p+=SizeOf(DROPFILES)
lstrcpy(p,files)
p+=lstrlen(p)+1
lstrcpy(p,Chr$(0))
GlobalUnlock(medium.hGlobal)
/* IDataObjectをセット */
lpDataObj->SetData(fmtetc, medium, FALSE)
/* OLE Drag & Drop開始 */
' hr = DoDragDrop(lpDataObj, lpDropSource, DROPEFFECT_MOVE or DROPEFFECT_COPY or DROPEFFECT_LINK, effect)
/* リソースを開放 */
lpDataObj->Release()
lpDropSource->Release()
End Sub