トップページ > 過去ログ > 記事閲覧
プロシージャを使用したドラッグ&ドロップについて
名前:uNeg 日時: 2012/10/28 11:05

過去ログにてそれぞれ  ・ドラッグアンドドロップを使用する  ・DXライブラリにて自作プロシージャを使用する 等の質問を検索しましたが、これといった答えが見つからなかったので質問させて頂きます。  現在私は、XP、VC++2008EEにてDXライブラリを使用したプログラムを作成しています。 作成したいのは、デスクトップに常駐するいわゆるデスクトップアクセサリのような物なのですが、 ウィンドウにファイルをドロップすることで、それを再生(あるいは表示)する機能を付けたいと考えています。  そこで、まずはドロップファイルからその数とパスを得るべく、後述のようにプログラムを組んだのですが、 ファイルをドロップした際の動きが上手く行かず苦戦しています。 問題点を具体的に挙げると、  ・メインループにてドラッグ検出、ファイル名取得を行うと即座に反映される(意図通り)  ・プロシージャのWM_DROPFILESにてファイル名取得を行うと反映が一回分遅れる  ドロップしたファイルが、まるでキューにでも入ったかのように1回遅れて検出されてしまいます。 メインループにて実行することで解決は出来るのですが、個人的な趣向として 可能ならば自作プロシージャ内にて処理を実行したいと考えています。 何か解決法などあるでしょうか?それとも単に私が勘違いしているだけなのでしょうか?  ご助言等ありましたら、是非よろしくおねがいします。

Page: 1 |

Re: プロシージャを使用したドラッグ&ドロップについて ( No.1 )
名前:uNeg 日時:2012/10/28 11:17

…申し訳ありません、ソースの添付を忘れておりました。 // *********** 以下ソース ************************************************************ // *** main.cpp *** /////////////////////// #include "header.h" bool GameFlag; int WINAPI WinMain(省略) { ChangeWindowMode(TRUE); // Windowモードに変更 if(DxLib_Init() == -1) return -1; // DXライブラリの初期化 SetHookWinProc(WndProc_Main); // Init後に宣言、メッセージをフックするプロシージャの指定 SetDrawScreen(DX_SCREEN_BACK); // 基本描写先を裏画面に設定 SetAlwaysRunFlag(true); // バックグラウンドでも動作を継続 SetDragFileValidFlag(true); // ファイルのD&Dを許可 GameFlag = true; // ゲームを続けるフラグをtrueに変更 DragFileInfoClear(); // DDファイル情報の初期化 while(GameFlag) { if(ProcessMessage() == -1) break; // メッセージループに変わる処理 //F_DDFile(); // ■ここで実行すると上手くいく■ ScreenFlip(); // 画面の更新 WaitTimer(10); // 10ms待ち // 不要? } DxLib_End(); // DXライブラリ使用の終了処理 return 0 ; // 終了 } // *** w_proc.cpp *** /////////////////////// #include "header.h" // 外部グローバル変数 extern bool GameFlag; // ゲームループ判断フラグ、終了時に折る LRESULT CALLBACK WndProc_Main(省略) { switch(msg) { case WM_DESTROY: GameFlag = false; //PostQuitMessage(0); return 0; case WM_LBUTTONUP: // 左クリックで終了 PostMessage(hwnd, WM_CLOSE, wp, lp); return 0; case WM_DROPFILES: ClearDrawScreen(); F_DDFile(); // ■ここで実行するとうまくいかない■ return 0; } //return DefWindowProc(hwnd, msg, wp, lp); return 0; } // *** common.cpp *** /////////////////////// #include "header.h" void F_MB(char* mes) { // メッセージボックスを表示する MessageBox(GetMainWindowHandle(), mes, "確認", MB_OK); return; } void F_DDFile(void) { // DDファイルの処理 int num = 0; // DDファイルの数を格納 char path[256]; // DDファイルのパスを格納 while(GetDragFilePath(path) == 0) { // DDファイルが存在する場合 num = GetDragFileNum(); // DDファイルの数を取得 DrawFormatString(0, num*30, COL_WHITE, "ドロップされたファイルの数:%d", num); DrawFormatString(0, num*30+15, COL_WHITE, "パス:%s", path); WaitTimer(1); // 念のため } DragFileInfoClear(); // DDファイル情報の初期化 return; } // *** header.h *** /////////////////////// #include "DxLib.h" #define COL_WHITE GetColor(255, 255, 255) // 白 LRESULT CALLBACK WndProc_Main(HWND, UINT, WPARAM, LPARAM); void F_MB(char*); void F_DDFile(void); // *********** 以上ソース ************************************************************ 以上となります、よろしくお願いいたします。
Re: プロシージャを使用したドラッグ&ドロップについて ( No.2 )
名前:管理人 日時:2012/10/28 15:16

DXライブラリも WM_DROPFILES のメッセージが来たときにドロップされたファイルを取得していますので 自作プロージャで WM_DROPFILES の直後に処理してしまうとDXライブラリの関数にはまだ情報が届いていないので 結果として一回分遅れます なので、自作プロージャで処理するにはDXライブラリの機能を使わずに wparam を HDROP にキャストした ものと Win32API の DragQueryFile を使用して直接ファイルパスを取得するしかありません DXライブラリは自作プロージャを考慮していませんので 個人的にはメインループで取得する方をお勧めします
Re: ( No.3 )
名前:uNeg 日時:2012/10/28 17:47

なるほど、DXライブラリ側のプロシージャと競合してしまうのですね。 ということはWM_L(R)BUTTONUP等でも同様の現象が起こりそうですね。 追加の質問となるのですが、自作プロシージャを作成した場合、メッセージの処理の流れとしては  ・DXライブラリのプロシージャ  ├・自作プロシージャ  |├・自プでのWM_XXXの処理  |└・自プでのWM_YYYの処理  ├・DXプでのWM_XXXの処理  └・DXプでのWM_XXXの処理     (過去ログ質問番号2553を参考) となり、WM_DESTROYやWM_CLOSEを処理しなくてもゾンビ化することはないと考えても良いのでしょうか。  また、上記ソースではコメントアウトしておりましたが、自作プロシージャ内でDefWindowProcを呼んだ場合は DXライブラリ側のプロシージャはどのように動作するのでしょうか。 ”自作プロシージャを考慮していない”と仰ったにも関わらず重ねての質問申し訳ないです。 当初の質問は管理人様の迅速な回答で見事に解決いたしました。 プロシージャにはなるべく頼ることなく、当初の目的を解決しようともいます、ありがとうございました。
Re: プロシージャを使用したドラッグ&ドロップについて ( No.4 )
名前:管理人 日時:2012/10/31 00:17

(時間が無いため簡易レスです、すみません) フック設定をしてもDXライブラリのプロージャは動きますので WM_DESTROYを呼ばなくても問題なくソフトは終了します DXライブラリ側のプロージャでも DefWindowProc を呼んでいますので、 自作プロージャ内では DefWindowProc は呼ばないようにしてください
Re: ( No.5 )
名前:uNeg(解決) 日時:2012/11/04 18:09

御返事遅くなりまして申し訳ありません。 当初の質問、また追加の質問共に、迅速かつ丁寧な解説ありがとうございました! 製作中のプログラムも少しずつ形になってきましたので、この調子で頑張っていこうと思います。 素晴らしいライブラリに感謝です。

Page: 1 |