Win32 API 日本語リファレンス
ホームSystem.Ole › DoDragDrop

DoDragDrop

関数
ドラッグアンドドロップ操作を実行しその効果を返す。
DLLOLE32.dll呼出規約winapi対応OSWindows 2000 以降

シグネチャ

// OLE32.dll
#include <windows.h>

HRESULT DoDragDrop(
    IDataObject* pDataObj,
    IDropSource* pDropSource,
    DROPEFFECT dwOKEffects,
    DROPEFFECT* pdwEffect
);

パラメーター

名前方向説明
pDataObjIDataObject*inドラッグ対象のデータを保持するデータ オブジェクト上の IDataObject インターフェイスへのポインターです。
pDropSourceIDropSource*inIDropSource インターフェイスの実装へのポインターです。これはドラッグ操作中にソースと通信するために使用されます。
dwOKEffectsDROPEFFECTinOLE のドラッグ アンド ドロップ操作でソースが許可する効果です。最も重要なのは、移動を許可するかどうかです。dwOKEffect パラメーターと pdwEffect パラメーターは DROPEFFECT 列挙体から値を取得します。値の一覧については DROPEFFECT を参照してください。
pdwEffectDROPEFFECT*outOLE のドラッグ アンド ドロップ操作がソース データにどのような影響を与えたかを示す値へのポインターです。pdwEffect パラメーターは、操作がキャンセルされなかった場合にのみ設定されます。

戻り値の型: HRESULT

公式ドキュメント

OLE のドラッグ アンド ドロップ操作を実行します。

戻り値

成功した場合、この関数は S_OK を返します。その他に返される可能性のある値を次に示します。

戻り値 説明
DRAGDROP_S_DROP
OLE のドラッグ アンド ドロップ操作が成功しました。
DRAGDROP_S_CANCEL
OLE のドラッグ アンド ドロップ操作がキャンセルされました。
E_UNSPEC
予期しないエラーが発生しました。

解説(Remarks)

OLE のドラッグ アンド ドロップ操作のデータ ソースとして動作できるアプリケーションを開発する場合は、ユーザーが OLE のドラッグ アンド ドロップ操作を開始したことを検出した時点で DoDragDrop を呼び出す必要があります。

DoDragDrop 関数は、IDropSource インターフェイスと IDropTarget インターフェイスのさまざまなメソッドを呼び出すループに入ります。(ドラッグ アンド ドロップ操作を成功させるには、データ ソースとして動作するアプリケーションが IDropSource を実装し、ターゲット アプリケーションが IDropTarget を実装する必要があります。)

  1. DoDragDrop 関数は、現在のカーソル位置の下にあるウィンドウを特定します。次に、そのウィンドウが有効なドロップ ターゲットであるかどうかを確認します。
  2. ウィンドウが有効なドロップ ターゲットである場合、DoDragDropIDropTarget::DragEnter を呼び出します。このメソッドは、実際にドロップが行われた場合に何が起こるかを示す効果コードを返します。有効なドロップ効果の一覧については、DROPEFFECT 列挙体を参照してください。
  3. DoDragDrop は、ドロップ ソース インターフェイスがユーザーに適切な視覚的フィードバックを提供できるように、効果コードを指定して IDropSource::GiveFeedback を呼び出します。DoDragDrop に渡された pDropSource ポインターは、適切な IDropSource インターフェイスを指定します。
  4. DoDragDrop は、マウス カーソルの移動と、キーボードまたはマウス ボタンの状態の変化を追跡します。
    • ユーザーがウィンドウの外に移動した場合、DoDragDropIDropTarget::DragLeave を呼び出します。
    • マウスが別のウィンドウに入った場合、DoDragDrop はそのウィンドウが有効なドロップ ターゲットであるかどうかを判断し、そのウィンドウに対して IDropTarget::DragEnter を呼び出します。
    • マウスが移動したものの同じウィンドウ内にとどまっている場合、DoDragDropIDropTarget::DragOver を呼び出します。
  5. キーボードまたはマウス ボタンの状態に変化があった場合、DoDragDropIDropSource::QueryContinueDrag を呼び出し、その戻り値に基づいて、ドラッグを続行するか、データをドロップするか、操作をキャンセルするかを判断します。
    • 戻り値が S_OK の場合、DoDragDrop はまず IDropTarget::DragOver を呼び出して操作を続行します。このメソッドは新しい効果値を返し、続いて DoDragDrop は新しい効果を指定して IDropSource::GiveFeedback を呼び出すことで、適切な視覚的フィードバックを設定できるようにします。有効なドロップ効果の一覧については、DROPEFFECT 列挙体を参照してください。IDropTarget::DragOverIDropSource::GiveFeedback は対になっており、マウスがドロップ ターゲット上を移動するのに合わせて、ユーザーにマウスの位置に関する最新のフィードバックが提供されます。
    • 戻り値が DRAGDROP_S_DROP の場合、DoDragDropIDropTarget::Drop を呼び出します。DoDragDrop 関数は最後の効果コードをソースに返すため、ソース アプリケーションはソース データに対して適切な操作を実行できます。たとえば、操作が移動であった場合はデータを切り取ります。
    • 戻り値が DRAGDROP_S_CANCEL の場合、DoDragDrop 関数は IDropTarget::DragLeave を呼び出します。
