/*
    KAB-studio.h
        　ＫＡＢ−ｓｔｕｄｉｏで先週更新した内容
        が格納されたヘッダーファイルです（笑）。

    (C)KAB-studio 1999 - 2001 ALL RIGHTS RESERVED.
        http://www.kab-studio.com/
        info@kab-studio.com

    送信日： 2001/02/19(Mon) No.095
    配信数： 3900（ Mag2 + Pubzine ）
＊    発行元： まぐまぐ( URL: http://www.mag2.com/  ID: 0000012198 )
＊    発行元： Pubzine( URL: http://www.pubzine.com/  ID: 590 )
*/

/*              ２００１年２月１４日（月）の更新                  */
http://www.kab-studio.com/

・バレンタイン表紙壁紙公開
　思い付いたんで急遽描き上げた、バレンタインでどアップで思わせぶりな
火美ちゃんです。そのくちびるに身悶え間違いなし！　ダウンロードは CG 
Gallery にて。
[ CG Gallery ]
http://www.kab-studio.com/CG/Gallery/


/*              ２００１年２月１９日（月）の更新                  */
http://www.kab-studio.com/

・Codian にページを追加
　 Codian にページを追加します。今回は STL & iostream 入門から STL 
の #18 - #21 を追加。
[ Codian ]
http://www.kab-studio.com/Programing/Codian/


/*                        チョー普通な日記                        */
http://www.kab-studio.com/nikki2/

2001/02/11 (Sun)
　卒論＆ Codian 書き。スーパー戦隊２５作目スペシャルで昔に思いを馳せ
る。名作があったのよー。その他テレビ色々。あとブランドもの。

2001/02/12 (Mon)
　寝る前のギルティギアゼクス禁止(泣)。卒論の図を書きつつ、バレンタイ
ンな火美ちゃんも描いたり。あかんねぇ。

2001/02/13 (Tue)
　バレンタイン表紙壁紙完成！　雑かつ手抜きして描くとあとで痛い目を見
るということを蕩々と物語っております。さらに一応卒論が完成。２時間か
けてプリントアウト。謎のウェハース(謎)。検索して自分の文章が引っかか
るとなんか悲しい……。

2001/02/14 (Wed)
　卒論の推敲もせず、 ATOK14 やホームページビルダー６を試してみたり。
ATOK14 はいまいちどこが良くなったのか分からず。ほむびは思った以上に
使いやすいかも。んでやってみたいボクシングゲーム！

2001/02/15 (Thu)
　だから、寝る前のギルティギアゼクス禁止！！(泣)　ゼミに行って卒論を
提出。ちょびっツに絡んでマウスパッドの話。っつーかうちには縁のない話
だったり。

2001/02/16 (Fri)
　 Codian 書いたり時計の電池換えたり卒論プレゼン資料作ったりとそれな
りに大忙し？

2001/02/17 (Sat)
　卒論プレゼン資料を制作。っつーか台本書き。７分でまとめるってのは大
変。あとテレビ色々。金曜深夜っていいね〜。


/*                         鏑矢の憂鬱                             */
http://www.kab-studio.com/Programing/KabuU/

2001/02/11 (Sun)
お休み

2001/02/12 (Mon)
お便り
自分から通知メッセージを投げてもいいの？
メッセージ送るのは問題なし
WM_COMMAND の LPARAM 上位２バイトに通知メッセージを入れて送る
サンプルコード
WPARAM の下位２バイトにボタンの ID 、上位２バイトに BN_CLICKED 
WM_LBUTTONDOWN と WM_LBUTTONUP の方法もある
サンプルコード
左クリックをさせる

2001/02/13 (Tue)
お便り
VC++ はダイアログへコントロールを２５５個しか貼り付けられない
これを変更する方法は？
たぶんない
プロジェクト名）.rc を開いて直接書き換えるか
Create() するか

2001/02/14 (Wed)
ぷらとわ書き
ウィンドウズの仕様が複雑
Platform SDK 熟読は大変そう

2001/02/15 (Thu)
MSXML Parser のサンプルを解析
イベントハンドラとして実装する必要があるからクラスを作る必要がある
ISAXContentHandler がイベントハンドラとして呼び出される
開始タグで startElement() 、閉じタグで endElement() が呼ばれる
すべて Unicode で実装されている

2001/02/16 (Fri)
MSXML Parser 
サンプルはオーバーライドがちょっと複雑
SAX と DOM が XML 用パーサーとして有名
MSXML には両方とも実装されているらしい
これを勉強しておけば Java とかでも使えるかも
お便り
オリジナルのコントロールを作る方法は？
ActiveX コントロールを作ればいい
難しそう
ホームページは多そうだけど見つけるのが大変
やや時代遅れ？

