次の方法で共有


Win32 アプリケーションの作成 (C++)

更新 : 2007 年 11 月

Win32 API (Windows API とも呼ばれます) は、Windows アプリケーションを作成するための C ベースのフレームワークであり、Windows のバージョンが 1.0 のときから使用されています。この API の詳細については、「Windows API」を参照してください。

この手順では、ウィンドウに "Hello, World!" を表示する単純な Win32 アプリケーションを作成します。手順はすべての Win32 アプリケーションで同じです。この手順を完了した後、ここで作成したコードをスケルトンとして使用して、他の Win32 アプリケーションを作成できます。

前提条件

このトピックは、C++ 言語の基本を理解していることを前提としています。C++ の学習を始めたばかりのユーザーには、『C++ Beginner's Guide』(Herb Schildt 著) をお勧めします。このガイドはオンラインで入手できます (https://go.microsoft.com/fwlink/?LinkId=115303)。

ビデオへのリンク ビデオ デモについては、「Video How to: Creating Win32 Applications (C++)」を参照してください。

新しい Win32 プロジェクトを作成するには

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

  2. [プロジェクトの種類] ペインの [Visual C++] ノードの [Win32] を選択し、[テンプレート] ペインの [Win32 プロジェクト] を選択します。

    プロジェクトに「win32app」などの名前を付けて入力します。プロジェクトを保存する場所は、既定の場所をそのまま使用するか、新しい場所を入力するか、ディレクトリを検索します。

  3. Win32 アプリケーション ウィザードで、[次へ] をクリックします。

  4. Win32 アプリケーション ウィザードで、[アプリケーションの種類] の [Windows アプリケーション] を選択します。[追加のオプション] の [空のプロジェクト] を選択します。残りのオプションはそのままにします。[完了] をクリックして、プロジェクトを作成します。

  5. C++ ファイルをプロジェクトに追加するには、[プロジェクト] メニューの [新しい項目の追加] をクリックします。[新しい項目の追加] ダイアログ ボックスで、[C++ ファイル (.cpp)] をクリックします。「GT_HelloWorldWin32.cpp」などファイルの名前を入力し、[追加] をクリックします。

Win32 アプリケーションを起動するには

  1. C および C++ アプリケーションにはすべて main 関数が必要です。この関数は、アプリケーションの開始点です。同様に、Win32 アプリケーションもすべて WinMain 関数を必要とします。WinMain の構文は次のとおりです。

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

    この関数のパラメータと戻り値については、「WinMain 関数」を参照してください。

  2. WinMain に加えて、各 Win32 アプリケーションには、通常 WndProc と呼ばれるもう 1 つの関数が必要です。この名前はウィンドウ プロシージャを表しています。WndProc の構文は次のとおりです。

    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    

    この関数の目的は、アプリケーションがオペレーティング システムから受け取るメッセージを処理することです。アプリケーションは、オペレーティング システムから常にメッセージを受け取ります。たとえば、[OK] ボタンを持つダイアログ ボックスを作成したとします。ユーザーがそのボタンをクリックすると、オペレーティング システムはアプリケーションにこのボタンが押されたことを知らせるメッセージを送信します。WndProc 関数は、そのイベントに対する応答を担当します。この例での適切な応答は、ダイアログ ボックスを閉じることです。

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

