DirectXを始める前にWindowsAPIを知っておこう


概要

DirectXを始めるにはキャラクターなどの絵を表示するためのウィンドウや、
メインループと呼ばれるループを作成する必要があります。
このページではそれらを実装するために必要なWindowsAPIについての説明をします。

サンプル

サンプルはここからダウンロードできます。
環境については以下の内容となっています。

開発環境
VSのバージョン VisualStudio 2019
内容 WinMain関数を実装しただけのプロジェクトなので、
実行しても何も起きないので注意

WindowsAPI

WindowsAPIとはWindowsアプリを開発するためにMicrosoftが提供しているAPIのことで、
APIはApplication Programming Interfaces が略されており、
特定のアプリケーションを開発するために役に立つ関数や定数、規約が用意されています。
Windowsでアプリを開発する上で実装に必要な機能をWindoswAPIを使用すれば
自分で作成せずに済む可能性が高く、使いこなすことで作業工数を短縮することができます。

注意点

DirectXでゲームを使用するためにWindowsAPIを使用しますが、
ゲーム開発の中でWindowsAPIを多用することはありません。
使用する機能はこのページで使用する内容とその他の一部なので、
WindowsAPIの学習に深くのめり込まないようにしてください。
DirectXを使用するために必要な知識の一つではありますが、
ゲームアプリやDirectXの習得時間を削ってまでやる必要はありません

用語

WindowsAPIを使用する上でよく使用される用語の「インスタンス」と
「ハンドル」の説明をします。

インスタンス

インスタンスとは「実体」という意味で、オブジェクト指向においてよく使われる用語です。
メモリ上に領域が確保されたデータをインスタンスと呼び、
クラスを作成する場合、クラスのデータがメモリ上に確保されることから
インスタンス化と呼んでいます。

ハンドル

ハンドルとはWindowsがプログラムやウィンドウ、ファイルなどを
識別するためのユニーク(一意)な番号です。
この番号はWindowsが管理しており、Windowsはその番号を使用して
ウィンドウやファイルを操作しています。

ハンドルは識別するデータの種類ごとに「~ハンドル」と呼ばれており、
ウィンドウに対して設定しているハンドルと「ウィンドウハンドル」、
ファイルに対して設定してるハンドルを「ファイルハンドル」と呼んでいます。

directx_0001

インスタンスハンドル

ハンドルにはインスタンスハンドルと呼ばれるハンドルがあります。
これはOS(Windows)がアプリに設定したハンドルで、この後に説明するWinMain関数の引数に
インスタンスハンドルがありますが、そのインスタンスハンドルはOS(Windows)が決めた
アプリのハンドル(番号)が代入されています。

プロジェクトの作り方

VisualStudio2019でC/C++を使ってアプリを開発する場合のプロジェクトの作り方を説明します。
まずはプロジェクト作成画面からですが、以下の内容になっていることを確認してください。

番号 項目 設定
言語設定 C++
プロジェクトの種類 空のプロジェクト
directx_0097 二つの項目が設定どおりになっていることを確認してから 「③.次へ」ボタンを押してください。 次はプロジェクトの構成画面ですが、こちらは通常のプロジェクトと同じで問題ありません。 directx_0098 これでプロジェクトが作成されましたが、最後に確認すべき箇所があります。 それは「サブシステムの種類」が「Windows (/SUBSYSTEM:WINDOWS)」になっているかです。 確認は上段の「①.デバッグ」のメニューで「②.プロジェクト名のプロパティ」で 開かれるプロパティ画面内で行います。 directx_0099 プロパティ画面が表示されたら構成プロパティの「①.リンカー」メニューにある 「②.システム」を選択してシステムの画面のサブシステムの項目が 「Windows (/SUBSYSTEM:WINDOWS)」になっているかを確認してください。 ここが「コンソール (/SUBSYSTEM:CONSOLE)」になっていたりすると、 この後に説明するWinMain関数の実装ができないので注意です。 ※「設定なし」でも動作しますが、きちんと明示しておきましょう。 directx_0100 設定を変更した場合のみ「④.適用」を押して変更を反映してください。

WinMain関数

Windoswアプリを作成する場合、コンソールアプリのmain関数ではなく、
「WinMain関数」をエントリポイントとして使用します。

directx_0088
#include <Windows.h>

int APIENTRY WinMain(
	HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR     lpCmpLine,
	INT       nCmdShow)
{
	// ここに実装コードを書く
	return 0;
}

第一引数のインスタンスハンドルにはアプリのハンドルが代入されています。
このハンドルはウィンドウを作成などで使用します。

必須ヘッダ

WindowsAPIを使用する場合は「Windows.h」のincludeが必須です。
このヘッダをincluddすることでHINSTANCEやLPSTRやCreateWindowなどの
WindowsAPIの定数や関数を使うことができます。

WINAPI or APIENTRY

WinMain関数には「WINAPI」か「APIENTRY」のキーワードが使われています。
この二つはどちらも同じ「__stdcall」というキーワードをdefineで
別の名前に置き換えているだけです。

// WINAPIとAPIENTRYの宣言部
#define CALLBACK    __stdcall
#define WINAPI      __stdcall
#define WINAPIV     __cdecl
#define APIENTRY    WINAPI
#define APIPRIVATE  __stdcall
#define PASCAL      __stdcall

では、__stdcallコールは何かということになりますが、
これは「関数実行時の呼び出し規約」です。
このページでは__stdcallを深堀する必要はないと考えているので、
以下の二点を抑えておけば問題ありません。

「WINAPI」や「APIENTRY」はWindowsAPIのキーワードで、
どちらも「__stdcall」キーワードが使われている
__stdcallは関数呼び出しの規約(ルール)の指定をしている
以上がWindowsAPIについてでした。
他にもDirectXを実行する前に知っておく、作っておく必要がある項目として
「」「」がありますので興味があれば読んでみてください。