ドラッグ&ドロップのファイル選別

解決


ふらぷら  2008-05-30 23:41:35  No: 68435  IP: 192.*.*.*

フォームへのドラッグ&ドロップ処理において、
Shift-JISテキストファイルかどうか選別を行いたいのですが、

private: System::Void Form1_DragEnter(System::Object^  sender, System::Windows::Forms::DragEventArgs^  e) {
  array<String^>^ files = dynamic_cast<array<String^>^>(e->Data->GetData(DataFormats::Text ) );
・・・
}

と書くと、「DataFormats::Text」がMSDNのヘルプ通りANSIのテキストファイルしか無理なためfilesが受け入れてくれません。

DataFormatsフィールドにShift-JISが見つからず、仕方がないので
DataFormatsのTextをFileDropに変更し、門戸を広くして

array<String^>^ files = dynamic_cast<array<String^>^>(e->Data->GetData(DataFormats::FileDrop) );
  if(files->Length == 1){
  ・・・
  }

と変更し、files[0]の中身を取得し、それがShift-JISのファイルであるか調べようと思ったのですが、その選別がうまく行きません。



行いたいことは、Shift-JISであるならば「DragDropEffects::All」そうでな
ければ、「DragDropEffects::None」にするという処理です。

別のやり方も色々模索しているのですがいまだ見つからず困り果ててしまいました。


どなたかご教示お願いします。

編集 削除
ふらぷら  2008-05-31 08:44:51  No: 68436  IP: 192.*.*.*

すいません、追記です。

環境はWindowsXP(SP2)でVisualStdio2005です。
よろしくお願い致します。

編集 削除
Blue  2008-05-31 11:03:41  No: 68437  IP: 192.*.*.*

>files[0]の中身を取得し、それがShift-JISのファイルであるか調べようと
おそらくそういう判定は難しいと思います。
(どんな拡張子のファイルでもメモ帳で開けてしまうことを考えると,,,)

とりあえず、テキストファイルであろう拡張子であるかでまずチェックして、
(先頭だけでなく)1バイトずつ、Shift_JISコードではありえない文字コードがあれば対象外にする程度ぐらいしか
制御できないでしょう。

「文字コード 判定」で検索してみると良いでしょう。

編集 削除
ふらぷら  2008-05-31 14:50:09  No: 68438  IP: 192.*.*.*

Blueさんすみません。

>とりあえず、テキストファイルであろう拡張子であるかでまずチェックして

これができずに困っています。
「DataFormats::Text」などDataFormatsを使った方法しか思いつかず、そのためfiles[0]を取得し、つまづきます。

「Find」を行い、拡張子であるかでまずチェックしようと思いついたものの、System::Stringをstd::stringに変換する方法が分からず失敗。

別の方法をご教示お願いできないでしょうか。

>(先頭だけでなく)1バイトずつ、Shift_JISコードではありえない文字コードがあれば対象外にする程度ぐらいしか
>制御できないでしょう。

1バイトずつ調べ2バイト文字であるか(全角文字であるか)判定するってことですね。

テキストファイルであろう拡張子であるかでまずチェックが成功した後に行ってみたいと思います。

今の知識だと、全ての拡張子のファイルを総当りでチェックするしか行えない状態です。

初心者で本当に申し訳ございません。

編集 削除
Blue  2008-05-31 17:25:59  No: 68439  IP: 192.*.*.*

> System::Stringをstd::stringに変換する
なんでこんなことする必要が?

とりあえずこんな感じでは?

System::Void textBox1_DragEnter(System::Object^ sender, System::Windows::Forms::DragEventArgs^ e) 
{
    if (e->Data->GetDataPresent(DataFormats::FileDrop))
    {
        array<String^>^ fileName = static_cast<array<String^>^>(e->Data->GetData(DataFormats::FileDrop, false));
        if (fileName->Length == 1 && isTextFile(fileName[0]))
        {
            e->Effect = DragDropEffects::All;
            return;
        }
    }
    e->Effect = DragDropEffects::None;
}
bool isTextFile(String^ path)
{
    // 拡張子取得
    String^ ext = System::IO::Path::GetExtension(path);
    if (ext->Compare(ext, L".txt", true) == 0)
    {
        return true;
    }
    return false;
}

>1バイトずつ調べ2バイト文字であるか(全角文字であるか)判定するってことですね。
そういうことではないのですが、、、

本当に、DragEnterでテキストファイルをいちいち開いてShift_JISコードかどうかまでチェックするのでしょうか?
馬鹿でかいファイルをドラッグしてきたときカナリ遅くなると思うのですが。

編集 削除
Blue  2008-05-31 17:39:16  No: 68440  IP: 192.*.*.*

>と書くと、「DataFormats::Text」がMSDNのヘルプ通りANSIのテキストファイルしか無理なためfilesが受け入れてくれません。
というかこの認識は間違っているのでは?
エクスプローラからファイルをドラッグするので、DataFormats::Textは使えません。
DataFormats::Textをつかうのはテキストエディタから文字列をドロップしたときとかです。

編集 削除
ふらぷら  2008-05-31 18:43:39  No: 68441  IP: 192.*.*.*

Blueさん

Compateで文字比較でしたか・・・。

文字検索がstd::stringしか思いつかず大変助かりました。
ありがとうございました。


>馬鹿でかいファイルをドラッグしてきたときカナリ遅くなると思うのですが。
そうですね。1バイトずつ調べるとDragEnter時に間違いなく固まりますね。


あるアプリケーションによって吐き出されたテキストファイルであるか調べるための選別ですが、分かっていることは。
・そのアプリケーションはShift-JISで吐き出す。
・特有のヘッダーを持っている。

アプリケーションのバージョンによってヘッダーが異なるので避けたのですが、アプリケーションを細かく調べ可能性のある全てのヘッダーを盛り込んでそのヘッダーと一致するか検査した方がよさそうですね。

馬鹿でかいファイルはFileOpenするだけで重くなってしまうのもなんでしょうか?

編集 削除
Blue  2008-05-31 19:13:50  No: 68442  IP: 192.*.*.*

Shift_JISコードにないコードが現れるまでファイルを読み込みという前提であるときは
馬鹿でかいファイルであるとき遅くなることになります。

ただ、ヘッダがあることなので、先頭何バイトだけ読むのであれば
>馬鹿でかいファイルはFileOpenするだけで重くなってしまうのもなんでしょうか?
ということはないでしょう。

編集 削除
ふらぷら  2008-05-31 19:17:29  No: 68443  IP: 192.*.*.*

Blueさん

ヘッダーを照らし合わせて選別を行いたいと思います。
本当にありがとうございました。

編集 削除