Unicode?Ansi?Windowsでの文字列の表現が紛らわしい
2015/07/28
エディットコントロールを作る際に「文字列リテラル」について考えたこと。
定義した型と文字コード
今回使用した CreateWindow関数は、第1引数に LPCWSTR型の引数をとる。
エディットコントロールを作りたいので、第1引数には「EDIT」の文字列を渡すことになる。
ここで、渡し方として
1. “EDIT”
2. L”EDIT”
3. (LPCWSTR)”EDIT”
4. TEXT(“EDIT”)
を試してみた。
すると全てコンパイルすることは出来たが、実行結果に違いが出た。
結果
1,3はエディットコントロールが表示されなかった。
2,4は問題なく表示された。
違いはなぜ起きたのか?
まず、1の場合、そもそもVC++上のエディタに「パラメータの互換性がない」という注意が表示されていた。
それでもコンパイルが通ったのだが、やはり注意が気になるので LPCWSTR型にキャストしてみた(3の状態)。
すると注意が消えたので問題はなくなったのだと思った(思ってしまった)。
だが、実行してみるとエディットコントロールが表示されない。
調べるとCreateWindow()がNULLを返していた。
要は文字化けを起こして「EDIT」という文字列を関数に正しく渡せていなかったのだと思う。
そのためウィンドウクラス名が正しく指定されず、作成に失敗。
キャストしても文字コードは変わらない
1はUNICODEじゃないから文字化けしたんだな~とわかる(そもそも注意があったし)。
が、3の場合、注意が消えたのでうまいことUNICODEに変換しているものだと勘違いした。
しかし、UNICODEを扱う型にキャストしても、元がUNICODEでない場合はUNICODEにならない模様。
まあキャストしたらメモリの中身が置き換わる、というのも問題があるような気がするのでそれは別にいいと思う。
ただ、注意を消さないで欲しかった。キャストしても互換性の問題が解消できてない。
そもそもコンパイルエラーにするのは無理なのだろうか。
Windowsでの文字を表す型
Windowsでの文字の扱いがややこしい。表現が多すぎる。
型名(マクロ?)
CHAR:char(マルチバイト文字を使うとき)
WCHAR:wchar_t(ワイド文字を使うとき)
TCHAR:CHAR or WCHAR(環境に応じて置き換わる)
LP、P:*
C:const
TSTR:TCHAR
WSTR:WCHAR
STR:CHAR
文字列リテラルを宣言した時の型
“”:const char *
L””:const WCHAR *
TEXT(“”):const TCHAR *
これであってるのか不安。
今の時代はUNICODEで作る
とりあえず、今後新しく作るプログラムはUNICODEで作るべきらしい。
TCHAR や TEXT() といったマクロなども昔の名残っぽい。
以前はマルチバイト文字とUNICODEの両方に対応する必要があったが、今は全てUNICODEで作ればOKなはず。
なので文字列リテラルを宣言するときはTEXT() じゃなくて L”” で宣言することにしよう。
個人的に作ってる分には、UNICODEしか使わないと決めれば問題はないだろうし。
関連記事
-
「>」、「<」を含む文字列をコピーしたら自動でエスケープ文字にするアプリを作った
以前、文字列置換の記事でちょこっと書いたものを実際に作ってみた。クリップボードの …
-
C言語(win32api)で文字列の置換。改善の余地あり
コピー → 置換 → ペースト。 ある文字列をコピーした際、既定した文字列で自動 …
-
エディットコントロールにクリップボードの内容を出力してみた
今回はテキスト入力を処理する「エディットコントロール」を作ってみた。 前回取得し …
-
クリップボードの内容を取得しよう→_crtisvalidheappointerエラーで落ちる
前回の記事でClipboardを取得する際に発生したエラーについて こちらのペー …
-
クリップボードの内容を取得してみた
何を書けばいいのかわからなくなってきた。 行動指針が見つからない。今、自分は何を …
スポンサーリンク
週間人気記事
AndroidStudioでコピペする方法。デフォルトではクリップボードから貼り付けできない
Android Serviceのメモ。onBind,onRebind,onUnbindが呼ばれる条件