レガシー Windows API(概要)について

ここで紹介しているAPIは、Windows95、Windows NT3.5時代のAPI群であり、最新のAPIは含まれていないことに注しして欲しい。なお、当時の解説書は現在よりもより詳細に解説しているため、参考になるはずである。

  • レイアウトを変換する際、崩れているページがあります。
  • 概要およびSampleコードはありますが、APIの解説はありません。

ご要望があれば旧版のWin32 API(HELP形式)をお譲りします。問い合わせフォームより申し込みください。

Windows API ハンドルとオブジェクトの概要

「オブジェクト」とは、 ファイルやスレッド、 グラフィック イメージなどのシステム リソースを表現する内部構造体です。アプリケーションは、 オブジェクトの内部構造体や、 オブジェクトが表現するシステム リソースには直接アクセスすることはできません。その代わりに、 アプリケーションは、 オブジェクト 「ハンドル」を取得し、 そのハンドルを使って、 システム リソースを調査、 修正します。Microsoft(R) Windows NT(TM) オペレーティング システムでは、 ハンドルは通常間接ポインタとして実装されていますが、 必ずしもそうとは限りません。

次に示すトピックでは、 Win32のハンドルとオブジェクトについて説明しています。

ハンドルとオブジェクトについて

ハンドルの制限

ユーザー オブジェクトとグラフィック デバイス インターフェイス (GDI) オブジェクト

 

カーネル オブジェクト

2つの理由のため、 Windows NTでは、 オブジェクトとハンドルを使ってシステム リソースへのアクセスを制御しています。第1に、 オブジェクトを使うことによって、 低レベルの内部構造体を意識したコードを作成しなくてもよくなります。これによって、 元の呼び出し規約を使っていれば、 Microsoftは、 オペレーティング システムの将来のバージョンで機能を追加したり変更できます。オペレーティング システムの新しいバージョンがリリースされたときは、 アプリケーションにほとんど変更を加えずに新しい機能を利用できるようになります。

第2に、 オブジェクトを使うことによって、 Windows NTのセキュリティを利用できます。各オブジェクトには、 プロセスがオブジェクトに対して実行できる操作の種類を示すアクセス制御リスト (ACL) がそれぞれあります。アプリケーションがオブジェクトのハンドルを作成しようとすると、 オペレーティング システムは、 オブジェクトのACLを調べます。セキュリティについて詳しくは、 セキュリティを参照してください。

Microsoft(R) Win32(R) APIでは、 ほとんどのオブジェクトについて、 オブジェクト ハンドルの作成やクローズ、 オブジェクトの破棄を行うための関数を用意しています。これらの操作は、 オブジェクトの種類や状況によって、 組み合わせて使う場合や、 不要な場合があります。たとえば、 あるアプリケーションがイベント オブジェクトを作成し、 ほかのアプリケーションがそのイベントをオープンして、 同じイベント オブジェクトに対してそれぞれ固有のハンドルを持っているとします。この場合、 アプリケーションは、 オブジェクトを使い終わったらハンドルをクローズします。イベント オブジェクトに対してオープンされているハンドルがなくなったら、 オペレーティング システムはメモリからオブジェクトを削除します。

また、 アプリケーションが既存のウィンドウ オブジェクトのハンドルを取得する場合もあります。この場合、 ウィンドウ オブジェクトが不要になったら、 アプリケーションはオブジェクトをメモリから削除しなければなりません。オブジェクトをメモリから削除すると、 ウィンドウ ハンドルは無効になります。

プロセスが終了すると、 システムはハンドルを自動的にクローズし、 そのプロセスが作成したオブジェクトを削除します。しかし、 通常、 スレッドが終了しても、 オペレーティング システムはハンドルのクローズやオブジェクトの削除は行いません。例外として、 ウィンドウ、 フック、 ウィンドウ位置、 動的データ交換 (DDE) などのオブジェクトは、 作成したスレッドが終了すると削除されます。