WinMain に機能を追加するには

  1. まず、WinMain 関数の内部に WNDCLASSEX 型のウィンドウ クラス構造体を作成します。この構造体には、ウィンドウに関する情報が格納されます。たとえば、アプリケーションのアイコン、ウィンドウの背景色、タイトル バーに表示する名前、ウィンドウ プロシージャ関数の名前などです。一般的な 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(hInstance, MAKEINTRESOURCE(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, MAKEINTRESOURCE(IDI_APPLICATION));
    

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

  2. これでウィンドウ クラスが作成されました。次に、登録を行う必要があります。RegisterClassEx 関数を使用して、ウィンドウ クラス構造体を引数として渡します。

        if (!RegisterClassEx(&wcex))
        {
            MessageBox(NULL,
                _T("Call to RegisterClassEx failed!"),
                _T("Win32 Guided Tour"),
                NULL);
    
            return 1;
        }
    
  3. これでウィンドウ クラスが登録されました。次に、ウィンドウを作成する必要があります。次のように CreateWindow 関数を使用します。

    static TCHAR szWindowClass[] = _T("win32app");
    static TCHAR szTitle[] = _T("Win32 Guided Tour Application");
    // The parameters to CreateWindow explained:
    // 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, length)
    // NULL: the parent of this window
    // NULL: this application dows not have a menu bar
    // hInstance: the first parameter from WinMain
    // NULL: not used in this application
    HWND hWnd = CreateWindow(
        szWindowClass,
        szTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        500, 100,
        NULL,
        NULL,
        hInstance,
        NULL
    );
    if (!hWnd)
    {
        MessageBox(NULL,
            _T("Call to CreateWindow failed!"),
            _T("Win32 Guided Tour"),
            NULL);
    
        return 1;
    }
    

    この関数は HWND を返します。これはウィンドウのハンドルです。詳細については、「Windows Data Types」を参照してください。

  4. これでウィンドウが作成されました。次に、以下のコードを使って画面に表示します。

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

    この段階ではこのウィンドウは多くを表示しません。まだ WndProc 関数を実装していないからです。

  5. WinMain の最後の手順は、メッセージ ループです。このループの目的は、オペレーティング システムが送信するメッセージを待機することです。アプリケーションがメッセージを受け取ると、メッセージは処理のために WndProc 関数にディスパッチされます。メッセージ ループは次のようになります。

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

    メッセージ ループで使用される構造体と関数の詳細については、「MSG」、「GetMessage」、「TranslateMessage」、および「DispatchMessage」を参照してください。

  6. ここで完了した手順は、ほとんどの Win32 アプリケーションに共通しています。この時点で、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(hInstance, MAKEINTRESOURCE(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, MAKEINTRESOURCE(IDI_APPLICATION));
    
        if (!RegisterClassEx(&wcex))
        {
            MessageBox(NULL,
                _T("Call to RegisterClassEx failed!"),
                _T("Win32 Guided Tour"),
                NULL);
    
            return 1;
        }
    
        hInst = hInstance; // Store instance handle in our global variable
    
        // The parameters to CreateWindow explained:
        // 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, length)
        // NULL: the parent of this window
        // NULL: this application dows not have a menu bar
        // hInstance: the first parameter from WinMain
        // NULL: not used in this application
        HWND hWnd = CreateWindow(
            szWindowClass,
            szTitle,
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT,
            500, 100,
            NULL,
            NULL,
            hInstance,
            NULL
        );
    
        if (!hWnd)
        {
            MessageBox(NULL,
                _T("Call to CreateWindow failed!"),
                _T("Win32 Guided Tour"),
                NULL);
    
            return 1;
        }
    
        // The parameters to ShowWindow explained:
        // hWnd: the value returned from CreateWindow
        // 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. WndProc 関数の目的は、アプリケーションが受け取るメッセージを処理することです。これは通常、switch 関数を使って実装します。

    最初に処理するメッセージは、WM_PAINT メッセージです。アプリケーションは、ウィンドウの一部が更新される必要があるときにこのメッセージを受け取ります。最初にウィンドウが作成されたときは、ウィンドウ全体を更新する必要があり、このメッセージが渡されることによってそのことを通知します。

    WM_PAINT メッセージを処理するときにまず行うことは BeginPaint を呼び出すことです。そして最後には EndPaint を呼び出す必要があります。これら 2 つの関数呼び出しの間に、ウィンドウのテキスト、ボタン、およびその他コントロールをレイアウトするためのすべてのロジックが処理されます。このアプリケーションでは、ウィンドウ内に "Hello, World!" という文字列を表示します。テキストを表示するには、次に示すように TextOut 関数を使用します。

    PAINTSTRUCT ps;
    HDC hdc;
    TCHAR greeting[] = _T("Hello, World!");
    
    switch (message)
    {
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
    
        // Here your application is laid out.
        // For this introduction, we just print out "Hello, World!"
        // in the top left corner.
        TextOut(hdc,
            5, 5,
            greeting, _tcslen(greeting));
        // End application-specific layout section.
    
        EndPaint(hWnd, &ps);
        break;
    }
    
  2. 通常、アプリケーションは WM_CREATEWM_DESTROY など、他にも多くのメッセージを処理します。単純でありながら完成した WndProc 関数を次に示します。

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        PAINTSTRUCT ps;
        HDC hdc;
        TCHAR greeting[] = _T("Hello, World!");
    
        switch (message)
        {
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
    
            // Here your application is laid out.
            // For this introduction, we just print out "Hello, World!"
            // in the top left corner.
            TextOut(hdc,
                5, 5,
                greeting, _tcslen(greeting));
            // 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;
    }
    

説明

すべての手順を完了した後、コードは次のようになります。アプリケーションをビルドするには、[ビルド] メニューの [ソリューションのビルド] をクリックします。エラーなしでアプリケーションをコンパイルできた場合は、F5 キーを押してアプリケーションを実行できるようになります。簡単なウィンドウが表示され、画面の左上隅付近に "Hello, World!" というテキストが表示されます。

コード

// GT_HelloWorldWin32.cpp
// compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>

// Global variables

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

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

HINSTANCE hInst;

// Forward declarations of functions included in this code module:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

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(hInstance, MAKEINTRESOURCE(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, MAKEINTRESOURCE(IDI_APPLICATION));

    if (!RegisterClassEx(&wcex))
    {
        MessageBox(NULL,
            _T("Call to RegisterClassEx failed!"),
            _T("Win32 Guided Tour"),
            NULL);

        return 1;
    }

    hInst = hInstance; // Store instance handle in our global variable

    // The parameters to CreateWindow explained:
    // 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, length)
    // NULL: the parent of this window
    // NULL: this application dows not have a menu bar
    // hInstance: the first parameter from WinMain
    // NULL: not used in this application
    HWND hWnd = CreateWindow(
        szWindowClass,
        szTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        500, 100,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hWnd)
    {
        MessageBox(NULL,
            _T("Call to CreateWindow failed!"),
            _T("Win32 Guided Tour"),
            NULL);

        return 1;
    }

    // The parameters to ShowWindow explained:
    // hWnd: the value returned from CreateWindow
    // 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, World!");

    switch (message)
    {
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);

        // Here your application is laid out.
        // For this introduction, we just print out "Hello, World!"
        // in the top left corner.
        TextOut(hdc,
            5, 5,
            greeting, _tcslen(greeting));
        // 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;
}

次の手順

前へ :Windows アプリケーションの作成 (C++) | 次へ :.NET Framework を使った Windows フォーム アプリケーションの作成 (C++)

参照

処理手順

Windows アプリケーションの作成 (C++)