限定しりとり

APIでWM_DROPFILESを処理することによって
ドラッグ&ドロップによって処理できるようにしようとしたのですが
このスペシャルフォルダはドラッグ&ドロップを受け付けません。
受け付けることができるようにするにはどうしたらいいのでしょうか?

A 回答 (8件)

>SendMessage(hW,WM_DROPFILES,wP,0);


>を送ろうと思ったのですが
>wPはHDROP構造体を送らないといけないみたいです。

まぁ、構造体というかハンドルとですね。
これは、Windowsが内部的に使っているものなので、外からはわかりません。
なので、WM_DROPFILESを送るのは、きっぱりとあきらめた方が楽です。

自分で
#define WM_MYDROP (WM_USER+1)
なんて感じで定義して使ってください。


と普通ならいいたいのですが、HDROPは、DropメソッドのIDataObject*から取得できます。

取得方法は、Drag&Dropではないですが、以下のサンプルがそのまま利用できます。
http://www.runan.net/program/tips/sdk_21_ShellEx …

このサンプルは、エクスプローラの右クリックメニューに項目を追加するものですが、CShellExtension::Initialize()の第2引数に、
LPDATAOBJECT pDataObj
を受け取っています。
ちなみに、LPDATAOBJECTは、IDataObject*と全く同じものです。(書き換えてもコンパイルとおります)

大雑把な手順としては、
1.IDataObject::GetData()で、STGMEDIUMを取得
2.GlobalLock()でHDROPを取得
3.SendMessage()
4.GlobalUnlock()
5.ReleaseStgMedium()

こんな感じですかね。

ただ、これでドロップされたファイル名は受け取れますが、DragQueryPoint()で、Dropされた位置が受け取れるかは確認していません。取得できないようでしたら、あきらめてTDropTarget::Drop()の引数を使ってください。
幸いWM_DROPFILEのLPARAMは使ってないのでそのまま突っ込んでも問題ないですし。

#でも、できるだけ独自にメッセージを定義するのをお勧めします。

参考URL:http://www.runan.net/program/tips/sdk_21_ShellEx …

この回答への補足

ありがとうございます。

何か大変そうですね。
もう少し余裕ができたらあらためて考えてみます。
また機会があったら教えてください。

補足日時:2003/10/24 22:28
    • good
    • 0

>case WM_DROPFILES:


>を処理してくれません。
>今まで処理してくれていた通常のディレクトリの処理もしてくれません。

そうなります。
で、その代わりがTDropTarget::Drop()になります。

ここにDropされたときの処理を記述することになります。
WM_DROPFILESよりも、多くの情報が引数に渡ってきます。

ただ、ウィンドウプロシージャにドロップ時の処理を色々記述しているのであれば、TDropTarget::DragEnterからSendMessage()で独自のメッセージを投げてあげるというのもありかと思われます。

この回答への補足

ありがとうございます。

SendMessage(hW,WM_DROPFILES,wP,0);
を送ろうと思ったのですが
wPはHDROP構造体を送らないといけないみたいです。
HDROP構造体は簡単に構成できるものなのでしょうか?
どこから送れば良いのでしょうか?

補足日時:2003/10/23 21:28
    • good
    • 0
この回答へのお礼

余り詳しいサイトが無くて困っています。
TDropTarget::DropにSendを記述したらいいところまでは付きとめました。

お礼日時:2003/10/24 01:48

>デスクトップ上のマイドキュメントをドラッグしても


>受付を拒否されます。

>>戻り値を変えてって書いちゃいましたね。ごめんなさい。
>>*effect = DROPEFFECT_LINK;
>>にしてください。

をしていただけました?

この回答への補足

ありがとうございました。
アイコンが禁止マークからリターンマークに変わり受け付けられるようになったようです。
しかし
case WM_DROPFILES:
を処理してくれません。
今まで処理してくれていた通常のディレクトリの処理もしてくれません。

メッセージが変わり
さらに関連関数も使えなくなったのでしょうか?

補足日時:2003/10/23 18:36
    • good
    • 0

>正常終了を確かめるにはどうしたら言いのでしょうか?



ヘルプはこちら。正常だったらS_OKを返すらしいです。
http://msdn.microsoft.com/library/default.asp?ur …

で、ヘルプに
Note If you use CoInitialize or CoInitializeEx instead of OleInitialize to initialize COM, RegisterDragDrop will always return an E_OUTOFMEMORY error.

という記述があるので、CoInitializeかCoInitializeExを呼んでCOMの初期化をしてくださいね。


>>ここでDROPEFFECT_LINKにすると、ドライブも
>>マイドキュメントも受け入れるようになります。
>*effect = DROPEFFECT_COPY;

戻り値を変えてって書いちゃいましたね。ごめんなさい。
*effect = DROPEFFECT_LINK;
にしてください。

IDropTargetインターフェイスの実装はそれでかまわないと思いますよ。

この回答への補足

ありがとうございます。
度々の回答恐縮しています。

一旦、サンプルをそのままmakeしてexeを作って動作を試してみることをお勧めします。
で、デバッグしてみるのがいいでしょう。 :

インクルードのパスが通らないので調べてみると
makefileにBCC32のありかの指定が無かったので指定の設定を追加すれば
サンプルのcppdt.cppがコンパイルでき
cppdt.exeができましたが
cppdt.exeを実行しそのウィンドウに
エクスプローラ上のC:¥をドラッグしても
デスクトップ上のマイドキュメントをドラッグしても
受付を拒否されます。

何か抜けていることがあるのでしょうか?

補足日時:2003/10/23 15:33
    • good
    • 0

RegisterDragDropを呼んで、正常終了していますか?



