メルマガ:あゆしゃのC言語プログラミング
タイトル:あゆしゃのC言語プログラミング(Vol.589) CE9 CCEMainクラス  2005/07/20


/*========================================================*/
    <<<あゆしゃのC言語プログラミング>>>
/*========================================================*/
 第589回 CE9 CCEMainクラス
 発行    2005年7月20日(水曜日)
 発行数   約2600

{magclick}
/*========================================================*/
 はじめに ( 決り文句 )
/*========================================================*/
・このメールマガジンは、主にまぐまぐさんから発行しています。
・ジャンルは、マルチメディアのプログラム、C言語です。
・横60文字で作成し、インデントは大抵半角スペース4つです。
・ここで扱うプログラムは、C言語と半光年以内のものです。
・登録解除は、メルマガのホームページでお願いします。
・過去ログはバックナンバー(下欄参照)を活用して下さい。
・内容は私が感じたもので、最新の技術も、へたれもあります。
・わかりやすさを優先させる為、たまに嘘があるかもしれません。
・セキュリティ突破のため、暗号化された単語があります。

/*========================================================*/
 ご挨拶
/*========================================================*/

 こんにちは。あゆしゃです。

 先日、とんでもない事件がありました。

 いつものように愛車のプリウスをぷりぷり言わせて走っていた
ところ、いきなり、

★「ピー」という音とともに、異常ランプが点灯。

 びっくりしたあゆしゃは、

★そのまま目的地まで走り続けました。

 いや、大丈夫かなぁとおもって。。


 異常ランプが付くだけで、なにが異常なのかという付加情報は
表示されません。

 おそらく、ECUがダイアグ(診断エラー)を出しているという
ことなので、検査機器をつなげれば何が故障しているのかが1発で
判るはずです。

 が、ユーザに何も伝わらないというのは、少し怖いですね。。

{magclick}
/*========================================================*/
 今回のお題  << CE9 CCEMainクラス >>
/*========================================================*/

 前回、メインの変数遷移図を作成しました。

「メイン」
 |
 |<初回、サイズ変更、ファイル変更>
 |    初期化、ファイル描画、フレーム描画
 |
 |<選択変更>前回選択消去、選択描画
 |
 |<更新>描画
 ↓
「スクリーン」

/*========================================================*/

 これを踏まえて、クラスを作成します。

class CCEMain : public CCEImage
{
public:
    CImage imgFile;
    CString m_stFilename;
    int m_selwk;
    int m_selwkold;
    int m_cell_size;
public:
    // コンストラクタ
    CCEMain();
public:
    // サイズ変更チェック
    virtual BOOL CheckResize( int width, int height );
    // ヒットチェック
    virtual int HitCheck( POINT& pos );
    // 背景描画
    virtual void DrawBack( void );
    // 選択消去
    virtual void EraseSelect( void );
    // 選択描画
    virtual void DrawSelect( void );
};

 クラスはこんな感じでしょうか。


// コンストラクタ
CCEMain::CCEMain()
{
    // とりあえず画像を作っておく
    imgFile.Create( 640, 480, 32 );
    
    m_cell_size = 32;
}

// サイズ変更チェック
BOOL CCEMain::CheckResize( int width, int height )
{
    // 幅は画面の半分、縦幅は比率に合わせて
    int w2 = width / 2;
    int fw = imgFile.Width();
    int fh = imgFile.Height();
    CCEImage:;CheckResize( w2, hys2( w2, 0, fw, fh ) );
}

// ヒットチェック
int CCEMain::HitCheck( POINT& pos )
{
    const int m = 2;    // マージン
    int xnum = GetXNum();
    int ynum = GetYNum();
    int xs = hys2<int>( pos.x, 0, m_dw, 0, xnum );
    int ys = hys2<int>( pos.y, 0, m_dh, 0, ynum );
    int sx1 = GetCellX1( xs ) + m;
    int sx2 = GetCellX2( xs ) - m;
    int sy1 = GetCellY1( ys ) + m;
    int sy2 = GetCellY2( ys ) - m;
    int s = MakeSel( xs, ys );
    if( xs >= xnum || ys >= ynum ||
        pos.x < sx1 || pos.x > sx2 ||
        pos.y < sy1 || pos.y > sy2 )    // 範囲外だったら、
    {
        s = m_sel; // 現在と同じ値を返す
    }
    return s;
}

 ヒットチェックは、座標をスクリーン座標から各イメージの
座標に変換する処理を、前回ではCCEPaletで行いましたが、
CCEImageでできる話なので、変更しました。

 メインの選択位置は2次元なので、上位ワードと下位ワードに
それぞれXとYを保存します。

 マージンがあるのはパレットと同じです。

 パレットのヒットチェックで、

    if( s >= PAL_SIZE &&
        x < x1 &&
        x > x2 &&
        y < m_dy + m &&
        y > m_dy2 - m )     // 範囲外だったら、

 と書かれていましたが、&&が間違いでした。
 ||に訂正しました。