ハンドルやオブジェクトはメモリを消費します。このため、 アプリケーションは、 システムの性能を保つため、 ハンドルやオブジェクトが不要になったら、 ハンドルをクローズし、 オブジェクトを破棄しなければなりません。アプリケーションがこの処理を行わないと、 ページング ファイルの使用量が多くなり、 オペレーティング システムの動作が低速になります。

Windows NTは、 次の表に示されるようにユーザー、 グラフィック デバイス インターフェイス、 カーネルの3種類のオブジェクトを用意しています。システムは、 ウィンドウ管理のサポートにユーザー オブジェクト、 グラフィックのサポートにGDIオブジェクト、 メモリ管理やプロセスの実行、 プロセス間通信 (IPC) にカーネル オブジェクトを使います。特定オブジェクトの作成と使用については、 関連した概要トピックを参照してください。

 

Windows NTユーザー オブジェクト

ユーザー オブジェクト 概要

アクセラレータ テーブル キーボード アクセラレータ

キャレット キャレット

カーソル カーソル

動的データ交換対話 動的データ交換管理ライブラリ

デスクトップ セキュリティ

フック フック

アイコン アイコン

メニュー メニュー

ウィンドウ ウィンドウ

ウィンドウ位置 ウィンドウ

ウィンドウ ステーション ウィンドウ

 

Windows NT GDIオブジェクト

GDIオブジェクト 概要

ビットマップ ビットマップ

ブラシ ブラシ

フォント フォントとテキスト

パレット 色

ペン ペン

拡張ペン ペン

リージョン リージョン

デバイス コンテキスト デバイス コンテキスト

メモリ デバイス コンテキスト デバイス コンテキスト

メタファイル メタファイル

メタファイル デバイス コンテキスト メタファイル

拡張メタファイル メタファイル

拡張メタファイル デバイス コンテキスト メタファイル

 

Windows NTカーネル オブジェクト

カーネル オブジェクト 概要

プロセス プロセスとスレッド

スレッド プロセスとスレッドds

ファイル ファイル

ファイル マッピング ファイル マッピング

イベント 同期

セマフォ 同期

ミューテックス 同期

パイプ (名前付きと名前なし) パイプ

メールスロット メールスロット

通信デバイス 通信

ヒープ メモリ管理

モジュール ダイナミック リンク ライブラリ

リソース更新 リソース

ファイル検索 ファイル

イベント ログ イベントのログ

変更通知 ファイル

トークン セキュリティ

サービス オブジェクト 印刷と印刷スプーラ

LZファイル データ圧縮解除ライブラリ

 

 

ハンドルの制限

ユーザー オブジェクトやGDIオブジェクトなどのオブジェクトは、 一度に1つのハンドルしかサポートしません。システムは、 アプリケーションがオブジェクトを作成するとハンドルを提供し、 アプリケーションがオブジェクトを破棄するとハンドルを無効化します。一部のカーネル オブジェクトなどは、 1つのオブジェクトに対して複数のハンドルをサポートします。最後のハンドルがクローズされると、 オペレーティング システムは、 オブジェクトを自動的にメモリから削除します。

オペレーティング システム内でオープン可能なハンドルの総数は、 オペレーティング システムで利用可能なメモリの量だけに制限されます。しかし、 1つのプロセスがオープンできるGDIオブジェクト ハンドルは16,384個以下です。ユーザー ハンドルのプロセス当たりの制限は2の30乗です。カーネル ハンドルのプロセス当たりの制限はありませんが、 システム全体では65,536個以下という制限があります。

 

 

ユーザー オブジェクトとGDIオブジェクト

ユーザー オブジェクトとGDIオブジェクトは、 1つのオブジェクトに対して1つのハンドルしかサポートしません。プロセスは、 ユーザー オブジェクトやGDIオブジェクトのハンドルを継承したり複製することはできません。

ユーザー オブジェクトのハンドルは、 すべてのプロセスに対してパブリックです。つまり、 ユーザー セキュリティで定義されているオブジェクトへのアクセスを持つプロセスは、 ユーザー オブジェクト ハンドルを使うことができます。セキュリティについて詳しくは、 セキュリティの概要を参照してください。

