1-2 VisualStudioでプロジェクトを作ってみる

ここでは実際にVisualStudioを使い、開発を行うための流れを一通りやってみます。
なお、ここで使用しているVisualStudioは2015版ですが、VC2005からはほぼ同じやり方で出来ます。


■新規プロジェクトの作成

とりあえずVCがまだ起動していなければ起動してください。

標準ではスタートページが表示されると思いますが、タブ内の×ボタンで閉じてしまってかまいません。

1.プロジェクトの新規作成
プロジェクトとはアプリ単位でソースコードを管理する機構です。
たとえばここではテストプログラムを作るので、
「テストプログラム用のプロジェクトを作成する」と表現します。

まず、上のメニューの「ファイル」→「新規作成」→「プロジェクト」を選択してください。


次に作成するプロジェクトのテンプレートから「Visual C++」内の「Win32」を選び、その中の「Win32プロジェクト」を選択します。
※コンソールアプリケーションとはDOS窓を使ったプログラムを作成する場合に使用しますが、
 ここではウィンドウを表示するアプリとするため、この場合はWin32プロジェクトを選択します


次にプロジェクト名を指定しますが、この時プロジェクトを保存するための場所を先に選択してください。
また、ここでは「ソリューションのディレクトリを作成」のチェックを外しておきます。
そしてプロジェクト名は仮に「TestProgram」とします。

※場所の指定ですが、これは全プロジェクトを1つのフォルダで管理するようなイメージになります。
 たとえば上記では「D:¥source」と指定しましたが、このsourceに他のプロジェクトもまとめて入れるという意味になります。
 この設定でプロジェクトを作成すると「D:¥source¥TestProgram」というフォルダが作成され、この中にソースコードなどを入れていく形になります。
 また「ソリューションのディレクトリを作成」にチェックを入れると、プロジェクト内にさらにソリューション名に指定した名前でフォルダが作成され、
 その中にプロジェクトが作成されてしまってややこしくなってしまうため、ここでは余計なフォルダを作らないためにもこのチェックははずしています。

プロジェクト名を決めたら次は作成するアプリの設定を行うためのウィザードが表示されます。

最初は作成するプロジェクトの確認画面なので、問題なければ「次へ」をクリックします。
なお、完了を押すと次以降の詳細設定がスキップされてしまうため、ここでは必ず「次へ」をクリックしてください。


次にアプリの種類を設定します。
ここではウィンドウアプリなので「Windowsアプリケーション」を選択し、さらにオプションの「空のプロジェクト」にチェックを入れます。
なお、SDLチェックとは古いCの関数で使い方によってはメモリバッファを越えてしまうような関数を使った場合に、
警告ではなくエラーにしてしまう機能ですが、ここでは古い関数を使うことも想定してチェックを外しています。

※「空のプロジェクト」にチェックを入れない場合、余計なソースコードが勝手に追加されてしまい、
 自分で作成したソースがうまくコンパイル出来なくなることがあります(stdafx.hなどを必ずインクルードしなければならなくなるなど)

完了を押してこの画面が出たらひとまずプロジェクトの作成は完了です。



プロジェクトが正しく作成されたかは「D:¥source¥TestProgram」を見ることで確認できます。
参考として以下のようなファイルが生成されているはずです。


なお、VisualStudioのプロジェクトファイルの拡張子は「sln」となります。
今後はこのファイルをダブルクリックすることで、プロジェクトを直接開くことが出来ます。
2.ソースコードの登録
まずは、ソースコードを記述するためにcppファイルを作成します。

上のメニューから、「ファイル」→「新規作成」→「ファイル」を選択します。


新しいファイルとして「Visual C++」の「C++ ファイル」を選択して、開くを押してください。


これで「Source1.cpp」という名前でファイルが開かれます。
ただし、この状態は実はまだファイルとして保存はされていません。


開いたファイルを保存するには「ファイル」から「名前を付けて Source1.cppを保存」を選択します。


保存先としてプロジェクトの中を選択し、ファイル名としてここでは「Main.cpp」として保存します。


プロジェクトフォルダに以下のようにファイルが保存されます。