(&&なんて、動くわけないじゃん、ねぇ?)

// 背景描画
void CCEMain::DrawBack( void )
{
    CCEImage::DrawBack();   // 背景色を黒で塗りつぶし
    int xnum = GetXNum();
    int ynum = GetYNum();
    HDC hFile = imgFile.GetDC();
    int i, j;
    for( i = 0; i < ynum; i++ )
    {
        for( j = 0; j < xnum; j++ )
        {
            DrawCell( MakeSel( i, j ) );
        }
    }
    imgFile.ReleaseDC();
    
    // フレームの描画
    DrawFrame();
}

 昔からの慣例として、iがY座標、jがX座標になっています。

 CCEPaletと同じように、各パーツの描画は単独の関数として、
消去関数でも使用します。

// セルの描画
void CCEMain::DrawCell( HDC hFile, int sel )
{
    // 表示座標
    int dx1 = GetCellX1( sel );
    int dx2 = GetCellX2( sel );
    int dy1 = GetCellY1( sel );
    int dy2 = GetCellY2( sel );
    int dw = dx2 - dx1;
    int dh = dy2 - dy1;
    // イメージ座標
    int ix1 = GetImgX1( sel );
    int ix2 = GetImgX2( sel );
    int iy1 = GetImgY1( sel );
    int iy2 = GetImgY2( sel );
    int iw = ix2 - ix1;
    int ih = iy2 - iy1;
    // 描画
    img.StretchBlt( hFile,
        dx1, dy1, dw, dh, ix1, iy1, iw, ih );
}

// フレームの描画
void CCEMain::DrawFrame( void )
{
    int xnum = GetXNum();
    int ynum = GetYNum();
    CDC& dc = *CDC::FromHandle( img.GetDC() );
    imgPalet.SetFrameColor( dc );   // フレーム色を設定
    int i;
    for( i = 0; i <= xnum; i++ )
    {
        int dx = GetCellX1( i ) - 1;
        dc.MoveTo( dx, 0 );
        dc.Lineto( dx, m_dh );
    }
    for( i = 0; i <= ynum; i++ )
    {
        int dy = GetCellY1( i ) - 1;
        dc.MoveTo( 0, dy );
        dc.Lineto( m_dw, dy );
    }
    imgPalet.ReleaseColor( dc );    // 色を元に戻す
    img.ReleaseDC();
}

// 選択消去
void CCEMain::EraseSelect( void )
{
    COLORREF fcol = imgPalet.GetFrameColor();
    DrawCellFrame( m_selold, fcol );
    DrawCellFrame( m_selwkold, fcol );
}

// 選択描画
void CCEMain::DrawSelect( void )
{
    DrawCellFrame( m_sel, imgPalet.GetFrameColor() );
    DrawCellFrame( m_selwk, imgPalet.GetSelectColor() );
}

 ふぅ、こんな感じでしょうか。

{magclick}
/*========================================================*/
 さいごに
/*========================================================*/

 るっっぱ〜ん気分が、このボリュームになりました。

{magclick}
/*========================================================*/
 次回予告
/*========================================================*/

 次回は7月22日(金曜日)に、第590回をお送りします。
 お題は「CE9 キャラエディッタ2」

 パレットと同じように、このソースをかき集めて、メインまで
動作するバージョンを固めましょう。

 お楽しみに!

/*========================================================*/
 最後の決り文句
/*========================================================*/
 このメールマガジンは、まぐまぐさんから発行しています。
 このメールマガジンを解除したい場合は、まぐまぐさんをご利用
ください。このメルマガのまぐまぐアイディーは最後にあります。
 このメールマガジンには広告が挿入されていますか?
 このメールマガジンの内容に文面の引用はありませんか?
 めーらっくすの場合はめーらっくすの利用方に従ってください。
 このメールマガジンの内容の、転用、流用、宣伝、リンク、
意味不明でも故障が報告されるだけまし? なんて大歓迎です。

{magclick}
/*========================================================*/
 
/*========================================================*/

発行者 あゆしゃ

ホームページ::あゆしゃの世界
http://ayusya.hp.infoseek.co.jp/

ご意見・ご感想・ご質問メール
mailto:ayusya@flamenco.plala.or.jp

まぐまぐ::アイディー
0000020674

まぐまぐ::登録と解除
http://www.mag2.com/m/0000020674.htm

まぐまぐ::バックナンバー
http://jazz.tegami.com/backnumber/frame.cgi?id=0000020674

めーらっくす::アイディー
MM3E1AEE285AB4F

めーらっくす::登録と解除
http://www.mailux.com/mm_dsp.php?mm_id=MM3E1AEE285AB4F 

めーらっくす::バックナンバー★最近のものならこちらが便利★
http://www.mailux.com/mm_bno_list.php?mm_id=MM3E1AEE285AB4F

ブラウザの閉じるボタンで閉じてください。