MFC編 目次

 MFC全般

 

・MFCの開発環境をそろえよう
・MFCをスタティックリンクしたときに出るエラー
・関数追加時に出るエラー
・Windows XPスタイルの外観にする

 文字列操作

 

・CStringの基本1 文字列の連結と追加
・ATL/MFC共有版のCStringについて
・CStringと三項演算子の問題

 DDX/DDV

 

・DDXの基本1
・DDXの基本2
・DDX変数に複数コントロールを割り当てる
・DDX変数を配列にする

 ダイアログ

 

・ダイアログの色変更

 ボタン

 

・ボタンの基本

 チェックボックス

 

・チェックボックスの基本
・プッシュボタンのようなチェックボックス
・チェックボックスの色変更

 エディットボックス

 

・エディットボックスの基本
・エディットボックスの色変更

 コンボボックス

 

・コンボボックスの基本
・コンボボックスに初期データを入れる
・コンボボックスの色変更
・拡張コンボボックス

 リストボックス

 

・リストボックスの基本
・リストボックスの色変更
・チェックリストボックスを作る

 ラジオボタン

 

・ラジオボタンの基本
・ラジオボタンの色変更

 スタティックテキスト

 

・スタティックテキストの内容を動的に変更する
・スタティックテキストに複数行入力する
・スタティックテキストの文字色変更

 リストコントロール

 

・リストコントロールの基本1
・リストコントロールの基本2
・リストコントロールの一行全体を選択する
・リストコントロールを単一行選択にする
・フォーカスが移ったときも選択状態を維持する
・アイテムにユーザデータを付加する
・アイテムにアイコンをつける
・アイテムに状態イメージをつける
・ヘッダ項目にアイコンをつける

 ツリーコントロール

 

・ツリーコントロールの基本

 タブコントロール

 

・タブコントロールの基本1
・タブコントロールの基本2
・タブコントロールをXPスタイルにする

 スライダコントロール

 

・スライダコントロールの基本1
・スライダコントロールの基本2

 スピンコントロール

 

・スピンコントロールの基本

 プログレスバー

 

・プログレスバーの基本

 日時指定コントロール

 

・日時指定コントロールの基本

 月間予定表コントロール

 

・月間予定表コントロールの基本
・月間予定表のプロパティと色変更

 IPアドレスコントロール

 

・IPアドレスコントロールの基本
・IPアドレスコントロールの操作

 ピクチャーコントロール

 

・ピクチャーコントロールの基本

 アニメーションコントロール

 

・アニメーションコントロールの基本

 時刻管理

 

・CTimeとCTimeSpan
・CTimeの引数について

 メニュー

 

・ダイアログにメニューをつける
・ダイアログにポップアップメニューをつける

 ステータスバー

 

・ダイアログにステータスバーをつける
・ステータスバーに文字列を表示する

 プロパティシート

 

・プロパティシートの基本1
・プロパティシートの基本2

 コモンダイアログ

 

・ファイル選択ダイアログ
・フォント選択ダイアログ
・色選択ダイアログ

 ファイル入出力

 

・ファイル入出力の基本
・テキストファイルの入出力
・ファイルの検索、列挙1
・ファイルの検索、列挙2

 ネットワーク

 

・MFCソケット通信の基本 (クライアント編)
・MFCソケット通信の基本 (サーバ編)
・MFC非同期ソケット (クライアント編1)
・MFC非同期ソケット (クライアント編2)
・MFC非同期ソケット(サーバ編1)
・MFC非同期ソケット(サーバ編2)

 デバイスコンテキスト

 

・デバイスコンテキストの基本
・文字列の描画
・ペンを使った描画
・ブラシを使った描画1
・ブラシを使った描画2

 FTPクライアント

 

・FTPクライアントを作る1
・FTPクライアントを作る2
・FTPクライアントを作る3
・FTPクライアントを作る4
・FTPクライアントを作る5

 ドキュメント・ビュー

 

・ドキュメント・ビューの基本
・エディットビューの基本
・リストビューの基本
・ツリービューの基本
・フォームビューの基本

 ダイアログバー

 

・ダイアログバーの基本
・ダイアログにダイアログバーをつける

 

 

トップページへ戻る

FTPクライアントを作る2

 前回の続きでFTPクライアントを作っていきます。では早速コードを実装していきましょう。まずは"接続"ボタンが押されたときのイベントハンドラです。

// "接続"ボタン押下
void CFtpClientDlg::OnBnClickedBtnConnect()
{
    int        err = 0;
    
    UpdateData();
    OnBnClickedBtnDisconnect();
    
    try
    {
        m_iSessionP = new CInternetSession;
        m_ftpConP = m_iSessionP->GetFtpConnection
            (m_xvEditServer, m_xvEditUser, m_xvEditPass,
            INTERNET_INVALID_PORT_NUMBER, TRUE);
        Refresh();
    }
    catch (CInternetException *eP)
    {
        eP->ReportError();
        eP->Delete();

        if (m_ftpConP) m_ftpConP = NULL;
        if (m_iSessionP) {delete m_iSessionP; m_iSessionP = NULL;}
        err = 1;
    }
}

 まずは、入力したサーバ名、ユーザ名、パスワードを読み取るためにUpdateData()関数を実行しておきます。また、現在接続中である場合は新しく接続する前に切断しておきます。そのため、OnBnClickedBtnDisconnect()を実行しておきます。

 次は、前回に説明した通りに、CInternetSessionクラスのオブジェクトを作成し、GetFtpConnection()関数でサーバに接続し、CFtpConnectionクラスのオブジェクトを取得します。