実はこの状態ではただファイルを保存しただけに過ぎないので、今度はこれをプロジェクトに登録します。
プロジェクトを右クリックして「追加」→「既存の項目」を選択します。


選択ダイアログからさきほど保存したMain.cppを選択し、追加ボタンを押します。


正しく追加されると以下のようにプロジェクト内に登録されます。


これでこのMain.cppは今回のプロジェクトでコンパイル対象となり、右側のエディタ部分にプログラムを打ち込んで実行することが出来るようになります。

ちなみにプロジェクト階層にある「ソースファイル」や「ヘッダーファイル」といったグループ名ですが、
これは見た目上のものであり、どこにファイルが追加されていてもコンパイルは可能です。
単にhファイルやcppファイルを分かりやすいように分けているだけなので、グループ名を変えたり新たに追加することも出来ます。

また、実はソースファイルはエクスプローラーからドラッグして入れることも出来ます

直接「ソースファイル」や「ヘッダファイル」内にドラッグすればその中に、プロジェクト名の部分にドラッグすれば自動的に拡張子を見て振り分けられて登録されます。
※デフォルトで作成される「ソースファイル」にはcとcppファイル、「ヘッダファイル」にはhファイルを受け入れるように設定されています
3.サンプルソースコード
とりあえずサンプルコードとして、Main.cppに以下の内容をコピーペーストしてください。
そして、コピーしたらファイルを上書き保存(ショートカットはCTRL+S)してください。
#include <Windows.h>

const WCHAR mClassName[] = L"TestProgramClass";
const WCHAR mTitleName[] = L"テストプログラム";

LRESULT CALLBACK WinProc( HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam )
{
    switch (uMsg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_SYSCOMMAND:
        switch (wParam)
        {
        case SC_CLOSE:
            PostQuitMessage(0);
            return 0;
        }
        break;
    }
    return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}

int WINAPI WinMain( HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdParam,int nCmdShow )
{
    // ウインドウクラス登録
    WNDCLASSW wc;
    ZeroMemory( &wc,sizeof(wc) );
    wc.style            = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNCLIENT;
    wc.lpfnWndProc      = WinProc;
    wc.cbClsExtra       = 0;
    wc.cbWndExtra       = 0;
    wc.hInstance        = hInstance;
    wc.hIcon            = LoadIconW( hInstance,IDI_APPLICATION );
    wc.hCursor          = LoadCursorW( NULL, IDC_ARROW );
    wc.hbrBackground    = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wc.lpszMenuName     = NULL;
    wc.lpszClassName    = mClassName;
    if( !RegisterClassW(&wc) )
        return -1;

    // ウインドウ生成
    HWND hWnd = CreateWindowExW( 0, mClassName, mTitleName, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 640, 480, NULL, NULL, hInstance, NULL );
    if( !hWnd )
        return -1;

    MSG msg;
    while( GetMessage(&msg,NULL,0,0) ) {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }

    DestroyWindow( hWnd );
    return 0;
}
4.ビルド
次にソースコードをビルド(コンパイル・リンク)してみます。

まずソースコードが正しく入力されたことを確認します。


上のメニューから「ビルド」→「ソリューションのビルド」をクリック、もしくはショートカットとしてF7キーを押してください。


問題が無ければ下の出力ウインドウに以下のようなメッセージが出ます。


ビルド結果が「ビルド: 1 正常終了」となっていればコンパイルは成功です。
もし問題があった場合はここにその内容が表示されるので、そのエラーをダブルクリックすることで、
直接エラーのある行番号にジャンプすることが出来ます。
5.実行
正しくビルドが出来たらあとは実行するだけです。

上のメニューから「デバッグ」→「デバッグの開始」をクリックするか、ショートカットとしてF5キーを押してください。


または、ツールバーの「ローカルWindowsデバッガー」をクリックしても実行出来ます。


これで作成したプログラムが実行されます。


このプログラムは単純なウインドウを生成するだけのものです。
終了するには右上の×ボタンを押してください。