2001/02/17 (Sat)
お休み


/*             プログラミング辞書・今週の追加単語                 */
http://www.kab-studio.com/Programing/Dictionary/

・追加単語：
#else DOS/V GP-IB

・今週の状況：
　今週は３単語。卒論発表が２２日なんで、それまではこのくらいがいい
なー(汗)。


/*                       金菜さんの憂鬱                           */
http://www.kab-studio.com/Programing/KanaU/

テンプレート
#13 メンバ関数の定義

　クラステンプレートのメンバ関数は、定義もクラスの中に書かれているこ
とが多いと思います。

template< class type_MemVar >
class CTmplForMemFunc
{
public:
    type_MemVar MemFunc( type_MemVar p_MemVar )
    {
        return p_MemVar;
    }
};

　別にこうしなきゃいけないってわけじゃないんです。定義を外に出したい
場合には、次のようにします。

template< class type_Var >
class COutFuncDef
{
public:
    type_Var MemFunc( type_Var p_MemVar );
};

// 定義。
template< class type_Var >
type_Var COutFuncDef< type_Var >::MemFunc( type_Var p_MemVar )
{
    return p_MemVar;
}

　って感じに、定義部にも template を付けて、クラス名でもテンプレート
引数を指定すれば、メンバ関数を定義することができます。
　でもこれ、正直ちょっと面倒。特に打ちこむんだとね。コピー＆ペースト
でもそれなりに大変だし、っていうのがこういうふうに書かない理由のひと
つ。
　他に、定義部をこう分けても、定義部をソースファイルの方に移せるわけ
じゃないっていうのも理由のひとつ。 #09 で言ったように、呼び出すとき
にコンパイラが関数テンプレートの実装を見られなきゃ使えないでしょ。だ
からメンバ関数も結局ヘッダーファイルに置かなきゃいけないのよね。

　もちろん、定義部を外に出すとすっきりする場合もあるから、そういう長
いメンバ関数だけ外に出すっていう手もあるかな。でも、テンプレートって
何かに特化した実装って滅多にしないから、実装の長いメンバ関数って少な
いのよね。結局は定義も中に書いちゃうことが多いかも。次回は typedef 。
じゃね。


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[KCM]
「どうしよう火美ちゃん……」
『どしたの？』
「変な小包が来たんだけど」
『こ、こづつみ？』
「それがね、送り主も僕の名前と住所なんだよ！　爆弾かなんかじゃ」
『爆弾ってなによ！』
「！？？」
『体がないんだから、水希ちゃんの借りるしかないじゃない……』
「って、じゃあ火美ちゃんが送ったの？」
『いいから開けてみ？』
「うん……あ、チョコだ……」
_______________________________________________________________[KCM]


/*                       #pragma twice                            */
http://www.kab-studio.com/Programing/PragmaTwice/

　Version 5.30
ファイルダイアログを使おう！

『コントロール編も終わったし、次はなに？』
「まず今回はファイルダイアログっていうの。復習も兼ねて……」

void CFileTestDlg::OnBtnShow() 
{
    m_cDataLstBox.ResetContent();

    std::ifstream cIFStrm;
    cIFStrm.open( "Data.txt" );
    if( cIFStrm.fail() )
    {
        MessageError( IDS_E_NOFILE );
        return;
    }

    int i;
    CString cDestStr;
    while( 1 )
    {
        cIFStrm
            >> i;
        if( cIFStrm.eof() )
        {
            break;
        }

        if( cIFStrm.fail() )
        {
            MessageError( IDS_E_NONINT );
            return;
        }
        cDestStr.Format( "%d", i );
        m_cDataLstBox.AddString( cDestStr );
    }
}

bool CFileTestDlg::MessageError(unsigned int p_puiID)
{
    const unsigned int iIDOffset = 1000;
    CString cStr;
    cStr.LoadString( p_puiID );
    CString cStrCap;
    cStrCap.LoadString( p_puiID + iIDOffset );
    MessageBox
        ( cStr, cStrCap
        , MB_OK | MB_ICONEXCLAMATION );
    return true;
}

『表示ボタンを押したときのメンバ関数と、エラー表示用のメンバ関数だね』
「この中でファイル名を "Data.txt" って書き込んでるでしょ。でもホント
は使う側が自由に変えられるようにするから」
『それを選ぶんでファイルダイアログなんだ！』
「そう、【参照】ボタンを押したらファイルダイアログが出て、それで選ん
だファイルが【ファイル】コンボボックスに書き込まれるようにします」
『……聞いてるだけだとなんか難しそうなんだけど』
「簡単簡単！　まずは【参照】ボタンのハンドラ関数作って」
『メンバ関数のことだよね。右クリックで……』
「詳しくは Ver 4.01 （ No.051 ）を参照にね」
『そんなの見なくてもできるもん。 CFileTestDlg::OnBtnBrowse() ができ
たよ』
「ファイルダイアログは MFC だと CFileDialog を使えば表示できます。と
りあえず使ってみましょう」

