[[BORLAND C++ CWCC]]
RETURN
CWCC#12 CWCC Evolution #2
いやいや、お膳立てに結構手間取ったのだ。本題は、ここからかなぁ。とりあえず、お膳立てで定義した初期化タイミングで、何が初期化出来るのかを考えてみた。
  • WinMain以前(INITCASE1)
    ここでは、Instance等の情報がなくても使える部分を初期化する。フォント,フォントの色等は、ここで初期化出来るかな?あと、ESCシークエンスを装備したEDITを使うか否かも設定出来る。メインのウインドウを表示するか否かもここで…って!何だかここで、全部出来てしまいそうだなぁ?前回のStep2は要らなかったかも…いやいや、今後の展開で絶対必要になると思うし…無駄にはならないだろう。

  • WinMainの最初(INITCASE2)
    ここでは、上記のWinMain以前で設定出来た項目に加え、Instanceや、コマンドラインの引数が明らかになってくるので、コマンドプロンプトから起動した場合や、アイコンにファイルをドロップされた場合の処理を記述出来る筈だから、その辺りの処理を解放しても良いかも知れない。

  • コンソール生成後(INITCASE3)
    ここで、何の情報が揃うかと言うと、コンソールのHWND辺りか?ただ、これをいじられちゃうと、CWCCとしての動作に支障が出るので、ユーザに持たせる部分は慎重に考えなければ…実際は、ここまで、ユーザプログラムで書いて来る事が出来る人ならば、HWNDを渡してしまっても問題は無いと思うが…

