#pragma twice

KAB-studio > プログラミング > #pragma twice > 178 Version 9.17 キー入力の秘密

#pragma twice 178 Version 9.17 キー入力の秘密

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

 Version 9.17
キー入力の秘密

というわけで、前回の続きから

void CSdiTestView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
    // メンバ変数に入力した文字を追加。
    m_cMainTextStr += nChar;
    // 再描画を指示。
    InvalidateRect( NULL );

    // 文字コードを16進表示。
    TRACE( "%X, %X\n", nChar, '\n' ); // ここ追加。

    CView::OnChar(nChar, nRepCnt, nFlags);
}



D, A

って結果なんだよね
これは、キー入力と \n の両方を16進数で表したもの
ようするに数字でってことだよね。 D は 13 で A は 10 だね
そう。ここからはちょーっと難しくなるし、後でまたちゃんと解説するか

わかんなくてもいい?
うん、解らなくてもいいけどがんばってみて
がんばってみます! で?
まず、今まで改行は \n って言ってきたよね
うん。だから今度もリターンキー押したらそれが出ると思ったんだけど、
違うのだね。この前はこれ、 \r って言ってたね
そう、 \r 。実は改行には2種類あるんです

\r : キャリッジリターン ( Carriage Return ) 0x0D
\n : ラインフィード ( line feed ) 0x0A

2種類あるんだねー。でも今まで \r って出てこなかったよね
それは、実際には \r では改行できないから
へ、そうなの?
たとえば

    TRACE( "改行前\r改行後" );

ってしても改行しないから
ホントだ、じゃあ改行でもなんでもないんじゃない
ところがそうじゃないんだよね。えっと、適当なテキストファイルを新規
作成して
ほーい。右クリック新規作成テキストファイルっと。中身は?
中身は

AAA
BBB

ってして
ほい
じゃあ、それを VC でバイナリーモードで開いて
ほいほい
ちなみにバイナリーモードは Version 1.0 ( No.003 ) を参照
1回目……お、こんなん出てきたよ?

000000  41 41 41 0D 0A 42 42 42                        AAA..BBB

 A は16進数で 0x41 、 B は 0x42 だから
ってことは間にある 0D 0A ってのが改行……??? って、これってつ
まり \r\n って並んで入ってるってこと??
そういうこと。つまり、テキストファイルの中での改行は \r\n ってこと
なんです
??? 二文字で改行ってなんか不思議……
だから、改行に \r も関係してるんです。ただ、改行が \r\n なのはウィ
ンドウズだから
え? ってことは他のOSは?
 \r だけだったり \n だけだったり
なにそれ……
プログラムでファイルに書き込むときは \n でいいんだけど、それをOS
ごとに \r\n や \r とかに変換してファイルに書き込んでるんです
な、なんか複雑!
そう、この辺は文字コードの問題で
文字コードっていろんなとこで話題になってるよね
そう、プログラミングの中でやっかいな問題のひとつ。これは数章あとで
じっくり取りかかるから、それまでは
パスってことね
で、話を戻して。ウィンドウズのテキストファイルが \r\n ってことも
あって、ウィンドウズの中身的には改行が \r って部分があるんです
だから改行すると \r が来る?
ってことかな。他にも、エディットボックスあるでしょ
うん。あれも \r\n ?
そう、エディットボックスは複数行にできるんだけど、その時入ってる改
行も \r\n なんだよね
なんか複雑ね……
そう、実際複雑だから。プログラミングでは気をつけなきゃいけない部分
があって
そのひとつがこの改行の問題なわけね
改行コード問題って言って、根が深い問題だから。これからも、こういう
気を付けなきゃいけないことがいっぱいあるから
……いっぱい?
実際のプログラムに関わってくるのはその一部なんだけど、自分が作るプ
ログラムがその問題に関わってくる、ってことに気付かなきゃいけないか

どゆこと?
たとえば、普通にプログラミングしてる時には改行コードは気にしなくて
いいでしょ
うん、今までは特に問題なかったもんね
でも、火美ちゃんが他のOS向けのテキストファイルを作ることになった

