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

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

    送信日： 2000/11/06(Mon) No.081
    配信数： 3870（ Mag2 + Pubzine ）
＊    発行元： まぐまぐ( URL: http://www.mag2.com/  ID: 0000012198 )
＊    発行元： Pubzine( URL: http://www.pubzine.com/  ID: 590 )
*/

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

・表紙を１１月バージョンに！
　毎月恒例、新しい表紙です。
　今月はまーまーの出来かな。ってゆーかもっとペース上げないとダメね。
詳しい解説はチョー普通な日記１１月２日をご覧ください。ちなみに今回は
壁紙バージョンはナシ。

・ Codian - STL に追加！
　Codian の STL にページを追加します！
　今回は「 STL & iostream 入門」の中から STL の #06 - #09 を追加。関
数オブジェクトの導入部を図入りで解説します。「自分でクラス作るのって
大変そう」というあなたもこれで安心！
[Codian]
http://www.kab-studio.com/Programing/Codian/


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

2000/10/29 (Sun)
　謎のストラップ届く。突発シリーズ・アンケートの結果発表！　っつーか
メルマガに載るのタイミング悪過ぎ（汗）。積極的に参加しましょう！

2000/10/30 (Mon)
　パスネット大実験大会！　こーゆー意識が科学を育てる（爆）。あとゼミ
の掃除したりとか。

2000/10/31 (Tue)
　サイファイハリー、面白いっす。「こんなんアニメやなくてもえーやん」
とか思ってたんだけど、この演出はアニメでないと無理かもしんない。魅せ
るとこ魅せるしためるとこためるし。

2000/11/01 (Wed)
　Codian 書いて表紙描いて就職前研修やって。なんか忙しいねぇ。これか
ら就職前研修があるからさらに忙しくなるし。

2000/11/02 (Thu)
　１１月表紙完成！　細かい解説描いてるんで「この CG えーわー参考にし
たいわぁ」とゆー方は読んでねん。それにしてもドリキャス欲しい……。

2000/11/03 (Fri)
　所沢古本まつりに行って参りました。いやなんつーか、やっぱこーゆーと
こで探すのは「お」なアイテムなんだが、いかにもな人達の中に紛れると自
分もその１人なんだなーとか実感したりなんかして。

2000/11/04 (Sat)
　なんか疲れてしまったのですよ。疲れる人っているのねぇ。そして古本ま
つりでニアミス。でも現在怖い人な顔なんで声掛けられる可能性低い（爆）。


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

2000/10/29 (Sun)
お知らせ
Codian の iostream #06 はミス訂正版
お便り
CListCtrl でドラッグで選択できるようにする方法は？
デフォルトでできると思う
何かが邪魔しているのかも

2000/10/30 (Mon)
お便り
シリアルポートからデバイスの操作
GetCommState() などを使用
サンプルコードへのリンク

2000/10/31 (Tue)
プログラミング辞書
米マイクロソフトからの Platform SDK ダウンロード方法

2000/11/01 (Wed)
STL & iostream 入門から STL の #06 - #09 を Codian 化
就職前研修で情報処理２種レベルの勉強
思いの外ためになる
プログラムのスキルを身に着けるのは比較的簡単
文章書く技術は必要かも

2000/11/02 (Thu)
リストビューのソート
スタイルを使って自動的に
ラベルでしかソートされない
LVM_SORTITEMS か CListCtrl::SortItems() を使う
サンプルコード
コールバック関数の作成
渡されるのが「おまけ」なのでひと工夫
「おまけ」をインデックスナンバーに書き換え
全部配列等に入れてからソートする方法も

2000/11/03 (Fri)
お便り
「外部シンボル」リンクエラー
関数本体が見つからない
ライブラリファイルを設定しているか
VC のバージョンが古いのかも

2000/11/04 (Sat)
お休み


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

・追加単語：
ホットトラッキング クラスライブラリ #ifdef 参照カウント スワップ 
スワップファイル 仮想メモリ 共有メモリ スタンドアローン バイトコード
タグ 修飾子 IntelliSense OS WNDPROC 

・今週の状況：
　再び goo のデータベースに復活した関係で、これから爆発的に単語数が
増えそうな予感。しかーし、わてはこれから就職前研修とかでかなり忙しい
ことになりそう……というわけで、もしかしたら辞書の単語登録を少しの間
休止するかもしんない。そしたらゴメン。


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

テンプレート
#01 関数テンプレート

　テンプレート。私が初めて使ったのは、 MFC の CArray だったと思いま
す。その頃は「謎の機能」だったのが、 STL を使い始めたことで必須のア
イテムになりました。未だに私が C++ オンリーなのは、テンプレートがあ
るからと言っても過言ではないと思います。今回からは、そのテンプレート
について紹介していきます。
　まず、テンプレートには「関数テンプレート」と「クラステンプレート」
があります。最初は、簡単な「関数テンプレート」について見ていきましょ
う。
　関数テンプレートの例を見てみましょう。

template< class type_numeral >
type_numeral Increment( type_numeral p_num )
{
    ++p_num;
    return p_num;
}

　普通の関数に見慣れた方にとっては、かなり分かりにくいかもね。関数の
前に template って付いてるのが、関数テンプレートの証。この関数テンプ
レートは、次のように使います。

void Use_Increment_int()
{
    printf( "%d\n", Increment( 100 ) );
    // 101
}

　つまり、この関数テンプレートは「整数値をインクリメントして、戻り値
として返す」という機能を持っています。
　でもこれだけだと、ただの関数になってしまいます。関数テンプレートの
すごいところは、他の型としても使えるという点です。たとえば実数とか。

void Use_Increment_double()
{
    printf( "%f\n", Increment( 10.5 ) );
    // 11.500000
}

　と、実数でもこの関数は使うことができ、ちゃんとインクリメントできて
います。この点から分かるとおり、テンプレートの機能は「様々な型を使用
できる」というものです。来週はこの仕組みについて。じゃね。


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[KCM]
『あったらしー、表紙！』
「なんで秋なのに半袖なの？」
『じゃなくてー、あー、もう秋なんだ、って感じ』
「それで焼き芋連想しちゃうわけだね」
『うっさいねー、あ！』
「な、なに？」
『自分が表紙になんないからってひがんでるんでしょー』
「ってゆーか先輩が……」
『あの人ぷらとわにも出てこないよね……』
　金菜さんを表紙で見たい方は日記でリクエストしてねー。
http://www.kab-studio.com/
_______________________________________________________________[KCM]


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

　Version 5.16 
API で読み取る！

『現在 API でファイルアクセス中！』
「前回はファイルを開きました。今回は読み込んでみます。が、その前に」

    char chAllLine[1024];
    if( 1024 < GetFileSize( hFile, NULL ) )
    {
        TRACE( "ファイルが大きすぎます！\n" );
        CloseHandle( hFile );
        return;
    }

『 GetFileSize() で F1 っと、あ、ファイルサイズを調べるのなんだ』
「今回は〈一度にファイル全体を読み込む〉ってことをするんだけど、読み
込むためのサイズを１０２４バイトって限定してるから」
『 1024 って数字は例によって適当よね。あ、ってことは chAllLine って
変数に読み込むんだ』
「これを 1024 文字の配列にしてるから、ファイルサイズがそれ以上大きい
と入りきらないからね」
『……』
「 char ひとつが１バイトだから」
『あー』
「それよりも、メモリ想像した方がいいかも」
『メモリを？』
「そう、 char ひとつ１バイト、１バイトひとつ１マス、それが１０２４個
メモリに並んでる、ってね」
『そういうのやったねー。そっか、配列って考えない方がいいんだね』
「配列よりも、１０２４バイトの領域確保、ってことで」
『ファイルも、メモリと同じ感じになってるの？』
「そうだよ、コンピューターの世界のものはすべてオンとオフでできてるか
らね。このオンとオフが？」
『１ビット！　それが８つ並んで１バイト』
「だからメモリもファイルも同じって考えていいかも」
『で、戻り値にファイルサイズが返ってくるからそれが１０２４より大きい
かどうかチェックね。そういえば、第２引数は？　型が LPDWORD ってへん
てこだけど』
「戻り値の型が DWORD でしょ」
『あ、ホントだ』
「まず DWORD について。これは API が作った型。前に〈 API の型はこの
ファイルで定義されてる〉って言ったよね」
『 Wtypes.h ！　Ver 5.08 ( No.073 ) でやったね』
「そのときは LPCTSTR が typedef されてるっていうのを見たんだよね。今
回の DWORD もこのファイルにあるから」
『あった！』

typedef unsigned long DWORD;

『えーっと、 unsigned だから符号ナシ、 long は４バイト整数』
「つまり４バイト符号ナシ整数値としてファイルサイズが返ってくるってこ
とだね」
『サイズだからマイナスないんだもんね』
「で、同じく LPDWORD もあるから」

typedef DWORD __RPC_FAR *LPDWORD;

『あ、 LPCTSTR のときのと同じのだ』
「同じように、 __RPC_FAR は空白に置き換えられるから、つまり」
『よーするに DWORD のポインタね』
「そゆこと。ま、 LP が頭に付いてたらポインタだから」
『……で、ポインタなのは分かったけど、なんでそれを引数に渡すの？』
「そういうのがポインタの使い道にあったでしょ。変数のアドレスを渡す、
関数側はそのアドレスを使って変数にアクセスできる」
『そのアドレスで値を格納できる！　戻り値の他に値を返す方法！』
「ファイルサイズがものすごーく大きいときに、戻り値だけじゃその大きさ
を表せないから、そのためにもうひとつ値を返す部分を用意してるわけ」
『それが MSDN のリファレンスに書いてある〈上位ダブルワード〉とか
〈下位ダブルワード〉のこと？』
「そういうこと。ワードは２バイトサイズだから、ダブルワードで４バイト。
ファイルサイズが大きい場合、桁の小さい方の４バイトを戻り値で、大きい
方を第２引数から返す仕組みになってるってこと」
『なんで〈ワード〉は２バイトなの？』
「昔は２バイトが１番一般的だから〈単語〉サイズだったのかも。ちなみに」

typedef unsigned short WORD;

「って定義されてるから」
『あ、 WORD 型だ……』
「ちなみにリファレンスに書いてあるとおり、ホントは戻り値が 0XFFFFFFFF
かどうかのチェックもした方がいいかも」
『えっと、必要ないなら第２引数 NULL 渡していいけど、それで戻り値に入
りきらなかったりすると 0XFFFFFFFF が返ってきちゃうんだ』
「ま、 unsigned だから if に失敗することはないんだけどね」
『戻り値に入りきらないサイズって？』
「符号ナシ４バイトの最大値は？」
『 4294967295 だから……あ、これが４ギガなんだ。でかっ』
「そんなファイル滅多にないってことでここでは処理してるけど、仕事用な
らちゃんとエラーチェックした方がいいかも」
『はーい。で、ここでは chAllLine が１０２４バイトだからそれ以上なら
関数終了ね。あ、 CloseHandle() って fclose() みたいなの？』
「そう、 CreateFile() で開いたファイルは CloseHandle() で閉じなきゃ
ダメ」
『 fopen() と fclose() と同じってことね』
「というわけでファイルサイズの確認をしたら、次にファイル全体を読み込
んでしまいます」

    DWORD dwReadedSize;
    BOOL bRes
        = ReadFile
            ( hFile, chAllLine, 1023
            , &dwReadedSize, NULL );
    if( bRes == 0 && dwReadedSize == 0 )
    {
        TRACE( "ファイルから読みとれませんでした。\n" );
        CloseHandle( hFile );
        return;
    }

『またひとつの API 呼ぶのに４行も書いてる……』
「コーディングスタイルはいいから、リファレンスと見比べてみて」
『えっと、第１引数はお約束のファイルハンドル、第２引数は、さっきの
１０２４バイトサイズの配列、これにデータ受け取るんだね』
「この API で一気にファイル全体を読み込んじゃうから、その前にチェッ
クする必要があったから」
『第３引数の 1023 は限界サイズ。これがあるんならさっきサイズのチェッ
クする必要なかったんじゃない？』
「リファレンスにはその辺詳しく書いてないから、念のためってことで」
『ふーん。第４引数は……アドレス渡してるね』
「これはさっき言ったのとほとんど同じ。型が LPDOWRD でしょ」
『ホントだ。リファレンスには〈実際に読み込んだサイズ〉って書いてある
ね』
「これを後で使うから。ま、 GetFileSize() の戻り値を使ってもいいんだ
けどね」
『ふと思ったんだけど、この部分とか、第３引数のサイズとかって４ギガま
でしか指定できないじゃん、そしたらさっきのおっきなファイルの場合には
どうすればいいの？』
「ポインタのサイズは？」
『４バイト』
「ってことは、確保できるメモリの領域も４バイトってこと」
『……ってことは、そのでっかいファイルの時って、メモリに全部コピーで
きないってこと！？』
「そうなるね。そういう場合には、ファイルから少しずつ取り出して処理し
てくことになるかな」
『はー、めんどそー』
「確かに面倒だけど、そのくらい大きなファイルを操作するってことはかな
りの仕事だから、ミスがないようにプログラムしないとね」
『なんかすごい……』
「最後の引数は、特別な形式でファイルを開いたときだけのものだから 
NULL 」
『戻り値と、さっきの〈読み込んだサイズ〉をチェックするのね』
「成功してればどっちも０以外が返ってくるからね。成功してれば chAllLine
にファイル全体がまるごとそのままコピーされることになります」
『ファイルが失敗したら CloseHandle() ……って、さっきのだ』
「面倒な話なんだけど、こういう風にエラー処理が頻繁に出てくる時には、
後始末用の処理をその都度呼ばなきゃいけないんだよね」
『げ、ホントだ、あと２回も出てきてる！』
「これはランタイムの fclose() を使う時も同じ」
『ってことは、それ以外の場合はいいってこと？』
「そう、 iostream や MFC の場合には〈クラス〉使ってたでしょ」
『 std::ifstream と CStdioFile ね』
「クラスには〈後始末が必要なときに自動的に関数を呼び出すシステム〉が
備わってて、それを利用してファイルを閉じてるから」
『だからその都度後処理をしなくていいんだ』
「だけど関数のランタイムや API はそういうことできないから、いちいち
こういうふうにしなきゃいけないんだよね」
『んー、でもなんとかする方法とかないの？』
「あることはあるよ。たとえば関数にまとめるとか」
『どゆこと？』
「 CreateFile() のあとの処理を関数に入れる方法。で、関数から抜けたと
きに CloseHandle() するようにする」
『？』
「エラー処理はただ return するようにすれば、いつ return しても関数か
ら抜けたときに閉じられるようになるでしょ」
『そっか、どのエラーも return 呼ぶんだもんね』
「そう、鍵はそこ。うまく後処理をする部分へジャンプすればいいわけ」
『クラスの〈後処理機能〉も、そんな感じだもんね』
「で、ジャンプするための最後の手段が、 goto 」
『ごーつー？』
「そう。たとえば、とある行に」

LABEL__CLOSE:

「って書いておきます。で、エラー処理の時に」

    goto LABEL__CLOSE;

「ってすると、上の LABEL__CLOSE まで一気に飛ぶことができます」
『へー、そんな便利な物があるんだ』
「でもこれ、使っちゃダメ」
『ええ！？』
「 goto は for とかの流れをぐちゃぐちゃにしちゃうから、できる限り使
わないように」
『ならなんで教えるのよ〜』
「他の人のプログラム読むときに困るでしょ」
『まーそりゃそうだけど』
「とりあえず今のうちは、その都度エラー処理した方がいいかもね」

/*
    Preview Next Story!
*/
『 API 長くて複雑ねー』
「あ、でも次回は API じゃないよ？」
『あらそなの』
「でもそのあとさらに複雑になるけど」
『イヤーっ！！』
「というわけで次回」
＜ Version 5.17 iostream で文字列操作！ ＞
『につづく！』
「というわけで std::strstream が登場します」
『あらまた STL & iostream 入門の登場ねー』


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

・ Codian - iostream に追加！
　Codian の iostream にページを追加します！
　今回は「 STL & iostream 入門」の中から iostream の #07 - #10 を追
加。今回ももちろん図入りです！


/*                          ご注意！！                            */

・このメールを返信しないでください。
・ご意見・ご希望・ご感想は[チョー普通な日記]よりお送りください。
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://bigbeat.tegami.com/~mgsearch/frame.cgi?id=0000012198
http://www.kab-studio.com/Freeware/

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

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


/*                      See you next week!!                      */


