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

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

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


/*              ２０００年２月２１日（月）の更新                  */
http://www2.justnet.ne.jp/~kabstudio/Info/News/

・更新なし。
　基本的にナシ。引越前でごたごたしてるからねぇ。もうちょっと待って
ねー。ちなみに引越は３月６日を予定してます。


/*                        チョー普通な日記                        */
http://www2.justnet.ne.jp/~kabstudio/nikki2/

２０００年２月１３日（日）：
　テスト勉強、そして新番組タイムレンジャー。ってなことを堂々とメール
マガジンに書いてる私は２５歳。

２０００年２月１４日（月）：
　確率統計のテスト。まーまーできた。そして明日もテスト。でも勉強して
ない。謎だ。

２０００年２月１５日（火）：
　ちょっとテストやばいかもー、そしてテスト終了！　さらにガチャックの
謎へ。そういえば ATOK は商標登録されてる単語はチェックしてくれるはず
なんだけど、これは引っかからないなぁ。

２０００年２月１６日（水）：
　プログラミングとかレポート書きとか CD-R ドライブとか iBook 黒とか。

２０００年２月１７日（木）：
　アクセスログの結果から、この日記がかなり人気あることが判明！！　謎
だ。そして、全国の文章書きさんに忠告。「以外」と「意外」に気を付けよ
う。

２０００年２月１８日（金）：
　新宿へ行って CD-R ドライブを……買わなかった（爆）。今思えば正解。
さらにエキスパンダー買ったり。わての小市民ぶりを赤裸々に告白。あと
「以外」と「意外」ネタ。

２０００年２月１９日（土）：
　格闘技とかアニメとかアクセスログとかハードディスクとかといつも通り
とりとめのない話。


/*                         鏑矢の憂鬱                             */
http://www2.justnet.ne.jp/~kabstudio/Programing/KabuU/

２０００年２月１３日（日）：
お休み

２０００年２月１４日（月）：
謝罪
#pragma twice でのレジストリの解説について
「Windows\Profiles\ログオン名」にも user.dat が置かれる
NTUser.dat なんてものもあり
Perl 着手
コンソールにいいのがない
お便り
フックでコンパイルエラー
フックプロシージャが static メンバ関数になってるかどうか
お便り
44100Hz のサンプリングレートについて
D/A 変換のノイズの関係から余裕を持たせている

２０００年２月１５日（火）：
リンクログ作成
Cygwish は２バイト文字を表示できなかった
お便り
関数シグネィチャーの throw() の意味は？
例外指定（ exception-specification ）
サンプルコード
呼び出す側に「何を投げるか」を知らせるため
「例外指定の連鎖」が大変
Visual C++ 6.0 では実装されていない
お便り
半角文字と全角文字の相互変換は？
標準ライブラリには入ってない
他の人が作ったのを使わせてもらうのが楽

２０００年２月１６日（水）：
Perl で CGI
ディレクトリパーミッションのポカミス
お便り
スマートポインタの作り方
デストラクタは virtual でないとダメ
std::auto_ptr を使った方が楽
サンプルコードへのリンク

２０００年２月１７日（木）：
Perl で CGI
アクセスログの設置
ヒアドキュメントがうまくいかなかった
日付処理の超初歩的なミス……
お便り
ダイアログボックスに線を引く方法は？
「ピクチャーコントロール」を貼り付ける
更新時間について
お便り
KTL::GlobalInstance() の使い道は？
「グローバル変数の代わり」に使う
グローバル変数を作りたくないから
Effective C++ という本に載っていた関数
ぜひ買いましょう

２０００年２月１８日（金）：
Perl プログラミング
手元にあるドキュメント
今の目的はテキスト処理が中心
Perl は面白いし C に似てる気がする
たいがいの文が通るのが怖い、でも面白い

２０００年２月１９日（土）：
C マガジンの C 言語テストをする
結構間違えたけど大丈夫
間違えたのは使っちゃいけないものについて
でも笑えないミスもいくつか
満点取れなくちゃいけなかったかも
２号前のかなゆ〜についてのごめんなさい


