root.html から順にたどってご覧下さい。
ビルド(F7)
。ソリューションのビルド
。make
と打って Enter。smake
と打って Enter。makedoc
と打って Enter。・プログラム開始点は、GpMain.cpp の int kmain() です。 もちろんその前にkilib内部で色々動作は走ってますが、その辺り細かいことは 気にしないでOK。kmain()からトレースして下さい。 ・editwingは、大きく分けて Control, Document, View, Cursor の4パートからなります。 ・Control は、いわゆる普通のエディットコントールっぽい体裁をなしています。 普通に外から触るのはこの部分だけとなるでしょう。 ・Document は文字列データを保持します。 キーワード色分け用設定や、色分け用にパース済みのデータなども持ちます。 ・Viewは、データの表示担当です。 文字列の折り返し箇所や、折り返しの設定、行番号領域の表示/非表示設定を保持します。 ・Cursorは、Viewの一部で、ユーザーからの入力処理担当です。 カーソル位置の制御や、そこへのテキスト入力などを管理します。 ・Documentは、単独でも存在できるようになってます。ViewやControlは、 Documentにイベントリスナとして登録することで、Documentと連携します。 ・一つのDocumentに、複数のViewを対応させることが出来ます。 同じテキストだけど表示箇所は違う、という分割Windowなどを サポートできるようにするためです。 ・一つのView毎に、一つのCursorを持ちます。
☆小型化にあたって 1.スタートアップコードを省くため、C/C++標準ライブラリを 用いることができない。ひょっとしたら初期化無しでも使える 関数があるかもしれないが、いちいち調べるのも面倒なので 全部使わないことにする。 ただし、コンパイラによる組み込み関数生成が可能な abs, fabs, labs, memset, memcpy, strcat, strcmp, strcpy, strlen は例外的に使うことが出来る。memmoveも作ったのでこれも○。 2.スタートアップを省略した弊害として、グローバルオブジェクト やstaticオブジェクトが利用できなくなる。コンストラクタ等の 呼び出しが行われないためである。関数内のstaticオブジェクト の場合はOKとは思うが、いずれにせよデストラクタは呼ばれな さそうな気がする。よって×。 Singletonを作りたい時に少しキビシイが、まぁ大して困らないはず…。 なお、VC++の場合はマクロSUPERTINYを#undefすることで、他の コンパイラの場合は何もしなくても、ライブラリ関数/staticオブジェ を使えるように復帰できる。 3.例外を扱わない。巻き戻し処理の分を省くためである。 ただし、コンパイルオプションを変更するだけで例外安全を 保証できるようなソースを書くよう心がける。 try/catch 無しでも例外安全にすることは不可能ではない。 …と偉そうなことを書いたのはどこのどいつだムキィ! …えーと、めんどーになってきたので程々に。 4.operator new の実装は、標準のmalloc等を使わず直にHeapAlloc APIを 毎回呼ぶのがデフォルトになっている、がこれは恐ろしく遅い。 各種コンテナを書くときや、クラスオブジェクトのデストラクタなどでは mem().Alloc/Dealloc() でメモリ操作する。なお、class Object から 派生することで自動で operator new を mem().Alloc() に振り替えられる。 ☆命名規則 1.クラス名、フリー関数名、メンバ関数名 は基本的に大文字始まり ex) class Dog : public Animal { ... }; int PrintSomeData(); 2.名前空間名は全て小文字 ex) namespace utility { ... } 3.ローカル変数名、メンバ変数名は小文字始まり。Java風、ラクダ風。 メンバ変数の最後には _ をつける。 ex) int x = this->canvasSize_; #4.組込型と同等に扱いたいような基本的なクラスは全て小文字 ex) templateclass array { ... }; #5.単なるプロパティ取得用のメンバ関数は小文字始まり ex) int ClassA::sizeOfXxx() { ... } #6.参照として用いるポインタ、ハンドル型のメンバ変数には、 それぞれ接頭辞 p, h をつける。この接頭辞が付いたメンバの 指すオブジェクトの生成/解放については、そのクラスは関知しない。 ex) Window* pParent; 逆に、new/delete で動的に処理するためだけにポインタと なっているようなメンバについては、この接頭辞は付けない。 ex) MyPImpl* impl_; 参照型変数については、常に前者の使い方しかされないと 考えられるため、r 等のプレフィックスは不要とする。 #7.イベントハンドラ関数は on_xxxx_yyy() という名前 ex) void Dialog::on_button_down() { ... } ☆コーディングスタイル・メモ クラスのメンバは、 ・公開オペレーション関数 ・公開アトリビュート関数 ・公開ユーティリティ関数(static) ・protected 内部構造体 ・protected 関数 ・private 内部構造体 ・private 関数 ・private メンバ ・friend/NOCOPY など の順序で書く。基本的に。 1文 if/for/while/do-while の場合は {} を用いない。 私にとってはその方がずっと読みやすいので。ただし、 if {} else if {} else {} において、{}を用いるものと 用いないものが入り交じるようには書かない。その場合は 1文のものでも {} で囲う用にする。 ☆コンパイラ識別マクロ… _MSC_VER __BORLANDC__ __DMC__ ☆プロジェクトの設定(VC++): ・プリプロセッサの定義 += SUPERTINY ・例外処理, RTTI を無効にする ・最適化 (グローバルの最適化・組み込み関数の生成・サイズ優先・フレームポインタ略) ( /GF オプション追加 ) ・デバッグ /GZ オプション削除 ・PCH: kilib/stdafx.c ==> stdafx.hまでで作成 その他のファイル ==> stdafx.hまでを使用 どのソースファイルにも一番先頭に #include "stdafx.h" を記述。kilib配下でないファイルについても上の通りで良い。 (stdafx.hに対するincludeは自動的にpchへ振り返られる) ☆SHELL32.LIB/IMM32.LIB for DMC++ まず Borland の impdef.exe で、 -a オプションを付けて shell32.dll から 定義ファイル作成。あとは @nn という形式で、スタックずらしサイズを手で PlatformSDK付属のlibからうつして書いていく。 完成したら Borland の implib.exe で def から lib を作成。