GDIオブジェクトのハンドルは、 プロセスにプライベートです。つまり、 GDIオブジェクト ハンドルを使えるのは、 そのオブジェクトを作成したプロセスだけです。

次の図では、 アプリケーションはウィンドウ オブジェクトを作成しています。CreateWindow関数は、 ウィンドウ オブジェクトを作成して、 オブジェクト ハンドルを返します。

アプリケーションは、 ウィンドウ オブジェクトを作成したら、 ウィンドウ ハンドルを使ってウィンドウを表示、 変更できます。ハンドルは、 ウィンドウ オブジェクトを破棄するまで有効です。

次の図では、 アプリケーションはウィンドウ オブジェクトを破棄しています。DestroyWindow関数は、 ウィンドウ オブジェクトをメモリから削除して、 ウィンドウ ハンドルを無効化します。

次の表は、 Windows NTのユーザー オブジェクトと、 各オブジェクトの作成関数と破棄関数を示しています。作成関数は、 オブジェクトとオブジェクト ハンドルを作成するか、 既存のオブジェクトのハンドルを返します。破棄関数は、 オブジェクトをメモリから削除し、 オブジェクト ハンドルを無効化します。

ウィンドウ ステーション オブジェクトやデスクトップ オブジェクトは、 システムが作成して管理しており、 アプリケーションが削除することはできません。

 

ユーザー オブジェクト
オブジェクト 作成関数 破棄関数
アクセラレータ テーブル CreateAcceleratorTable DestroyAcceleratorTable
カーソル CreateCursorLoadCursorGetCursorSetCursor DestroyCursor
動的データ交換対話 DdeConnectDdeConnectListDdeQueryNextServer DdeReconnect DdeDisconnect
DdeDisconnectList
デスクトップ GetThreadDesktop なし
フック SetWindowsHookSetWindowsHookEx UnhookWindowsHook
UnhookWindowsHookEx
メニュー CreateMenu CreatePopupMenuGetMenu
GetSubMenu
GetSystemMenuLoadMenu
LoadMenuIndirect
DestroyMenu
ウィンドウ CreateWindow CreateWindowExCreateDialogParam
CreateDialogIndirectParam
CreateMDIWindow、
FindWindow
GetWindowGetClipboardOwner
GetDesktopWindow
GetDlgItemGetForegroundWindow
GetLastActivePopup
GetOpenClipboardWindow
GetTopWindowWindowFromDC WindowFromPointなど
DestroyWindow
ウィンドウ位置 BeginDeferWindowPos EndDeferWindowPos
ウィンドウ ステーション GetProcessWindowStation なし

次の表は、 Windows NTのGDIオブジェクトと、 各オブジェクトの作成関数と破棄関数を示しています。作成関数は、 オブジェクトとオブジェクト ハンドルを作成するか、 既存のオブジェクトのハンドルを返します。破棄関数は、 オブジェクトをメモリから削除し、 オブジェクト ハンドルを無効化します。

 

GDIオブジェクト
オブジェクト 作成関数 破棄関数
ビットマップ CreateBitmap CreateBitmapIndirect
CreateCompatibleBitmap
CreateDIBitmap
CreateDIBSection
CreateDiscardableBitmap
DeleteObject
ブラシ CreateBrushIndirect CreateDIBPatternBrush
CreateDIBPatternBrushPt
CreateHatchBrush
CreatePatternBrush
CreateSolidBrush
DeleteObject
フォント CreateFont CreateFontIndirect DeleteObject
パレット CreatePalette DeleteObject
ペン CreatePen CreatePenIndirect DeleteObject
拡張ペン ExtCreatePen DeleteObject
リージョン CombineRgn CreateEllipticRgnCreateEllipticRgnIndirect
CreatePolygonRgn
CreatePolyPolygonRgn CreateRectRgn
CreateRectRgnIndirect
CreateRoundRectRgn
ExtCreateRegion
PathToRegion
DeleteObject
デバイス コンテキスト CreateDCGetDC DeleteDC ReleaseDC
メモリ デバイス コンテキスト CreateCompatibleDC DeleteDC
メタファイル CloseMetaFile CopyMetaFile
GetMetaFile
SetMetaFileBitsEx
DeleteMetaFile
メタファイル デバイス コンテキスト CreateMetafile CloseMetaFile
拡張メタファイル CloseEnhMetaFile CopyEnhMetaFile
GetEnhMetaFile
SetEnhMetaFileBits
DeleteEnhMetaFile
拡張メタファイル デバイス コンテキスト CreateEnhMetaFile CloseEnhMetaFile

 