/*                       今週の追加単語                           */
http://www2.justnet.ne.jp/~kabstudio/Programing/Dictionary/

・追加単語：
マッピング カレット サンク this アサーション ウィンドウズオブジェクト
リソース 機械語 アセンブラ ニーモニック IIS signed unsigned

・今週のごめんなさい
スレッド winaspi32 WaitforSingleObject SendMessage 時間

　今回は「サンク」とか「ニーモニック」とか英語的に面白いのがありまし
た。難しい用語を憶えるにはまず英語の意味を知ることから、がうちのモッ
トーなんで、なるたけ「英単語の意味」も付け加えるようにしています。
そーゆーとこも評価してねん（爆）。
　ではお知らせを挟んでぷらとわをどうぞー。

---------------------------------------------[かぶスタＣＭ]---------
　噂のメールマガジン、登場間近。


　……間に合うかなぁ。
---------------------------------------------[かぶスタＣＭでした]---

/*                       #pragma twice                            */
http://www2.justnet.ne.jp/~kabstudio/Programing/PragmaTwice/

　Version 3.20
CString とストリングテーブル


「さて、前回はレジストリについて見てみました」
『レジストリにー、数字いれてー、取り出したんだよねー』
「その辺を書き出すと……」

// CCalcApp::InitInstance() の中。
    SetRegistryKey( "KamichanFactory" );
    dlg.m_iAns = GetProfileInt( "CalcDialog", "Ans", 0 );
    int nResponse = dlg.DoModal();
    if (nResponse == IDOK)
    {
        WriteProfileInt( "CalcDialog", "Ans", dlg.m_iAns );
    }

「となります」
『あれ、質問！　SetRegistryKey() って WriteProfileInt() の前にもあっ
たと思うんだけど』
「 CWinApp::SetRegistryKey() でセットしたキーはちゃんと保存されてる
から、 CWinApp::WriteProfileInt() を呼んだときもちゃんと効いてるんで
す」
『つまり、最初に一度だけ呼んじゃえばいいってことね』
「そゆこと」
『もひとつ、 TODO のコメントのとこって消しちゃっていいの？』
「いいんじゃないかな。あのコメントの意味は分かるでしょ？」
『うん、 OK ボタンを押したら、戻り値がどーたらこーたらして、この中
カッコの中に入るってことだもんね、まー分かっちゃえばなくてもいっか』
「それじゃあ、今日の本題。もしうっかり」

        WriteProfileInt( "CalcDialog", "Ams", dlg.m_iAns );

「なんてなったらどうしましょう」
『……どっか違うの？』
「 "Ams" になってるでしょ！」
『あ、ホントだ』
「こういうミスは、プログラムが大きくなればなるほど多くなるし、見つけ
るのも大変」
『というわけで？』
「今回は、このまえ見た〈ストリングテーブル〉の使い方について見てみま
しょう」
『あ、あれを使うんだ！』
「まずは CWinApp::SetRegistryKey() のから。リソースビューからストリ
ングテーブルを開いて」
『はーい。ワークスペースの ResourceView の String Table をダブルクリ
ック！　はい開いたよー、あ、前の〈バージョン情報じゃ！〉のままだ』
「直しておいた方がいいかも……。で、 IDS_ABOUTBOX の下に点線で囲んで
るのがあるでしょ。それを」
『ダブルクリック！　あ、プロパティ出た』
「まず【 ID 】から。今回は IDS_REG_COMPANY にしましょう」
『その意味は？』
「 ID で String で Registry で会社名だから」
『まんまねー』
「だからこーゆーのはまんまの方がいいんだって」
『そっか。で、キャプションは？』
「【キャプション】は KamichanFactory だってば」
『 SetRegistryKey() に渡すのなんだもんね』
「そういうこと。そしたらプログラムに戻って」
『えーっ！！』
「なんやねその非難ごーごーは」
『言ってみただけ。やっぱ SetRegistryKey() まわり書き換えるの？』
「そういうこと。 SetRegistryKey() の行と、その前２行を……」

    CString cCompanyStr;
    cCompanyStr.LoadString( IDS_REG_COMPANY );
    SetRegistryKey( cCompanyStr );

