#pragma twice

KAB-studio > プログラミング > #pragma twice > 132 Version 7.12 文字を書こう!

#pragma twice 132 Version 7.12 文字を書こう!

前のページへ 表紙・目次へ 次のページへ

 Version 7.12
文字を書こう!

「さて、今回は文字を書いてみます」
『文字を書く! なんか大変そう』
「それが大変じゃないんだよね」

void CAnimeDlg::OnBDraw() 
{
    HDC hCanvasDC = ::GetDC( m_cCanvasStatic.GetSafeHwnd() );
    const char pchText[] = "あいうえお";

    // 文字を書きます。
    ::TextOut( hCanvasDC, 0, 0, pchText, strlen( pchText ) );
}

『あら簡単』
「文字を書くのは TextOut() って API 」
『第1引数はデバイスコンテキスト、第2、3引数は書く位置ね。第4引数
は書く文字列、第5引数は……その文字数?』
「文字数っていうか長さね。これで文字をデバイスコンテキストに書くこと
ができます」
『ほい。お、ちゃんと出た』
「これだけなら簡単にできるってことだね」
『あれ、でもなんか背景色が変……』
「これは Ver 7.10 ( No.130 ) の背景モードと同じ、 SetBkMode() を使い
ます」

void CAnimeDlg::OnBDraw() 
{
    HDC hCanvasDC = ::GetDC( m_cCanvasStatic.GetSafeHwnd() );
    const char pchText[] = "あいうえお";

    // 背景を透明モードに。
    ::SetBkMode( hCanvasDC, TRANSPARENT );

    ::TextOut( hCanvasDC, 0, 0, pchText, strlen( pchText ) );
}

『あ、今度はちゃんとデバイスコンテキストと同じ色になった』
「同じく、背景色を変えることもできます」
『文字の色は? ペン?』
「ううん、 SetTextColor() って専用の API があるからそれで」

void CAnimeDlg::OnBDraw() 
{
    HDC hCanvasDC = ::GetDC( m_cCanvasStatic.GetSafeHwnd() );
    const char pchText[] = "あいうえお";

    // 文字色変更。
    ::SetTextColor( hCanvasDC, RGB( 255, 0, 0 ) );
    // 背景色変更。
    ::SetBkColor( hCanvasDC, RGB( 0, 0, 255 ) );

    ::TextOut( hCanvasDC, 0, 0, pchText, strlen( pchText ) );
}

『おお、文字が赤く、背景が青くなった!』
「こういうふうに、文字を書く時も、他のと違う部分があるからねー」
『っつーか、そういうのを憶えるのがこのシリーズのテーマじゃないの?』
「それはそうだけど、文字列関係は特別に特別な部分が多いかな。文字を書
くってことは、結構面倒な部分多くてねー」
『たとえば?』
「たとえば、位置」

void CAnimeDlg::OnBDraw() 
{
    HDC hCanvasDC = ::GetDC( m_cCanvasStatic.GetSafeHwnd() );
    ::SetBkMode( hCanvasDC, TRANSPARENT );

    const char pchText[] = "あいうえお";
    ::TextOut( hCanvasDC, 0, 0, pchText, strlen( pchText ) );

    const char pchText2[] = "かきくけこ";
    ::TextOut( hCanvasDC, 0, 0, pchText2, strlen( pchText2 ) );
}

『ん? ただ2度書いてるだけじゃない』
「そう。だから」
『あいうえおの上にかきくけこが書かれてる……』
「ってことは、今書いた文の次に新しい文を書く時には、 TextOut() の第
2引数で指定する X 座標を増やさないといけないわけ」
『げ! そういえばそうね、それってめんどくさそう』
「というわけで、自動的に次の位置に持ってきてくれるモードがあります」

void CAnimeDlg::OnBDraw() 
{
    HDC hCanvasDC = ::GetDC( m_cCanvasStatic.GetSafeHwnd() );
    ::SetBkMode( hCanvasDC, TRANSPARENT );

    // 座標移動モード。
    ::SetTextAlign( hCanvasDC, TA_UPDATECP );

    const char pchText[] = "あいうえお";
    ::TextOut( hCanvasDC, 0, 0, pchText, strlen( pchText ) );

    const char pchText2[] = "かきくけこ";
    ::TextOut( hCanvasDC, 0, 0, pchText2, strlen( pchText2 ) );
}