ちなみに「デバッグの開始」を行う際にまだプログラムがビルドされていない、もしくはソースコードを改変した状態でビルドをしていない場合は、
先にそのソースコードが自動的に上書き保存されてからビルドが行われます。
この時ビルドエラーがあれば実行はされませんが、問題無くビルドできたらそのままプログラムが実行されるため、ビルド操作を省略することが出来ます。
6.その他
上記までの流れで一通りの作業は終わりですが、ここではさらに他の重要な設定項目についての説明です。

デバッグビルドとリリースビルド
アプリを作成している間は通常はデバッグモードでビルドと実行を行います。

このモードではエラーが発生したり途中で現在の変数がどのようになっているかを確認することが出来ますが、
そのため実行速度やコードの最適化はまったく行われません。
最終的にそのアプリを公開する場合はリリースモードにてビルドします。
これで最適化された状態や、デバッグ情報などが入らない実行ファイルを作成できます。

また、VisualStudio2015ではプロジェクトを作成すると始めから32bit版と64bit版のアプリをビルド出来るようになっています。
つまり、ここでは32bitデバッグ版の他に、32bitリリース版、64bitデバッグ版、64bitリリース版の4つのビルドを行うことが出来ます。

デバッグとリリース、32bitと64bitの切り替えは以下の場所で変更出来ます。
32bitデバッグ版
32bitリリース版
64bitデバッグ版
64bitリリース版
プロジェクトのプロパティ
以下はデバッグビルドやリリースビルド、32bit、64bitごとに設定を変えられるものです。

上のメニューから「プロジェクト」→「TestProgram のプロパティ」をクリックし、設定画面を出して各設定を変更します。


・シングルスレッドとマルチスレッド
 スレッドを使用したプログラムを作る場合「マルチスレッド」にて作成する必要があります。
 VisualC++2005以降からは標準でマルチスレッドにてビルドされるようになっているため基本的に変更は必要ありませんが、
 マルチスレッド版にはDLL版とリンク版があり、デフォルトでDLL版が指定されています。

 DLL版の場合は実行ファイル(exe)のサイズを小さくすることは出来ますが、このためVisualC++のランタイムのインストールが必須となるため、
 作成したゲームを配布する場合、ユーザーにランタイムをインストールしてもらわなければならず、多少面倒な作業を行わせてしまうことになります。

 これを避けるにはリンク版を設定しておきますが、同じくリンク版にもデバッグ用とリリース用の2つが存在するため、
 以下の「構成」部分がDebugならデバッグ用、Releaseならリリース用に設定すると良いでしょう。
 
  リンク版とは実際には「DLL」と書かれていないものです。
   Debug用の場合
    
   Release用の場合
    


