鏑矢の憂鬱2001年3月前半
透明1ドットイメージ
 
2001/03/01 (Thu)
・今日はお便り紹介!
 
透明1ドットイメージ
透明1ドットイメージ
  こんにちは。
 先日、貼り付け可能なコントロールの制限について質問したものですが、またコントロールについて質問です。
 ダイアログへ、プロパティで、「右詰」、「複数行」を設定したコントロールを40個程度貼り付けたら、DoModalによる表示はおろか、エディタでの表示テストさえできないようになってしまいました。
 「右詰」、「複数行」のどちらかはわかりませんが、そのような設定をしたコントロールの貼り付け可能数にも制限があるのでしょうか?
 制限を越えたコントロールを使用するには、コード上でコントロールを生成するしかないのでしょうか?
 教えてください。よろしくお願いします。
透明1ドットイメージ
透明1ドットイメージ
 
・うおホントだ! これはかなりアヤシイなー、 MFC はモーダルダイアログを CreateDialogIndirect() で作るんだけど、この戻り値が NULL で、しかも GetLastError() で 0 が返ってきてる(汗)。なんで普通出るはずの "Warning: Dialog creation failed!" が出てないんだよね。
 
この前のは VC の制限だったけど、これは API のだからねぇ。試してないんで想像だけど、たぶんコード上での追加はうまくいくと思うです。っていうのも、実はダイアログエディタ上のダイアログって、本物のダイアログなんです。コントロールを追加するたびに実際にそのダイアログに追加されてるとゆー。
 
・ Spy++ で照準合わせてみるとダイアログ全体やコントロールに照準合うんで分かると思うです。だからダイアログを表示してから追加ならたぶんうまくいくと思うです。たぶんそれしかないだろうなー、 API の問題だからねぇ。それかもしかしたら、 Win9x 系だけの問題だったりするのかも。それでもどうしようもないか。
 
・でわまたっ!
透明1ドットイメージ
 
2001/03/02 (Fri)
・今日もお便り紹介〜。
 
透明1ドットイメージ
透明1ドットイメージ
 ドラッグアンドドロップの実現方法が分かりません。
 Explorerでドラッグしたファイルをリストビューにドロップし、複数のファイル名を取得し、リストビューに追加する方法は分かったのですが、逆にリストビューでドラッグし、Explorerにドロップするドラッグの方法、記述が分かりません。
 ご存知であれば教えてください。
透明1ドットイメージ
透明1ドットイメージ
 
・実はドラッグアンドドロップって詳しくなかったり(汗)。なんでちょっと調べてみたんだけど、どうも見つかるのは「ドロップを受け付ける方法」ばっかし。でやっとこさサンプルコードの情報を見つけました。試してないんでこれでうまくいくかどうかは不明。っつーか COM インターフェイスを自前で作る必要があるみたいです(汗)。 結構難しそう……。
 
・もひとつお便り。
 
