変化を求める人

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/C++ , ,

スポンサーリンク

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

  関連記事

「>」、「<」を含む文字列をコピーしたら自動でエスケープ文字にするアプリを作った

以前、文字列置換の記事でちょこっと書いたものを実際に作ってみた。クリップボードの …

C言語(win32api)で文字列の置換。改善の余地あり

コピー → 置換 → ペースト。 ある文字列をコピーした際、既定した文字列で自動 …

エディットコントロールにクリップボードの内容を出力してみた

今回はテキスト入力を処理する「エディットコントロール」を作ってみた。 前回取得し …

クリップボードの内容を取得しよう→_crtisvalidheappointerエラーで落ちる

前回の記事でClipboardを取得する際に発生したエラーについて こちらのペー …

クリップボードの内容を取得してみた

何を書けばいいのかわからなくなってきた。 行動指針が見つからない。今、自分は何を …