OLE D&D

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
返信する
メッセージ
作成者
しーぷ

OLE D&D

#1 投稿記事 by しーぷ »

OLE D&Dでエクスプローラ等とファイルのやり取りをやってみたいと、
いろいろと調べたのですが、ほとんど理解できなかったので質問させていただきます。

この記事のおかげでD&Dのドロップ(ファイルの受け取り)の部分は実現できましたが、ドラッグ(ファイルの受け渡し)の部分がさっぱりできません。

まず、イグトランスさんがどうやってIDropTargetを実装しているのかコードをみても何をやっているのかまったく分からなかったのですが、無理やり自分なりにIDropSourceを実装してみました。次に、このページを参考に実際に書いてみましたがアクセス違反が起こってしまいます。

なぜアクセス違反になってしまうのでしょうか?それともうひとつ質問ですが、前記のCでの実装のページで使われている、実際にドラッグを開始すると思われるDoDrugDropですが、これは一体何者ですか?

以下にコード(ほぼ前述の記事のパクリですが…)を載せます。
なにか分かる方がいらっしゃればアドバイスよろしくお願いします。

OleDragDropImpl.sbp OleDragDropInterface.sbp OleDragDropThunk.sbp MainWnd.sbp内 [/hide]
イグトランス
記事: 899
登録日時: 2005年5月31日(火) 17:59
お住まい: 東京都
連絡する:

#2 投稿記事 by イグトランス »

お疲れ様です。ところでAB5ではどうやらThunk処理が不要になり,その分コードが簡素化しそうです,CP4ではまだでしたが。

とりあえずlpDataObjが変数宣言しただけで実体が(Newで)作られていないから落ちるのです。事実上ドラッグを開始する側はIDropSourceだけでなく,IDataObjectも実装する必要があります。

DoDragDropは,確かにドラッグ&ドロップを開始させる関数です。OLEシステムにドラッグ&ドロップを依頼すると言えば良いのかもしれません。

この関数を呼ぶと,以後OLEシステムがマウスの動きを捕捉して,通り過ぎるウィンドウに対してマウスが通っていると通知を出します。そして最後にボタンが離されたときにマウスポインタの背後にあったウィンドウへドロップされたという通知を出します。通知と言いましたが,これはウィンドウに関連付けられた(RegisterDragDropされた)IDropTargetのメソッドをOLEシステムが呼び出すという形で実現されています。
しーぷ

#3 投稿記事 by しーぷ »

ご指摘ありがとうございます。

> とりあえずlpDataObjが変数宣言しただけで実体が(Newで)作られていないから落ちるのです。事実上ドラッグを開始する側はIDropSourceだけでなく,IDataObjectも実装する必要があります。

ということなのでIDropSourceと同様に無理やりIDataObjectも実装しようと、このページを参照しながら試みたのですがCのことがよく分からず(特に演算子)ABに移植することができませんでした。
しかも今の時点でコードを実行しようとするとコンパイラごと落ちてしまいました…。

またコードをすべて載せます。お手数ですが、IDataObjectの実装の方法(というかIDropTargetも自信ないのですが…)・Cからの移植方法等をご教示ください。よろしくお願いします。

OleDragDropImpl.abp

OleDragDropInterface.abp


OleDragDropThunk.abp


MainWnd.sbp内

また、DoDragDropについての詳しい解説ありがとうございました。
疑問をひとつ解消することができました!
しーぷ

#4 投稿記事 by しーぷ »

いろいろと試してみたのですが、OleDragDropThunk.sbp内の
CreateDataObjectImplにミスがありました。
以下のように修正したところコンパイラが落ちることはなくなりました。 しかし、lpDataObj->SetDataでアクセス違反が起こってしまいます。
そこをコメントアウトしても次のlpDataObj->Release()、lpDropSource->Release()でアクセス違反が起こります。IDataObject、IDropSourceともに正しく実装できていないということでしょうか…。
イグトランス
記事: 899
登録日時: 2005年5月31日(火) 17:59
お住まい: 東京都
連絡する:

#5 投稿記事 by イグトランス »

自分でもやってみたいのは山々ですが,そんな時間がなくてやれていません。

IDataObjectの全てのメンバが揃っていないようです。メモリ配置の問題で,全てのメンバが正しい順番で宣言されていないといけません。よくわからない関数は,単にE_NOTIMPLを返すようにするだけにしてでも,とりあえず実装してみてください。
しーぷ

#6 投稿記事 by しーぷ »

お忙しい中コメントいただきありがとうございます。
ご指摘どおりすべてのメンバを揃え(すべてE_NOTIMPLを返していますが…)、更に諸々を見直して修正したところアクセス違反はでなくなりました!

しかし今度はどうやらDoDragDropが失敗しているようでE_INVALIDARGが返ってきます。MSDNで調べてみたのですが返り値にないのですが… やはりまだ実装に失敗しているのでしょうか。それともSTGMEDIUM構造体の格納が間違っているのか、DoDragDropの定義が誤っているのか、、、(STGMEDIUM構造体の格納にはこの記事を参考にしました)

再三恐れ入りますが、何かお気づきのことがあればご指摘おねがいします。

OleDragDropImpl OleDragDropInterface OleDragDropThunk MainWnd内
しーぷ

#7 投稿記事 by しーぷ »

自分でいろいろ言いましたがやはり最低でもSetData()及びQueryGetData(),GetData()を記述しなければならないのに、それらをただE_NOTIMPLを返すだけで処理しているのが動作しない最大の原因だと思います。以前にも書きましたが、Cで書かれたこのページの内容を上手くABに移植できれば動作すると思うのですが…

ほとんどCのことが分からないのですが、分からないなりに調べ、勝手に解釈し、更に配列やらエラーの処理やらをまったく無視して書いてみました。結局動かなかったのですが、GetDataが呼び出されればpmediumに対してfromatetcInと同じ形式のこちらで保持していたmediumを格納し、QueryGetDataはpformatetcと同じ形式のデータを持っているかを応え、SetDataではpFormatetcとpmediumを自分のところにコピーして保持するようにすればいいのですから原理的にはこれであっているのではないでしょうか?なぜ上手く動いてくれないのでしょうか…

OleDragDropImpl.abs OleDragDropInterface.abs

コード: 全て選択


Const DVASPECT_CONTENT = 1
Const DV_E_FORMATETC = &h80040064
Const DV_E_DVASPECT = &h8004006BL
Declare Function OleDuplicateData Lib "Ole32" (hSrc As HANDLE, cfFormat As CLIPFORMAT, uiFlags As Long) As HANDLE
返信する