プログラミングのメモ帳(C/C++/HSP)

日々のプログラミングで気づいた点や小技集を紹介します。(Windows 10/XP/Vista、VC2017、HSP)

ひらがな一覧の描画(横タイプ)

2011年05月24日 03時40分00秒 | 無料で学べる講座

CreateFont 関数で64×64ドットの大きい論理フォントを作成して「ひらがな一覧」を横タイプで描画します。

  1. SetBkMode 関数で背景モードを TRANSPARENT 定数で透過表現。
  2. CreateFont 関数で64×64ドットの大きい論理フォントを作成。
  3. SelectObject 関数で新しい論理フォントに切り替え。
  4. funcDrawHiraH 関数でひらがな一覧を横タイプで描画。
  5. SelectObject 関数で GetStockObject 関数の SYSTEM_FONT 定数に切り替え。
  6. DeleteObject 関数で作成した論理フォントを削除。

プロトタイプ宣言

HFONT CreateFont(
    int     nHeight,                // フォントの高さ
    int     nWidth,                 // 平均文字幅
    int     nEscapement,            // 文字送り方向の角度
    int     nOrientation,           // ベースラインの角度
    int     fnWeight,               // フォントの太さ
    DWORD   fdwItalic,              // 斜体にするかどうか
    DWORD   fdwUnderline,           // 下線を付けるかどうか
    DWORD   fdwStrikeOut,           // 取り消し線を付けるかどうか
    DWORD   fdwCharSet,             // 文字セットの識別子
    DWORD   fdwOutputPrecision,     // 出力精度
    DWORD   fdwClipPrecision,       // クリッピング精度
    DWORD   fdwQuality,             // 出力品質
    DWORD   fdwPitchAndFamily,      // ピッチとファミリ
    LPCTSTR lpszFace                // フォント名
);

上記の CreateFont 関数は引数が14個もあって使いづらいので便利なマクロ関数を2つ紹介します。1つ目は apiCreateFont マクロ関数でフォントの文字幅、高さ、太さ、斜体、下線、取り消し線、フォント名の7つの引数を取ります。このマクロ関数で一通りのフォントを作成できますが、たまに文字セットを SYMBOL_CHARSET を使いたくなる場合があります。そこで文字セットを引数で指定できる apiCreateFontEx マクロ関数も紹介します。こちらはフォントの文字幅、高さ、太さ、斜体、下線、取り消し線、文字セット、フォント名の8つの引数を取ります。このように便利なマクロ関数を独自に用意しておくとプログラミングが楽になります。その他にも break 付きの CASEDEFAULT も用意すると switch 文のときに毎回 break 命令を記述しなくても良くなります。こちらも便利ですからヘッダ部に定義します。

サンプル

下記に「ひらがな一覧」を横タイプで描画する funcDrawHiraH 関数とプロシージャ関数を載せます。
なお WinMain 関数の基本部のウインドウ・クラスの登録、ウインドウの作成、メッセージ・ループは省略してます。
ご自身で記述して下さい。

//==============================================================================
// ひらがな一覧を描こう
//==============================================================================
#include <tchar.h>
#include <Windows.h>

//------------------------------------------------
// break付きのキーワード
//------------------------------------------------
#define CASE        break;case
#define DEFAULT     break;default

//------------------------------------------------
// このファイルで使用する定数
//------------------------------------------------
#define CHP_WIDTH       (64)        // タイルの横サイズ
#define CHP_HEIGHT      (64)        // タイルの縦サイズ

//------------------------------------------------
// このファイルで使用する関数
//------------------------------------------------
#define apiCreateFont(x,y,n,i,u,v,s)        apiCreateFontEx(x,y,n,i,u,v,SHIFTJIS_CHARSET,s)
#define apiCreateFontEx(x,y,n,i,u,v,c,s)    CreateFont(y,x,0,0,n,i,u,v,c,\
                                             OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,\
                                             (FIXED_PITCH|FF_DONTCARE),s)