void CFileTestDlg::OnBtnBrowse() 
{
    CFileDialog cFileDlg( TRUE );
    int iRes
        = cFileDlg.DoModal();
    if( iRes == IDCANCEL )
    {
        return;
    }

    CString cPathStr = cFileDlg.GetPathName();
    TRACE( "%s\n", cPathStr );
}

『んじゃビルドして実行……おおっ、ファイルダイアログが出た！　ホント
に簡単ねー』
「とりあえず何かファイル選んでみて【開く】押してみて」
『ほい。あ、そのファイルのが出た』

C:\WINDOWS\1stboot.bmp

『おお！』
「じゃ、１行ずつ見ていこうか。まずは CFileDialog 型の変数を作ります」
『コンストラクタっていう関数呼んで、 TRUE 渡してるんだよね』
「この TRUE は【開く】ダイアログにするフラグ。これを FALSE にすると」
『ダイアログのタイトルが【名前を付けて保存】になった！　つまり、開く
ダイアログも保存ダイアログも同じってこと？』
「そゆこと。これが TRUE か FALSE かってことだけで決まるから」
『簡単って言えば簡単ね。次の DoModal() ってどっかで見たことあるね』
「 DoModal() はダイアログを実際に表示させるメンバ関数。 FileTest.cpp
で〈てすと〉ダイアログを表示するとこでも呼んでるよ」

    int nResponse = dlg.DoModal();
    if (nResponse == IDOK)
    {
        // TODO: ダイアログが <OK> で消された時のコードを
        //       記述してください。
    }
    else if (nResponse == IDCANCEL)
    {
        // TODO: ダイアログが <キャンセル> で消された時のコードを
        //       記述してください。
    }

『そうそうそう！　これ呼ばないとダイアログ出ないんだよね。で、その戻
り値で【OK】ボタンか【キャンセル】ボタンかって分かるんだよね。あ、
ファイルダイアログの方も同じことしてるんだ！』
「そう、 DoModal() の戻り値が IDOK なら【開く】ボタンが、 IDCANCEL
なら【キャンセル】ボタンが押されたってこと」
『ファイルダイアログの方は IDCANCEL だとすぐ終わらせるってふうにして
るんだね。〈てすと〉ダイアログのと、っつーか MFC のとスタイル違う』
「僕はこっちの方が見やすいと思うんだよね。 IDCANCEL の場合には特にす
ることないからとっとと return させて、 IDOK の方が大事だからそっちを
普通に書くってスタイル」
『あんま変わらないと思うけど……』
「これは if が１重だからね。何度も何度もチェックするようになると、ネ
ストがどんどん深くなって」
『タブが増えて右の方に来ちゃうね。それは見にくそう』
「ま、今回くらいならそんなに変わらないけどね」
『で、 IDCANCEL じゃないなら CFileDialog::GetPathName() を呼んで……
これはファイル名返すメンバ関数なんだね』
「ドライブからファイル名まで全部ね。こういうのを〈フルパス〉って言い
ます」
『ふるぱす？』
「さっきの例だと 1stboot.bmp はファイル名、 C:\WINDOWS\1stboot.bmp が
フルパス。フルパスはドライブも含めてのだから、ばっちりどこのどのファ
イルか言えるからね」
『そっか、 1stboot.bmp だけだと、同じ名前のファイルがいろんなフォル
ダにあったらどれか分かんなくなっちゃうんだもんね』
「そゆこと。そのフルパスを CString で受け取って、 TRACE() で表示」
『うん、実際に簡単ねー』
「じゃ、もちっと凝ってみようか。開いたフォルダってどこだった？」
『なんか自動的にマイドキュメントになってたけど』
「それを指定しましょう」

