各コントロールに対して何らかの処理を行ったときのデフォルトの処理というのは、どのようなレベルで制御されているのでしょうか?
例えば、
「ボタンをクリックしたら、へっこんで見える」
「テキストボックスを選択してキーボードを入力したら、その文字がテキストボックス上に表示される」
などです。
これらの処理は、各言語レベルで制御(OnClickイベントのメソッド内のどこか見えない所に書いてある?)のか、WindowsがAPIのような形で提供(Windowsが処理?)しているのでしょうか?
今まで、前者(言語レベルのメソッド)のようなものであり、普段のOnClickイベントの中身は、ボタンを継承(?)して、(どこかで)上位クラスのメッセージハンドラを呼び出した後にコードを追加(?)してるようなイメージでした。
しかし、職場の先輩は後者(Windows標準の処理をしてくれている)というイメージだったようです。
いろいろ調べてみたのですが、イマイチよくわかりません。
詳しい方、いらっしゃいましたら、ご教授のほどお願いいたします。
・まずC&Win32APIの場合で説明します。
結論から言えばボタンが凹むなどの標準的な動作はWin32APIで用意されていて、
特殊なコードを書かない限りはメッセージループの中でこれらを呼び出します。
メッセージループはプログラマが自分で書くこともありますし(その場合、標準動作を
呼び出すための適切なAPIが存在します)、ボタンなどの標準コントロールはいちいち
メッセージループを書かなくとも内部で自動的に処理されるようです(もちろん自前で
書くことも出来ますよ)。
・C++&MFCの場合も基本的にはC&Win32APIと同じことです。
メッセージループがフレームワークの中に組み込まれているので、外からは見辛いと
思います(MFCのコードは公開されているのでそれを追うことは十分可能です)。
・JavaのJFCはもはや完全にメッセージループ自体がブラックボックス化されています。
SwingのJButtonは軽量コンポーネントですので、恐らくWin32APIを呼んでいるのではなく、
Javaのフレームワークが自前で“押されて凹んでいるボタンの描画”を行っています。
つまり同じメッセージドリブンでも上述の2つとは全く違ったしくみとなっています。
…ところで「各言語レベルで制御(OnClickイベントのメソッド内のどこか見えない所に
書いてある?)のか、WindowsがAPIのような形で提供(Windowsが処理?)しているの
でしょうか?」と書かれていますが、これって「MFCなどがやっているのか、Win32APIが
やっているのか」という意味ですね?
だとするとMFCはあくまでライブラリであって言語ではありません。僭越ながら
“言語”と“ライブラリ”の区別をきちんとしておいた方がよいかと思います。
http://www.kumei.ne.jp/c_lang/
猫でもわかるプログラミング
「マウスの左ボタンが何処で押された。」
「キーボードから文字が入力された。」
などなどの基本的な物は、Windowsが処理し、“メッセージ”という概念で各プログラムに渡しています。
基本的に、すべてのWindowsプログラムは、この各メッセージを処理し、動作しています。
メッセージループというループ処理がプログラムの中に組み込まれていて、その中でメッセージを拾っては、適切な関数にその値を渡しています。
この仕組みによって、C言語メインでイベントドリブンを実現させているんです。
OnClickのようなメソッドは、このメッセージを受け取った関数が、オブジェクト指向のポリフォーフィズムを上手く利用し、実現しているんです。
ボタンをクリックしたらへっこんで見える、というのは、BUTTONというWindows標準のコントロールがそれらメッセージを処理し、描画しているからです。
テキストボックスも同様です。
.Net frameworkとか、MFCとか、VBとか、Delphiとかとか、そういったもの達は、うま~くこれらメッセージをラッピングしているわけです。
デフォルトの動作ってのは、そのラッピングの仕方によりますが、WinAPIでDefWindowProcという関数があり、通常何にもしないイベントはそれに渡され、Windowsが改めて処理し、画面を描画したり、ウィンドウを移動させたり、基本的な動作を行っています。
それにしても、オブジェクト指向って、便利ですよね~。
ちなみに、そのメッセージはWindowsがどうやって作っているのかっていう話になると、今度はCPUの割り込みの話になります。
外部割込みが発生すると、OSが登録したあるルーチンが呼び出されます。
それを拾って、メッセージを作り出し、分散処理させた各アプリケーションにメッセージを送信(メッセージプールにメッセージを投下)しているんです。
各アプリケーションはそのメッセージをこまめに拾っては処理しています。(C言語だったら、メッセージを各ウィンドウクラスに登録された関数に渡し、それをswitch文で振り分け、処理しています。)
ありがとうございます。
一応、大まかに言えば「後者」です。でもOnClickイベントが見えないところで実装されているといえば、されています。
Windows OS のGUI実装は、各プロセスに「イベント」を送付し、各プロセスは「イベント」を取得して、各イベントに沿った処理を行います。
で「コントロール」とは単に一プログラムにすぎません。「標準コントロール」はWindows OSとして中に入っています。そういう意味で、「Windows標準の処理をしてくれている」ということになります。でも、「OS」としては(Vistaからは異なるけど)イベントドリブン機能までが「OS」で、「標準コントロール」が「偶然」Windows標準と「みなすことができる」だけでOSの機能そのものではありません、、、ん~言い切っていいのかな。
「上位クラスのメッセージハンドラを呼び出した後にコードを追加」も必ずしも間違ってはいませんけど。この意味の「上位クラス」とは「標準コントロール」を指すのであれば。「追加」とは言わないかもしれない。。。
ということで、どっちかといえば「後者」。細かく言えば微妙に違う。という感じですか。
ありがとうございます。
私の考え方がおかしかったのですね……。
やっぱり、プログラミングは奥が深いです。
これで回答を締め切りたいと思います。
回答していただいた方、拙い文章から私の疑問を汲み取っていただき、的確に回答していただき、ありがとうございました。
詳しくご説明くださり、ありがとうございます。
言語・ライブラリの違いについては、申し訳ありませんでした。この辺りの言葉について、不理解でした。
どうもありがとうございました。