チュートリアル: 従来の Windows デスクトップ アプリケーションを作成する (C++)

このチュートリアルでは、Visual Studio で従来の Windows デスクトップ アプリケーションを作成する方法について説明します。 作成するアプリケーションでは、Windows API を使用して 、ウィンドウに Hello、Windows デスクトップ! を表示します。 このチュートリアルで開発したコードは、Windows デスクトップ アプリケーションを作成するためのパターンとして使用できます。

Windows API (Win32 API、Windows Desktop API、Windows Classic API とも呼ばれます) は、Windows アプリケーションを作成するための C 言語ベースのフレームワークです。 何十年もの間、Windows アプリケーションを作成するために使用されてきました。 より高度でプログラムしやすいフレームワークは、MFC、ATL、.NET フレームワークなど、Windows API 上に構築されています。 C++/WinRT で記述された、UWP およびストア アプリの最新の Windows ランタイム コードでも、下に Windows API が使用されています。 Windows API の詳細については、「Windows API インデックス」を参照してください。

重要

コード内のコード ブロックは説明の抜粋であり、移動中に貼り付ける手順ではありません。 各概念を見やすくするために、サポート コードは省略されています。 空のプロジェクトを作成したら、「コードをビルドする」でビルド可能な完全なソース 使用します。

前提条件

  • Microsoft Windows 7 以降のバージョン。 最適な開発作業のためには、Windows 11 以降をお勧めします。

  • Visual Studio。 Visual Studio をダウンロードしてインストールする方法について詳しくは、「Visual Studio のインストール」をご覧ください。 インストーラーを実行するときに、[C++ によるデスクトップ開発] ワークロードがオンになっていることを確認してください。 Visual Studio をインストールしたときにこのワークロードをインストールしていなくても問題ありません。 インストーラーをもう一度実行して、すぐにインストールできます。

    Visual Studio インストーラーの C + + ワークロードを使用したデスクトップ開発のスクリーンショット。

  • Visual Studio IDE の使用方法に関する基本的な理解。 以前に Windows デスクトップ アプリを使ったことがあれば、おそらくついていけるでしょう。 概要については、Visual Studio IDE の機能ツアーに関するページをご覧ください。

  • C++ 言語に関する知識。 あまり複雑な作業は行わないので、ご安心ください。

Windows デスクトップ プロジェクトを作成する

最初の Windows デスクトップ プロジェクトを作成するには、以降の手順に従います。 個々のコードの抜粋を貼り付けないでください。 プロジェクトを作成したら、「コードのビルド」の完全なソース を使用します

Visual Studio の優先バージョンの手順を確認するには、このページの目次の上部にある バージョン セレクターを使用します。

Visual Studio で Windows デスクトップ プロジェクトを作成するには

  1. メイン メニューで、[ファイル]>[新規作成]>[プロジェクト] の順に選択して、[新しいプロジェクトの作成] ダイアログ ボックスを開きます。

  2. ダイアログの上部で、[言語][C++] に、[プラットフォーム][Windows] に、[プロジェクト タイプ][デスクトップ] に設定します。

  3. フィルター処理されたプロジェクト タイプの一覧から、[Windows デスクトップ ウィザード] を選択して、[次へ] を選択します。 次のページで、プロジェクトの名前 (DesktopApp など) を入力します。

  4. [作成] ボタンをクリックしてプロジェクトを作成します。

  5. これで、[Windows デスクトップ プロジェクト] ダイアログが表示されます。 [アプリケーションの種類] ドロップダウンで、[デスクトップ アプリケーション (.exe)] を選択していることを確認します。 Windows アプリケーションを作成しているため、コンソール アプリケーションを選択すると、これから使用するコードではビルドできないプロジェクトになってしまいます。 次に、[追加のオプション][空のプロジェクト] を選択します。 [OK] を選択して、プロジェクトを作成します。

  6. [ソリューション エクスプローラー] で、DesktopApp プロジェクトを右クリックし、[追加] を選択して、[新しい項目] を選択します。

    Visual Studio 2019 で DesktopApp プロジェクトに新しい項目を追加することを示すアニメーション。

    アニメーションでは、ソリューション エクスプローラーでプロジェクト名を右クリックし、表示されるメニューで [追加] を選択し、[新しい項目] を選択しています。

  7. [新しい項目の追加] ダイアログ ボックスで、 [C++ ファイル (.cpp)]をクリックします。 [ 名前 ] ボックスに、ファイルの名前を入力します (例: HelloWindowsDesktop.cpp)。 追加を選択します。

    Visual Studio 2019 の [新しい項目の追加] ダイアログ ボックスのスクリーンショット。C + ファイル (.cpp) オプションが選択されています。名前フィールドは Hello Windows Desktop.cppに設定されます。

