コンピューターと戯れて |
-- Williamの窓 -- |
ちょっと悪乗りしてスタイルシートで遊んでみました。 |
今回からいよいよ本格的にコンピューターと戯れましょう。ただ、どこまで初心を貫徹できるか少々不安です。 さて、タイトルにもあるように今回は 窓 をテーマにします。 「おぃ!色はどうした!」そんな声が聞こえてきそうですが、その前置きとして今回も脱線しちゃいます。 ・・・・ もっとも今回取り上げる「 窓 」は、近年の GUI (Graphical User Interface)環境にとっては切り離すことのできない重要な役割を果たしているので、コンピューターと戯れる前にどうしても理解しておきたい登竜門だと思ってください。 ですから、窓型 I/F ( InterFace ) に興味の無い方や「今更 window なんぞ教鞭してもらいたくないや」ってな方は、次のリンクをクリックしてください。 あ!そうそう、取り扱う環境ですが 悪名高い Microsoft Windows 上の 窓 で戯れるつもりですので、MacやUNIX系、BeOS等の OS をお使いのユーザーの方は残念ですがここでお別れですね。 戻る 改めてこんにちは! これからしばらく Microsoft Windows システムの 窓 で戯れますのでお付き合いください。 では、サブタイトルを一新して はじめての窓 -- 苦々しい想いでともに さて、テーマである「窓」ですが、現在メジャーになっているこのシステムの歴史は古く、遡ればゼロックス社のパロアルト研究所で作られたアルトが始祖になります。 「だからどうした」、はい、その通りですね。ただ今では当たり前の I/F を最初に思いついたのがパロアルトの方々だということを強調させてください・・・ 一応、彼らに敬意をはらって 簡単な説明になりますが 「窓」 とは、高度に TimeSharing された環境下で、端末と向き合ったユーザーがもっとも効率よく、多彩且つ複数の機能を効果的に使える環境として考え出されたものです。 「??」な説明の仕方でしたが、ようはWindowsやMac、Be、XWindow、(其の他もろもろ)のような GUI 上で、ユーザーとアプリケーションが意思を疎通させるディスプレー上の領域のことです。 これ以上 GUI の歴史や思想と戯れるつもりがないので、さくさく話を進めましょう。 さて、この Window システムでどのようなコード (プログラム) を書けば、プログラマーがエンドユーザーに対して Window を提供することができるのでしょうか? これが今回のメインテーマになります。 プログラムなんぞに興味がない方もここでお別れですね、ではまた! あと、申し訳ないのですが、お話のベースに C 言語或いは C++ を使わせて頂きますが、C 言語の解説は致しません さて、単純な窓を作成しましょう。 例えばUNIXのXWindowになりますが、OSFのMotifを用いたコードでは次のようなコードになります。
行き成り Motif を使ってごめんなさい。ついでに内容が「??」な方にもごめんなさい。 え〜っと、補足ですが、UNIXのXWindow上でWindowを使うアプリケーションを作成する際に、昔はよく使われていたライブラリーが Motif です。・・・ 少なくともわたしくは もっともこの Motif、最近はあまり使われていないようですが・・・ 取り敢えず、他の環境での実装の仕方ということで敢えてMotifのコードを紹介しました さて、話をWindowsに戻します。 Windowsでもっとも簡単な窓の作り方は以下のようなコードになります。
上記のコードをコンパイルして起動すると こんな感じ(←)の画面がでます。 さて、なじぇ、こんな簡単なコードで window が生成されるのか? 実は、window を作るためにメッセージボックスと呼ばれるダイアログボックスの一種を用いたためです。 では、少し用語の説明しましょう。 まず、ダイアログボックスとは window の一種で、MSDN (Microsoft Developer Network) では、状況の通知、ユーザーからの入力を受けたりする temporary window だと言っています。 つぎにメッセージボックスですが、こちらはダイアログボックスの一種で、単純な I/F で構成された状況通知専用の window になります。 話を纏めます ダイアログボックスとは複雑な window に対して、単純な入力I/Fのみで構成された window のことを示し、メッセージボックスはダイアログボックスをさらに簡易化したものです。 つまりはもっとも簡単なメッセージボックスはもっとも簡単に作成することが可能な window となります。 では、上記のコードの説明を致しましょう。 非 Windows 出身者の方には馴染みが無い形式でプログラムが始まりますが、ここで用いられている WinMain 関数が Win32 アプリケーションのエントリーポインターとなります。 プログラミングに馴染みの無い方は、取り敢えず Win32 アプリケーションは WinMain 関数から実行されるものと解釈しておいてください。 さて、ここで行き成り話しを脱線させましょう。 エントリーポイントやロードモジュールは任意に指定 ( ユーザーがカスタマイズ ) できるのか? 答えは、「はい、できます」です。 っと、その前に、ここから話が思いっきり脱線しますので、興味のない方や先に進みたい方はこちらから跳んでください。 この辺の話って、通常はリンカーに任せるべきところなので、一般的なプログラマーは気にしないところなのですが、取り敢えずざっと、ついでにさらりと解説してみたいと思います。 ちなみにお話の対象は Microsoft Visual C++ になりますので、使われているコンパイラーとリンカーのメーカーによっては、ぜんぜん違うものになっている可能性があるのであしからず まず、エントリーポイントについてですが、こちらは Linker に対して 『 /ENTRY 』 オプションを切ることで開始アドレス(初期実行関数)を設定することができます。ただし、あたりまえのことですが、指定される関数は必ず __stdcall で指定してください。 なじぇって?それはですね、起動モジュールが呼び出す対象がインスタンス化されていなければならいないからさぁ ところでエントリーポイントを変更しても、守らなければいけないルールが存在します。 それは・・・・ 引数と戻り値は、必ず Win32 API 内で定義されている WinMain (.EXE ファイルの場合)、または DllEntryPoint (DLL ファイルの場合) はたまた main と同じにしなければならないのです! つまりは Windows システムのロードモジュールには、エントリーポイントを細かくカスタマイズする機能がないのです。 ですから、任意に決めた関数名をエントリーポイントにしても、引数および戻り値はロードモジュールに依存しなかればならないのです。 (つまり戻り値及び引数の構造はデフォルトのエントリーポイントと同じ型じゃなきゃいけないのよ) っていうか、ロードモジュールの起動関数呼び出しに対してスタックのカスタマイズ機能がないのよね。 またまた話が跳びます ・・・・ __sdcall 規約について Microsoft 固有の規約があるので以下に列挙しました。さて、ではロードモジュール(スタートアップ)に関してです。 こちらもユーザーが、どのロードモジュールを採用するか決めることができますが、基本的にはリンカーに任せていたほうが無難です。下手にいじると実行モジュールを生成できなくなってしまうから・・・ でも、知っていても損はしないので、さらっと紹介します。 まず、WindowsOS にはいくつかのロードモジュールがありまして、具体的には GUI 用とか CUI 用、はたまた DLL 呼び出し用等に対して、各々の専用ロードモジュールが用意されております「・・・ 関数のレファレンステーブルでロードモジュールのセレクトを行っているのであって、動的にスタック管理等はやらない構造なのね」 MSDN を読んだ当初はこんな認識を持っていましたが、実際に内部のコードを見てみると、なんのことはない、マクロでコンパイル箇所が別れており、コンパイルオプションを指定することで採用されるロードモジュールのコードが選択される構造なのね、まぁ自由度よりもリスクとのトレイドオフで、この方式を採用したのだろう さて、ロードモジュールを決めるためのオプションが 『 /SUBSYSTEM 』 になります。このオプションを切ることで起動モジュールが決められます。 オプションの説明を致しましょう。(基本的には MSDN に書かれていることなので、詳細は MSDN を参照のこと) オプションの定義は以下のようになります。 ・CONSOLE を指定すると CUI ベースのロードモジュールが指定されます。纏めましょう。 ・/ENTRY を指定することで起動関数(エントリーポイントを指定)を指定することが可能 ・/SUBSYSTEM をしてするとロードモジュールが指定できる 取り敢えず、これ以上深追いすると OS の内部構造まで説明せにゃならんので、ここら辺で止めときます。 さて、話を戻して、どんどん進めちゃいましょう。 次に起動関数(エントリーポイント)を説明します。 Win32の基本的なエントリーポイントには、通常 WinMain 関数が用いられます。 では、このWinMain 関数とは?
一先ず、なんにもしないプログラムはこんな感じになります。
さて、この辺で思いっきり話を戻します。 もっとも簡単な window を表示するコードの説明途中でしたね。 msgwin.c を思い直してください。 さて、このコードの七行目、赤字で MessageBox の一行に注目してください。 実は、この一行だけで window が作成されているのです。(ただし、生成した window はメッセージボックスですけど) では、この一行をご説明しましょう。 これは MessageBox 関数と呼ばれる関数で、メッセージボックスを作成する関数です。 たいへんにシンプルな関数であるため、メッセージボックスができることも制約されています。基本的には、タイトルおよびメッセージ、定義済みのアイコン、プッシュボタンの組み合わせを決めることしかできません。 故にメッセージボックスの役割は、主に状態通知になるのです。 では、関数の説明をしましょう。 関数定義 引数は以下の通りです。
ここまでだらだらと書いてきたが、なんのこはない、ようするに MSDN の焼き写しをだらだらと纏めただけである。 簡単に言ってしまえば、メッセージボックスなんぞ、MessageBox 関数を使ってサックっと呼び出しているだけである。 その使い方は至って簡単で、第一引数にメッセージボックスの呼び出し元を、さらに第二引数にはメッセージボックスが通知する内容を、第三引数にタイトル、最後の引数にメッセージボックスの形態を指定すれば OK! なんでこんな簡単なことに時間を費やしていたのだろう ( ・・・ 読んでくれている人はもっと退屈したはずだ ) っていうか、ここまで我慢して読んでいないかぁ・・・・・反省 でぇ、改めて上記のコードを説明しましょう。
以上! ねぇ、簡単なことでしょう ・・・・ こんな簡単なことを説明するのに、なんでこんなに書を要したのか? 取り敢えず、今回はこの辺りで止めときます・・・・つづく 参考までに以下に MSDN のメッセージボックスに関する記述を無断で抜粋しました。 ・A secondary window that is displayed to inform a user about a particular condition. ・A message box is a special kind of modal dialog box that an application uses to display messages and prompt for input. ところでなぜ文字が小さいって? ・・・ それはですね、無断転載だからさぁ ・・・ わたくし小心者ですから |