antenn-a
company profile

MFC航海日記 六十四日目(ファイルをアイコンにドロップされて起動した時)


jpgファイルをアイコンに落としたら起動して直ぐにサムネイル作成に入ろうかな、と思っている。
まず、引数付きでアプリケーションが起動されたかどうかを確認するには
char* p = AfxGetApp()->m_lpCmdLine;
こんな感じで引数を取る事が出来る。もし、引数なしで起動された場合は *p = ""; という状態になって返ってくる。
では、私が作ったドロップ確認関数を紹介

BOOL CDropToIconDlg::OnInitDialog()
{
    //
    // 省略
    //
    
    // アイコン状態の時に何かドロップされて起動したかをチェック
    CStringArray	argv;
    if( IsDropOnIcon( &argv, TRUE ) ){
        int		i;
        for( i = 0; i < argv.GetCount(); i++ ){
            MessageBox( argv[ i ], "ドロップされたファイルは", MB_OK );
        }
    }
	
    return TRUE;  // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}

/*
    アイコンにドロップされて起動されたかどうかをチェックし
    もし、ドロップされていたならば引数で貰った CStringArray
    に分解、格納してTRUEを返す
*/
BOOL CDropToIconDlg::IsDropOnIcon( CStringArray* argv, BOOL acceptFolder )
{
    CString			cmdlin = "";
    CString			resToken;
    char*			p;
    int				startnum = 0;

    p = AfxGetApp()->m_lpCmdLine;
    if( strlen( p ) == 0 || p[ 0 ] == '-')
        return FALSE;

    cmdlin = p;

    resToken= cmdlin.Tokenize( "\"", startnum );
    while( resToken != "" ){
        if( resToken != " " && IsExist( resToken, acceptFolder ) )
            argv->Add( resToken );
        resToken= cmdlin.Tokenize( "\"", startnum );
    };
    return TRUE;
}

/* 引数で貰った文字列がファイルかどうかをチェック */
BOOL CDropToIconDlg::IsExist( CString filepath, BOOL acceptFolder )
{
    CFile	fp;

    if( fp.Open( filepath, CFile::modeRead ) ){
        fp.Close();
        return TRUE;
    }

    /*
    ディレクトリも受け付けたい場合はディレクトリの存在確認をする
    */
    if( acceptFolder )
        return ( ::GetFileAttributes( filepath ) & FILE_ATTRIBUTE_DIRECTORY) ? TRUE : FALSE;

    return FALSE;
}						


prev


OnInitDialog() の中でIsDropOnIcon() を呼んでいる。
この自作関数はコマンドライン引数を分解して、CStringArray に入れていく関数です
# Tokenize() 便利!
引数自体、どう来るのかというと、
「"C:\WINDOWS\hoge1.jpg" "C:\WINDOWS\hoge1.jpg" "C:\WINDOWS\hoge1.jpg" "C:\WINDOWS\hoge1.jpg" 」
という具合にやってくる。
これを " をトークンに分解して入れている。
ここのミソはトークンを 「"」 だけにしてる所。スペースをトークンにしてはいけない。
何故なら、"C:\Program Files" の様にスペースを含むディレクトリが有るからです。
なので、" をトークンにして分解してスペースのみに分解されたらシカトする、としなければなりません。
更に、ドロップされたのがフォルダである可能性も有るので、ファイルの存在チェックと共に確認を行っています。
文字列が、ディレクトリで、それが存在する、という事を確認するには GetFileAttributes()を使います。
return ( ::GetFileAttributes( filepath ) & FILE_ATTRIBUTE_DIRECTORY) ? TRUE : FALSE
上記例では3項演算子でやりました。
# 一応3項演算子について、
# (条件) ? 満たす場合 : 満たさない場合
# という感じです。 # 例えば、 A > 0 ? A++ : A--;
# この場合はAが0以上ならば++して、0未満なら--する、という事。
# 上の奴だと、ディレクトリであるならばTRUEを返し、違うならFALSEを返す、という事
# 3項演算子、慣れると便利ですよ。

prev


今回のサンプルはここからダウンロード出来ます。
次回は他のアプリにファイルを引数に渡して起動するのをやってみます。


antenn-a

prev


antenn-a