これで、プロジェクトが作成され、ソース ファイルがエディターで開きます。

Visual Studio 2017 で Windows デスクトップ プロジェクトを作成するには

  1. [ファイル] メニューの [新規作成] を選択し、[プロジェクト] を選択します。

  2. [新しいプロジェクト] ダイアログ ボックスの左側のペインで、[インストール]>[Visual C++] の順に展開し、[Windows デスクトップ] を選択します。 中央のペインで、[Windows デスクトップ ウィザード] を選択します。

    [名前] ボックスに、プロジェクトの名前 (DesktopApp など) を入力します。 OK を選択します。

    Visual Studio 2017 の [新しいプロジェクト] ダイアログ ボックスのスクリーンショット。Windows デスクトップ ウィザードの項目が選択されています。名前のテキスト ボックスに DesktopApp と表示されます。

  3. [Windows デスクトップ プロジェクト] ダイアログの [アプリケーションの種類] で、[Windows アプリケーション (.exe)] を選択します。 [追加のオプション][空のプロジェクト]を選択します。 [プリコンパイル済みヘッダー] が選択されていないことを確認します。 [OK] を選択して、プロジェクトを作成します。

  4. [ソリューション エクスプローラー] で、DesktopApp プロジェクトを右クリックし、[追加] を選択して、[新しい項目] を選択します。

    Visual Studio 2017 で DesktopApp Project に新しい項目を追加することを示すアニメーション。

    アニメーションでは、ソリューション エクスプローラーでプロジェクト名を右クリックし、表示されるメニューで [追加] を選択し、[新しい項目] を選択しています。

  5. [新しい項目の追加] ダイアログ ボックスで、 [C++ ファイル (.cpp)]をクリックします。 [ 名前 ] ボックスに、ファイルの名前を入力します (例: HelloWindowsDesktop.cpp)。 追加を選択します。

    Visual Studio 2017 の [新しい項目の追加] ダイアログ ボックスのスクリーンショット。左側で [Visual C plus plus] が選択され、[C+ ファイル] オプションが強調表示されています。

これで、プロジェクトが作成され、ソース ファイルがエディターで開きます。

Visual Studio 2015 で Windows デスクトップ プロジェクトを作成するには

  1. [ファイル] メニューの [新規作成] を選択し、[プロジェクト] を選択します。

  2. [新しいプロジェクト] ダイアログ ボックスの左側のペインで、[インストール]>[テンプレート]>[Visual C++] の順に展開し、[Win32] を選択します。 中央のペインで、 [Win32 プロジェクト]を選択します。

    [名前] ボックスに、プロジェクトの名前 (DesktopApp など) を入力します。 OK を選択します。

    Visual Studio 2015 の [新しいプロジェクト] ダイアログ ボックスのスクリーンショット。[Win32 プロジェクト] オプションが強調表示され、[名前] テキスト ボックスに DesktopApp が入力されています。

  3. [Win32 アプリケーション ウィザード][概要] ページで、[次へ] を選択します。

    [Win32 アプリケーション ウィザードの概要] ページを示す Visual Studio 2015 のダイアログ ボックスのスクリーンショット。

  4. [アプリケーションの設定] ページの [アプリケーションの種類] で、[Windows アプリケーション] を選択します。 [追加オプション] で、[プリコンパイル済みヘッダー] をオフにしてから、[空のプロジェクト] を選択します。 [完了] を選択して、プロジェクトを作成します。

  5. [ソリューション エクスプローラー] で、DesktopApp プロジェクトを右クリックし、[追加] を選択して、[新しい項目] を選択します。

    Visual Studio 2015 で DesktopApp プロジェクトに新しい項目を追加することを示すアニメーション。

    アニメーションでは、ソリューション エクスプローラーでプロジェクト名を右クリックし、表示されるメニューで [追加] を選択し、[新しい項目] を選択しています。

  6. [新しい項目の追加] ダイアログ ボックスで、 [C++ ファイル (.cpp)]をクリックします。 [ 名前 ] ボックスに、ファイルの名前を入力します (例: HelloWindowsDesktop.cpp)。 追加を選択します。

    Visual Studio 2015 の [Add New Item]\(新しい項目の追加\) ダイアログ ボックスのスクリーンショット。Visual C plus plus が選択され、[C+ ファイル] オプションが強調表示されています。