・マルチバイトとUNICODE文字列
 マルチバイトとは日本語で言うとShiftJISで、英語は1バイト、日本語は2バイトで表現されます。
 UNICODEとは全世界共通の文字コードであり、英語や日本語の漢字、中国語、韓国語など1文字を必ず固定2byteで表します。
 ※正確にはUNICODEにも種類があり16bit版と32bit版がありますが、OS内部では16bit版を使用しています

 Windows関数で引数に文字列を渡す場合、このどちらの文字コードを使うのかというのをプロジェクト単位で管理していますが、
 例えば上記のサンプルコードでは、ウィンドウを生成する関数として「CreateWindowExW」を呼び出しており、
 最後の「W」がUNICODE関数であることを明示しています。(ちなみにマルチバイト版なら「A」が付きます)

 実はこの関数は「CreateWindowEx」と書くのが本来の使い方ですが、その場合は現在の設定がマルチバイトかUNICODEかをコンパイラが判断し、
 自動的にW付きの関数かA付きの関数かを判断して置き換えています。

 一般的なC言語は各国の言語を正しく扱うといった概念は無かったため、まず最低限英数記号が表現でき、
 日本の場合はそれに英数以外の任意のコードを勝手に使うことで漢字などを表現していました。
 VCもあくまで基本はC言語であり、言語を正しく扱う必要は無かったためマルチバイトを使うのが基本でしたが、
 最近のVisualStudioではOSがそもそもUNICODEで動作していることもあり、デフォルト設定がUNICODEになっています。
 このため昔のソースコードをそのままコピペすると、A付きのWindows関数を想定していたプログラムはW付きの関数に置き換わってしまうため、
 そのままではコンパイルが出来なくなってしまいます。

 そのためマルチバイトでプログラムを行う場合は、言語設定をUNICODEからマルチバイトに変更しなければなりません。
 この設定は以下の場所で変更出来ます。
 
 この設定もDebug版やRelease版、32bit版と64bit版それぞれで設定が保持されます。

 マルチバイト版に変更するには以下のようにしてください。
 

 ちなみに上記のようにAやWが付かない関数や構造体に対して、手動でAやWの付いた物に修正すれば言語設定をする必要はありません。
 ※要はデフォルトの呼び出し関数を決めるための設定なので、常に指定した関数を呼び出すようにすればこの設定は関係無くなります

 VisualStudioではUNICODE文字列を扱う型としてwchar_tが定義されており、新しい型としてコンパイラに実装されていますが、
 古いC言語にはこの型が存在しないため、この場合は単に16bitの数値型として定義されています。

 この違いを吸収するため、VisualStudioではWCHARという型で統一していますが、これで文字列を定義する場合は文字列の最初に「L」をつけます。
 Lを付けた文字列は常にUNICODE文字列となるため、この文字列をマルチバイト型の関数に渡そうとするとエラーになります。

 VCではこれも考慮され、マルチバイトかUNICODEか分からずAやWの付かない関数を呼び出す場合、マクロ定義された_T("文字列")や
 TEXT("文字列")という書き方をすることで、言語設定に合わせてL付きかそうで無いかをコンパイル段階で制御してくれますが、
 この方法もいろいろとややこしいので、出来れば最初からA付きやW付きの関数を明示的に呼び出すようにした方が安全です。

  いろいろな例
     WCHAR s[16] = L"文字列";
     MessageBox( hWnd, TEXT("エラーが発生しました"), TEXT("エラー"), MB_OK );
     MessageBoxA( hWnd, "エラーが発生しました", "エラー", MB_OK );
     MessageBoxW( hWnd, L"エラーが発生しました", L"エラー", MB_OK );


・実行ファイル(exe)の出力先
 デバッグ実行を行う際、カレントディレクトリは通常はプロジェクトフォルダになっています。
 つまり上記のプロジェクトでは「D:¥source¥TestProgram」がカレントディレクトリとなって実行されます。
 例えばここでファイルのロード関数を使用するとこの位置から相対で検索されます。
 ※実行ファイルの存在する場所が初期状態でカレントフォルダとは限りません。
  カレントフォルダは実行元(この場合はVC)が変更したり、実行中のプログラムが明示的に変更することが出来ます。

 しかし、デフォルトのプロジェクトの設定では実行ファイルはデバッグビルドではDebugフォルダ、
 リリースビルドではReleaseフォルダ内に生成されるため、直接このexeをダブルクリックなどで実行すると、
 カレントディレクトリが「D:¥source¥TestProgram\Debug」や「D:¥source¥TestProgram\Release」内となってしまうため、
 ロードしたいファイルが見つからずエラーとなってしまいます。

 そこで、このexeの出力先をプロジェクトフォルダと同一にすることで、VCでのデバッグ時と同様のファイル構成で実行が可能になります。

 まず実行ファイルの出力名を設定します。
 以下のように「$(OutDir)」を消去し、出力ファイルを「$(TargetName)$(TargetExt)」だけにするか、任意のexeファイル名にしてください。
 
 ※たとえばRelease版では「TestProgram.exe」、Debug版では「TestProgram
D.exe」と「D」を最後に付けておくことで、
  プロジェクトフォルダ内にリリース用とデバッグ用の実行ファイルを共存させることも出来ます。
  例としてこの場合は「$(TargetName)
D$(TargetExt)」とします。

 次にデバッグ実行時に起動される実行ファイルとして、上記で指定した出力ファイルを指定します。
 

 これらの設定は当然Debug版やRelease版、32bit版や64bit版それぞれで設定出来るので、
 他の設定を忘れると正しく実行ファイルが生成されないといった問題が発生します。