カーネル オブジェクト

カーネル オブジェクト ハンドルはプロセス固有です。つまり、 オブジェクト ハンドルを取得するには、 プロセスは、 カーネル オブジェクトを作成するか、 既存のオブジェクトをオープンしなければなりません。オブジェクトの名前を知っていて、 ユーザー セキュリティで定義されているオブジェクトへのアクセスを持つプロセスは、 (ほかのプロセスが作成したオブジェクトでも) 既存のカーネル オブジェクトのハンドルを作成できます。

プロセスは、 次に示す種類のカーネル オブジェクトのハンドルを継承、 複製できます。

・ プロセス

・ スレッド

・ ファイル (ファイル マッピング オブジェクトも含みます)

・ イベント

・ セマフォ

・ ミューテックス

・ パイプ (名前付きおよび名前なし)

・ メールスロット

・ 通信デバイス

 

上記以外のカーネル オブジェクトは、 すべて、 オブジェクトを作成したプロセスにプライベートであり、 オブジェクト ハンドルを複製したり継承することはできません。

元のハンドルを作成するときに継承が指定されており、 「ハンドル継承」フラグをセットして子プロセスを作成したときは、 子プロセスは、 親プロセスでオープンされているハンドルを継承します。継承したハンドルは、 子プロセスのコンテキスト内だけで有効です。

DuplicateHandle関数は、 現在のプロセスまたはほかのプロセスにハンドルを複製します。アプリケーションがハンドルをほかのプロセスに複製すると、 複製したハンドルは、 複製先のプロセスのコンテキスト内だけで有効になります。

複製したり継承したハンドルは一意な値ですが、 元のハンドルと同じオブジェクトを参照しています。

カーネル オブジェクト ハンドルには、 アプリケーションがオブジェクトに対して行える操作を示すアクセス権が設定されています。アプリケーションは、 オブジェクトを作成したり既存のオブジェクト ハンドルを取得するときにアクセス権を指定します。各種のカーネル オブジェクトには、 それぞれ、 アクセス権のセットがあります。たとえば、 イベント ハンドルには「設定」アクセスと「待機」アクセスがあり、 ファイル ハンドルには「読み取り」アクセスと「書き込み」アクセスがあります。アクセス権について詳しくは、 セキュリティの各オブジェクトを説明したトピックを参照してください。

次の図では、 アプリケーションはイベント オブジェクトを作成しています。CreateEvent関数は、 イベント オブジェクトを作成して、 オブジェクト ハンドルを返します。

アプリケーションは、 イベント オブジェクトを作成したら、 イベント ハンドルを使ってイベントを設定、 待機できます。ハンドルは、 アプリケーションがハンドルをクローズするか、 アプリケーションが終了するまで有効です。

ほとんどのカーネル オブジェクトは、 1つのオブジェクトに対して複数のハンドルをサポートしています。たとえば、 上記の図のアプリケーションは、 次の図のように、 OpenEvent関数を使って、 イベント オブジェクト ハンドルをさらに取得できます。

これによって、 アプリケーションは、 異なるアクセス権のハンドルを取得できます。たとえば、 ハンドル1にイベントへの「設定」アクセスと「待機」アクセスを設定し、 ハンドル2には「待機」アクセスだけを設定できます。

別のプロセスでも、 イベント名を知っており、 オブジェクトへのセキュリティ アクセスを持っていれば、 OpenEventで自分自身のイベント オブジェクト ハンドルを作成できます。