void CFileTestDlg::OnBtnBrowse() 
{
    CFileDialog cFileDlg( TRUE );
    cFileDlg.m_ofn.lpstrInitialDir = "C:\\Windows\\";
// あとは同じ。

『うわ簡単！　m_ofn ってメンバ変数の……』
「の、 lpstrInitialDir ってメンバ変数に〈最初に表示するフォルダのパ
スを示す文字列ポインタ〉を格納すればいいってこと」
『こういうメンバ変数のメンバ変数ってなんか苦手……』
「左から順々に見ていけば大丈夫だよ。で、この m_ofn っていうのが鍵」
『リファレンス見ると OPENFILENAME っていうのなんだね』
「そう。いつものことなんだけど、ファイルダイアログの表示にはホントは
API を使います」
『それを MFC が便利に使いやすくしてるって例のパターンね』
「そ、【開く】ダイアログは GetOpenFileName() 、【保存】ダイアログは
GetSaveFileName() を呼び出します」
『 CFileDialog と違って別々なんだ』
「で、これを呼び出すときに、いろんな設定を渡すのが OPENFILENAME 」
『なんかすんごくメンバ変数多いんですけど……』
「これ、省略できないからほとんど全部設定しないと渡せないしね」
『げげ』
「で、その中の lpstrInitialDir っていうので開くフォルダを指定します」
『ようするに CFileDialog もこれと同じ仕組み持ってるからこれを使えば
色々できるってことね』
「そゆこと。最初の例みたく簡単に使うこともできるし、こういうふうに
ちょっと拡張させることもできるし」
『いつもみたく、この API 使ってみせたりしないの？』
「これまでしつこく言ってきたのは、 MFC が API をただ呼び出してるだけ
ってことを憶えて欲しかったから」
『それが分かっちゃえばいいの？』
「とりあえずね。もう少ししたら、こういう API 呼ぶのに難しい部分を教
えたりするから。さて、実際にこの最初のフォルダってどこにすればいいと
思う？」
『前回開いたフォルダ！』
「うん、そう。でもそれは〈レジストリ〉っていうのを使ってその〈前回開
いたフォルダ〉を保存しなきゃいけないから」
『知ってる！　WriteProfileInt() とか使うんだよね』
「 Ver 3.19 ( No.044 ) でやったね。そのレジストリへの書き込みはもう
ちょっとあと」
『じゃーどのフォルダ開けばいいのかな……とりあえずそのアプリとか？』
「じゃ、それしてみましょう」

void CFileTestDlg::OnBtnBrowse() 
{
    CFileDialog cFileDlg( TRUE );
    char chPath[MAX_PATH];
    GetModuleFileName
        ( AfxGetInstanceHandle(), chPath, MAX_PATH - 1 );
    cFileDlg.m_ofn.lpstrInitialDir = chPath;
// あとはそのまま。

『えっと、まず文字配列作ってるね。 MAX_PATH ってなに？』
「 API で定義されてる定数値。実は、ファイルのフルパスって、この 
MAX_PATH よりも大きい文字列って使えないんです」
『ってことは、そんだけ深いフォルダとか、長いファイル名とかは』
「ダメってこと。なんで、この MAX_PATH で文字配列作るとファイルのフル
パスは絶対入るっていう」
『それは安心。次の GetModuleFileName() は API だね』
「これは今実行されてるアプリのフルパスを取得する関数」
『あ、そうすると FileTest.exe のフルパスが分かるんだ』
「それが第２引数に渡されるから、それを lpstrInitialDir に渡せばＯＫ」
『なるほどねん』
「あ、でも〈初めて開くフォルダ〉はアプリのとこにしない方がいいかも」
『じゃあどこ？』
「マイドキュメント」
『なにぃ！？』

/*
    Preview Next Story!
*/
『まいどきゅめんとぉ！？　あたしあのフォルダ嫌いなんだけど』
「でもプログラミング初心者がアプリのフォルダ見て理解できると思う？」
『う”』
「マイドキュメントなら保存するときファイルが散らばらなくて済むし」
『というわけで次回』
＜ Version 5.31 コンボボックスとエディットボックス ＞
「につづく！」
『うがーっ初心者ってムカツク！！』
「僕も本当は嫌だけど、フォルダ作ったことない人は山ほどいるんだから」


/*              ２００１年２月２６日（月）の更新予定              */
http://www.kab-studio.com/

・Codian にページを追加
　 Codian にページを追加します。今回は STL & iostream 入門から 
iostream の #21 - #24 を追加。
[ Codian ]
http://www.kab-studio.com/Programing/Codian/


/*                          ご注意！！                            */

・このメールを返信しないでください。
・ご意見・ご希望・ご感想は[チョー普通な日記]よりお送りください。
http://www.kab-studio.com/nikki2/
・プログラミングに関する質問は[鏑矢の憂鬱]にお送りください。
http://www.kab-studio.com/Programing/KabuU/
・購読登録を解除したいときにはこのページで行なってください。
＊http://www.mag2.com/m/0000012198.htm
＊http://www.pubzine.com/detail.asp?id=000590
・解除は自分で行なってください。
・バックナンバーはこれらのページにあります。
http://backno.mag2.com/reader/Back?id=0000012198
http://www.kab-studio.com/Freeware/

/*
    KAB-studio.h
    Weekly Mail Magazine.
    Written by Kaburaya Seiden.

    (C)KAB-studio 1999 - 2001 ALL RIGHTS RESERVED.
        http://www.kab-studio.com/
        info@kab-studio.com
*/


/*                      See you next week!!                      */