これで、プロジェクトが作成され、ソース ファイルがエディターで開きます。

コード

次に、Visual Studio で Windows デスクトップ アプリケーションのコードを作成する方法について説明します。

プログラムの組み合わせ

従来のWindows デスクトップ アプリケーションでは、ウィンドウを表示する前に、いくつかのセットアップ コードを使用します。

プログラム部分 Purpose
ヘッダーと共有宣言 Windows型を指定し、複数の関数で使用される値を宣言します。
WinMain ウィンドウ クラスを登録し、ウィンドウを作成して表示し、メッセージ ループを実行します。
WndProc ウィンドウを描画または閉じる要求など、Windowsからのメッセージを処理します。

次の抜粋では、一度にプログラムの 1 つの部分に焦点を当てています。 完全なソースは、正しい順序でパーツを結合します。

Windows デスクトップ アプリケーションでコードの実行を開始する場所

  1. すべての C アプリケーションおよび C++ アプリケーションに開始点として main 関数が必要なように、すべての Windows デスクトップ アプリケーションには WinMain 関数が必要です。 WinMain の構文は、次のとおりです。

    int WINAPI WinMain(
       _In_ HINSTANCE hInstance,
       _In_opt_ HINSTANCE hPrevInstance,
       _In_ LPSTR     lpCmdLine,
       _In_ int       nCmdShow
    );
    

    この関数のパラメーターと戻り値については、WinMain エントリ ポイントに関する記事を参照してください。

    WINAPICALLBACKHINSTANCE_In_ などの追加の単語は何でしょうか。 従来の Windows API では、typedef とプリプロセッサ マクロを広範囲に使用して、型の詳細とプラットフォーム固有のコードの一部 (呼び出し規則、__declspec 宣言、コンパイラ pragma など) を抽象化します。 Visual Studio では、IntelliSense クイック ヒント機能を使用して、これらの typedef およびマクロの定義内容を確認できます。 目的の単語の上にマウス ポインターを置くか、それを選択して Ctrl+K キー、Ctrl+I キーを押して、定義を含む小さなポップアップ ウィンドウを表示します。 詳細については、「IntelliSense の使用」を参照してください。 パラメーターと戻り値の型では、多くの場合、プログラミング エラーをキャッチするのに役立つ "SAL 注釈" が使用されます。 詳細については、「SAL 注釈を使って C/C++ のコード障害を減らす方法」を参照してください。

  2. Windows デスクトップ プログラムには <windows.h> が必要です。 #include <tchar.h>も頻繁に表示されます。 これは、charwchar_t のどちらでも動作するアプリを簡単に作成できるようにするためです。 その動作方法は、代わりにコードで TCHAR マクロを使用することです。 TCHARは、プロジェクトがUNICODEシンボルを定義するときにwchar_tに解決されます。それ以外の場合は、charに解決されます。 常に UNICODE を有効にしてビルドする場合は、TCHAR は不要であり、wchar_t だけを直接使用できます。 詳細については、「汎用テキスト マップの使用」を参照してください。 次のコードは、ファイルの先頭にあるこれら 2 つの #include ステートメントを示しています。

    #include <windows.h>
    #include <tchar.h>
    
  3. WinMain 関数の他に、すべての Windows デスクトップ アプリケーションにはウィンドウ プロシージャ関数も必要です。 このチュートリアルでは、 WndProc関数に名前を付けますが、コード内で任意の名前を付けることができます。 WndProc の構文は、次のとおりです。

    LRESULT CALLBACK WndProc(
       _In_ HWND   hWnd,
       _In_ UINT   message,
       _In_ WPARAM wParam,
       _In_ LPARAM lParam
    );
    

    この関数では、"イベント" が発生したときに Windows からアプリケーションが受け取る "メッセージ" を処理するコードを記述します。 たとえば、ユーザーがアプリケーションで [OK] ボタンを選択した場合、Windows からメッセージが送信されます。 適切な処理を行うコードを WndProc 関数内に記述します。 これは、イベントの "処理" と呼ばれます。 処理するのは、アプリケーションに関連するイベントのみです。

    詳細については、「 ウィンドウ プロシージャ」を参照してください。

