Windows API/文字表示の命令
文字表示の関数

「Windows API/Windows デスクトップアプリケーション」で自動作成されたコードをもとに説明しますので、そのコードを用意してください。(空のテンプレートで作ったコードでもウィンドウに文字や画像を描画することは可能。とりあえず本wikibooksでは、説明の単純化のために、先に「Windows デスクトップアプリケーション」で自動作成されたコードで説明する。)
文字表示の関数

Windows APIの文字表示で、いちばん簡単な関数は、 TextOut という関数です。
文字表示の関数

のように使います。「hdc」は対象のウィンドウ名(「ハンドル名」などという)です。初期設定をウィザードで自動作成した場合に標準ではこの名前になってるので、本書では、特に断らない限り、この関数名を使う事とします。
文字表示の関数

上記の末尾の「3」は文字数です。もし、この数字を2に書き換えると「テス」と2文字しか表示されません。
文字表示の関数

第2引数の「10」と第3引数の「20」の意味は、x座標が10の位置、y座標が20の位置、という意味です。
文字表示の関数

ただし、このTextOut関数など、ウィンドウを描画するための関数を書ける位置は限られていて、
文字表示の関数

という関数(120行目あたりにある。)から始まるブロック中にある条件分岐「 case WM_PAINT: 」のブロック中で書きます。
文字表示の関数

「// TODO: HDC を使用する描画コードをここに追加してください...」とあるので、 その直後の行で書けばいいのです。
文字表示の関数

すでに、
文字表示の関数

とあるので、そこに TextOut 関数を挿入し、
文字表示の関数

のようになります。
文字表示の関数

なお、TextOut関数は改行を表現できません。改行したい場合は、DrawText関数に改行の機能があります。
文字表示の関数

TEXT("テスト")のように TEXT()とありますが、これは何かというと、単にWindows独自の関数(のようなもの)で、カッコ内にある二重引用符 「"」 と 「"」 で囲まれた文字列を、文字型だと認識される機能のものです。
文字表示の関数

これが必要な理由は、単に、最近のWindowsの開発者が、文法をそう決めたからです。
文字表示の関数

なので、2001年ぐらいの古いWin32APIの技術書を読むと、TEXT() が使われていない書籍もあります(例えば CQ出版社『Win32 API 完全マスター』山本潔 著、2001年3月1日初版、2006年8月1日第8版、41ページのコード「リスト2.2」「定番 hello のプログラム」など)。過去のWin32APIでは、このTEXT()という記法を採用してなかった時代もあります。
文字表示の関数

しかし、現在のWin32APIでは、文字列を宣言する際には TEXT() を使わないとコンパイルエラーになる仕様になっているので、TEXT() を使ってください。
文字表示の関数

ネット上にはTEXT() の存在意義について、「Unicodeがどうこう」とか「リテラルがどうこう」とか、もっともらしい理屈が転がってますが、しかし本当の理由は マイクロソフト社が単に、TEXT() という記法を採用したというだけに過ぎません。
文字表示の関数

たぶん、マイクロソフト社でVisual Studioコンパイラを作っている人にとっては、こういう記法があったほうが、コンパイラ内での二重引用符「"」 と 「"」 の管理の実装がラクなのでしょう。プログラム上では、文字列を使うたびに何度も「"」を使用しますので、この「"」が文字列の始めの「"」か、それとも終わりの「"」なのかをTEXT()という文法を使わずに判別できるコンパイラを製作することは、きっと、メンドウくさいのでしょう(原理的には不可能ではないが)。
文字表示の関数