//------------------------------------------------
// ひらがな一覧の描画
//------------------------------------------------
static VOID funcDrawHiraH( HDC hDC )
{
    static LPCTSTR hiraTable[] = {
        TEXT("あかさたなはまやらわ"),
        TEXT("いきしちにひみゐりを"),
        TEXT("うくすつぬふむゆるん"),
        TEXT("えけせてねへめゑれ "),
        TEXT("おこそとのほもよろ "),
    }; RECT rc; TCHAR szBuff[ 10 ];
    
    for ( INT cx = 0 ; cx < 10 ; cx++ ){
        for ( INT cy = 0 ; cy < 5 ; cy++ ){
            wsprintf( szBuff, TEXT("%c"), hiraTable[cy][cx] );
            SetRect( &rc, 0, 0, CHP_WIDTH, CHP_HEIGHT );
            
            // 影文字
            OffsetRect( &rc, ((9 - cx) * CHP_WIDTH), (cy * CHP_HEIGHT) );
            SetTextColor( hDC, RGB(0x00,0x00,0x00) );
            DrawText( hDC, szBuff, -1, &rc, (DT_CENTER | DT_VCENTER | DT_SINGLELINE) );
            
            // 薄い緑色
            OffsetRect( &rc, -1, -1 );
            SetTextColor( hDC, RGB(0xCC,0xFF,0xCC) );
            DrawText( hDC, szBuff, -1, &rc, (DT_CENTER | DT_VCENTER | DT_SINGLELINE) );
            
            // 濃い緑色
            OffsetRect( &rc, -2, -2 );
            SetTextColor( hDC, RGB(0x00,0x99,0x00) );
            DrawText( hDC, szBuff, -1, &rc, (DT_CENTER | DT_VCENTER | DT_SINGLELINE) );
        }
    }
}

//------------------------------------------------
// ウインドウ・プロシージャの関数
//------------------------------------------------
extern LRESULT CALLBACK mainWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    switch ( uMsg ){
        CASE WM_CREATE:
            
        CASE WM_CLOSE:
            DestroyWindow( hWnd );
        CASE WM_DESTROY:
            PostQuitMessage( 0 );
        CASE WM_PAINT:
        {
            PAINTSTRUCT     ps;
            HDC             hDC;
            
            hDC = BeginPaint( hWnd, &ps );
            SetBkMode( hDC, TRANSPARENT );
            SelectObject( hDC, apiCreateFont(0,48,FW_NORMAL,0,0,0,TEXT("HG明朝E")) );
            funcDrawHiraH( hDC );
            DeleteObject( SelectObject(hDC,GetStockObject(SYSTEM_FONT)) );
            EndPaint( hWnd, &ps );
        }
        DEFAULT:return DefWindowProc( hWnd, uMsg, wParam, lParam );
    }
    return 0;
}

解説

//------------------------------------------------
// ひらがな一覧の描画
//------------------------------------------------
static VOID funcDrawHiraH( HDC hDC )
{
    static LPCTSTR hiraTable[] = {
        TEXT("あかさたなはまやらわ"),
        TEXT("いきしちにひみゐりを"),
        TEXT("うくすつぬふむゆるん"),
        TEXT("えけせてねへめゑれ "),
        TEXT("おこそとのほもよろ "),
    }; RECT rc; TCHAR szBuff[ 10 ];
    
    for ( INT cx = 0 ; cx < 10 ; cx++ ){
        for ( INT cy = 0 ; cy < 5 ; cy++ ){
            wsprintf( szBuff, TEXT("%c"), hiraTable[cy][cx] );
            SetRect( &rc, 0, 0, CHP_WIDTH, CHP_HEIGHT );
            
            // 影文字
            OffsetRect( &rc, ((9 - cx) * CHP_WIDTH), (cy * CHP_HEIGHT) );
            SetTextColor( hDC, RGB(0x00,0x00,0x00) );
            DrawText( hDC, szBuff, -1, &rc, (DT_CENTER | DT_VCENTER | DT_SINGLELINE) );
            
            // 薄い緑色
            OffsetRect( &rc, -1, -1 );
            SetTextColor( hDC, RGB(0xCC,0xFF,0xCC) );
            DrawText( hDC, szBuff, -1, &rc, (DT_CENTER | DT_VCENTER | DT_SINGLELINE) );
            
            // 濃い緑色
            OffsetRect( &rc, -2, -2 );
            SetTextColor( hDC, RGB(0x00,0x99,0x00) );
            DrawText( hDC, szBuff, -1, &rc, (DT_CENTER | DT_VCENTER | DT_SINGLELINE) );
        }
    }
}