WinMain 関数に機能を追加する

WinMainする前に、プログラムの他の部分で使用する値とウィンドウ プロシージャを宣言します。 これらの宣言は、完全なソースで WinMain する前に表示されます。

// The main window class name.
static TCHAR szWindowClass[] = _T("DesktopApp");

// The string that appears in the application's title bar.
static TCHAR szTitle[] = _T("Windows Desktop Guided Tour Application");

// Stored instance handle for use in Win32 API calls such as FindResource.
HINSTANCE hInst;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  1. WinMain 関数では、メイン ウィンドウに関するいくつかの基本情報を取得する必要があります。 そのためには、WNDCLASSEX 型の構造を入力します。 構造には、アプリケーション アイコン、ウィンドウの背景色、タイトル バーに表示する名前など、ウィンドウに関する情報が含まれています。 重要なのは、Windows がアプリに送信するメッセージを処理するウィンドウ プロシージャへの関数ポインターが含まれていることです。 一般的な WNDCLASSEX 構造体の例を次に示します。

    WNDCLASSEX wcex;
    
    wcex.cbSize         = sizeof(WNDCLASSEX);
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(wcex.hInstance, IDI_APPLICATION);
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, IDI_APPLICATION);
    

    この構造のフィールドについては、 WNDCLASSEXを参照してください。

  2. WNDCLASSEX構造を入力したら、ウィンドウとメッセージの送信方法を認識できるように、Windowsに登録します。 RegisterClassEx 関数を使用して、ウィンドウ クラス構造体を引数として渡します。 _T マクロは、Unicode に関する前の説明で説明したように、文字列リテラルを TCHAR によって選択された文字型と一致させます。 次のコードは、ウィンドウ クラスを登録する方法を示しています。

    if (!RegisterClassEx(&wcex))
    {
       MessageBox(NULL,
          _T("Call to RegisterClassEx failed!"),
          _T("Windows Desktop Guided Tour"),
          NULL);
    
       return 1;
    }
    
  3. CreateWindowEx関数を使用してウィンドウを作成します。

    // The parameters to CreateWindowEx explained:
    // WS_EX_OVERLAPPEDWINDOW : An optional extended window style.
    // szWindowClass: the name of the application
    // szTitle: the text that appears in the title bar
    // WS_OVERLAPPEDWINDOW: the type of window to create
    // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
    // 500, 100: initial size (width, height)
    // NULL: the parent of this window
    // NULL: this application doesn't have a menu bar
    // hInstance: the first parameter from WinMain
    // NULL: not used in this application
    HWND hWnd = CreateWindowEx(
    WS_EX_OVERLAPPEDWINDOW,
       szWindowClass,
       szTitle,
       WS_OVERLAPPEDWINDOW,
       CW_USEDEFAULT, CW_USEDEFAULT,
       500, 100,
       NULL,
       NULL,
       hInstance,
       NULL
    );
    if (!hWnd)
    {
       MessageBox(NULL,
          _T("Call to CreateWindowEx failed!"),
          _T("Windows Desktop Guided Tour"),
          NULL);
    
       return 1;
    }
    

    この関数は HWND を返します。これはウィンドウへのハンドルです。 ハンドルはポインターのようなものです。 Windows では、作成したウィンドウを管理するためにハンドルを使用します。 詳細については、「 Windows のデータ型」を参照してください。

  4. この時点で、ウィンドウは作成されていますが、これを表示させるように Windows にさらに指示する必要があります。 それがこのコードで実行する内容です。

    // The parameters to ShowWindow explained:
    // hWnd: the value returned from CreateWindowEx
    // nCmdShow: the fourth parameter from WinMain
    ShowWindow(hWnd,
       nCmdShow);
    UpdateWindow(hWnd);
    

    WndProc 関数をまだ実装していないため、表示されるウィンドウはただの空白の四角形です。 アプリケーションは、Windows が現在それに送信しているメッセージをまだ処理していません。

  5. メッセージを処理するには、まずメッセージ ループと呼ばれるものを追加して、Windows が送信するメッセージをリッスンします。 アプリケーションがメッセージを受け取ると、このループはそれを処理するために WndProc 関数にディスパッチします。 メッセージ ループのコードは、次のようになります。

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
       TranslateMessage(&msg);
       DispatchMessage(&msg);
    }
    
    return (int) msg.wParam;
    

    メッセージ ループ内の構造体と関数の詳細については、 MSGGetMessage、「TranslateMessage」、DispatchMessage を参照してください。

    アプリケーションのメイン ウィンドウを作成し、Windows がアプリを送信するメッセージをリッスンする基本的な WinMain 関数は、次のようなコードになります。

    int WINAPI WinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPSTR lpCmdLine,
                       int nCmdShow)
    {
       WNDCLASSEX wcex;
    
       wcex.cbSize = sizeof(WNDCLASSEX);
       wcex.style          = CS_HREDRAW | CS_VREDRAW;
       wcex.lpfnWndProc    = WndProc;
       wcex.cbClsExtra     = 0;
       wcex.cbWndExtra     = 0;
       wcex.hInstance      = hInstance;
       wcex.hIcon          = LoadIcon(wcex.hInstance, IDI_APPLICATION);
       wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
       wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
       wcex.lpszMenuName   = NULL;
       wcex.lpszClassName  = szWindowClass;
       wcex.hIconSm        = LoadIcon(wcex.hInstance, IDI_APPLICATION);
    
       if (!RegisterClassEx(&wcex))
       {
          MessageBox(NULL,
             _T("Call to RegisterClassEx failed!"),
             _T("Windows Desktop Guided Tour"),
             NULL);
    
          return 1;
       }
    
       // Store instance handle in our global variable
       hInst = hInstance;
    
       // The parameters to CreateWindowEx explained:
       // WS_EX_OVERLAPPEDWINDOW : An optional extended window style.
       // szWindowClass: the name of the application
       // szTitle: the text that appears in the title bar
       // WS_OVERLAPPEDWINDOW: the type of window to create
       // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
       // 500, 100: initial size (width, height)
       // NULL: the parent of this window
       // NULL: this application doesn't have a menu bar
       // hInstance: the first parameter from WinMain
       // NULL: not used in this application
       HWND hWnd = CreateWindowEx(
          WS_EX_OVERLAPPEDWINDOW,
          szWindowClass,
          szTitle,
          WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, CW_USEDEFAULT,
          500, 100,
          NULL,
          NULL,
          hInstance,
          NULL
       );
    
       if (!hWnd)
       {
          MessageBox(NULL,
             _T("Call to CreateWindowEx failed!"),
             _T("Windows Desktop Guided Tour"),
             NULL);
    
          return 1;
       }
    
       // The parameters to ShowWindow explained:
       // hWnd: the value returned from CreateWindowEx
       // nCmdShow: the fourth parameter from WinMain
       ShowWindow(hWnd, nCmdShow);
       UpdateWindow(hWnd);
    
       // Main message loop:
       MSG msg;
       while (GetMessage(&msg, NULL, 0, 0))
       {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
       }
    
       return (int) msg.wParam;
    }
    

