contents

  1. 文字列
  2. スマートポインタ
  3. コレクション
  4. ファイル処理
  5. ウィンドウ

ATL のクラスを使ってみる

MSDNを見ていると、ATL/ATL Server に属する便利そうなクラスがいくつか見つかります。 STLと重なる部分もありますが、Windows用途に特化されていますので、より便利な部分もあるようです。

はじめに

私はWTLから入ったので、ATL/COMのことがほとんどわかってません。 (WTLはテンプレートがわかっていればATLを知らなくても使えてしまいますし。) おかしなところもあると思いますが、ご容赦ください。 コンセプトは、「とりあえずヘッダをインクルードするだけみたいなんで使ってみよう」です。

文字列

CStringT < CharType, StringTraits >

ヘッダ : atlstr.h
依存関係 : CRT (optional)

既存の MFC::CString とインタフェース互換の文字列。 std::string に比べ、内部バッファの取得ができるのと、operator const CharType*が定義されているのが大きな違い。 また、StringTraits のおかげでCRTを使わない場合でも様々な文字列処理関数が使えるのがメリット。 std::iostream と組み合わせる必要が無ければ、std::string よりも使い勝手がよいと思われる。

CSourceType2[C]DestinationType[EX]

ヘッダ : atlconv.h
依存関係 : malloc

マルチバイトとワイド文字列を相互に変換するクラス。 通常は、typedefされた名前(CW2A, CA2CT, CT2WEX etc.)を使う。 MultiByteToWideChar() / WideCharToMultiByte() の代わりに使うと便利。 変換前と後の文字コードが同じで、文字列を変更する必要が無い場合は、文字列のコピーさえ行われないのでほとんど無駄が無い。

使用例

BOOL MySetWindowTextW(HWND hWnd, const WCHAR* wtext)
{
    return ::SetWindowText(hWnd, CW2CT(wtext)); // SetWindowTextW()は9xで使えないため
}

CPathT < StringType >

ヘッダ : atlpath.h
依存関係 : CStringT, shlwapi.dll

ファイルパス操作をするための CStringT ラッパー。 shlwapi に含まれる、Path*関数群をクラス化している。 また、スタティック関数として、ATLPath namespace内に別名が定義されている。 (PathAddExtensionAATL::ATLPath::AddExtension() など)

CAtlRegExp < RECharTraits >

ヘッダ : atlrx.h
依存関係 : CRT

正規表現。 ただ、必ずCRTを使用するという部分が、CStringT との互換性が取れていない面で設計ミスか? (正規表現を使用するような場合は大抵CRTを使う必要があるとは思うが)

スマートポインタ

どれもデフォルトでoperator T*が定義されているのがSTL/Boostのポインタとの最大の違いかと。 明示的に破棄するためのメソッドがそれぞれ違うのが気に入らない?

CAutoPtr < T >

ヘッダ : atlbase.h

破壊式コピーポインタ。メソッドは、Attach(), Detach(), Free()。

CHeapPtr < T >

ヘッダ : atlcore.h

配列に対するポインタ。通常の配列のほかに、可変長構造体のメモリ確保にも便利。 メソッドは、Allocate(), Reallocate(), AllocateBytes(), ReallocateBytes(), Free()。

CComPtr < T > / CComQIPtr < T, IID >

ヘッダ : atlcomcli.h

業界標準COMポインタ。メソッドは、Attach(), Detach(), Release()。

CHandle

ヘッダ : atlbase.h

CloseHandle()できるハンドルが対象。無効ハンドルはNULLのみ;INVALID_HANDLE_VALUEが使われるものに使用する場合は注意。 メソッドは、Attach(), Detach(), Close()。

コレクション

さすがにSTLコレクションにと比べると貧弱。CRTを使用しない場合のみ、使う価値があるか?

CAtlArray / CAutoPtrArray / CInterfaceArray

ヘッダ : atlcoll.h

メンバ関数は貧弱なものの、INARGTYPEOUTARGTYPEを定義することで、破壊式コピーポインタ(auto_ptr)に対応している。 _ATL_MIN_CRT 環境では、VC7付属のSTLではリンクエラーになるので、これを使わざるを得ない。 その際、慣れ+std::algorithm のために、std::vector 互換メンバを追加してみた(Array.h)。

CAtlList / CAutoPtrList / CHeapPtrList / CInterfaceList

CAtlMap

CRBMap / CRBMultiMap

ファイル処理

CAtlFile / CAtlTemporaryFile

ヘッダ : atlfile.h

ファイルハンドルのラッパー。 64bit単位で扱え、Low, Highを意識しなくて済む。 テンポラリファイルは、Close()時に名前を与えた場合はその名前にリネームされ、与えない場合は削除される。

CAtlFileMapping < T > / CAtlFileMappingBase

ヘッダ : atlfile.h

メモリマップトファイル。 いろいろな使い方はあるが、ただ単にファイルを読み込むのに使っても便利。

使用例:ビットマップの読み込み

struct BitmapFile
{
    BITMAPFILEHEADER header;
    BITMAPINFO       info;
    BYTE* getBits() { return (BYTE*)this + header.bfOffBits; }
};
CAtlFile file;
file.Create("image.bmp", GENERIC_READ, 0, OPEN_EXISTING);
CAtlFileMapping<BitmapFile> mapping;
mapping.MapFile(file);
BitmapFile* bmp = static_cast<BitmapFile*>(mapping);

ウィンドウ

CWindow

ヘッダ : atlbase.h, atlwin.h

すべてのウィンドウ関係のAPIをラッピングし、 CenterWindow(), ResizeClient() などの便利なメソッドも追加されています。 インテリセンスを機能させるためだけでも利用価値があります。

CWindowImpl < T, Base, Traits >

ヘッダ : atlbase.h, atlwin.h
依存関係 : _AtlBaseModule, _AtlWinModule, atl*.lib

ATL7.0より、グローバル変数 CComModule _Module を宣言しなくてもCWindowImplが使用可能になりました。 (内部的には _AtlBaseModule, _AtlWinModule を含むライブラリが自動的にリンクされます。) 非常に軽量のライブラリなので、単にウィンドウを出すような場面(=ほとんどすべてのWin32プログラム)ではいつでも使えるでしょう。 誰もが一度は苦労するHWNDのクラス化を、Thunkingという面白い手法で実現しています。 VC7のスケルトンと同等なコードの例