CFtpConnection* CInternetSession::GetFtpConnection(
LPCTSTR pstrServer,
LPCTSTR pstrUserName = NULL,
LPCTSTR pstrPassword = NULL,
INTERNET_PORT nPort = INTERNET_INVALID_PORT_NUMBER,
BOOL bPassive = FALSE
);
説明: FTPサーバへ接続し、CFtpConnectionクラスオブジェクトへのポインタを取得
引数: pstrServer:サーバ名
pstrUserName:ユーザ名。NULLの場合anonymousになる
pstrPassword:パスワード。NULLの場合anonymousであればユーザの電子メールアドレス、anonymousでなければ空白のパスワードになる
nPort:TCP/IPポート番号、指定しなければデフォルトポートが使われる
bPassive:PASSIVEモードで接続する場合TRUE、ACTIVEモードで接続する場合FALSE
戻り値: CFtpConnectionクラスオブジェクトへのポインタ。エラーの場合はCInternetException例外をスローする。

 GetFtpConnection()関数を呼ぶと、指定したサーバへ、指定したユーザ名、パスワードで接続されます。接続できなかった場合はCInternetExceptionの例外がスローされるので、catchブロックでエラー処理をします。これをやらないとエラー発生時にGetFtpConnection()から後の処理が飛ばされて関数を抜けてしまいますので、必ず例外処理をするようにしましょう。

 FTPの転送モードはACTIVEモードとPASSIVEモードがあります。これはデータ転送のためのコネクションをサーバ側、クライアント側のどちらから張るかという違いがあります。詳しくは詳細に説明しているサイトがたくさんあるのでそちらを見てください。

 接続が成功したら、ファイル一覧を取得して表示します。これは後で説明する自作のRefresh()関数でやっています。

 次は"切断"ボタンが押されたときのイベントハンドラです。

// "切断"ボタン押下
void CFtpClientDlg::OnBnClickedBtnDisconnect()
{
    UpdateData();
    if (m_ftpConP) m_ftpConP = NULL;
    if (m_iSessionP) {delete m_iSessionP; m_iSessionP = NULL;}
    
    while (m_xcList.DeleteString(0) != LB_ERR);
    m_xvEditCurDir = _T("");
    UpdateData(FALSE);
}

 CFtpConnectionクラスのオブジェクトはCInternetSessionクラスの内部で作成、破棄されるので、自分で破棄する必要はありません(というよりしてはいけません)。CInternetSessionクラスのオブジェクトは自分で破棄します。破棄すると自動的にFTPのコネクションが切断されます。

 切断したら、リストボックスやカレントディレクトリの文字列を消去しておきます。

 では、次はサーバからファイル一覧を取得して表示する部分を見ていきましょう。

// 表示更新
void CFtpClientDlg::Refresh(void)
{
    int        err = 0, lbErr = 0;
    
    if (!err) if (!m_ftpConP) err = 1;
    if (!err)
    {
        CFtpFileFind    finder(m_ftpConP);
        CString         fileName;
        BOOL            bWorking = FALSE;
        
        // カレントディレクトリ取得
        m_ftpConP->GetCurrentDirectory(m_xvEditCurDir);
        UpdateData(FALSE);
        
        // ファイル一覧取得
        while (m_xcList.DeleteString(0) != LB_ERR);
        if ((bWorking = finder.FindFile()) == 0) err = 1;
        if (!err)
        {
            while (bWorking)
            {
                bWorking = finder.FindNextFile();
                fileName = finder.GetFileName();
                if (finder.IsDirectory()) fileName = _T("[D]") +fileName;
                lbErr = m_xcList.InsertString(-1, fileName);
                if (lbErr == LB_ERR || lbErr == LB_ERRSPACE) err = 1;
                if (err) break;
            }
        }
    }
    return;
}

 まずはカレントディレクトリの表示を更新しておきます。カレントディレクトリはCFtpConnection::GetCurrentDirectory()で取得できます。引数にはCStringオブジェクトの参照を渡します。

 次はカレントディレクトリにあるファイルの一覧を取得します。ファイル一覧の取得はCFtpFileFindクラスを使います。CFtpFileFindクラスのコンストラクタにCFtpConnectionオブジェクトへのポインタを渡します。

 ファイル一覧取得の流れはプログラムを見るとわかると思いますが、CFtpFileFind::FindFile()関数で検索を開始します。その後はCFtpFileFind::FindNextFile()関数で一つずつファイルを検索していきます。ファイル名の取得はCFtpFileFind::GetFileName()関数でできます。

 また、取得するものはファイルとディレクトリが混在しています。ディレクトリかどうかはCFileFind::IsDirectory()関数で判断できます。今回は簡易的に作っているので、ディレクトリだった場合は名前の頭に"[D]"をつけて区別しています。もちろんこれではファイル名の先頭に"[D]"がついているものがあった場合は区別できなくなるので、ちゃんと作る場合はディレクトリなのかどうかのフラグを別に持つように作らないといけません。

 では各関数の詳細を解説していきます。

virtual BOOL CFtpFileFind::FindFile(
LPCTSTR pstrName = NULL,
DWORD dwFlags = INTERNET_FLAG_RELOAD
);
説明: FTPファイル検索を開始する
引数: pstrName:検索するファイルの名前。NULLの場合ワイルドカード(*)になる。
dwFlags:処理方法を指定するフラグ
戻り値: 正常終了した場合は0以外、それ以外の場合は0

 

virtual BOOL CFtpFileFind::FindNextFile( );
説明: 次のFTPファイルを検索する
引数: なし
戻り値: まだファイルがある場合は0以外、ディレクトリ内の最後のファイルを取得した場合やエラーが発生した場合は0

 では、ここまでで一区切りにします。次回はディレクトリの移動や作成、削除を作っていきます。