ひらがな一覧の横タイプですから横方向と縦方向の繰り返し文で10×5=50個の文字を描画します。

static LPCTSTR hiraTable[] = {
    TEXT("あかさたなはまやらわ"),
    TEXT("いきしちにひみゐりを"),
    TEXT("うくすつぬふむゆるん"),
    TEXT("えけせてねへめゑれ "),
    TEXT("おこそとのほもよろ "),
};

for ( INT cx = 0 ; cx < 10 ; cx++ ){
    for ( INT cy = 0 ; cy < 5 ; cy++ ){
        ここでひらがな一覧の1つの文字を描画
    }
}

1つの文字は cx、cy で hiraTable 配列の添え字に使って wsprintf 関数で文字から文字列に変換します。

TCHAR szBuff[ 10 ];

wsprintf( szBuff, TEXT("%c"), hiraTable[cy][cx] );

続いて DrawText 関数で64×64ドットの領域に文字を描くために RECT 構造体の rc にサイズをセットします。

RECT rc;

SetRect( &rc, 0, 0, CHP_WIDTH, CHP_HEIGHT );

上記の rc に描画する場所の座標分だけ OffsetRect 関数でずらします。
cx の 9~0 の数値に横方向のドット数(CHP_WIDTH=64)を掛けます。
cy の 0~4 の数値に縦方向のドット数(CHP_HEIGHT=64)を掛けます。
その後に SetTextColor 関数で影色を指定してから DrawText 関数で描画します。

// 影文字
OffsetRect( &rc, ((9 - cx) * CHP_WIDTH), (cy * CHP_HEIGHT) );
SetTextColor( hDC, RGB(0x00,0x00,0x00) );
DrawText( hDC, szBuff, -1, &rc, (DT_CENTER | DT_VCENTER | DT_SINGLELINE) );

続いて薄い緑色を描くために OffsetRect 関数で1ドット左上にずらします。
その後に SetTextColor 関数で薄い緑色を指定してから DrawText 関数で描画します。

// 薄い緑色
OffsetRect( &rc, -1, -1 );
SetTextColor( hDC, RGB(0xCC,0xFF,0xCC) );
DrawText( hDC, szBuff, -1, &rc, (DT_CENTER | DT_VCENTER | DT_SINGLELINE) );

続いて濃い緑色を描くために OffsetRect 関数で2ドット左上にずらします。
その後に SetTextColor 関数で濃い緑色を指定してから DrawText 関数で描画します。

// 濃い緑色
OffsetRect( &rc, -2, -2 );
SetTextColor( hDC, RGB(0x00,0x99,0x00) );
DrawText( hDC, szBuff, -1, &rc, (DT_CENTER | DT_VCENTER | DT_SINGLELINE) );

上記のように影文字、薄い緑色、濃い緑色の順にドットをずらして同じ文字を3つ描くと実行結果のように少々カッコ良い「ひらがな一覧」が描画できます。SetTextColor 関数で赤色系統、青色系統、紫色系統、桃色系統、橙色系統などに変更すると面白いでしょう。

実行結果


コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« ひらがな一覧の描画(縦タイプ) | トップ | カタカナ一覧の描画(縦タイプ) »
最新の画像もっと見る

無料で学べる講座」カテゴリの最新記事