わたしの名はフレイ 作家・デザイナー見習い
神々とともに生きる詩人 一等星シリウスの導きを信じて

Visual C++/MFC/COM

MFCの概要

MicrosoftによるC++オブジェクト指向のクラスライブラリ(フレームワーク)。

MFCは、.NET Frameworkが登場するまでは、Windowsプログラミングの主役だった。Windows APIのラッパー的フレームワークだが、生産性が高いと言われ、AppWizardやクラス・メンバ関数などのGUIによる自動作成ができるという特徴がある。ただし、ドキュメント・ビューと呼ばれる仕組みを理解するのが難解であることや、変数の名前付けルールに古いシステムハンガリアン記法を用いており、意味が分かり辛い。

アプリケーションを作るためのフレームワークとして使えるほか、ファイル処理やGDI・デバイスコンテキストからスレッド、ソケット、FTP/HTTP、文字列や配列・リストなどのコンテナなど、C++向けのクラスライブラリとして使用できる。

MFCのクラス一覧

MFCで提供されるクラスには、CStringやCFileのような基本的なAPIC++を拡張したようなクラスライブラリ)や、CDocumentやCViewのような継承されることを前提とされるドキュメント・ビューのフレームワーク、CDC(DCはデバイス・コンテキストの略)やCPen, CBrush, CRectのようなGDI+関係のAPI、そしてCButtonのようなWindowsコントロールのクラスなどがある。また、クラスだけではなく専用の関数や型がたくさん用意されている。TCP/IPネットワークについてはWinSockを使う。

バイス・コンテキストはWindowsとデバイスの橋渡し役のようなもので、Windowsはデバイスを直接操作するのではなく、デバイス・コンテキストを仲介役として操作する。このデバイス・コンテキストを上手く使うことで、たとえばペイントアプリケーションのようなGDI+を使ったグラフィックス操作を行うプログラムを記述することができる。

MFCのメッセージハンドラ・メッセージマップ

Windows APIにおけるWindowsメッセージの処理は、MFCではメッセージマップによって行う。

これはBEGIN_MESSAGE_MAP()とEND_MESSAGE_MAP()の間にメッセージハンドラを追加することによって行われる。

コントロールであれば「ON_COMMAND(ID名, 関数名)」や、Windowsメッセージであれば「ON_WM_メッセージ名()」などを記述する。

オーバーライドを多用する

MFCではメソッドのオーバーライドを多用する。

たとえば、WindowsメッセージではWM_PAINTに対応するメソッドを記述したい場合、WM_PAINTのメッセージハンドラであるOnPaint()をオーバーライドする。

C++のこうしたオーバーライドを使うことで、「あるイベントが起きた時やあるメソッドが実行されたタイミングに合わせて処理を実行しクラスの内容を書き換える」ことができる。

また、既定の描画処理の後にカスタム描画したい、などといった場合はDefault()メソッドを加える。

分散システムとCOM

UNIXでは、中央コンピュータと端末、あるいはXのようにクライアント・サーバモデルでの、ネットワーク分散環境を利用できる。たとえば、端末のXサーバから別のパソコンのXクライアントを実行できる。

こうしたUNIXの分散システムとは全く別のやり方をしているのが、MicrosoftWindowsが頑張っていたCOM。

たとえば、たくさんのPCがあるとして、その中にアプリケーションを導入するのであれば、同じソフトウェアを全部のOSに入れることもできるが、ネットワークに繋がった別のコンポーネントを再利用して使いたい場合がある。

そうした時に、それぞれのソフトウェアをコンポーネントに分割して、相互に通信し合って、決められたインターフェースで各PCが協調して動くようにする。また、遠隔地に離れたコンポーネントでも、サービスとしてそのコンポーネントを利用可能にする。