タッチまたはペンの入力を処理する際に、DoDragDrop によるドラッグ アンド ドロップのサポートを呼び出すことはできません。

タッチまたはペンの入力をサポートするには、タッチ ハンドラーから DoDragDrop を呼び出さないでください。代わりに、タッチ入力に応じてシステムが合成するマウス メッセージ用のハンドラーから DoDragDrop を呼び出してください。

アプリケーションは、GetMessageExtraInfo 関数を呼び出すことで、合成されたメッセージを識別できます。GetMessageExtraInfo を使用してマウス入力と Windows タッチ入力を区別する方法の詳細については、アプリケーションのトラブルシューティングを参照してください。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

// OLE32.dll
#include <windows.h>

HRESULT DoDragDrop(
    IDataObject* pDataObj,
    IDropSource* pDropSource,
    DROPEFFECT dwOKEffects,
    DROPEFFECT* pdwEffect
);
[DllImport("OLE32.dll", ExactSpelling = true)]
static extern int DoDragDrop(
    IntPtr pDataObj,   // IDataObject*
    IntPtr pDropSource,   // IDropSource*
    uint dwOKEffects,   // DROPEFFECT
    out uint pdwEffect   // DROPEFFECT* out
);
<DllImport("OLE32.dll", ExactSpelling:=True)>
Public Shared Function DoDragDrop(
    pDataObj As IntPtr,   ' IDataObject*
    pDropSource As IntPtr,   ' IDropSource*
    dwOKEffects As UInteger,   ' DROPEFFECT
    <Out> ByRef pdwEffect As UInteger   ' DROPEFFECT* out
) As Integer
End Function
' pDataObj : IDataObject*
' pDropSource : IDropSource*
' dwOKEffects : DROPEFFECT
' pdwEffect : DROPEFFECT* out
Declare PtrSafe Function DoDragDrop Lib "ole32" ( _
    ByVal pDataObj As LongPtr, _
    ByVal pDropSource As LongPtr, _
    ByVal dwOKEffects As Long, _
    ByRef pdwEffect As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

DoDragDrop = ctypes.windll.ole32.DoDragDrop
DoDragDrop.restype = ctypes.c_int
DoDragDrop.argtypes = [
    ctypes.c_void_p,  # pDataObj : IDataObject*
    ctypes.c_void_p,  # pDropSource : IDropSource*
    wintypes.DWORD,  # dwOKEffects : DROPEFFECT
    ctypes.c_void_p,  # pdwEffect : DROPEFFECT* out
]
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('OLE32.dll')
DoDragDrop = Fiddle::Function.new(
  lib['DoDragDrop'],
  [
    Fiddle::TYPE_VOIDP,  # pDataObj : IDataObject*
    Fiddle::TYPE_VOIDP,  # pDropSource : IDropSource*
    -Fiddle::TYPE_INT,  # dwOKEffects : DROPEFFECT
    Fiddle::TYPE_VOIDP,  # pdwEffect : DROPEFFECT* out
  ],
  Fiddle::TYPE_INT)
#[link(name = "ole32")]
extern "system" {
    fn DoDragDrop(
        pDataObj: *mut core::ffi::c_void,  // IDataObject*
        pDropSource: *mut core::ffi::c_void,  // IDropSource*
        dwOKEffects: u32,  // DROPEFFECT
        pdwEffect: *mut u32  // DROPEFFECT* out
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("OLE32.dll")]
public static extern int DoDragDrop(IntPtr pDataObj, IntPtr pDropSource, uint dwOKEffects, out uint pdwEffect);
"@
$api = Add-Type -MemberDefinition $sig -Name 'OLE32_DoDragDrop' -Namespace Win32 -PassThru
# $api::DoDragDrop(pDataObj, pDropSource, dwOKEffects, pdwEffect)
#uselib "OLE32.dll"
#func global DoDragDrop "DoDragDrop" sptr, sptr, sptr, sptr
; DoDragDrop pDataObj, pDropSource, dwOKEffects, varptr(pdwEffect)   ; 戻り値は stat
; pDataObj : IDataObject* -> "sptr"
; pDropSource : IDropSource* -> "sptr"
; dwOKEffects : DROPEFFECT -> "sptr"
; pdwEffect : DROPEFFECT* out -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "OLE32.dll"
#cfunc global DoDragDrop "DoDragDrop" sptr, sptr, int, var
; res = DoDragDrop(pDataObj, pDropSource, dwOKEffects, pdwEffect)
; pDataObj : IDataObject* -> "sptr"
; pDropSource : IDropSource* -> "sptr"
; dwOKEffects : DROPEFFECT -> "int"
; pdwEffect : DROPEFFECT* out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; HRESULT DoDragDrop(IDataObject* pDataObj, IDropSource* pDropSource, DROPEFFECT dwOKEffects, DROPEFFECT* pdwEffect)
#uselib "OLE32.dll"
#cfunc global DoDragDrop "DoDragDrop" intptr, intptr, int, var
; res = DoDragDrop(pDataObj, pDropSource, dwOKEffects, pdwEffect)
; pDataObj : IDataObject* -> "intptr"
; pDropSource : IDropSource* -> "intptr"
; dwOKEffects : DROPEFFECT -> "int"
; pdwEffect : DROPEFFECT* out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	ole32 = windows.NewLazySystemDLL("OLE32.dll")
	procDoDragDrop = ole32.NewProc("DoDragDrop")
)

// pDataObj (IDataObject*), pDropSource (IDropSource*), dwOKEffects (DROPEFFECT), pdwEffect (DROPEFFECT* out)
r1, _, err := procDoDragDrop.Call(
	uintptr(pDataObj),
	uintptr(pDropSource),
	uintptr(dwOKEffects),
	uintptr(pdwEffect),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // HRESULT
function DoDragDrop(
  pDataObj: Pointer;   // IDataObject*
  pDropSource: Pointer;   // IDropSource*
  dwOKEffects: DWORD;   // DROPEFFECT
  pdwEffect: Pointer   // DROPEFFECT* out
): Integer; stdcall;
  external 'OLE32.dll' name 'DoDragDrop';
result := DllCall("OLE32\DoDragDrop"
    , "Ptr", pDataObj   ; IDataObject*
    , "Ptr", pDropSource   ; IDropSource*
    , "UInt", dwOKEffects   ; DROPEFFECT
    , "Ptr", pdwEffect   ; DROPEFFECT* out
    , "Int")   ; return: HRESULT
●DoDragDrop(pDataObj, pDropSource, dwOKEffects, pdwEffect) = DLL("OLE32.dll", "int DoDragDrop(void*, void*, dword, void*)")
# 呼び出し: DoDragDrop(pDataObj, pDropSource, dwOKEffects, pdwEffect)
# pDataObj : IDataObject* -> "void*"
# pDropSource : IDropSource* -> "void*"
# dwOKEffects : DROPEFFECT -> "dword"
# pdwEffect : DROPEFFECT* out -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "ole32" fn DoDragDrop(
    pDataObj: ?*anyopaque, // IDataObject*
    pDropSource: ?*anyopaque, // IDropSource*
    dwOKEffects: u32, // DROPEFFECT
    pdwEffect: [*c]u32 // DROPEFFECT* out
) callconv(std.os.windows.WINAPI) i32;
proc DoDragDrop(
    pDataObj: pointer,  # IDataObject*
    pDropSource: pointer,  # IDropSource*
    dwOKEffects: uint32,  # DROPEFFECT
    pdwEffect: ptr uint32  # DROPEFFECT* out
): int32 {.importc: "DoDragDrop", stdcall, dynlib: "OLE32.dll".}
pragma(lib, "ole32");
extern(Windows)
int DoDragDrop(
    void* pDataObj,   // IDataObject*
    void* pDropSource,   // IDropSource*
    uint dwOKEffects,   // DROPEFFECT
    uint* pdwEffect   // DROPEFFECT* out
);
ccall((:DoDragDrop, "OLE32.dll"), stdcall, Int32,
      (Ptr{Cvoid}, Ptr{Cvoid}, UInt32, Ptr{UInt32}),
      pDataObj, pDropSource, dwOKEffects, pdwEffect)
# pDataObj : IDataObject* -> Ptr{Cvoid}
# pDropSource : IDropSource* -> Ptr{Cvoid}
# dwOKEffects : DROPEFFECT -> UInt32
# pdwEffect : DROPEFFECT* out -> Ptr{UInt32}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
int32_t DoDragDrop(
    void* pDataObj,
    void* pDropSource,
    uint32_t dwOKEffects,
    uint32_t* pdwEffect);
]]
local ole32 = ffi.load("ole32")
-- ole32.DoDragDrop(pDataObj, pDropSource, dwOKEffects, pdwEffect)
-- pDataObj : IDataObject*
-- pDropSource : IDropSource*
-- dwOKEffects : DROPEFFECT
-- pdwEffect : DROPEFFECT* out
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('OLE32.dll');
const DoDragDrop = lib.func('__stdcall', 'DoDragDrop', 'int32_t', ['void *', 'void *', 'uint32_t', 'uint32_t *']);
// DoDragDrop(pDataObj, pDropSource, dwOKEffects, pdwEffect)
// pDataObj : IDataObject* -> 'void *'
// pDropSource : IDropSource* -> 'void *'
// dwOKEffects : DROPEFFECT -> 'uint32_t'
// pdwEffect : DROPEFFECT* out -> 'uint32_t *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("OLE32.dll", {
  DoDragDrop: { parameters: ["pointer", "pointer", "u32", "pointer"], result: "i32" },
});
// lib.symbols.DoDragDrop(pDataObj, pDropSource, dwOKEffects, pdwEffect)
// pDataObj : IDataObject* -> "pointer"
// pDropSource : IDropSource* -> "pointer"
// dwOKEffects : DROPEFFECT -> "u32"
// pdwEffect : DROPEFFECT* out -> "pointer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
int32_t DoDragDrop(
    void* pDataObj,
    void* pDropSource,
    uint32_t dwOKEffects,
    uint32_t* pdwEffect);