いっぽう、TEXT()という記法があれば、TEXT(の後に1回目にくる「"」は必ず、文字列の開始をあらわす記号だと分かります。このため、コンパイラを作りやすくなります。
文字表示の関数

さて、コールバック関数の冒頭の「WndProc」の部分は我々が変更できる関数名ですが、初期設定をウィザードで自動作成したときに、この名前になります。
文字表示の関数

また、このコールバック関数をウィンドウと関連づける必要があるため、そのための登録を、冒頭のクラス宣言で行う必要があったのですが、初期設定により既に自動登録されています。
文字表示の関数

どこで自動登録されているか言うと、60行目あたりを見れば、
文字表示の関数

とありますが、
文字表示の関数

そのクラス登録の一連のコード中の70行目あたりに、
文字表示の関数

とあるはずです。これにより、コールバック関数 WndProc が、ウィンドウと関連づけられています。
文字表示の関数

のように、毎回、字数を入力するのは、面倒である。
文字表示の関数

そこで、「lstrlen()」という、文字列の長さを返す関数を使う。これは、C言語のstrlen関数のWindows版である。
文字表示の関数

APIプログラミングでは、strlen関数ではなく、lstrlen関数を使わないといけないだろう。
文字表示の関数

また、毎回メッセージごとにTextOut関数を書き換えるのは非効率であるので、たとえば変数aisatuをあらかじめ用意して、実用的にはTextOut(hdc, 10, 20, aisatu, lstrlen(aisatu)); のように変数(このコードではaisatuが変数)を使うのが効率的である。
文字表示の関数

コード例
文字表示の関数

のように書くのが実用的である。
文字表示の関数

TCHARは型であり、C言語でいう文字型 char のWindows版である。このほかにもWindowsにはWinodws版の文字型変数はあるが、とりあえず初心者は、まず TCHAR を知っておけばいい。
文字表示の関数

C言語では、文字列を宣言するときには、配列として必要な要素数を決めて宣言しなければならないので、とりあえず60とした。
文字表示の関数

文字列については、ユニコードなど文字コードとの対応の問題があるが、とりあえずTCHARをつかっておけば、あまり問題が起きないだろう。
文字表示の関数

lstrcpyは、C言語でいう文字列のコピー関数strcpyのWindows版である。
文字表示の関数

このように、Windows独自の関数がいろいろとあるので、とりあえず初心者は、上記のコードをそのままコピーして、自分の使いたいように改造すれば効率的だろう。
文字表示の関数

TextOutする事じたいは難しくないのだが、それを実用的なコードにするためにWindows独自の型などを学ばなければならず、そっちが難しい。
文字表示の関数

TCHAR型でもchar型と同様の方法で、下記コードのようにユーザ定義関数の引数に使うことができます。(ただしwindowsAPI側の特殊事情として、HDC hdc などデバイスコンテクストも引数に加えないといけない。)
文字表示の関数

windowsAPIではあまり実用性の無い例だが、下記コードのようにTCHAR型もユーザ定義関数の引数にすることが可能である。
文字表示の関数

コード上部の「// グローバル変数」宣言部分には、
文字表示の関数

case WM_PAINT: 側は、
文字表示の関数

となります。
文字表示の関数

たとえば、マイクロソフトの開発者むけサイト MSDN を見ると、TextOut関数について、
文字表示の関数

と、冒頭に、あかたも文法のような何か が書いてある。MSDN TextOutA function
文字表示の関数

なお、MSDN英語版では、このような冒頭に書かれているアレを「Syntax」と説明している。日本語に直訳すると、「統語論」、「公文法」、「文法」である(※ 参考文献: 『ジーニアス英和辞典 <改訂版> 2色刷』1997年3月1日 改訂版)。
文字表示の関数

これは、
文字表示の関数

が書かれている。
文字表示の関数

より詳細に説明すれば、
文字表示の関数

である。
文字表示の関数

さて、このシンタックスに書かれている関数は TextOut関数ではなくTextOutA関数だが、これは単に文字コードのANSI版との互換性に対応したバージョンがTextOutA関数なだけである。TextOut関数を使用すれば、Visual Studioが内部でコンパイル時に文字コード関連の設定を適切な設定に置き換えてくれるので、初心者は気にせずTextOutで置き換えてよい。
文字表示の関数

msdnのサンプルコードでも、TextOut関数で説明している(2019年10月4日に閲覧)。
文字表示の関数

冒頭の BOOL が気になる人もいるだろうが、冒頭の型は、その関数を呼び出した時の戻り値の型である。BOOL型 という型がある。
文字表示の関数

TextOut関数にかぎらず、API関数を実際に使う場合、冒頭の型は宣言しない。つまり、
文字表示の関数

プログラミング中にTextOut関数を実際に呼び出して使用するための関数を記述したい場合は、単に
文字表示の関数

のような、冒頭のBOOL型を除去した書式で書く必要がある。
文字表示の関数

つまり、実際のプログラミング作業では、シンタックスにある冒頭の型を除去した書き方で、コードを記述することになる。
文字表示の関数

もし仮にシンタックスの記法のまま、冒頭の型をAPI関数の呼び出し時に宣言しても、単にコンパイル時にエラーになるだけだろう。
文字表示の関数

市販の解説書など、書籍によっては、シンタックスのことを「書式」などという用語で、こういう書き方をして説明しているが(※ 参考文献: 林晴彦『明快入門Visual C++ 2010 シニア編』ソフトバンククリエイティブ、2009年8月24日 初版 第1刷発行、24ページ。)、しかし、けっして実際のコードでは、こういうふうにBOOL型などを宣言してから使うわけではない。
文字表示の関数

またシンタックスでは、数行に分けて書かれているが、これは単に読みやすいようにマイクロソフト社が改行して紹介しているだけであるので、実際の使用では改行せずに1行にまとめて宣言しても良い。
文字表示の関数

実際、MSDNのサンプルコードでは、
文字表示の関数

のように、冒頭の型を除去したあとに1行でまとめて宣言している。
文字表示の関数

TextOut関数のほかにもDrawText関数など、さまざまなAPI関数があるが、それらのどれも、実際のコード中での使用宣言の際には、シンタックスの冒頭にある型を除去した形で宣言することになる。
文字列型

windowsAPIプログラミングの標準的な文字列型は TCHAR 型です。(char型は入門者には、おすすめできません。特殊な用途では char 型も使う。)
文字列型

TCHR型の宣言は、 TCHAR moji[40] = TEXT("おはよう");
文字列型

のようになります。
文字列型

moji[40]の数値「40」の意味は、「文字列長が英数字の40文字ぶんまで」という意味です(日本語だと20文字ぶんになるかもしれません)。
文字列型

TCHR 型を用いたサンプルコードなどについては、後述の節を参照してください。
いくつかの例

ウィンドウ内に変数を文字描画できなければ、実用性がありません。
いくつかの例

たとえば、タロウくんの去年の身長が約153センチだったとして、今年は約157センチだったとしましょう。(説明を単純化するため、小数部分は切り捨て or 丸めた。)
いくつかの例

タロウくんの身長を変数 sintyo としましょう。
いくつかの例

さて、TextOut 関数では、変数の値をそのまま表示することは不可能です。
いくつかの例

よって、まずC言語の標準ライブラリ関数 sprintf という、これは数値型を文字列型に変換できる標準ライブラリ関数ですが、これのWindows版で _stprintf_s というのがありますので、Win32 API では _stprintf_s を使って、変数を文字列型に変換します。
いくつかの例

しかし、この _stprintf_s 関数による文字列への変換は、整数型から文字列への変換しか、うまく変換できません。
いくつかの例

浮動小数を文字列に変換すると、誤差が出てきます。たとえば、数値 152.7 を変換した場合、文字列 152.69997 みたいに変換される場合があります。 なので、整数以外の変換は、あまり、オススメできません。
いくつかの例

もし、小数点2桁まで文字列に変換したい場合、例えば
いくつかの例

あるいは、
いくつかの例

工夫してください。
いくつかの例

結局、身長の変数 sintyo を画面に表示するには・・・
いくつかの例

のように、なります。
いくつかの例

_stprintf_s の第2引数(上記コードでは200)は、文字バッファーのサイズです。
いくつかの例

_stprintf_s で代入先になる第一引数になる文字列変数(例では henkan )は TCHAR 型でなければなりません。(もし char型だと コンパイルでエラーになる。)
いくつかの例

_stprintf_s 関数で代入する数値(例では sintyo )は、整数型でなければなりません。もし実数型(たとえば double 型)で数を定義してある場合には、型変換 (int) を使ってから代入します。
いくつかの例

となります。
いくつかの例

とりあえず、値 0.38 くらいの数値の1未満の大きさの入っている変数 hensuu の中身の数値を画面表示する方法を考えましょう。
いくつかの例

まず、とりあえず100倍して、それを型変換の (int) 関数で、整数型として型変換したあとに、他の整数型の変数 bufseisuu に入れます。(バッファ用の整数でbufseisuu のつもり)
いくつかの例

そのあと、上記の章と同様に sprintf すれば、小数点の上位2ケタの表示がされます。
いくつかの例

C言語の文法上は問題が無くても、しかし次のコードは現実にはVisual Studio のコンパイラが正常動作せず、まちがった実行結果になります。
いくつかの例

もし
いくつかの例

と _stprintf_s 内部で同時に宣言しても、異常な動作になります。
いくつかの例

つまり、
いくつかの例

このコードは駄目なのです。
いくつかの例

正常動作すれば 0 が入ってるハズなのに、実際には 2034859527 (一例)みたいな、なんかオカシな数が入ってしまいます。
いくつかの例

文法上は、このような同時宣言もありそうですが、しかし実際にはウィンドウズVisual Studio のコンパイラ製作の都合などにより、このような同時宣言は異常動作になります。
いくつかの例

_stprintf_s 関数にかぎらず、Visual Studio にもとから用意されているライブラリ関数の中で、他のライブラリを使うと、異常動作をする場合が、しばしば、あります。
いくつかの例

なので、あまり、使用するライブラリ関数のなかには、別のライブラリ関数を入れないようにしましょう。
いくつかの例

数値を文字列に変換する方法には、_stprintf_s の他にもあります。
いくつかの例

_itoa_s や _itot_s などの型変換のライブラリ関数を使う方法です。
いくつかの例

しかし、これは、型を厳密に指定する必要があり、そのため、windows独自のさまざまな型や、ポインタ型などについても、プログラマは把握しておく必要があります。
いくつかの例

なお、int整数値を TCHAR 形に変換するには、_itot_s を使います。
いくつかの例

のように、なります。
いくつかの例

_itot_s の第3引数(上記コードでは200)は、文字バッファーのサイズです。
いくつかの例

詳しくは、マイクロソフトの公式サイトを参照してください。 msdn
文字の連結

2つ以上の文字を連結したい場合は、単に、C言語の sprintfs のTCHAR版である _stprintf_s を使えばいいだけです。
文字の連結

のようになります。 mojibuf をTCHARであらかじめ宣言しておいて、さらにTCHAR型で宣言された person_name にあらかじめ「山田太郎」が代入されていれば、上記のようなコードを実行すれば「私の名前は 山田太郎」と表示されます。
文字の連結

標準C言語(無印C言語)からの変更点は、「 TEXT("%s %s") 」のように、「TEXT( )」 で囲まれるのを忘れないようにしてください。
文字列の多重配列

TCHAR型の配列は、下記のようになります。
文字列の多重配列

宣言の配列の見た目が[3][40]と二重配列なので、ついつい初心者は初期値を代入する際の記述も二次元配列にしがちですが、
文字列の多重配列

しかし最後の [40] は文字列長を意味するので、syouhinName[3][40]初期値の書き方は1次元配列のようになります。このような規則は何もwindowsAPIプログラミングに限らず、一般のC言語プログラミングでも同様です(同様に、char型での多重配列の宣言時の最後の数値は文字数を意味する。)
文字列の多重配列

上記例のように、TCHAR 宣言時の配列は2次元配列の書式であっても、TextOut など利用時には次元が一段階だけ下がるので書式は1次元配列でアクセスすることになるので、注意してください(初心者はよく間違えてエラーになり悩む)。