『 SetTextAlign() を使うんだ』
「この API に TA_UPDATECP を渡すと」
『あいうえおかきくけこってなった!』
「直前に書いた位置をしらべて、自動的にそのあとに継ぎ足してくれるわ
け」
『便利ねー』
「他にも、手動で移動する方法もあります」

void CAnimeDlg::OnBDraw() 
{
    HDC hCanvasDC = ::GetDC( m_cCanvasStatic.GetSafeHwnd() );

    const char pchText[] = "あいうえお";
    SIZE stSize;

    ::GetTextExtentPoint32
        ( hCanvasDC, pchText, strlen( pchText )
        , &stSize );
    TRACE( "%d, %d\n", stSize.cx, stSize.cy );
    // 80, 18
}

『 GetTextExtentPoint32() って API 使って……何してるの?』
「〈あいうえお〉って文字列の横幅と高さを調べてます」
『……?? どゆこと?』
「後で教えるけど、こういうふうに書き込む文字列は、フォントとか文字の
大きさとかも変えられます」
『変えられなきゃ困るもんね』
「でもそしたら、〈次の位置〉を TextOut() の第2、第3引数で指定する
時に困るでしょ」
『そういえば! つまり、次に書く時に〈あいうえお〉の〈お〉の右端の位
置が分からなきゃいけないわけだ』
「それを取得するのが GetTextExtentPoint32() 」
『第1引数にデバイスコンテキスト、第2引数と第3引数は文字列の、第4
引数……の SIZE って?』
「 RECT みたいな構造体で、これは横幅と縦幅だけを入れるためのもの」
『なるほど、 SIZE::cx と SIZE::cy に、第2引数の文字列の横幅と高さが
入るわけだ』
「そゆこと。で、ここでは横幅 80 、高さ 18 ってことが分かりました」
『……ホントにそう?』
「文字列を〈あいうえおあいうえお〉にすれば」
『あ、横幅が倍になった』
「他に、実際に画像処理ソフトでキャプチャーしたものを計ってもいいし」
『それってなんかアレ……』
「で、これを踏まえて、実際に横幅の分だけ進めてみましょう」

void CAnimeDlg::OnBDraw() 
{
    HDC hCanvasDC = ::GetDC( m_cCanvasStatic.GetSafeHwnd() );

    const char pchText[] = "あいうえお";
    ::TextOut( hCanvasDC, 0, 0, pchText, strlen( pchText ) );

    SIZE stSize;
    ::GetTextExtentPoint32( hCanvasDC, pchText, strlen( pchText ), &stSize );

    const char pchText2[] = "かきくけこ";
    // 進めて書き込みます。
    ::TextOut( hCanvasDC, stSize.cx, 0, pchText2, strlen( pchText2 ) );
}

『お、最後の TextOut() でその横幅分進めてる』
「こうすれば」
『あいうえおかきくけになるわけね』
「それに、最後の行を」

    ::TextOut( hCanvasDC, 0, stSize.cy, pchText2, strlen( pchText2 ) );

「に変えれば」
『2行目に書かれる! そっかー、改行したいときはこういうふうにすれば
いいんだー』
「ただ、こういう風に直に書くことは、もしかしたら少ないかも」
『なんで?』
「だって、テキストボックスとかあるでしょ」
『あ、そういえば』
「テキストボックスだと色変えたりはできないんだけど、リッチエディット
ボックスっていうの使えば、こっちは変えることできるし」
『そういう便利なのを使えばいいってわけね』
「こっちなら文字の幅とか調べなくても普通に書き込めるし。ただ」
『ただ?』
「デバイスコンテキストに対して書くんならこういう形式じゃないといけな
いから、これは憶えとく必要あるかも」

/*
    Preview Next Story!
*/
『っつーか、全部憶えきれないって』
「んー、憶えとくと憶えないとこを分けるのが大事かも」
『分ける?』
「仕組みはしっかりイメージできるように憶えておいて」
『憶えなくていいのは?』
「それは、いっぱいメンバ変数のある構造体とか」
『げ、それイヤそう!』
「というわけで次回」
< Version 7.13 フォントを変えよう! >
『につづく!』
「ってゆーか、僕自身憶えられないし」
『それ違うと思う』
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。