その時に改行コードの問題が……それに気付かなきゃいけない!!
そういうこと。これってかなり重要だから
ちょいまち!! あたし、改行コードひとつならなんとかなると思うけ
ど、いっぱいあったら!!
でもそのいっぱいを憶えていて、常に気をつけなきゃいけないし、最新情
報も取り入れないと
それってかなり大変!!
もちろん大変だし……まぁ、世の中のプログラマーのほとんどはそういう
の全然気にしないから問題ないってことも言えるけどね……
うわぁ、なんか暗くなってるし……
ま、その辺は言ってたら切りないし、とりあえず覚悟だけしておいて
覚悟、ねぇ……
さて。ここまでは改行コードの話だったけど、ここからはまた別の問題に
ついて説明します
つまり、それもいっぱいの中のひとつ?
ううん、これはそれほど気にしなくていい話。前回、カーソルキーが効か
ないって話をちょっとだけしたでしょ
あ、そういえばカーソルキー押してもあのメンバ関数は呼ばれないよね
そう、これがもうひとつの問題。 CSdiTestView::OnChar() の第1引数の 
nChar に入力した文字が入ってたよね
うん、入ってた
ってことはこれは文字ってこと
あ! カーソルキーとか、文字で表せない!?
そゆこと。だから送られてこないんです
なるほど。でもさ、それだとカーソルキー押されたときにカーソル移動、
とかってできないじゃん
それは別のメンバ関数で受け取るんです。正確に言うとメッセージだけ
ど。 CSdiTestView::OnChar() は WM_CHAR だったでしょ
 Version 9.15 ( No.176 ) でやったね
カーソルキーとかは WM_KEYDOWN と WM_KEYUP ってメッセージでするんで

ってことはそれようのメンバ関数を作ればいいんだ
そゆこと。実際に作ってみようか。クラスウィザードを開いて
 CSdiTestView::OnChar() と同じだよね。 WM_KEYDOWN と WM_KEYUP 、
どっち?
 WM_KEYDOWN の方。マウスと違って、キーボードはリピートがあるから
離したとき、じゃないわけねー。関数の追加っと。お、 
CSdiTestView::OnKeyDown() って関数ができた
これなら、全部のキー入力を拾えます。これをこう修正してみて

void CSdiTestView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
    if( nChar == VK_LEFT )
    {
        TRACE( "左カーソルキーが押されました。\n" );
    }
    
    CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

お、左カーソルキーを押すとちゃんと引っかかる……けど、 VK_LEFT 
って何?
これは左カーソルキーを意味する【仮想キーコード】
仮想キーコード?
そう。 CSdiTestView::OnChar() の第1引数には文字が入ってたでしょ。 
CSdiTestView::OnKeyDown() の第1引数は文字じゃない、仮想キーコードが
入ってるんです
だからカーソルキーも大丈夫?
そういうこと。仮想キーコードは〈特定のキー〉を指してて、左カーソル
キーなら VK_LEFT 、シフトキーなら VK_SHIFT 、ってぐあい
ってことは普通の A なら VK_A ?
じゃないんだよね。それは普通の文字。こんな感じに

void CSdiTestView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
    if( nChar == 'A' )
    {
        TRACE( "Aキーが押されました。\n" );
    }
    
    CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

あらま
で、ここからが問題。実際に試してみて
うん。 A 押すとちゃんと呼ばれるよ
画面に出力される文字は?
 a ……あ! 大文字小文字違う!
そゆこと。仮想キーコードは大文字小文字は関係ないんです
そっか、キーだからそんなの関係ないんだもんね。でも、それって不便じ
ゃない?
だからそのために CSdiTestView::OnChar() があるってこと
おお! つまり、文字は OnChar() 、直接のキー入力は OnKeyDown() 
ってわけね
そういう使い分けが必要ってことだね。この辺はややこしいから注意して

ややこしい……けど、こういう仕組みは便利よねー
あ、ちなみにこれ、 MFC の機能だから
……それってつまり、 MFC 使わなかったら自分でやんなきゃいけないっ
てことですか?
そういうこと。あ、あと、仮想キーコードって MSDN に載ってないっぽい
から、 winuser.h を直接見てください。さて
さて?
ずっと MFC を使った SDI プログラムを見てきたけど、この辺で一度切り
上げます
え? こんなとこでいいの?
んーと、はっきり言って中途半端
やっぱそうなんだ
 MFC を使った SDI アプリは、実は機能がかなりいっぱいあるんです
それを説明するときりがない?
それもあるんだけど、それよりももっと基礎知識を付けておいた方がいい
から。というわけで新章に続く!

/*
    Preview Next Story!
*/
確かにねー
何が?
ほらさ、新しい機能の次の回は、 C++ の勉強だったでしょ
それはそれでいいと思うんだけど、そればっかりもね
ちゃんと勉強してからってことね
そゆこと
というわけで次回
< Version 10.01 1からウィンドウを作る! >
につづく!
……でも、相変わらず……
相変わらず?
無計画よねー
う”
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。