「って感じに書き換えて」
『……やっぱむずかしーね』
「だから〈えーっ！！〉？」
『分かる人にはこの苦労分かんないわよっ！』
「……〈君は労せず理解できたんだよね〉って思われるのはやだな」
『うっ』
「はっきり言うよ。火美ちゃんは僕の１００分の１の労力でマスターできる
はず！」
『ってそれ自慢してない？』
「かもね。じゃ、プログラム見ていきましょう。１行目は？」
『んー、 CString って前に見たよね、確か文字とか使うためのクラス』
「そうそう。頭文字が C でしょ、これは MFC のクラスのあかし」
『あ、 CDialog とか CWinApp とかもそうだもんね』
「 CString も MFC のクラスのひとつ、文字列を操作するためのクラス。１
行目はこの CString 型の変数を作ってます」
『変数を作る、っていうのがクラスには必ず必要なんだね』
「そういうこと。クラスは鋳型、変数は実物。文字列を格納するためには、
変数として作らなきゃいけないわけ」
『それが cCompanyStr なんだ。で、２行目は、 CString::LoadString() っ
てメンバ関数を使ってるんだよね。レッツＭＳＤＮ！』
　LoadString をダブルクリックし F1 キーを押す。【該当するトピック】
ダイアログが表示される。
『あ、 API にも LoadString() ってあるんだ』
「ストリングテーブルはウィンドウズのものだから、 MFC 使わなくてもも
ちろん操作できるわけ。でも」
『 CString 使った方が楽ってことねー。んじゃ CString::LoadString() を
ダブルクリック』
　ＭＳＤＮの CString::LoadString() のページが開く。
『なんか簡素。あ、使用例がある！　でもなんか複雑？』
「エラー処理はあとに回して、引数は？」
『えーっと、文字列リソースの ID だって。文字列リソースってストリング
テーブルのこと？』
「そう。ってことは？」
『 ID ってことはさっきの……あ、だから IDS_REG_COMPANY なんだ』
「【解説】に書いてあるとおり、この ID で指定した文字列をさっき作った
cCompanyStr の中に書き込みます」
『ここに書いてある〈オブジェクト〉って？』
「これは〈変数〉って読み替えていいかな。ホントはもっと広い意味なんだ
けど」
『広いって？』
「たとえば、ウィンドウズ上のウィンドウとかも〈オブジェクト〉のひとつ」
『ウィンドウってことは HWND の変数のこと？』
「ううん、ウィンドウズの中に、ウィンドウの情報が入ってるの。それがオ
ブジェクト。 HWND はそのオブジェクトを操作するためのものってことだね」
『なんかむつかしいかも……』
「確かにね。ま、今のところは変数ってことで」
『はーい。で、 cCompanyStr に IDS_REG_COMPANY にあたる文字列が入るか
ら、それを SetRegistryKey() に渡してるってことねー３行目』
「そういうこと。んじゃチェックしてみて」
『はーい。ビルドして実行！　あ、答にさっきの数字が入ってる。ってこと
はちゃんと会社名があってるってことだよね』
「あってるってこと。こういうチェックをちゃんとすることが大切だから」
『はーい。で、他のもするの？』
「もちろん。自分でしてみて」
『う”、難しそう……』
「こういうのは聞くだけじゃなくて、ちゃんと自分で試すことが大事」
『分かってますよーだ。えーっと、まずストリングテーブルを開いて……』
「……と、皆さんには答を見てもらいましょう。まずストリングテーブルは、
こんな感じになります」

IDS_REG_COMPANY    KamichanFactory
IDS_REG_DIALOG     CalcDialog
IDS_REG_ANS        Ans

『そーいえば【値】ってどーでもいーの？』
「どうでもいいの。大事なのは IDS_REG_COMPANY とかの文字列の方だから」
『はーい』
「で、プログラムの方は」