また、 次の図のように、 イベント オブジェクトを作成したアプリケーションは、 DuplicateHandle関数を使って、 そのオブジェクトのハンドルを同じプロセスや別のプロセスに複製できます。

次の図は、 親プロセスが作成したハンドルを子プロセスが継承する方法を示しています。

ハンドルを作成するときに継承を指定し、 「ハンドル継承」フラグをセットして子プロセスを作成すると、 子プロセスは、 親プロセスが作成したハンドルを自動的に継承します。上記の図では、 ハンドル2とハンドル1は同じではありませんが、 同じイベント オブジェクトを参照しています。

継承について詳しくは、 プロセスとスレッドの概要およびファイルの概要を参照してください。

オブジェクト ハンドルが少なくとも1つ存在していれば、 オブジェクトはメモリに残されます。次の図では、 アプリケーションはCloseHandle関数を使ってイベント オブジェクト ハンドルをクローズしています。イベント ハンドルがなくなれば、 オペレーティング システムは、 オブジェクトをメモリから削除します。

場合によっては、 オブジェクト ハンドルをすべてクローズしてもオブジェクトがメモリに残ることがあります。たとえば、 スレッドがイベント オブジェクトを作成し、 イベント ハンドルで待機するとします。そして、 そのスレッドが待機している間に、 ほかのスレッドが同じイベント オブジェクト ハンドルをクローズしたとします。この場合、 イベント ハンドルがなくても、 イベント オブジェクトがシグナル状態に設定されて待機操作が完了するまで、 イベント オブジェクトはメモリ内に残ります。待機動作が完了すると、 システムがオブジェクトをメモリから削除します。

Windows NTは、 ファイル オブジェクトをほかのカーネル オブジェクトとは少し異なる方法で管理します。ファイル オブジェクトには、 ファイル ポインタ (ファイルの次に読み書きする位置を指すポインタ) があります。アプリケーションが新しいファイル ハンドルを作成すると、 オペレーティング システムは新しいファイル オブジェクトを作成します。このため、 次の図に示すように、 ディスク上の1つのファイルを複数のファイル オブジェクトが参照する場合があります。

次の図に示すように、 同じファイル オブジェクトを複数のファイル ハンドルから参照するには、 複製か継承を使うしかありません。

次の図は、 Windows NTのカーネル オブジェクトと、 各オブジェクトの作成関数と破棄関数を示しています。作成関数は、 オブジェクトとオブジェクト ハンドルを作成するか、 既存のオブジェクトのハンドルを返します。破棄関数は、 オブジェクトをメモリから削除し、 オブジェクト ハンドルを無効化します。カーネル オブジェクトの最後のハンドルをアプリケーションがクローズすると、 オペレーティング システムはオブジェクトをメモリから削除します。

 

カーネル オブジェクト

オブジェクト 作成関数 破棄関数
プロセス CreateProcessOpenProcess
GetCurrentProcess
CloseHandle TerminateProcess
スレッド CreateThread CreateRemoteThread
GetCurrentThread
CloseHandle TerminateThread
ファイル CreateFile CloseHandleDeleteFile
ファイル マッピング CreateFileMapping OpenFileMapping CloseHandle
イベント CreateEventOpenEvent CloseHandle
セマフォ CreateSemaphore OpenSemaphore CloseHandle
ミューテックス CreateMutexOpenMutex CloseHandle
パイプ CreatePipe CloseHandle
名前付きパイプ CreateNamedPipe CloseHandle DisconnectNamedPipe
メールスロット CreateMailslot CloseHandle
通信デバイス GetStdHandle CloseHandle
ヒープ HeapCreate HeapDestroy
モジュール LoadLibrary GetModuleHandle FreeLibrary
リソース更新 BeginUpdateResource EndUpdateResource
ファイル検索 FindFirstFile FindClose
イベント ログ OpenEventLog RegisterEventSource
OpenBackupEventLog
CloseEventLog
変更通知 FindFirstChangeNotification FindCloseChangeNotification

 

 

▲ページトップに戻る

【本を読んでもよくらからない】 … 個別指導でわかりやすくお教えします
inserted by FC2 system