C, "OLE32.dll");
// $ffi->DoDragDrop(pDataObj, pDropSource, dwOKEffects, pdwEffect);
// pDataObj : IDataObject*
// pDropSource : IDropSource*
// dwOKEffects : DROPEFFECT
// pdwEffect : DROPEFFECT* out
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Ole32 extends StdCallLibrary {
    Ole32 INSTANCE = Native.load("ole32", Ole32.class);
    int DoDragDrop(
        Pointer pDataObj,   // IDataObject*
        Pointer pDropSource,   // IDropSource*
        int dwOKEffects,   // DROPEFFECT
        IntByReference pdwEffect   // DROPEFFECT* out
    );
}
@[Link("ole32")]
lib LibOLE32
  fun DoDragDrop = DoDragDrop(
    pDataObj : Void*,   # IDataObject*
    pDropSource : Void*,   # IDropSource*
    dwOKEffects : UInt32,   # DROPEFFECT
    pdwEffect : UInt32*   # DROPEFFECT* out
  ) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef DoDragDropNative = Int32 Function(Pointer<Void>, Pointer<Void>, Uint32, Pointer<Uint32>);
typedef DoDragDropDart = int Function(Pointer<Void>, Pointer<Void>, int, Pointer<Uint32>);
final DoDragDrop = DynamicLibrary.open('OLE32.dll')
    .lookupFunction<DoDragDropNative, DoDragDropDart>('DoDragDrop');
