プロジェクトの作成
ウィンドウアプリ用のプロジェクトの作成
ウィンドウアプリを作る場合、C言語の開発などで今まで使用してきた「コンソールアプリケーション」用のプロジェクトの作成は適当ではありません。
後で設定を変えればこれでも出来るのですが、面倒なので最初からウィンドウアプリ用のプロジェクトを新規作成します。
テンプレートから作成
Visual Studio2015の場合は「Win32」というツリー項目の中に「Win32プロジェクト」というテンプレートがあります。
選択後にダイアログが開きますが、そのまま「完了」を選択します。
Visual Studio2019の場合は「C++」「Windows」「デスクトップ」で絞り込むと「Windowsデスクトップアプリケーション」というテンプレートがあります。
どちらの場合も自動的にいくつかのファイルが作成され、ソースコード(プロジェクト名.cpp)が開いた状態になります。
ソースコードには百数十行程度のコードが既に記述された状態になります。
Visual Studioではこれだけの手順で、ビルド可能なウィンドウアプリケーション(の原型)を作ることができます。
以下は何も手を加えずにビルド&実行したところです。
(ウィンドウサイズは縮めています)
自動生成されるソースファイルの名前は「○○.cpp」ファイルなのでこれはC++言語用です。
Visual Studioでは、拡張子を「.c」に変更するとC++の機能は使えなくなります。
自動生成されるコードにはC++の記法が使われているため、拡張子を「.c」に変更するとコンパイルできなくなります。
C++はC言語の記法をそのまま使用できるので、.cppファイルのままでもC言語のコードを追加していくことができます。
Visual Studio2015と2019とでは生成されるコードが少しだけ異なりますが、動作は同じです。
この自動生成されたコードを利用して、ここに色々と追記して機能を追加していくのが最も簡単なウィンドウアプリの作成方法です。
しかし、Windows APIの説明をまだほとんどしていない段階では、自動生成されたコードが何をしているのかほとんどわからないと思います。
全部を完璧に理解する必要はありませんが、ある程度は理解できないと動作の変更などが出来ず、満足にプログラムを作ることはできないでしょう。
そこで、当サイトでは空のソースコードにゼロからコードを記述していく方法でウィンドウアプリを作っていこうと思います。
最終的にテンプレートに近い動作をするウィンドウアプリを作ります。
テンプレートを利用した開発はWindows APIに慣れてからにしましょう。
空のプロジェクトから作成
Visual Studio2015では、上記の手順通り「Win32プロジェクト」を選択します。
その後に開くダイアログで「次へ」を選択し、「空のプロジェクト」にチェックを入れて「完了」を選択します。
Visual Studio2019では、「C++」「Windows」「デスクトップ」で絞り込み、「Windowsデスクトップウィザード」を選択します。
以下のダイアログが開きますので、アプリケーションの種類に「デスクトップアプリケーション(.exe)」を選択し、「空のプロジェクト」にチェックを入れてOKを選択します。
アプリケーションの種類を「デスクトップアプリケーション(.exe)」に変更するのを忘れないようにしてください。
これを忘れると上手く動きません。
プロジェクト作成直後は何もファイルが無いので、ソリュージョンエクスプローラーから「ソースファイル」フォルダ内に新しいソースファイルを追加します。
名前は何でも良いですが、ここでは「main.c」というファイル名にします。
拡張子が「.c」なので、C++の機能は使えません。
(C++を使う場合は「.cpp」にしてください)
これで空のソースファイルが作成されます。
WinMain関数
作成された空のソースファイルに、以下のコードを書いてみましょう。
(コピペでOKです)
#include <windows.h>
#include <tchar.h> //←TCHAR型を使わない場合は必要ない
//ワイド文字版
int APIENTRY wWinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nCmdShow)
{
MessageBox(NULL, L"ウィンドウアプリのテスト", L"タイトル", MB_OK);
return 0;
}
////TCHAR型版
//int APIENTRY _tWinMain(
// HINSTANCE hInstance,
// HINSTANCE hPrevInstance,
// LPTSTR lpCmdLine,
// int nCmdShow)
//{
// MessageBox(NULL, _T("ウィンドウアプリのテスト"), _T("タイトル"), MB_OK);
// return 0;
//}
//マルチバイト文字版
//int APIENTRY WinMain(
// HINSTANCE hInstance,
// HINSTANCE hPrevInstance,
// LPSTR lpCmdLine,
// int nCmdShow)
//{
// MessageBoxA(NULL, "ウィンドウアプリのテスト", "タイトル", MB_OK);
// return 0;
//}
ビルド&実行するとメッセージボックスが表示されると思います。
このコードには今までC言語で使用してきたmain関数がありません。
Windows APIでは、main関数の代わりにWinMain
という関数を使用します。
main関数と同様に、WinMain関数からプログラムは開始され、WinMain関数を抜けるとプログラムは終了します。
main関数とは引数が異なります。
引数にももちろん意味はありますが、今は使わないので説明は省きます。
また、WinMain関数の関数名の手前にAPIENTRY
またはWINAPI
というキーワードが必要です。
これはWinMain関数を使う場合の約束事と思ってください。
三種類のWinMain関数
WinMain関数にはマルチバイト文字版、ワイド文字版、TCHAR型版の三種類があります。
- マルチバイト文字版は「
WinMain
」、第三引数の型は「LPSTR(char*)」 - ワイド文字版は「
wWinMain
」、第三引数の型は「LPWSTR(wchar_t*)」 - TCHAR型版は「
_tWinMain
」、第三引数の型は「LPTSTR(TCHAR*)」
それぞれ関数名と第三引数の型が異なる以外は同じものです。
もちろん、ひとつのプログラム中ではどれかひとつしか使用できません。
どれが優れているとか劣っているということはないので、好きなものを使用して構いません。
ただ、TCHAR版は記述が面倒なのに今となってはメリットがほとんどないのであまりお勧めしません。
このサイトでは基本的にワイド文字版を使用して説明を進めていきます。
使用する関数もワイド文字版を使用します。
もしマルチバイト文字版を使用したい場合は関数名の末尾に「A」を記述してください。
(例:MessageBox→MessageBoxA。ただしマルチバイト文字版が存在しない関数も一部存在します)