プログラミング研究所 プログラミング研究所 http://www.program-lab.jp/
プログラミング研究所
プログラム研究自作ソフトウェアプログラムメモリンク


  • カテゴリ別アーカイブ

    .NET Framework
    C++/CLI
    DirectX
    GBA
    JavaScript
    OSSの移植
    PHP
    Win32/64
    WordPress
    その他
    ソフトウェアの設定
    ツール
    ライブラリ
    自作ソフト
    製品レビュー


  • エントリ一覧


    Syndicate this site (XML)

    Powered by
    Movable Type







  • 管理者:NMVL

    nmvl★program-lab.jp
    ※アドレスの ★ を @ に置き換えてください。

    釣りの話題はこちらから
    www.fishing.hokkaido.jp






    « ウィンドウの無効化 | メイン | mp3infpをx64へ移植(VC6編 part2) »

  • ドラッグ&ドロップの遅延レンダリングもどき(ファイル) 【C++/CLI】
    MFCのCOleDataSourceなんかだと、ドロップ時に遅延レンダリングなんてこともできるらしいが、 .NET・C++/CLIで似たような事が出来ないかと、思いつきだけで作ってみた。

    やり方としては、DataObjectのGetDataをオーバーライドして マウスのボタンが押されていない状態で、GetDataが呼ばれたタイミングを (マウス操作としての)ドロップ完了と見なす。
    それを検出したドロップ元は、 メモリの内容をファイルに保存したり 圧縮ファイルから中のファイルを取り出してたりして、 ドロップ先に渡すファイルを作成する。

    public ref class DataObject_DelayRender : public System::Windows::Forms::DataObject
    {
    public :
        //----------------------------------------------------------------
        // コンストラクタ
        DataObject_DelayRender(void)
            : DataObject()
        {
            Initialize();
        }

        DataObject_DelayRender( System::Object^ data )
            : DataObject( data )
        {
            Initialize();
        }

        DataObject_DelayRender( System::String^ format, System::Object^ data )
            : DataObject( format, data )
        {
            Initialize();
        }

        //----------------------------------------------------------------
        // GetDataをオーバーライド
    /*/
        virtual System::Object^ GetData( System::String^ format ) override
        {
            ButtonCheck();
            return DataObject::GetData( format );
        }

        virtual System::Object^ GetData( System::Type^ format ) override
        {
            ButtonCheck();
            return DataObject::GetData( format );
        }
    //*/
        // これだけオーバーライドしておけば大丈夫?
        virtual System::Object^ GetData( System::String^ format, bool autoConvert ) override
        {
            ButtonCheck();
            return DataObject::GetData( format, autoConvert );
        }

    protected:
        // 遅延レンダリング 関数
        virtual void OnRender( void )
        {
            System::Windows::Forms::MessageBox::Show( L"ドロップされました!" );
        }

        // 変数の初期化
        virtual void Initialize( void )
        {
            m_bComplete = false;
        }

        // ボタンの状態を調べる
        virtual void ButtonCheck( void )
        {
            // ボタンが離れた後の初回にレンダリングを行う

    /*/            // .NET版
            if( ( m_bComplete == FALSE )
             && ( System::Windows::Forms::Control::MouseButtons == System::Windows::Forms::MouseButtons::None ) )
    //*/
    //*            // Win32 API版
            // GetAsyncKeyStateでマウスの状態を調べる
            if( ( m_bComplete == false )
             && ( !::GetAsyncKeyState( VK_LBUTTON )
             && !::GetAsyncKeyState( VK_RBUTTON )
             && !::GetAsyncKeyState( VK_MBUTTON )
             && !::GetAsyncKeyState( VK_XBUTTON1 )
             && !::GetAsyncKeyState( VK_XBUTTON2 )
             ) )
    //*/
            {
                // 初回終了
                m_bComplete = true;

                OnRender();
            }
        }

        bool m_bComplete;
    };


    使うときは、これを更に継承してOnRender()をオーバーライドするのがいいと思われる。

    DoDragDropする箇所では、
    DataObject_DelayRender^ objDataObj;

    objDataObj = gcnew DataObject_DelayRender( DataFormats::FileDrop, strDropFiles );

    // ここでは、リストビューからのD&D例
    frmListView->DoDragDrop( objDataObj, DragDropEffects::Copy );

    みたいに書く。

    マウスのボタンの状態を取得するところがWin32 APIになっているのは、 System::Windows::Forms::Control::MouseButtonsだと、 Explorerへのドラッグ中にボタン状態がNoneになってしまうことがあったためで、 原因もわからないので、とりあえずWin32にしておいた。
    strDropFilesは、遅延レンダリング時に作成するファイル名と同じものをあらかじめ入れておくこと。
    違う名前だとうまくいきません。

    以上でドラッグ&ドロップの遅延レンダリングもどき(ファイル)の実装はおわり。
    完璧ではないと思うが、一通り試した限りではうまくいくようなのでこれでOKとしておく。

    もっと正攻法だったり完璧な方法なんかがあれば教えてください>凄いプログラマのみなさま。


    更新:2006/04/30
    GetKeyState → GetAsyncKeyStateに変更。
    ネームスペースを修正


    投稿者 NMVL : 2006年4月29日 13:48