一旦、サンプルをそのままmakeしてexeを作って動作を試してみることをお勧めします。
で、デバッグしてみるのがいいでしょう。

cppdt.cppの中で、
TDropTarget::DragEnter
TDropTarget::DragOver
TDropTarget::Drop
の戻り値が、DROPEFFECT_COPYになってますよね。

ここでDROPEFFECT_LINKにすると、ドライブもマイドキュメントも受け入れるようになります。

この違いは、普通のファイルをドラッグ&ドロップしてみるとわかりますよ。

この回答への補足

ありがとうございます。

RegisterDragDropを呼んで、正常終了していますか?:

case WM_CREATE:
 DropTarget = new TDropTarget;
 RegisterDragDrop(hW,DropTarget);
 ・・・・・・・・・
としているだけなのでRegisterDragDropを検索したのですがRegisterDragDropが見つかりません。

正常終了を確かめるにはどうしたら言いのでしょうか?

ちなみに実装は以下をコピーしてます。

HRESULT __stdcall
TDropTarget::DragEnter(IDataObject* /*source*/, DWORD /*keyState*/, POINTL /*pt*/, DWORD* effect)
{
*effect = DROPEFFECT_COPY;
return S_OK;
}

HRESULT __stdcall
TDropTarget::DragOver(DWORD /*keyState*/, POINTL /*pt*/, DWORD* effect)
{
*effect = DROPEFFECT_COPY;
return S_OK;
}

HRESULT __stdcall
TDropTarget::Drop(IDataObject* /*source*/, DWORD /*keyState*/, POINTL /*pt*/, DWORD* effect)
{
*effect = DROPEFFECT_COPY;
return S_OK;
}

補足日時:2003/10/22 20:18
    • good
    • 0

>なにかヘッダファイルがいるのでしょうか?


OLE2.Hかな
OLEIDL.Hでも平気かもしれませんが。

ちなみにサンプルはshlobj.hを使ってますね。


>cppdt.cppがいるのでしょうか?
自分で作るんだったらいらないのでは?

ページの一番上にある「ダウンロード」で落とせるファイルの中です。

この回答への補足

ありがとうございます。

実装してエラーは出なくなったのですが実装しただけではC:¥もMy Documentsもドラッグを受け付けません。

IDropTargetインターフェイスを実装し、
(これは多分終了)
IDropTarget::DragOver()で
DROPEFFECT_COPYを返さないとドライブは受け取れないようです。

をしたいのですがどうしたらいいのでしょうか?

補足日時:2003/10/22 17:45
    • good
    • 0

たぶんWM_DROPFILESじゃだめですね。


http://www.okweb.ne.jp/kotaeru.php3?q=592672

と同じようなことをしてください。

IDropTarget::DragEnterやIDropTarget::DragOverで
DROPEFFECT_COPYではなくDROPEFFECT_LINKを返せばドロップ可能です。

参考URL:http://www.okweb.ne.jp/kotaeru.php3?q=592672

この回答への補足

ありがとうございます。
参考サイトのコードを入力しコンパイルすると以下のエラーが発生しました。
なにかヘッダファイルがいるのでしょうか?

Error: 外部シンボル '__stdcall TDropTarget::QueryInterface(const _GUID&, void * *)' が未解決(C:\goo.OBJ が参照)
Error: 外部シンボル '__stdcall TDropTarget::AddRef()' が未解決(C:\goo.OBJ が参照)
Error: 外部シンボル '__stdcall TDropTarget::Release()' が未解決(C:\goo.OBJ が参照)
Error: 外部シンボル '__stdcall TDropTarget::DragEnter(IDataObject *, unsigned long, _POINTL, unsigned long *)' が未解決(C:\goo.OBJ が参照)
Error: 外部シンボル '__stdcall TDropTarget::DragOver(unsigned long, _POINTL, unsigned long *)' が未解決(C:\goo.OBJ が参照)
Error: 外部シンボル '__stdcall TDropTarget::DragLeave()' が未解決(C:\goo.OBJ が参照)
Error: 外部シンボル '__stdcall TDropTarget::Drop(IDataObject *, unsigned long, _POINTL, unsigned long *)' が未解決(C:\goo.OBJ が参照)

補足日時:2003/10/22 15:54
    • good
    • 0
この回答へのお礼

参考サイトに

サンプル cppdt ---- 使用ファイル[cppdt.cpp]。BCC55の場合は make -D0
サンプル cdt ------ cppdt.cppを C言語に変更したもの 使用ファイル[cdt.c]。BCC55の場合は make -D1

とあります。
cppdt.cppがいるのでしょうか?
これはどこで手に入れたらいいでしょうか?

よろしくお願いします。

お礼日時:2003/10/22 16:15

>My Documentsディレクトリを



って、デスクトップにはっついてるアイコンのことですか?

Win9xとかだったらエクスプローラの
C:\My Documents
とかじゃないですよね?

この回答への補足

ありがごうとざいます。

SHGetSpecialFolderLocation(NULL,CSIDL_PERSONAL,&pidl))
のCSIDL_PERSONALすなわち
0x0005 (CSIDL_PERSONAL) 「マイ ドキュメント」(ファイルシステムディレクトリ)
のフォルダです。

補足日時:2003/10/22 12:59
    • good
    • 0
この回答へのお礼

しつれいしました。
エクスプローラからのドラッグ&ドロップは可能で
ディスクトップ上のアイコンのドラッグ&ドロップがだめみたいです。
ディスクトップ上のマイドキュメントアイコンのドラッグ&ドロップを可能にする方法はないのでしょうか

お礼日時:2003/10/22 13:13

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!