と言う訳で、とりあえず、CWCCのソースコードを開いてみると…おぉ,まさしくヤキソバである。う〜ん,2年という月日は長い…。

  • フォント設定
    気を取り直して、とりあえずはフォントの設定から…。これについては、それほど難しい話では無い。ユーザ設定のHFONT型変数を、何処かに設定しておいて、これを適当なタイミング(WM_CREATE辺りで良いか??)に、コンソールのエディットにSetFontすれば良い。ユーザが設定したい部分は、大概,フォントのFaceとサイズ(高さ)、後は、Bold属性(残念ながら、この構造体には、フォント色は含まれない)くらいだろうか?後は、細かい設定をしたい人の為に、LOGFONTそのものをセットするインタフェースを用意する事にする。
    void CwccSetFont(char *FontFace,int FontHeight,BOOL BOLD) ;
    void CwccSetFont(LOGFONT *USERFONT) ;
    尚、ここで設定(Create)したHFONTについては、ESCシークエンスの場合も使いたいので、グローバル変数として定義して、消さない事にして、アプリの終了時にDeleteObjectする。但し、後者の関数は、LOGFONTをそのまま解放してしまう事になるので、angleやら、フォントの種類まで設定出来てしまう,これでは、表示させた場合に不都合が起きる場合が想定出来るので、INITCASE2,3でのみ使用出来る事にしたい。(INITCASE1は、比較的誰にでも使えてしまうが、INITCASE2,3は、有る程度の知識が無いと到達出来ないので、この様な仕組みを使える人ならば、当然、LOGFONTを適切に使えるだろう…と言う判断である)あと、フォントのサイズを変更した際の初期画面サイズの設定変更については、現時点では考えていない。

  • フォントカラー
    フォント(バックグラウンド含む)カラーの設定は、親ウインドウから行うのだが、CWCCでは、親ウインドウと、EDITの主従関係はハッキリしているので、これは問題無い。メインウインドウに、Consoleのハンドルで、WM_CTLCOLOREDITが届いたら、フォント色をセットして、背景色を返せば良いのだ。問題は、上記のフォント設定と絡めるべきか否かであるで、以下の様にする。
    INITCASE1から使用可能,
    void CwccSetFont(char *FontFace,int FontHeight,BOOL BOLD,long FFColor=0l) ;

    INITCASE2以降で使用可能,
    void CwccSetFont(HFONT *USERFONT) ;
    void CwccColors(COLORREF FFColor,COLORREF TextBk,HBRUSH BgColor) ;
    FFColorは、フォアグラウンド色
    TextBkは、テキストのBG色
    BgColorは、ウインドウのクライアント領域を塗りつぶすBRUSHである。

  • コンソールを隠す
    こちらの方は、多分、今回は無理なので、次回以降の改版に回す…スマソ!

  • ESCシークエンス
    これが今回の山場である。今回は、初期化関数として、
    void UseCwccESCConsole(int widthx,int heighty) ;
    等と言う関数を用意しようと思う。これを呼ばれたか否かを示すフラグで、Create時の切り分けを行う事にする。

    • 構成
      ベースは、Editコントロールとする。オーナドローなので、コントロールは何でも良いのだが、元々Cwccにては、コンソールにノーマルのEDITコントロールを使っているので、上記指定が為されたら、同じエディットコントロールを改造して使えば良いと考えたのである。現行の関数CwccGetch等を、そのまま使用するには、これの方が良いと言う事もある。但し、Editコントロールのバッファは使用せず、128×32のテキスト用バッファと、128x32のAttribute(属性)バッファを使う事にする。widthx,heightyについては、コンソールのサイズで、widthxは、40〜120,heightyは、20〜30で許可しようと思う。

    • 属性
      属性は、long型(32bit)とし、共用体(union)で扱う。
      リザーブ斜体太字下線リザーブブリンク(blink)反転(reverce) テキスト背景テキスト色
      1bit1bit1bit1bit2bit1bit1bit12bit12bit
      色指定は4096色とし、MSBより、4bitずつでR,G,Bの濃さを示す。なお、今回は、斜体,太字,下線部分については対応無し(一応、試作は行ったのだが、ボールドやイタリックは、フォントのサイズ自体に影響してくるので、根本的に変更が必要になりそう…)とする。(ブリンクについては、タイマを使うので、対応しない可能性大)

    • 表示
      横幅は、半角で40〜120まで指定出来るものとし、高さは、20行から30行まで指定出来るものとする。基本的には、この間でテキスト用バッファと、属性バッファの内容に従って、オーナドローで、表示を行う。リペイントをかけるタイミングについて、EDITコントロール側では、WM_CHARによる入力が完了した事を知り得ないので、1文字入力される度にリペイントをかける事になるが、Cwccの仕様上は、文字列が渡されるケースが多く、このままでは効率が悪いので、WM_USERのメッセージを1個用意し、そのメッセージをターミネータに使う。また、下記の様にマウス入力をクラックするので、EDITにフォーカスを入れる手だてが無くなる。キャラクタ(WM_CHAR)は、親ウインドウから、意図的に投げる様にする。

    • マウス入力
      EDITへのマウス入力は、EDITのプロシージャで、0を返すので、すべて無効となる。(そのままほったらかしておくと、右クリックでメニューとか出ちゃうし、余分なリペイント等が走るので…) 但し、専用のクラス(class ESC_MOUSE(仮))を用意して、ユーザがクリックされた座標を検出出来る仕組みを取る予定。

    • ESCシークエンス
      文字列に含まれるESCシークエンスについては、色々考えたがEDITコントロール側で対処する事にした。(若干遅くなるが…) 対応内容について、今回は、とりあえずのトライアル版であるので、以下を対応する。
      書式意味note
      ESC *画面クリアESC [2Jは未対応
      ESC [pl;pc H
      ESC [pl;pc f
      カーソル位置指定ESC = lcは未対応
      ESC [nn m nnで、テキストの属性を指定する nnについては、下記
      また、ESCを含めて、250文字以内であれば、
      セミコロン(;)区切りの複数指定は可能とする。

      属性は、以下の通りとする。リバースの意味合い等、若干、本来の意味とニュアンスが違う箇所もあるが、そこはCWCCオリジナルって事で…。
      nn属性notenn属性note
      0 または無しデフォルト
      属性
      Fw=0x000
      Bk=0xFFF
      4ブリンク
      停止
      brink=0
      5ブリンクbrink=1
      6正転reverce=0
      7リバースreverce=1
      17Fw=0xF00
      18Fw=0x00F
      19Fw=0xF0F
      20Fw=0x0F0
      21黄色Fw=0xFF0
      22水色Fw=0x0FF
      23Fw=0xFFF
      30Fw=0x000 40黒反転Bk=0x000
      31Fw=0xF00 41赤反転Bk=0xF00
      32Fw=0x0F0 42緑反転Bk=0x0F0
      33黄色Fw=0xFF0 43黄色反転Bk=0xFF0
      34Fw=0x00F 44青反転Bk=0x00F
      35Fw=0xF0F 45紫反転Bk=0xF0F
      36水色Fw=0x0FF 46水色反転Bk=0x0FF
      37Fw=0xFFF 47白反転Bk=0xFFF
      50灰色Fw=0x777 60灰色反転Bk=0x777
      51赤(暗)Fw=0x700 61赤(暗)反転Bk=0x700
      52緑(暗)Fw=0x070 62緑(暗)反転Bk=0x070
      53黄色(暗)Fw=0x770 63黄色(暗)反転Bk=0x770
      54青(暗)Fw=0x007 64青(暗)反転Bk=0x007
      55紫(暗)Fw=0x707 65紫(暗)反転Bk=0x707
      56水色(暗)Fw=0x077 66水色(暗)反転Bk=0x077
      57シルバーFw=0x777 67シルバー反転Bk=0x777
      ※表中、色付き部分は、Cwccオリジナル

    • 試作
      という事で、ここで紹介しているwinlib.cpp,winlib.hを使って試作してみた。

      と言っても、CWCCに取り込んだ訳では無いので、マニュアル入力になっている。例えば、緑色でTESTと表示させたければ、本来は、CwccPrintf("\x1b[32mTEST…の様に、入力するのだが、この試作では、[ESC],[[],[3],[2],[m],[T],[E],[S],[T]…の様な手順でキーを押下する事になる。勿論、CWCCに組み込んだ場合は、CwccPrintf()等の作業の中で、この手順が行われる訳だな…。因みに、ESC BでBOLD(太字),ESC Iでイタリックを選択出来るが、試して貰えば分かる様に、BOLDやITALICにすると、文字幅が若干広くなる為か、ノーマル幅と混ぜて使うと、表示段階でズレてしまう。という事もあって、現状ちょっと保留状態である。あっと、因みに、フォントは、MSゴシックとした。尚、マウス入力については、今回のサンプルでは、マウスの左ボタン押下時のみをアクティブとしている。左ボタン押下で、押下時のコンソール座標をMessageBox表示する様にした。
      試作のサンプルコード
      サンプルとして、試作コードをソース付きで、置いておくけど、半ば思いつきで造ったので、自分で読んでも意味不明な所がある(TT)…真性ヤキソバである。暇で、勇気のある人は解読してみて!まぁ、それはさておき、CWCCに組み込む場合は、もう少し整理して、クラスに纏めないと、収集付かなくなるだろうし…。

      さてと、ずいぶん試作に時間掛けちゃったけど、次回は、組み込みまで行けるかな??
2004/11/04
HomeSweetHome2
Ozzy's Software