透明1ドットイメージ
透明1ドットイメージ
 三好です。
 エディタが完成しました。Vector への公開依頼はすでに終わっているのですが、公開は来週になりそうですので、ソースコードを添付したメールを送ります。
 
 一応私のページ(http://www.mambo.kuhp.kyoto-u.ac.jp/~miyoshi)でも公開しています。そのうち内部仕様をドキュメント化しますので、そのときはまたいろいろ教えてください。
 現時点で、意味不明な不具合が1つ判明しています。
 
1.私のパソコン(Win2k)では、リリースビルドのみ、ファイルをダブルクリックで開くと、めいいっぱいスクロールしたときにメモリ違反が発生する。(デバッグビルドでは起こらない)
 
 鏑矢さんの環境ではどうでしょうか。
透明1ドットイメージ
透明1ドットイメージ
 
・おおっ、とうとう完成しましたね! 試してみたけど、ホントにエディタらしくなっててすごいです。ちゃんとカーソルが動くんだもんなー。で、その不具合はこちらでは再現できなかったです。大きなファイルを見繕って、関連づけしてダブルクリックして、カーソルキーの下を押しっぱにして、ってしてみたけど落ちなかったです。
 
・デバッグビルドとリリースビルドの違いは「プロジェクトの設定」の違いだけなんで、一部をリリースビルドっぽくしてあとはデバッグビルドで、っていうこともできたりします。詳しくは尺八郎さんのページとか「金菜さんの憂鬱」過去ログの1997年7月20日前後を見てくださいです。でもやっぱ、リリースビルドだけの謎のエラーって絶対あると思う(爆)。ホントに謎なんだよなぁ……。
 
・でわまたっ!
透明1ドットイメージ
 
2001/03/03 (Sat)
・今日はぷらとわやかなゆ〜を書いてました。ぷらとわは101号から Ver 6 になります。でもいつまで続くのやら(汗)。かなゆ〜、100号で最終回にします(汗)。結構書くのに疲れちゃったっていうのあるかなぁ。前は気軽に書いてたんだけど、最近は BCC や gcc でのコンパイルチェックをしてからっていうのがあって、負担大きくて。書くネタもないし。
 
・あと……ここ、かぶゆ〜もたぶん3月一杯……。かぶヘッダーでちょこっと書いたけど、基本は「とりあえず休止させて、大丈夫そうもしくは必要なら再開」ってスタンスで行く事になると思います。どうも3月4月に対する不安が非常に強くて……。もしかしたら3月なかばにも休止するかも(汗)。あ、あと辞書も3月一杯だかんねー。
 
・でわまたっ!
透明1ドットイメージ
 
2001/03/04 - 06 (Sun - Tue)
作者沖縄旅行のため休載
透明1ドットイメージ
 
2001/03/07 (Wed)
・おひさっ! では休み中に送られてきたお便り!
 
透明1ドットイメージ
透明1ドットイメージ
 私はCOMの勉強している者で、さっき「DLLを作ろう!(関数編)」を見させていただきました。 私はCOMの中でAPIをたたきたいと思ってるんですけど、「DLLを作ろう!(関数編)」に載っているものを参考にできるのかな?と思って質問したのですが…。
 COMを作るにはIDLファイルを作らなければならないし…、なんせCOM初心者なもので…、どのファイルにどういうものを書けばいいのかわかりません。 よろしければ、お返事よろしくおねがいします。
透明1ドットイメージ
透明1ドットイメージ
 
・ COM を直に作っていくのはかなり大変だと思うです。わても IDL って書いたことないし文法も知らないです(汗)。 VC を使ってるなら「プロジェクトの新規作成」で ATL COM AppWizard か MFC ActiveX ControlWizard で作れば必要なファイルは全部用意されると思うんで、そこから解析していった方がいいかも。
 
・ COM を直に作っていく場合には「 Inside COM 」って本がお奨め。 COM の実装方法が書かれてて、最初の方は IDL とか使わないタイプの COM について解説してるんでそっから作っていくのがいいかもしんない。この辺の COM の仕組みは、なんかのプラグインにも使われてるらしいんで勉強しておいて損はないと思うし。まーでも、 .Net がスタートしつつある今はもう COM の時代じゃないのかもしんないけど……。
 
・もひとつお便り。
 
透明1ドットイメージ
透明1ドットイメージ
 これから、かぶスタはどうなってしまうのでしょう。とても残念です。できれば続けてほしい。
 
 ところで、いま悩んでいます。
 
 先日、周囲に USB 機器がこんなに普及しているのに、メジャーなファンのページがないので、つくることにしました(メジャーにはなり得ませんが)。
 
 目的は USB のさらなる普及に資することです。まずは多くの USB 機器を網羅しようとしました。
 
 私は保守的なプロバイダに属しているので asp だの、cgi だのは使えません。
 
 そこで、データは XML ファイルに置き、JScript で読み込んで検索しています。
 
 ところがです。サーチ・ソートが遅すぎるのです。
 
 ActiveXは、ダウンロードをしてもらわないと使えないし、なんか美しくありません。
 
 もし、VisualC++ を使ってもっと速く検索できる方法があれば教えてください。
透明1ドットイメージ
透明1ドットイメージ
 
・実際にその検索試してみたんだけど、検索が終了しませんでした(汗)。「ロジテック」で検索したんだけど……(うちはセレロン366メモリ192)。どの辺が原因か分かんないんだけど、検索に DOM を使ってるんなら SAX にした方がいいかも。実際「 DOM の特徴」みたいな文書に「 DOM はすべてを読み込んでから処理するから遅い」って書いてあるんで。 SAX は上から逐次処理するから少し早いかも。
 
・あとは、 XML ファイルをひとつにしないで、まずメーカー別とかに分けて検索時に選ぶようにしてもらうとかかな。あと、出力結果を PC 上でできるだけいろんな種類生成してそれを表示させるようにするとか。でもやっぱ、根治療法は CGI で処理することかなぁ。できるだけ安くて CGI 使えるとこを探して、検索機能だけそこに置くようにするとかした方がいいかもしんない。
 
・かなゆ〜はとりあえず休止! そのあとは、仕事環境次第。まず基本的に仕事がきつかったら書く暇ないし、仕事が楽でも、プログラミング=仕事だからそれが(いろんな意味で)書けるかどうかわかんないし。あーあと、かなゆ〜の最終回は今月の16日か21日になる予定。今度のかぶヘッダー送信予約までには決まるはず。訊きたいことがあったら今のうちに〜。
 
・でわまたっ!
透明1ドットイメージ
 
2001/03/08 (Thu)
・……決めた! この「鏑矢の憂鬱」は、今月の16日(金)の分で休止状態に入ることにします。むむ、っつーことは約1週間後!? 自分で決めといてなんだが、結構急だなぁ(汗)。まー、早めに決めちゃった方が後々楽っていうのもあるし、その方が再開も早いかも?<ホントかなぁ(汗)。
 
・あと、プログラミング辞書は21日(水)午後11時に単語受付を休止します。かぶゆ〜はともかく、辞書は最近単語が少なかったから、あんまり影響ないかも。さらに、19日(月)には KTL 、 KCL9542 、 まどかぶ、けしかぶのマニュアルページを削除する予定。ダウンロードは引き続きできるようにします。
 
・基本的にはこの予定で行きます。少なくとも、来週月曜のかぶヘッダーにはこの予定が載るはず。たーだ、金曜や水曜とかの中途半端な日時になってるのは就職関係や卒業式の関係なんで、他に予定が入ったら日時が変わるかもしんない(汗)。ま、逆に言えばいちんちやふつか延ばすことなんか問題ないんで、そんなに神経質になることでもないかも。
 
・でわまたっ!
透明1ドットイメージ
 
2001/03/09 (Fri)
・お便り受付は16日(金)午後9時まで! どうしても解決できない、でも誰にも訊けないプログラミングの難問があったら今のうちに! 答えられるかどうかは別にして(爆)。では今日のお便り。
 
透明1ドットイメージ
透明1ドットイメージ
 三好です。
 
 うー。休止は残念です。ここはどんな初歩的な質問でもいいから気楽に質問できるので。
 質問なのですが、私のME Edit で、大きなデータを扱えるようにするいい方法はないでしょうか。データの格納にCString を使っているので、50KB 位のデータをディスクから読み込もうとすると、止まってしまいます。
 文単位で連結リストにするとか、1MB とかの大きな単位でメモリを確保していくとか、いろいろ考えてみたのですが、いい方法が思いつきません。
 面倒な質問で申し訳ないのですが、ヒントでもいいです。よろしくお願いします。
透明1ドットイメージ
透明1ドットイメージ
 
・確か CString は大きなサイズの文字列を操作するの苦手じゃなかったかな。重くなるのはその辺が原因かも。とりあえず手っ取り早いのは std::string を使うことかも。これは普通にメモリを確保するはずだから、大きなサイズでも大丈夫……だと思う(汗)。ファイルを開くときにそのサイズを調べて、 std::string::size() で確保して渡すとかすれば大丈夫なはず。
 
・後はやっぱ、書かれてるよーに、 CString を1行ずつに割り当ててとか new で大きく確保してとかかな。あと思い付くのとしては、「余分に確保しない」とか。ギリギリ確保して、それ以降の入力は「ログ」として取って別に保存してくとか。これだとアンドゥしやすそう。この辺は、実際に各エディタの企業秘密とかなのかも。逆にうまいシステム考えれば対抗手段になるかも!
 
・えーっと、休止以降は「チョー普通な日記」で質問して大丈夫(爆)。本格的な回答とかは(時間的に)できないかもしんないけど、それこそ気軽に訊かれるんなら全然問題なし。あっちもツッコミ少ないし(爆)。メールでもいいしね。ホームページが色々変わるってだけで、わて自身が変わるわけじゃないんで……たぶん(爆)。会社入って変わったら嫌だなぁ。
 
・でわまたっ!
透明1ドットイメージ
 
2001/03/10 (Sat)
・今日はお休み(爆)。お便り受付は16日(金)午後9時までなんだから今のうちに!
透明1ドットイメージ
 
2001/03/11 (Sun)
・お便り受付は16日(金)午後9時まで〜。というわけで今日のお便り!
 
透明1ドットイメージ
透明1ドットイメージ
 三好です。
 
 一応解決しました。結局CStringArray のようなことをするクラスを作り、そのクラスを1つのCString のように見せかけることで解決させました。
 この方法は本質的ではないかも知れないと思っていたのですが、クラスの実装時にnew とdelete を駆使してデータをchar 配列に格納するようにしたので、今までより高速になりました。
 ここで相談したことで、一度冷静になれました。どうもありがとうございました。
 
P.S. お仕事がんばってください。
透明1ドットイメージ
透明1ドットイメージ
 
・おおっ、解決しましたか。 CString の連想配列みたいな感じかな? 確かにこれなら操作が面倒じゃないし、無駄も少なそう。お仕事はなー、内容がどうなるか……。ま、なんにせよがんばりますです。とりあえず30歳まではいるようにしよう(爆)。
 
・でわまたっ!
透明1ドットイメージ
 
2001/03/12 (Mon)
・お便り受付は16日(金)午後9時まで、ってことはあと4日? いや見てる人はもっと後だろうから……ダッシュ! というわけで今日のお便りですよ(なんだこのテンションは)。
 
透明1ドットイメージ
透明1ドットイメージ
 こんにちは、いつもお世話になってます。
 また、初歩的な質問なんですが、stdlib.hのbsearch()なんですが、
 
void * bserach(const void * key, const void * base, size_t num, size_t size, 
    int (* fcmp)(const void * e1, const void * e2)); 
	
 
 この voidのポインターっていったいなんですか? どうやって使えばいいのかよく分かりません。教えてください
透明1ドットイメージ
透明1ドットイメージ
 
・うお、こんなランタイムがあったなんて知らなかった!(爆) で、 void * っていうのは「汎用ポインタ」、つまり「なんにでもなるポインタ」って意味で使います。この bsearch() は、どんな要素の配列でも検索できるランタイムとして設計されてます。だから、 int のポインタも double のポインタも、とにかくどんなポインタでも受け付けますよ、って意味になってます。実際に void * にはキャストなしでどんなポインタも暗黙的変換ができるしね。じゃ、実際に使用例を見てみましょー。
 
// 比較用関数。
int compare_int( const void *p_piLh, const void *p_piRh )
{
    return *(int *)p_piLh - *(int *)p_piRh;
}

// では使ってみましょう。
void Test()
{
    const int iSource[] = { 100, 200, 300 };
    TRACE( "%X\n", iSource );

    const int iKey = 200;
    int *piRes
        = (int *)bsearch
            ( (const void *)&iKey    // 見つけたい値。
            , (const void *)iSource  // サーチ対象。
            , 3                      // 要素数。
            , sizeof( int )          // 要素のサイズ。
            , compare_int );         // 比較関数。

    if( piRes != NULL )
    {
        TRACE( "%X, %d\n", piRes, *piRes );
    }
    else
    {
        TRACE( "ない!\n" );
    }
}
// 結果
// 64F444
// 64F448, 200
	
 
・まず比較用関数を用意します。これは上記の compare_int() のような引数と戻り値を持ってる必要があります。実装については後で。
 
・ bsearch() はどんな要素の配列でも検索できます。なので、まずその検索対象にする配列 iSource を用意しました。これは「ソート済み」じゃなきゃダメ。わてが参考にした MSDN のリファレンスでは、 qsort() でソートしてますです。ここではあらかじめソートした状態にしておきます。
 
・では実際に bsearch() を呼びます。第1引数には「見つけたい値」へのポインタを渡します。ポインタって事が、 compare_int() の実装に関わってきます。第2引数は検索対象。これもポインタで。第3引数は、第2引数の要素数。ここでは3つ。第4引数は要素のサイズ。ここで要素のサイズを教えるから、各要素のアドレスを計算できて、「どんな要素の配列でも検索できる」ようになるんです。
 
・第5引数はさっきの比較用関数。で、この実装についてだけど、第1引数には「 bsearch() の第1引数そのもの」が渡されます。第2引数には「 bsearch() の第2引数の各要素へのポインタ」が渡されます。つまり、 compare_int() が呼び出されるたびに、 &iSource[0] か &iSource[1] か &iSource[2] かが渡されるってこと。
 
・この比較用関数が bsearch() から呼び出されて、その戻り値を元に検索します。戻り値は、第1引数の方が小さければマイナス、大きければプラス、同じならゼロを返すように実装する必要があります。ここではただ引き算してるだけです。で、この比較用関数がゼロを返した要素へのポインタを bsearch() が戻り値として返すんで、それでどこにあるのかが分かります。
 
・この void * と比較用関数の仕組みのおかげで、どんな要素の配列でも検索できるようになってるんです。構造体でもクラスでも文字列ポインタでも。まー、今はテンプレートっちゅー便利なもんがあるからこんなポインタ操作なんてしなくてもいいんだけど、プレディケート作って STL のコンテナとアルゴリズム用意してって方が面倒って人の方が多いんだろうなぁ……。
 
・もひとつお便り!
 
透明1ドットイメージ
透明1ドットイメージ
 MFC AppWizard (exe) でビューに CRichEditView を指定すると、ワードパッドのようなものができますよね。
 
 でも、選択の背景色がシステムカラーではないのでなんか違和感があります。
 
 これをなおすにはどうしたらいいでしょうか?
 
 CRichEditView クラスでやっているように、 OnSelChange(...) を定義して CHARFORMAT2 で背景色を設定してみてもぜんぜん変わりません。
 
 ステップで実行すると、 CRichEditView::PreCreateWindow からの呼び出しで「LoadLibraryA("RICHED32.DLL")」なんてやっていて、 Spy++ からみても、どうやらリッチエディット 2.0 ではなくて、1.0 のようです。
 
 そこで、次のようにしてみました。
 
BOOL C〜View::PreCreateWindow(CREATESTRUCT& cs)
{
   LoadLibraryA("RICHED20.DLL");
   m_strClass = "RichEdit20A";

   return CRichEditView::PreCreateWindow(cs);
}
	
 
 そうしたら、見かけ上はすんなりできているのですが、アウトプットウィンドウ(デバッグ)に、
「例外処理(初回)は 〜.exe (GDI32.DLL) にあります: 0xC0000005: Access Violation。」
が、文字を入力・選択などをする度に表示されてもっと気持ち悪い状態になってしまいました。
 
 いったいどうしたらいいんでしょう。
透明1ドットイメージ
透明1ドットイメージ
 
・うわホントだ、入力するたびに例外が出ますね。こりゃあかんわ。でも背景色が変えられるのはリッチエディット2.0かららしい……。なんで RichEdit20A を Google にかけたら CRichEdViewEx なるものを見つけました。サンプルをビルドしたら問題なく使えたんで、これをうまく移植すれば大丈夫だと思うです。
 
・で……実際に、今例外が出まくった例のでビュークラスを CRichEdViewEx から継承するようにしたんだけど、必ず閉じるときに例外が出るなー。上の例だと出ないんで、もしかしたら CRichEdViewEx から継承しちゃいけないのかも。とりあえず上のでできそうなんで試してみてくださいです。
 
・でわまたっ!
透明1ドットイメージ
 
2001/03/13 (Tue)
・お便り受付は16日(金)午後9時までですよー。では今日のお便り。
 
透明1ドットイメージ
透明1ドットイメージ
 初めまして。いつも楽しくROMさせてもらってます。
 かぶゆ〜がお休みになるということでちょっと寂しいですね。
 今日はどうしても行き詰まってしまったので質問させてください。
 
 環境はWindowsNT4.0 SP6、Visual C++6.0 SP4です。(ちなみにMFCを使ってます。)
 現在STLのmapを用いて開発をしていますが、コンパイル時にC4786のwarningが大量に出ます。そこで
 
// ヘッダーファイル内
#pragma warning (disable:4786)	// 識別子が '255' 文字に切り捨てられました
#include <map>
	
 
 のようにすれば良い、という情報を得てなんとかwarningを取り払うことができました。ところが、pairを使用するとまたC4786のwarningが復活してしまいました。#pragma warningを入れているのに何故???
 
 解決策があったら教えてください。warningが出ているのは気持ちが悪いもんで(^^;)
 
P.S.会社勤めがんばってください(^o^)/~~
透明1ドットイメージ
透明1ドットイメージ
 
・がんばります〜。なんせバイトのプログラミングとかもしたことないんで結構不安だったり、っていうか仕事がプログラミングかどうかも不明……。 C4786 をうち消す #pragma は、 MFC を使っているんだったら stdafx.h のいっちゃん最初くらいに書けばたぶんうまくいくと思うです。
 
・こっからはかなりややこしい話。 std::pair が定義されてる utility をインクルードしててもコンパイルエラーが出ないのは、テンプレートは「使わなければ無視される」から。 std::pair を使ってないときはコンパイルエラーが出なかったんだけど、使うと実体化(インスタンス化)されてコンパイルエラーになるんです。
 
・ utility ヘッダーファイルは、 algorithm や iterator 、 vector とかのヘッダーファイルからもインクルードされてるから、 #include <algorithm> の後で #pragma してると #pragma が間に合わない、ってことが原因なのかなーと。各 .cpp ファイルからのインクルードの兼ね合いとかも原因の可能性有り。ま、とにかくできるだけ早く #pragma がコンパイラに認識されるようにすれば問題ないと思うです。だから stdafx.h の最初に書いちゃいましょう。
 
・もひとつお便り。
 
透明1ドットイメージ
透明1ドットイメージ
 私のプログラムがリソースリークを起こしています。
 リージョンが原因だと思うのですが、下記の方法でリージョンが開放されているように思えません。本当にリージョンが開放されているのでしょうか?
 
    HRGN hBaseRgn = _msk.GetAniRgn();
    HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
    CombineRgn(hRgn, hBaseRgn, NULL, RGN_COPY);
    SetWindowRgn(hRgn, TRUE);
    DeleteObject(hRgn);
	
 
 下記のように何回開放しても何もなりません。AccessViorationにならないんですかぁ? HBITMAPも同様です。DeleteObjectが何をなさっているのか分かりません。ご存知でしたら教えて頂けませんか?
 
    DeleteObject(hRgn);
    DeleteObject(hRgn);
    DeleteObject(hRgn);
    DeleteObject(hRgn);
    DeleteObject(hBaseRgn);
    DeleteObject(hBaseRgn);
    DeleteObject(hBaseRgn);
    DeleteObject(hBaseRgn);
	
透明1ドットイメージ
透明1ドットイメージ
 
・ホントだ、 DeleteObject() って同じハンドルを何度も渡しても非ゼロが返ってくるんですね。基本的には Create と Delete は malloc() と free() の関係なんで、メモリを解放してるはず。実際、 DeleteObject() した hRgn をウィンドウに SetWindowRgn() してもゼロが返ってくるし。だから削除はできるはず。
 
・ただ、この例だとまずいと思うです。 SetWindowRgn() するってことは、そのウィンドウが hRgn に常にアクセスするってこと。ハンドル=ポインタだからね。だから DeleteObject() しちゃうと、ウィンドウが解放されたメモリ領域にアクセスすることになるからそれが原因かも。
 
・ _msk.GetAniRgn(); がよく分かんなかったんで完全なテストができなかったんだけど、こっちではアクセス違反は発生しなかったです。このときテストできなかった _msk.GetAniRgn(); や CombineRgn() が原因でアクセス違反が起きたのかも。ハンドルの管理はポインタの管理と同じ、つまり結構大変ってことなんで気を付けないと大変かも。
 
・でわまたっ!
透明1ドットイメージ
 
2001/03/14 (Wed)
・今日は、本屋で立ち読みしてきた方法で XML ドキュメントを新たに作成してみる。ずっと「 <?xml ?> ヘッダはどう書き込めばいいんだろう」とか思ってたんだけど、なんのことはない、 DOMDocument.loadXML() で文字列そのものを読み込むことができるんですね。これでなんとか。
 
・ただ、今は VBScript でやってるんで結構限界が(汗)。 "" の中に " を書き込むにはどうすればいいんだろうとかで悩んだり(単に "" ってすればいいらしい……)、謎のランタイムエラーに悩まされたり(これはまだ解決してないし……)、やっぱ VC でやった方がいいかもなー。
 
・今日のお便り。
 
透明1ドットイメージ
透明1ドットイメージ
 こんにちは。昨日#pragma warningで質問した者です。
 鏑矢さんの言うとおり、stdafx.hの先頭にいれたところwarningがなくなってくれました。おかげでとてもスッキリしました。どうもありがとうございました!!
 
 これからも「師匠」と仰ぎつづけます。
 では。
透明1ドットイメージ
透明1ドットイメージ
 
・はう〜「師匠」だなんて〜(照)。この鏑矢の憂鬱休止まであと2日。皆さんにとってはたぶん明日、ってことでしょう。まー、この前書いたように日記の方で質問してもいいし、知ってる人は知ってると思うけどメールで質問したってくれてもちゃんと答えるし、そんなに気にしなくていいと思うですよ。まー前みたいな気軽さはないかもしんないけど、ある意味日記はここより気軽だから(爆)。
 
・でわまたっ!
透明1ドットイメージ
 
2001/03/15 (Thu)
・投稿は16日午後9時まで!! っつーことはもはや残り24時間を切ったのでは!? これが質問のラストチャンス! たぶん。では今日のお便り!
 
透明1ドットイメージ
透明1ドットイメージ
 テンプレートで分からないこと聞きます。
 g++を使ってます。
 えっと、"m.h"では、テンプレートクラスを宣言してそこでフレンドで<<演算子を宣言しました。
 
template <class>
class m{
  friend ostream& operator<<(ostream &, const m&);

・・・・

};
	
 
 "m.cc"では、
 
template <class T>
ostream &operator<<(ostream &output, const m<T> &a){

....
  return output;
}
template class m<int>;
template class m<double>;
....
	
 
を定義しました。
 その後で、"main.cc"で
 
extern template class m<int>;
int main(){
  m<int> a;
  cout << a;

  return 0;
}
	
 
 としたんですが、<<へのリファレンスがないなどといわれてコンパイルできません。
 他の関数を呼び出す時はうまくいっているのにfriend関数を呼ぶときだけなんだかうまくいきません。
 どうすればいいんでしょうか? 助けてくださ〜〜い。
透明1ドットイメージ
透明1ドットイメージ
 
・えーっと、一番簡単なのは operator<<() を m.h の中( class m のあとね)に置くこと。この例、 operator<<() の実装を空にしとけば別に friend 指定しなくても大丈夫なはず( friend 指定は m の private メンバにアクセスするときだけ必要だから)。なのに、リンクエラーが出るでしょ。
 
・この辺は「テンプレートのインスタンス化」って部分。コンパイラが m.cc をコンパイルするとき、 operator<<() を「テンプレートだし、使われてないからコンパイルしなくていいや」って判断します。 << は main.cc の方で使われてるから、 m.cc をコンパイルする時点では operator<<() のテンプレート引数を指定できないんで。機械語コードにコンパイルされてないから、リンカが「その関数を呼び出すリファレンス」を解決できないんでそういうエラーが出るとゆー。
 
・あ、もしかしたら、メンバ関数として operator<<() 作ってたときはうまくいってたのかな。確かに template class m<int>; でなんかインスタンス化されてるような気もする……。でも、一応テンプレートはヘッダーファイルに全部書いちゃう方がいいと思うです。その方がテンプレートっぽいし(爆)。
 
・もひとつお便り。
 
透明1ドットイメージ
透明1ドットイメージ
 始めまして、not と申します。Kab-Stduio はいつも拝見しております。
 XMLにて、 <?xml ?> を書き込む方法で心当たりがありますので送ってみました。お役に立てれば幸いであります。
 
 <?xml ?> はXMLを解釈するプロセッサ(DOMパーサ、ブラウザ)がXMLデータの解釈に使うものなので、それらを情報を指定するためのインタフェイスを 生成して渡します。
 
 以下サンプルです。VB のコードですが、VBScript でもOKかと思います。
 
Dim document As DOMDocument
Set document = New DOMDocument

' createProcessingInstruction で <?xml ?> 作成 
	
document.appendChild document.createProcessingInstruction
    ("xml", "version=" + Chr(34) + "1.0" + Chr(34) + " encoding=" 
    + Chr(34) + "shift-jis" + Chr(34))
' 鏑矢注:上の3行は1行のものを入りきらないから3行にしたものです。
' 試すときは1行にしてくださいです〜。

' ここはドキュメントのルートとなる要素を作成する
Set document.documentElement = document.createElement("element") 
	
 
 作成しているところは、document.createProcessingInstruction() です。
 
 蛇足ですが、XMLを文字列で読み込む場合、動作させている言語が取り扱う文字列コードをもろに反映するらしいので注意が必要です。
 
 以上です。
透明1ドットイメージ
透明1ドットイメージ
 
・はじめまして〜、そしてありがとうです!! いやー、 createProcessingInstruction() なんてメソッドがあったんですね。これで最初の <?xml ?> 部分を普通に加えることができるんですね。確かに loadXML() 使うのは力業っぽい……。
 
・それに、ノード追加する前にまず createElement() 呼んで documentElement に格納しなきゃいけないんですね、これが分かるのにかなり時間かかった……。そのあと createTextNode() の戻り値を documentElement.appendChild() したらエレメントに要素加えることができたです。これで一歩前進です〜、ありがとう! っつーかもっと情報集めないとなわて……。
 
・もひとつお便り。
 
透明1ドットイメージ
透明1ドットイメージ
 親愛なる鏑矢様
 
 私は非常にトリッキーな事態に直面してしまいました。ぜひとも救いの手を差し伸べてください。
 
 やりたいことははっきりしています。 CRichEditView のテキストが変更されたとき、どこが変更されたかを知りたいのです。
 
 変更があるたびにテキストをバッファに格納しておき、違いを先頭と最後から比較していけば変更個所を知ることはできますが、遅いコードになることは明らかです。
 
 そこで、次のように考えました。
 
 EN_SELCHANGE は選択状態の変更を通知してくれます。(カーソルの移動も含めて)
 それでは、EN_SELCHANGE が来たら選択状態をとっておいて、 EN_CHANGE が来たらひとつ前の選択状態を読み出せばいいじゃないか。
 
 ところが事態は複雑なのです。
 リッチエディットコントロール(少なくとも 1.0)は不真面目なので、 EN_SELCHANGE を呼んでから EN_CHANGE を呼ぶとは限らないのです。
 
 どういうことかというと、半角文字入力では、そのままうまくいくのに対し、 BS や Del、ペーストは EN_SELCHANGE を 2 回以上呼んでから、 EN_CHANGE を呼んでいるらしいのです。
 
 おかげで、(n, m) だった選択状態は (n, n) になってしまうことがあります。
 
 全角があったりすると、文字入力でもさらに複雑なことになります。
 
必ず感覚的に操作前の選択状態を知りたいのです。
 
 EN_UPDATE でも試してみましたが、EN_UPDATE ではテキストが変更されても呼ばれないことすらありました。
 
 ちなみに、Undo メソッドは操作された文字列の先頭・末尾に改行コードなどがあると選択状態を正しく元に戻しません。(ワードパッドで「abc」, リターン, Shift+←, Shift+←, Del, Ctrl+Zとすればわかっていただけると思います)
透明1ドットイメージ
透明1ドットイメージ
 
・ホントだ、 EN_SELCHANGE メッセージが2回連続で送られてきますね。各メンバもまったく同じだし、なんか謎だ……。うーん、一番いいのはフック掛けるかサブクラス化して、キー入力を全部ログってく、ってのかなぁ。全部でなくても BS とかだけ取って、そのあと送られてきた EN_SELCHANGE は特別な処理する、とか。なんか根本的な解決法って感じじゃないな……。
 
・っつーか、これ以上リッチエディット使ってくと、問題が雪だるま式に増えてきそうな気が……。
 
・でわまたっ!
透明1ドットイメージ
 
2001/03/16 (Fri)
・今日はかぶゆ〜最終回! ま、一応休止扱いだけどね。かぶゆ〜の前身だったかなゆ〜は1997年9月からスタートしたんだけど、途中何度も休止してたし、かなゆ〜からかぶゆ〜になった間も休止状態だったし。何ヶ月かしたら、またかぶゆ〜始めたくなったりするのかもなー。ま、とりあえずこれまでのご愛顧、ありがとさん! これからはチョー普通な日記の方でね。
 
・では今日のお便り!
 
透明1ドットイメージ
透明1ドットイメージ
 ちーっす尺八郎です
 いよいよお互い社会人ですね。
 
 と言うわけで折角ですので最後に質問
 現在、VCでFOX-GUI(http://www.cfdrc.com/FOX/fox.html)なるものの上でvtk(http://www.kitware.com/vtk.html)を動かそうと格闘しております。
 さてはて、どちらも巨大ライブラリなのでプリコンパイル済みヘッダが動作してくれないと大変なことになってしまいます。
 ところが、「新規プロジェクト->Win32アプリ」のウィザードで自動的に設定される場合にはうまくいくのですが、手動でプロジェクトオプションで設定してもプリコンパイル済みヘッダが動作しないのです。プリコンパイル済みヘッダ(stdafx.h atdafx.cpp)自体はそのままコピーしましたし、プロジェクトの設定も「/Yu"stdafx.h"」はどちらも入っています。なんか他に注意すべき点ってありますかね?
 
 おまけ、リンク時にエントリポイントシンボルを「mainCRTStartup」にするとmain関数からアプリが起動するんですね。DOS窓も表示されません。ちょっと便利かも
 
 更におまけ、Ruby始めましたいい感じです
 
 では今後とも宜しく
透明1ドットイメージ
透明1ドットイメージ
 
・んー、なんか設定がうまくいってないのかな。まとめると、まず StdAfx.h で「プリコンパイルしたいヘッダーファイル」をインクルードして、 StdAfx.cpp 他各ソースファイルから StdAfx.h をインクルード。で、「プロジェクトの設定」の左ツリーで各ソースファイルに対しての「 C / C++ 」−「プリコンパイル済みヘッダー」の設定で、 StdAfx.cpp だけ「プリコンパイル済みヘッダーファイルの作成」( /Yc"stdafx.h" )、それ以外のソースファイルは「プリコンパイル済みヘッダーファイルを使用」( /Yu"stdafx.h" ただしこれは各ファイルの時は出ない)ってすればうまくいく、はず。
 
・基本的には、 StdAfx.h で「不変なヘッダーファイル」をインクルードして、 StdAfx.cpp が「作成」、他のソースファイルは「使用」になってりゃ大丈夫なはず。こんときに、 StdAfx.h でインクルードすべきファイルを各ソースファイルからインクルードしてたりするとうまくいかなかったりしたような気が……。「コピーした」とかってあるから、それがなにか影響してるのかも。
 
・ mainCRTStartup ってどっかで見たような……確か初期処理をしないからファイルサイズが小さくなるとか起動が早くなるとか? 違ったかも(汗)。 MSDN 見ると「そっから main() 呼ぶ」書いてあるから順序的には重くなりそうだし、記憶違いかも。 Ruby ……わてもクロ現出たい(爆)。でも出るんならサービスプロバイダなサイトの方がいいだろうなぁ。あー引っ越したらフレッツ ADSL 入ろっと。あれ、 IP もらえたんだったっけかな?
 
・ま、いーや。そんじゃ、でわまたっ!
 
 
(C)KAB-studio 2001 ALL RIGHTS RESERVED.