WndProc 関数内のメッセージを処理する

  1. アプリケーションが受信するメッセージを処理するには、switch 関数に WndProc ステートメントを実装します。

    処理する重要なメッセージは WM_PAINT です。 アプリケーションは、表示されたウィンドウの一部の更新が必要になったときに WM_PAINT メッセージを受け取ります。 このイベントは、ユーザーがお使いのウィンドウの前にあるウィンドウを移動し、それを再び離したときに発生することがあります。 アプリケーションは、ウィンドウが初めて表示されるときにこのメッセージを受け取り、アプリケーション UI を表示する機会が与えられます。 Windows がこれらのイベントを送信すると、アプリケーションはそのイベントを検出できます。 ウィンドウが初めて表示されるときには、その全体が更新される必要があります。

    WM_PAINT メッセージを処理するには、最初に BeginPaint を呼び出してから、ウィンドウ内のテキスト、ボタン、およびその他のコントロールをレイアウトするすべてのロジックを処理します。 次に、EndPaint を呼び出します。 このアプリケーションでは、BeginPaint()EndPaint() の間のコードは、Hello, Windows desktop! で作成したウィンドウに WinMain() を表示します。 次のコードでは、この TextOut 関数はウィンドウ内の指定した位置にテキストを表示します。

    PAINTSTRUCT ps;
    HDC hdc;
    TCHAR greeting[] = _T("Hello, Windows desktop!");
    
    switch (message)
    {
    case WM_PAINT:
       hdc = BeginPaint(hWnd, &ps);
    
       // Here your application is laid out.
       // For this introduction, we just print out "Hello, Windows desktop!"
       // in the top left corner.
       TextOut(hdc,
          5, 5,
          greeting, static_cast<int>(_tcslen(greeting))); // TextOut expects an int here but _tcslen returns a size_t. Thus the cast.
       // End application-specific layout section.
    
       EndPaint(hWnd, &ps);
       break;
    }
    

    前のコードでは、 HDC はウィンドウのクライアント領域に関連付けられているデバイス コンテキストへのハンドルです。 ウィンドウに描画するときは、このハンドルを使用してクライアント領域を参照します。 クライアント領域での描画を準備して完了するには、BeginPaint および EndPaint 関数を使用します。 BeginPaint は、クライアント領域での描画に使用されるディスプレイ デバイス コンテキストへのハンドルを返します。EndPaint は、描画要求を終了し、デバイス コンテキストを解放します。

  2. アプリケーションは通常、多くの他のメッセージを処理します。 たとえば、ウィンドウが最初に作成されたときに送信される WM_CREATE や、ウィンドウが閉じられたときの WM_DESTROY などです。 単純でも完成した WndProc 関数のコードを次に示します。

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
       PAINTSTRUCT ps;
       HDC hdc;
       TCHAR greeting[] = _T("Hello, Windows desktop!");
    
       switch (message)
       {
       case WM_PAINT:
          hdc = BeginPaint(hWnd, &ps);
    
          // Here your application is laid out.
          // For this introduction, we just print out "Hello, Windows desktop!"
          // in the top left corner.
          TextOut(hdc,
             5, 5,
             greeting, static_cast<int>(_tcslen(greeting))); // TextOut expects an int here but _tcslen returns a size_t. Thus the cast.
          // End application specific layout section.
    
          EndPaint(hWnd, &ps);
          break;
       case WM_DESTROY:
          PostQuitMessage(0);
          break;
       default:
          return DefWindowProc(hWnd, message, wParam, lParam);
          break;
       }
    
       return 0;
    }
    

