OLE D&D on Dialog

[戻る]
Pocket 2005/06/21(火) 18:49:24
WinXP, Visual Studio.NET 2003
Dialogベースアプリケーション

こんにちわ。

# 先日はCStaticの件でお世話になりました。

今回は、OLE D&Dの実装方法で質問が有り、参りました。

Dialogベースのアプリケーションで、Dialogの中に有るRichEditBoxに、ブラウザのアド
レス欄からURL、HTMLブラウザ中の画像をD&Dで拾い、URLを取得する様な物を作ろうとし
ています。こういうのを実装するのに、OLE D&Dという方法なのかも実は自身が無いので
すが、間違っていますでしょうか・・・。

仮に、合っていたとして現状の実装としては、DialogのApplicationクラス中で

COLETestApp::InitInstance()
{
    // 省略

    // Init Rich Edit
    AfxInitRichEdit();

    // Init OLE
    AfxOleInit();
}

をコールした後(AfxOleInit()の戻り値は1)DialogクラスのOnInitDialog()中で、

m_OleDropTarget.Register( &m_Edit );

の様な形でRegistしようとしていますが、この戻り値が0で、失敗している模様です。
同様にRichEditBox中でメンバー変数を定義して、Registしようとしても失敗しているの
で、Registする場所ややり方が違うのかなあ、、と思っています。

諸兄の皆様、すみませんがお知恵をお貸し下さい。

dairygoods 2005/06/22(水) 09:30:03
リッチエディットは、何もしなくてもテキスト等がドロップできます。
なので、すでに別の drop target に登録されているものと思われます。

自分の drop target に登録する前に、
古いのを解除(RevokeDragDrop)してみてください。

標準のdrop動作はそのままで、dropされたことを検出したいなら、
EN_DRAGDROPDONE の方がよいかもしれません。

Pocket 2005/06/22(水) 13:54:11
dairygoodsさん、返信有難う御座います。

も少し、教えてください。

僕もリッチエディットは何もしなくても出来ると思っていたのですが、ブラウザのアドレ
ス欄からD&Dした際に、リッチエディット上ではカーソル形状はD&D可状態なのですが、実
際はイベントが来ず、困っていました。

やった事は、リソースエディタ上で、リッチエディットのプロパティでAcceptFilesを
TRUEに設定し、OnDropFiles()をオーバーライドしただけです。

ちなみに、EN_DRAGDROPDONEをオーバーライドしてみましたが、やはりイベントが来ず
困っております。

***

また、DropTargetに指定する前にRevokeDragDrop()をコールしたら、上手く動作しまし
た。よく分からないのは、RevokeDragDrop()しているのに、OnDropFilesにもイベントが
来るのですね。

うーん・・・。

一応、解決といえば解決なのですが、上記の点がうやむやなので、暫く解決を保留させて
下さい。

dairygoods 2005/06/22(水) 15:20:27
> よく分からないのは、RevokeDragDrop()しているのに、OnDropFilesにもイベントが
> 来るのですね。

ファイルドロップはOLE D&Dとは別の仕組みだからじゃないでしょうか。

Pocket 2005/06/25(土) 02:35:50
[[解決]]
こんにちわ。

結局、下記の方法で実装したままにしました。
dairygoods さん、有難うございました。助かりました!

***

COleDropTarget を継承するクラスを作成(MyOleDropTarget)
MyOleDropTargetクラスで、OnDrop(), OnDragOver()をオーバーライド
OnDragOver()内では、return DROPEFFECT_COPY; する
OnDrop()で

OnDrop(・・・)
{
    if( pDataObject->IsDataAvailable( CF_TEXT ) ){
        HGLOBAL hData = pDataObject->GetGlobalData( CF_TEXT );
        ASSERT( hData );
        // ドロップするデータを取得
        const char *ptr = (const char *)GlobalLock( hData );
        m_DropSrc = ptr;
        GlobalUnlock(hData);
        
        SendMessage( m_hParent, MYMSG_DROP_OLE, 0, 0 );
    
        return TRUE;
    }
    return COleDropTarget::OnDrop(pWnd, pDataObject, dropEffect, point);
}

Dialogクラスで、MyOleDropTargetのメンバーを作り、のOnInitDialog()中で

OnInitDialog(・・・)
{
    RevokeDragDrop( m_MyEdit.GetSafeHwnd() );
    m_OleDropTarget.Register( &m_m_MyEdit);
    
    m_OleDropTarget.m_hParent = GetSafeHwnd();
}

という感じで実装しました。

ちょっと、RichEditで悔いが残りますが、解決にします。
有難うございました!

古いスレッドには追加発言できません。