// pDataObj : IDataObject* -> Pointer<Void>
// pDropSource : IDropSource* -> Pointer<Void>
// dwOKEffects : DROPEFFECT -> Uint32
// pdwEffect : DROPEFFECT* out -> Pointer<Uint32>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function DoDragDrop(
  pDataObj: Pointer;   // IDataObject*
  pDropSource: Pointer;   // IDropSource*
  dwOKEffects: DWORD;   // DROPEFFECT
  pdwEffect: Pointer   // DROPEFFECT* out
): Integer; stdcall;
  external 'OLE32.dll' name 'DoDragDrop';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "DoDragDrop"
  c_DoDragDrop :: Ptr () -> Ptr () -> Word32 -> Ptr Word32 -> IO Int32
-- pDataObj : IDataObject* -> Ptr ()
-- pDropSource : IDropSource* -> Ptr ()
-- dwOKEffects : DROPEFFECT -> Word32
-- pdwEffect : DROPEFFECT* out -> Ptr Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let dodragdrop =
  foreign "DoDragDrop"
    ((ptr void) @-> (ptr void) @-> uint32_t @-> (ptr uint32_t) @-> returning int32_t)
(* pDataObj : IDataObject* -> (ptr void) *)
(* pDropSource : IDropSource* -> (ptr void) *)
(* dwOKEffects : DROPEFFECT -> uint32_t *)
(* pdwEffect : DROPEFFECT* out -> (ptr uint32_t) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library ole32 (t "OLE32.dll"))
(cffi:use-foreign-library ole32)

(cffi:defcfun ("DoDragDrop" do-drag-drop :convention :stdcall) :int32
  (p-data-obj :pointer)   ; IDataObject*
  (p-drop-source :pointer)   ; IDropSource*
  (dw-okeffects :uint32)   ; DROPEFFECT
  (pdw-effect :pointer))   ; DROPEFFECT* out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $DoDragDrop = Win32::API::More->new('OLE32',
    'int DoDragDrop(LPVOID pDataObj, LPVOID pDropSource, DWORD dwOKEffects, LPVOID pdwEffect)');
# my $ret = $DoDragDrop->Call($pDataObj, $pDropSource, $dwOKEffects, $pdwEffect);
# pDataObj : IDataObject* -> LPVOID
# pDropSource : IDropSource* -> LPVOID
# dwOKEffects : DROPEFFECT -> DWORD
# pdwEffect : DROPEFFECT* out -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

使用する型