コードのビルド

約束どおり、動作するアプリケーションの完全なコードを次に示します。

この例をビルドするには

  1. エディターの HelloWindowsDesktop.cpp 内のすべてのコードを削除します。 次のコード例をコピーし、 HelloWindowsDesktop.cppに貼り付けます。

    // HelloWindowsDesktop.cpp
    // compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c
    
    #include <windows.h>
    #include <tchar.h>
    
    // Global variables
    
    // The main window class name.
    static TCHAR szWindowClass[] = _T("DesktopApp");
    
    // The string that appears in the application's title bar.
    static TCHAR szTitle[] = _T("Windows Desktop Guided Tour Application");
    
    // Stored instance handle for use in Win32 API calls such as FindResource.
    HINSTANCE hInst;
    
    // Forward declarations of functions included in this code module:
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain(
       _In_ HINSTANCE hInstance,
       _In_opt_ HINSTANCE hPrevInstance,
       _In_ LPSTR     lpCmdLine,
       _In_ int       nCmdShow
    )
    {
       WNDCLASSEX wcex;
    
       wcex.cbSize = sizeof(WNDCLASSEX);
       wcex.style          = CS_HREDRAW | CS_VREDRAW;
       wcex.lpfnWndProc    = WndProc;
       wcex.cbClsExtra     = 0;
       wcex.cbWndExtra     = 0;
       wcex.hInstance      = hInstance;
       wcex.hIcon          = LoadIcon(wcex.hInstance, IDI_APPLICATION);
       wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
       wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
       wcex.lpszMenuName   = NULL;
       wcex.lpszClassName  = szWindowClass;
       wcex.hIconSm        = LoadIcon(wcex.hInstance, IDI_APPLICATION);
    
       if (!RegisterClassEx(&wcex))
       {
          MessageBox(NULL,
             _T("Call to RegisterClassEx failed!"),
             _T("Windows Desktop Guided Tour"),
             NULL);
    
          return 1;
       }
    
       // Store instance handle in our global variable
       hInst = hInstance;
    
       // The parameters to CreateWindowEx explained:
       // WS_EX_OVERLAPPEDWINDOW : An optional extended window style.
       // szWindowClass: the name of the application
       // szTitle: the text that appears in the title bar
       // WS_OVERLAPPEDWINDOW: the type of window to create
       // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
       // 500, 100: initial size (width, height)
       // NULL: the parent of this window
       // NULL: this application doesn't have a menu bar
       // hInstance: the first parameter from WinMain
       // NULL: not used in this application
       HWND hWnd = CreateWindowEx(
          WS_EX_OVERLAPPEDWINDOW,
          szWindowClass,
          szTitle,
          WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, CW_USEDEFAULT,
          500, 100,
          NULL,
          NULL,
          hInstance,
          NULL
       );
    
       if (!hWnd)
       {
          MessageBox(NULL,
             _T("Call to CreateWindowEx failed!"),
             _T("Windows Desktop Guided Tour"),
             NULL);
    
          return 1;
       }
    
       // The parameters to ShowWindow explained:
       // hWnd: the value returned from CreateWindowEx
       // nCmdShow: the fourth parameter from WinMain
       ShowWindow(hWnd,
          nCmdShow);
       UpdateWindow(hWnd);
    
       // Main message loop:
       MSG msg;
       while (GetMessage(&msg, NULL, 0, 0))
       {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
       }
    
       return (int) msg.wParam;
    }
    
    //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
    //
    //  PURPOSE:  Processes messages for the main window.
    //
    //  WM_PAINT    - Paint the main window
    //  WM_DESTROY  - post a quit message and return
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
       PAINTSTRUCT ps;
       HDC hdc;
       TCHAR greeting[] = _T("Hello, Windows desktop!");
    
       switch (message)
       {
       case WM_PAINT:
          hdc = BeginPaint(hWnd, &ps);
    
          // Here your application is laid out.
          // For this introduction, we just print out "Hello, Windows desktop!"
          // in the top left corner.
          TextOut(hdc,
             5, 5,
             greeting, static_cast<int>(_tcslen(greeting))); // TextOut expects an int here but _tcslen returns a size_t. Thus the cast.
          // End application-specific layout section.
    
          EndPaint(hWnd, &ps);
          break;
       case WM_DESTROY:
          PostQuitMessage(0);
          break;
       default:
          return DefWindowProc(hWnd, message, wParam, lParam);
          break;
       }
    
       return 0;
    }
    
  2. [ビルド] メニューの [ソリューションのビルド]をクリックします。 コンパイルの結果は、Visual Studio の [出力] ウィンドウに表示されます。

    DesktopApp プロジェクトをビルドする手順を示すアニメーション。

    アニメーションでは、[すべて保存] ボタンをクリックした後、メイン メニューから [ビルド] > [ソリューションのビルド] を選択しています。

  3. アプリケーションを実行するには、F5 を押します。 テキスト Hello, Windows desktop! を含むウィンドウが表示されます。

    Windows デスクトップ ガイド付きツアー アプリケーションというタイトルのウィンドウのスクリーンショット。ウィンドウの内容は Hello、 Windows デスクトップです。

お疲れさまでした。 これで、従来の Windows デスクトップ アプリケーションのビルドが完了しました。

関連項目