// CCalcApp::InitInstance() の中。
    CString cCompanyStr;
    cCompanyStr.LoadString( IDS_REG_COMPANY );
    CString cDialogStr;
    cDialogStr.LoadString( IDS_REG_DIALOG );
    CString cAnsStr;
    cAnsStr.LoadString( IDS_REG_ANS );

    SetRegistryKey( cCompanyStr );
    dlg.m_iAns = GetProfileInt( cDialogStr, cAnsStr, 0 );
    int nResponse = dlg.DoModal();
    if (nResponse == IDOK)
    {
        WriteProfileInt( cDialogStr, cAnsStr, dlg.m_iAns );
    }

『うん、変数名違っちゃったけど、だいたい同じかな』
「ま、本当はもーっとシンプルにしたいんだけど、今の知識だとこれが限界
かな」
『シンプルって？』
「たとえば、今の状態だと cDialogStr と cAnsStr を逆に渡したりしかね
ないからね」
『そういうのも考えなきゃいけないんだ……。そういえばさ、こうやってす
れば、最初言ってた "Ams" な間違いってなくなるの？』
「もちろん。たとえば cAnsStr を cAmsStr にしたら……」
『あ、ビルドしたらエラーになっちゃった』
「 cAmsStr なんて変数作ってないからね。同じく IDS_REG_ANS を 
IDS_REG_AMS にしても」
『エラー。ストリングテーブルに IDS_REG_AMS なんてないもんね』
「こうすることで、ミスの起きやすさを大幅に減らせた」
『けど限界はある、と』
「そういうこと。それにね、色々問題もあってね」
『どゆこと？』
「火美ちゃんから見て、この新しいプログラムと古い方のと、どっちが分か
りやすい？」
『そりゃ前のでしょ。レジストリのキーにする文をそのまま渡してるんだか
ら』
「そうなんだよね。安全策を採ろうとすると、どうしても【距離が離れる】
ことになるから」
『どゆこと？』
「上の例だと、文字列をストリングテーブルに置いて、 CString を間に挟
んだことで安全性を増したわけ。つまり安全性を上げるためには」
『間に何か入れなきゃいけないってことね。つまりアレみたいなもん？』
「……まあそうだけど……」
『そうなの？』
「つ、つまり、距離を置いたおかげで安全性は増したけど、プログラムとし
ては、 cCompanyStr には IDS_REG_COMPANY が入ってる、 IDS_REG_COMPANY
はストリングテーブルの KamichanFactory って追って見る必要があるわけ」
『じゃーアレとは違うじゃん』
「うー、まあそうだねぇ」
『ようするにさ、プログラムが見にくくなるってこと？』
「そういうことになるかな。直感的じゃなくなるんだね」
『あー、じゃあアレと同じかも』
「と、とにかくっ、こういうデメリットはあるけど、プログラムの安全性を
考えても、ストリングテーブルを使って処理しましょうってことで」
『みんなも使ってねー』

/*
    Preview Next Story!
*/
「……」
『ほらそんな怒んないで。アメあげる』
「アメ？」
『ほら』
「……」
『というわけで次回』
＜ Version 3.21 イベントハンドラ ＞
「につづく！！」
『元気になった？』
「……」


// ごめんなさい！

　先週発行した号の #pragma twice では、レジストリについて取り上げま
した。
　その中で、レジストリファイルの user.dat の置き場所を Windows フォ
ルダと書きましたが、マルチユーザー環境の場合にはこれに加えて
Windows\Profiles\ログオン名
にも置かれます。また、Windows NT の場合には NTUser.dat というファイ
ル名になります。これらの点について書き忘れましたことをお詫び申し上げ
ます。

　……たぶん（汗）。
　実際にはマルチユーザー環境を試したことがなかったり、 NT に触れたこ
とがなかったりするので知りませんでした。実際の所、まだ完全に確認でき
たわけじゃないし。
　「こんな人に教えてもらうのなんてイヤ！」とかともお思いでしょうが、
たぶんこれからももっとこういうミスをすると思うんで、見限るんなら今か
も（爆）。
　……あともうひとつミス。それはこの下で。


