Excelファイルが開かれているかVC++で判断したい

[戻る]
うちわ 2008/07/09(水) 13:53:02
環境は、WinXP(SP2) VC++ 6.0 SDK です。

初心者です。
拙い文章で分かりずらいかもしれません。

今、VC++ から、「test.xls」というExcelファイルを開こうとしています。
 「test.xls」は、C:\Excelファイル\test.xls に保存されています。

「test.xls」ファイルを開くタイミングは、
exeを起動してダイアログ上にある"開く"ボタン をクリックした時です。

ここで、「test.xls」ファイルを開く時に、
既に「test.xls」ファイルが開かれていた場合に
エラーにしたいのです。

既に開かれていた場合とは、普通に「test.xls」をダブルクリックして
開いた状態です。


エラーにする方法をどなたかご教授くださいませんか。

宜しくお願い致します。

たいちう 2008/07/09(水) 15:38:03
排他的にファイルを開こうとして、失敗したら既に開いていると考えて良いのでは?
CreateFileで良いと思いますが。

玲音 (st.lain) 2008/07/09(水) 16:23:11
Excelからファイルを開いているときってROTに載ったような気がします。
# Excel2000でIROTVIEW.EXEを見る限りは、そのような挙動のように思われます。

調べてみると良いカモしれません。

うちわ 2008/07/09(水) 18:47:39
>たいちう さん

お返事ありがとうございます。
以下のようにコードを作ってみたのですが
思うとおりになりませんでした。
コードが間違っているのかもしれません。

あと、申し訳ありません。
言葉が足りなかったかもしれません。

C:\\Excelファイル\test.xls を開いた状態で動かすと
MessageBox() 処理に入りました。

D:\\Excelファイル\test.xls を開いた状態で動かすと
MessageBox() 処理に入りませんでした。

Excelファイルを何も開かない状態で動かすと
MessageBox() 処理に入りませんでした。

「test.xls」がどのドライブにあったとしても、「test.xls」というExcelファイル名が
開かれていたらエラーにしたいのです。

申し訳ありません。
ご教授を頂けましたどうぞ宜しくお願い致します。

    HANDLE        hFile;
    
    hFile = CreateFile("C:\\Excelファイル\test.xls ", GENERIC_READ, 0, 
        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hFile == INVALID_HANDLE_VALUE)
    {
        // エラーだよ
        MessageBox(NULL, "File Write Error !","Error!",MB_OK);
    }



>玲音 (st.lain)  さん

>Excelからファイルを開いているときってROTに載ったような気がします。

申し訳ありません。
ROT が何の事なのかが分かりません。

本当に何も分かってないので、ROT で調べてみたのですが、
検討違いなところへとんでしまいました。

ん? 2008/07/10(木) 10:49:02
各ドライブ情報を取得して、パスを編集しないと駄目みたいですね。


ULONG DrvList = _getdrives();

TCHAR Tgt[] = _T("A:\\Excelファイル\test.xls");
while(DrvList) {
    if (DrvList & 0x01) {
        hFile = CreateFile(Tgt, GENERIC_READ, 0, 
            NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

        if (hFile == INVALID_HANDLE_VALUE)
        {
            // エラーだよ
            MessageBox(NULL, "File Write Error !","Error!",MB_OK);
            break;    // 全ローカルドライブを調査する場合は、
                      // この break; をコメントにする。
        }
    }
    Tgt[0]++;
    DrvList >>= 0x01;
}

ん? 2008/07/10(木) 10:52:12
閉じ忘れてた。。

        if (hFile == INVALID_HANDLE_VALUE)
        {
            // エラーだよ
            MessageBox(NULL, "File Write Error !","Error!",MB_OK);
            break;    // 全ローカルドライブを調査する場合は、
                      // この break; をコメントにする。
        }
// ↓追加
        else {
            CloseHandle(hFile);
        }
// ↑追加

ITO 2008/07/10(木) 11:27:58
> D:\\Excelファイル\test.xls を開いた状態で動かすと
> MessageBox() 処理に入りませんでした。
 Excelファイルの場所は変更可能にしてもアプリで分かるようにしておかない
いけないと思います。
CドライブがDドライブになるぐらいなら予測できる範囲だけど、USBメモリー
とかで仮に「FドライブのExcelファイルも認識してよね」と言われてもそれは
「仕様上出来ない」としておかないと大変だと思います。

たいちう 2008/07/10(木) 13:09:47
> 「test.xls」がどのドライブにあったとしても、「test.xls」というExcelファイル名が
> 開かれていたらエラーにしたいのです。

ファイルのパスは、ドライブ名以外は固定ですか?
それならば、有効な全てのドライブについて調べれば良いでしょう。

固定でないとすると、起動しているExcelを列挙して、
ウィンドウキャプションに"text.xls"が含まれるかを調べれた方が良いかと。

PATIO 2008/07/10(木) 13:54:27
考え方的に正にそのファイルが開いているかどうかと言う話なら
狙い撃ちも可能だと思いますが、ファイル名が同じなら全部駄目ってのは
結構つらそうですね。
フォルダが違っていて偶々同じ名前のファイルであっても引っ掛けるわけですよね。
それこそ、たいちうさんが言われているみたいな方法でやるしかなさそうです。

ただ、ファイル名だけで判断すると偶々同じファイル名であっても駄目と言う話に
なるので使いづらいような気もしますね。

玲音 (st.lain) 2008/07/10(木) 14:50:11
> ROT で調べてみたのですが、
Running Object Table、の略称です。ここの過去ログでも1件出てきています。
(つい最近、の記事ですが)

GetRunningObjectTable(), CreateBindCtx()辺りで調べてみると良いと思われます。

# IROTVIEW.EXEって2003, 2005, 2008では付属してないのでしょうかねぇ・・・。
# フォーカス取得で自動更新してくれますし、有難いツールの1つなのですけどね。

玲音 (st.lain) 2008/07/10(木) 14:52:12
> (つい最近、の記事ですが)
VC++のカレントページにいましたね。

>> COMオブジェクトが作成されているかを知りたい
> http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200806/08060080.txt

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