多くのWindowsアプリケーションでは、エクスプローラなどからファイルをつかんでアプリケーションのウインドウに入れてやると、そのファイルを開く事ができます。自作のプログラムでもDragAcceptFilesというAPIでこの「ドラッグ&ドロップ」の機能を実装する(よう設定する)ことができます。
DragAcceptFilesを使うと、その名のとおり同時にドロップされた複数のファイルを取得できるようになりますが、まずはドロップされたファイル名を一つだけ取得するプログラムを作ってみましょう。
BMPファイルのドロップ
今回は、以前作ったBMPファイル読み込みプログラムをドラッグ&ドロップ対応にしてみましょう。ファイルのドラッグ&ドロップ対応にするには、まずアプリケーションのウインドウをドロップを受け入れるように設定して、ファイルがドロップされたら送られてくるWM_DROPFILESメッセージを処理する、という流れになります。
関連のAPIは以下の通りです。
ドロップの受け入れを設定します。hwndはウインドウのハンドル、fAcceptはドロップを受け入れるか否かのフラグです。
DragQueryFile(HDROP hDrop, UINT iFile, LPTSTR lpszFile, UINT cch)ドロップされたファイルのファイル名を取得します。hDropはドロップされたファイルを識別するハンドルで、WM_DROPFILEメッセージのwParamに入っています。iFileはドロップされたファイルのうち、何番めのファイル名を得るかを指定するもので、複数のファイルをドロップした時に特定のファイルを処理したい時は0からファイル数ー1までの値を指定してください。ドロップされたファイルの総数を得るには、ここを0xFFFFFFFFにします。なお、何個ドロップされてもその内の一つのファイル名だけを取得したい時は、0にしておけば良いでしょう。
最後にlpszFileはファイル名を格納するバッファへのポインタ、cchはバッファの大きさです。
ドラッグされたファイル名を転送するために使ったメモリを解放します。hDropはDragQueryFile()の時と同じです。
プログラム例
では、早速BMPファイル読み込みプログラムに、ドロップ受入機能を追加して行きましょう。まずウインドウを作ったら、DragAcceptFiles(hwnd,TRUE);とドロップを受入れるように設定します。これで、ファイルがドロップされるとWM_DROPFILESメッセージが送られてくるようになるので、このメッセージを捉えてドロップされたファイル名を調べたら、ファイルを読み込んで表示すれば良いわけです。
case WM_DROPFILES: /* ファイルがドロップされた時の処理 */ hDrop=(HDROP)wParam; /* HDROPを取得 */ DragQueryFile(hDrop,0,szFn,256); /* 最初のファイル名を取得 */ readBMP(szFn); /* BMPファイルを読み込んで表示 */ DragFinish(hDrop); /* ドロップの終了処理 */ break;
今回は、いくつファイルがドロップされてもそのうちの一つだけを表示するので、DragQueryFile()の第2引数には0を指定しています。起動したら、適当なBMPファイル(ただし16ビット以上)をドラッグ&ドロップしてみてください。