/*                       金菜さんの憂鬱                           */
http://www2.justnet.ne.jp/~kabstudio/Programing/KanaU/

アプリのツボ
#08 圧縮解凍 その１

　拡張子が lzh とか zip とかの圧縮ファイル。今回からはこの話。
　「圧縮」っていうのは、元のデータを変形させて、データサイズを小さく
すること。たとえば「A」って文字。この文字は 0x41 っていう数字を、
「 0x41 は アルファベット１番目の文字の大文字とみなす」っていう「変
換」をして、「アルファベット１番目の文字」にあたるフォントを表示して
います。もしこういう変換をしなかったら、「 A 」って文字を表示するた
めに常に「 A 」っていう図形としてのデータを持ってなくちゃいけないこ
とになります。「 A 」っていう図形が 0x41 って数字に圧縮されてるわけ
ね。逆に 0x41 を「 A 」に変換するのが解凍ってこと。
　圧縮解凍に常に必要なのが「変形」。これを「アルゴリズム」って言いま
す。このアルゴリズム次第で、圧縮率、変形にかかる時間、可逆不可逆とか
が決まってきます。

　圧縮解凍アルゴリズムには、大きく分けて「可逆」なものと「不可逆」な
ものがあります。
　可逆なものは、圧縮したあと、解凍したらちゃんと元に戻るもの。ちゃん
と元に戻らないと困るテキストファイルや実行ファイルは常にこの方法で圧
縮されてます。つまり lzh や zip はこの方法ってことね。 gif もそう。
　圧縮方法は基本的に単純。パズルみたいな感じかな。ただ、圧縮率の計算
とかには難かしーい数学が必要だったりします。ちょっと触れにくい領域か
な？
　不可逆なものは、圧縮して解凍したあと、データに劣化が発生します。つ
まり圧縮時にデータが間引かれているってことね。このアルゴリズムはデー
タが劣化してもそれほど困らない、音声画像データによく使われます。 jpeg
や mpeg がそう。
　圧縮方法は、フーリエ変換を使います。フーリエ変換を使うと、データを
違う形式のデータへと置き換えられます。このときに「必要のないデータ」
を間引くことで圧縮できるんだけど、「必要ない」の範囲を広げすぎると、
つまり圧縮しすぎるとデータが劣化しちゃうわけ。こっちも数学的な分野だ
からちょっと難しいかな。
　で、これをどうアプリケーションに組み込むか、は来週。じゃね。

// ごめんなさい！

　再びです。
　No.042 と No.043 ( 2/31 と 2/7 ) の金菜さんの憂鬱が、まったく同じ
内容でした。こちらの確認ミスです。申し訳ありませんでした。今後はこの
ようなことがないようにいたします。

　まぁつまりその、今さら教えてもらえたほど、このメールマガジンはレス
ポンスが低いということです（汗）。日記でもかぶゆ〜でもいいんで顔見せ
てくださいよー。
　……それともやっぱり、読まれてないのかなぁ……。


/*            ２０００年２月２９日（月）の更新予定                */
http://www2.justnet.ne.jp/~kabstudio/Info/News/

・更新なし。
　むー、この日に引っ越しできるかなとも思ったんだけど、ちょっと日程的
に厳しいかなと思って１週間遅らせます。引っ越しは３月６日を予定。この
日に引っ越し、新しい表紙、そしてあのメールマガジンのお知らせも……期
待しててねん。


/*                          ご注意！！                            */

・このメールを返信しないでください。
・ご意見・ご希望・ご感想は[チョー普通な日記]よりお送りください。
http://www2.justnet.ne.jp/~kabstudio/nikki2/
・プログラミングに関する質問は[鏑矢の憂鬱]にお送りください。
http://www2.justnet.ne.jp/~kabstudio/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://www2.justnet.ne.jp/~kabstudio/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!!                      */


