メルマガ:あゆしゃのC言語プログラミング
タイトル:あゆしゃのC言語プログラミング(Vol.592) CE12 ワークの設計  2005/07/27


/*========================================================*/
    <<<あゆしゃのC言語プログラミング>>>
/*========================================================*/
 第592回 CE12 ワークの設計
 発行    2005年7月27日(水曜日)
 発行数   約2500

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

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

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

 以前、このメルマガで「予約配信」と「即時配信」を間違えて
しまい、とんでもない順番で発行してしまったことがありました。

 メルマガの管理者ページの発行するところでは、これらの
「予約配信」と「即時配信」のボタンが隣同士だったため、
押し間違えてしまったのです。

 そのとき、まぐまぐさんに「使いにくい〜」という苦情メールを
だしました。

 よっぽどそういう苦情がたくさん来ていたのでしょうか、先日、
まぐまぐさんがユーザインターフェースを改善しました。

 もう、配信を間違えることはありません。

 めでたしめでたし。です。

{magclick}
/*========================================================*/
 今回のお題  << CE12 ワークの設計 >>
/*========================================================*/

 パレットは、色の管理を行います。

 メインは、ファイル画像の管理を行います。

 そして今回のワークは、作業単位の画像の編集を行うものです。

 フレームが描画され、マウス(ペン)が当たっている位置に
選択用のフレームが表示されます。

 つまり、見ための構造としてはCCEMainと大差ありません。

「ワーク」
 |
 |<初回、サイズ変更、データ変更>
 |     初期化、データ描画、フレーム描画
 |
 |<更新、選択変更>前回選択消去、選択描画
 |
 |<更新、編集>選択範囲のデータ再描画
 |
 |<更新>描画
 ↓
「スクリーン」

 クラスの構成も、ほとんどCCEMainとかわりがないです。

 最も大きく違うのは、メインが持っている内部データがファイル
の画像データであったのに対して、ワークの持つ内部データは
色情報の2次元配列だという点です。

 また、ワークは選択領域が複数あります。

 なぜなら、ペンが大きければそれ全体が選択領域になるから
です。

class CCEWork : public CCEImage
{
public:
    enum { WORK_SIZE_MAX = 128 };
    
    // 色情報を保存するバッファ
    COLORREF col_buff[ WORK_SIZE_MAX ][ WORK_SIZE_MAX ];
    
    // 選択情報を保存するバッファ
    BOOL sel_buff[ WORK_SIZE_MAX ][ WORK_SIZE_MAX ];
};

 関数構成はやっぱり似たようなもので、選択描画処理が2次元
ループになるというところが大きく違います。

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

// コンストラクタ
CCEWork::CCEWork()
{
    memset( col_buff, 0, sizeof( col_buff ) );
    memset( sel_buff, 0, sizeof( sel_buff ) );
    
    m_cell_size = 32;
    m_cell_width = GetCellWidth();
}

// 1セルあたりのドット数
int CCEWork::GetCellWidth()
{
    int ret = 0;
    switch( m_cell_size )
    {
    case 32 : ret = 7; break;
    case 64 : ret = 6; break;
    case 128 : ret = 5; break;
    default : ret = 2; break;
    }
    return ret;
}

 1セルあたりのドットすうが大きければ大きいほど、作業が
しやすくなります。

 しかし、左半分にメインがいるため、あまり大きくできません。

 メインを小さくすればよいのですが、1画面にすべての情報を
表示しておきたいのです。

 縮小表示をしすぎると、つぶれてしまいますから、困ります。

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

// セルの描画
void CCEWork::DrawCell( CDC& dc, int xn, int yn )
{
    if( xn >= 0 && xn < m_cell_size &&
        yn >= 0 && yn < m_cell_size )
    {
        int x1 = GetCellX1( xn );
        int x2 = GetCellX2( xn );
        int y1 = GetCellY1( yn );
        int y2 = GetCellY2( yn );
        dc.FillSolidRect(
            &CRect( x1, y1, x2, y2 ),
            col_buff[ xn ][ yn ] );
    }
}

 メインでは座標を割り出した後、その位置に相当するファイル
画像をコピーしましたが、ワークでは単純に塗りつぶしでOKです。

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

// 選択消去
void CCEWork::EraseSelect( void )
{
    COLORREF fcol = imgPalet.GetBackColor();
    DrawSelectFrame( fcol );
}

// 選択描画
void CCEWork::DrawSelect( void )
{
    MakeCellBuff();
    COLORREF fcol = imgPalet.GetSelColor();
    if( fcol == imgPalet.GetBackColor() ) {
        fcol = imgPalet.GetSelectColor();
    }
    DrawSelectFrame( fcol );
}

// 選択描画
void CCEWork::DrawSelectFrame( COLORREF fcol )
{
    int i, j;
    CDC& dc = *CDC::FromHandle( img.GetDC() );
    for( i = 0; i < m_cell_size; i++ )
    {
        for( j = 0; j < m_cell_size; j++ )
        {
            if( sel_buff[ i ][ j ] ) {
                DrawCellFrame( dc, i, j, fcol );
            }
        }
    }
    img.ReleaseDC();
}

 選択範囲の描画と消去は、ループ部分の処理が共通なので
関数で楽をできて幸せです。

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

// 選択位置を決定
void CCEWork::MakeCellBuff()
{
    memset( sel_buff, 0, sizeof( sel_buff ) );
    int xn = SelX( m_sel );
    int yn = SelY( m_sel );
    int i, j;
    for( i = 0; i < 5; i++ )
    {
        for( j = 0; j < 5; j++ )
        {
            int x = xn - 2 + j;
            int y = yn - 2 + i;
            if( x >= 0 && x < m_cell_size &&
                y >= 0 && y < m_cell_size )
            {
                sel_buff[ x ][ y ] = TRUE;
            }
        }
    }
}

 選択範囲を決定するのはペンの種類が必要ですが、それはこの後
に作成する、ツールクラスが必要です。

 とりあえず、5*5の矩形が選択されているものとして処理して
みましょう。

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

 なんだかエアコンが寒すぎるなぁ、壊れたかなぁと思っていた
ところ、

★設定温度が24度でした。

 死んでしまうよ。。設定項目はちゃんと確認しましょうね?

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

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

 ワークの表示まで固めます。

 お楽しみに!

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

{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

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