この仕組みは先進的だったため、LinuxでもCOMに似たCORBAを利用してこの仕組みを模倣したGNOMEと呼ばれるデスクトップ環境があり、Linuxの標準となっている。MozillaでもXPCOMと呼ばれる同様の技術があるほか、Plan 9などの研究用の分散OSでは、ファイルシステムとネットワークプロトコルを統合し、分散PC環境で同じアプリケーションリソースを共有できるようにしている。

ただし、COMはHTTPのサービスと比べて普及せず、MicrosoftはCOMよりもさらに先進的な.NET Frameworkを開発し、GNOMEでもMonoとしてこれを模倣したが、これも単なるJavaの亜種であると評価されている。ただし.NET FrameworkのクラスライブラリはJavaを模倣したためとても使いやすく、Windows開発者から人気で、唯一の欠点である「関数やクラスの内部の仕組みが分からず使うだけになってしまう」という点も、.NET Coreと呼ばれる.NET Frameworkオープンソース化が進んでおり、MSの技術は着実に新しくなっている。きちんと競争しなければ、Linuxの未来や優位性もMSに奪われてしまうだろう。

COMはコンポーネント技術だと見做されているところもあり、ActiveXのようにブラウザの中に別のソフトウェアをコンポーネントとして埋め込む(Flash Playerなど)ことができるが、分散システムとしての側面を見れば、「ネットワーク上に無数に散らばるコンポーネントとしてのオブジェクトが通信し合ってたくさんの操作を行う」という先進的なプラットフォームになり得た技術である。これはGNOMEでも同様で、ある意味GNOMEアプリケーションの中で別のGNOMEアプリケーションをコンポーネントとして使うために、CORBA/Bonoboが利用されている実態がある。

ActiveXとCOMはアプリケーションの一部だけを切り出して共有する感覚に近い

ActiveXとCOMは、アプリケーションの一部だけを切り出して、共有する感覚に近いです。

ActiveXとCOMでは、こうした「コンポーネントの共有」をネットワーク上で実現します。

ActiveXを使ったアプリケーションとしては、たとえば、Webブラウザに埋め込むことのできるFlash Playerなどが例として挙げられます。

ATL/WTL

ATLはCOMを利用するためのラッパーで、ActiveXを開発する際に良く用いられる。

MFC/ATLと同等のものとして軽量なWTLが存在する。WTLはATLの拡張ライブラリで簡単にWindowsアプリケーションの開発ができる。

GDIとDirectX

GDIとDirectXは、Windowsでグラフィックプログラミングを行う上で欠かすことのできないAPI

基本的に、二次元のグラフィックスにはGDIを使う。簡単なカードゲームなど、3Dの必要ないゲームを作る時や、ペイントソフトをWindowsで実装したい場合には、GDIを使う。

GDIはペンやブラシを用いた個性的なAPIを持っていて、C/C++以外に.NET言語などからも利用できる。

3Dのより高度なグラフィックスを用いたゲームなどを作りたい時はDirectXを使う。OpenGLLinuxなどからも利用可能なオープン系の3D技術だが、Windowsにおいて、たとえばミニ戦車で戦う3Dのネットゲームを作りたい時などは基本的にDirectXを使う。一昔前のWindowsでは、DirectXが標準では搭載されておらず、ネットゲームをインストールする際にMSのサイトからDirectXをダウンロードして導入する必要があった。

最近のゲームはC/C++のほかC#などで作られることもある。特にUnityなどの最新のゲームエンジンでは、Monoを主要プラットフォームにしているため、MSとは関係がなくてもC#を使う必要がある。また、XboxなどのMS系のハードでもC#を使うことが多い。(プレステなどはカーネルFreeBSDなどを使っていたこともある。)

バイスコンテキスト

バイスコンテキストは、Windowsとデバイスの橋渡し役のようなもの。

Windowsはデバイスを直接操作するのではなく、デバイス・コンテキストを仲介役として操作する。

後日注記:ある意味、何かを表示するには、まずデバイスコンテキストを取得してから。デバイスコンテキストを取得してしまえば、あとはそれに対して表示領域を操作することでグラフィックスを表示できる。そのように考えると良いかもしれない。