アトリエ・エクレア

2DCG&3DCG, プログラミング, 日記などを掲載してます。

Win32 API

Win32 API

※自分専用の覚え書き

<参考文献>

  • msdn "Win32 アプリケーションの作成 (C++)" → Link
  • msdn "C++ による Windows プログラミングの学習" → Link

Win32 アプリケーション

クリックするとメッセージボックスが出るウィンドウ

// プリプロセッサ ディレクティブ
#include <windows.h>                      // Win32 API を使用するためインクルード
#include <tchar.h>                        // TCHAR型 ※char型かwchar型に置き換わる

// 関数プロトタイプ宣言
LRESULT CALLBACK MyWinProc(HWND, UINT, WPARAM, LPARAM);

// ===================================================================================
// WinMain関数
// ===================================================================================
// Win32アプリケーションの初期エントリポイント。Windowsシステムが呼び出す。
// 戻り値はOSでは使用しないが、別のプログラムにステータスコードを伝達できる
int WINAPI WinMain(                       // WINAPI : 関数の呼び出し規約 __stdcall の再定義
	HINSTANCE hInstance,                  // アプリケーションの現在のインスタンス(current instance)へのハンドル
	HINSTANCE hprevInstance,              // アプリケーションの以前のインスタンス(previous instance)へのハンドル ※現在は、常にNULL
	LPSTR lpCmdLine,                      // コマンドラインが格納されたヌル終端された文字列(プログラム名を除く)へのポインタ
	int nCmdShow)                         // ウィンドウの表示状態
{
	// ===================================================================================
	// ウィンドウクラスの、作成・設定・登録
	// ===================================================================================
	// 作成
	WNDCLASSEX wcex;                                 // ウィンドウクラス構造体

	// 設定 ※ウィンドウに関する情報
	wcex.cbSize = sizeof(WNDCLASSEX);                // WNDCLASSEX構造体のサイズ(バイト)
	wcex.style = CS_HREDRAW | CS_VREDRAW;            // クラススタイル ※ここではサイズ変更時に再描画
	wcex.lpfnWndProc = MyWinProc;                    // ウィンドウプロシージャーへのポインタ
	wcex.cbClsExtra = 0;                             // ウィンドウクラスの追加バイト数
	wcex.cbWndExtra = 0;                             // ウィンドウインスタンスの追加バイト数
	wcex.hInstance = hInstance;                      // アプリケーションの現在のインスタンスへのハンドル
	wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);    // アイコン素材へのハンドル
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);      // カーソル素材へのハンドル
	wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);   // 背景ブラシへのハンドル
	wcex.lpszMenuName = NULL;   // メニューリソース名。※ヌル終端された文字列へのポインタ。NULL:デフォルトメニューなし
	wcex.lpszClassName = _T("MySampleWindow");       // ウィンドウクラス名。※ヌル終端された文字列へのポインタ、またはATOM
	wcex.hIconSm = NULL;                             // 小アイコンへのハンドル。NULLの場合、hIconで指定されたアイコンを縮小

	// OSに登録
	if (RegisterClassEx(&wcex) == 0) return 0;       // 成功:登録されたクラスを一意に特定するATOMを返す。失敗:0を返す

	// ===================================================================================
	// ウィンドウのインスタンス作成
	// ===================================================================================
	// インスタンス作成  ※オーバーラップウィンドウ、ポップアップウィンドウ、子ウィンドウのいずれかを拡張スタイル付きで作成
	// 新しいウィンドウへのハンドルを返し、関数が失敗した場合はNULLを返す。  ※#define NULL 0
	HWND hWnd = CreateWindowEx(            // ウィンドウを作成し、ウィンドウへのハンドルを返す。失敗した場合、NULLを返す
		0,                                 // 拡張されたウィンドウスタイル ※0:既定の動作
		_T("MySampleWindow"),              // 登録されているウィンドウクラス名
		_T("マイ サンプル ウィンドウ"),      // ウィンドウ名 ※タイトルバーがあれば、そこに表示される
		// オーバーラップウィンドウ(キャプションと境界線), タイトルバーにコントロールメニューボックス, 最小化ボタン
		WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX,     // ウィンドウスタイル  ※WS_OVERLAPPEDWINDOWが便利
		100,                               // 横位置 (初期の水平位置)
		200,                               // 縦位置 (初期の垂直位置)
		300,                               // 幅
		400,                               // 高さ
		NULL,                              // 親ウィンドウ、またはオーナーウィンドウへのハンドル  ※NULL:最上位ウィンドウ
		NULL,                              // メニューへのハンドル、または、子ウィンドウ識別子    ※NULL:メニューを使用しない
		hInstance,                         // アプリケーションの現在のインスタンスへのハンドル
		NULL);                             // ウィンドウ作成データ(追加のアプリケーションデータ) ※void* 型の任意のデータへのポインタ

	// インスタンス作成の失敗時の処理
	if (hWnd == NULL) return 0;              // 失敗した場合、NULL  ※#define NULL 0

	// ===================================================================================
	// ウィンドウの表示
	// ===================================================================================
	// ウィンドウ表示  ※CreateWindowExによって返されるウィンドウハンドルを利用
	ShowWindow(hWnd, nCmdShow);         // 指定されたウィンドウの表示状態を設定
	// ウィンドウ更新
	UpdateWindow(hWnd);                 // 指定されたウィンドウの更新リージョンが空ではない場合、
										// ウィンドウへメッセージを送信し、そのウィンドウのクライアント領域を更新

	// ===================================================================================
	// メッセージループ
	// ===================================================================================
	// MSG構造体
	MSG msg;              // メッセージ情報を格納するための構造体

	// メッセージループ
	BOOL bRet;                          // typedef int BOOL;
	while ((bRet = GetMessage(          // キューからメッセージを取得し、指定の構造体に格納する
		&msg,             // MSG構造体へのポインタ ※メッセージ情報が格納される
		NULL,             // メッセージの取得に使う(取得元)ウィンドウへのハンドル
						  // ※NULL:呼び出し側スレッドに関連付けられている全てのウインドウへのメッセージを取得
		0,                // 取得するメッセージの最小値  ※第3、第4引数が共に0の場合、利用可能なすべてのメッセージを返す
		0                 // 取得するメッセージの最大値
		)) != 0) {                      // WM_QUITメッセージのとき、0。違う場合、0以外の値
		if (bRet == -1) {               // エラーの場合、-1
			break;                      // while文を抜ける
		}
		else {                          // 0と-1 以外の値の処理  ※WM_QUITとエラー以外
			TranslateMessage(&msg);     // キーボード入力に関連付けられており、キー操作を文字に変換

			// メッセージのターゲットウィンドウのウィンドウプロシージャを呼び出すようOSに通知する。
			// これでOSがウィンドウハンドルを検索し、ウィンドウに関連付けられた関数ポインターを特定し、関数を呼び出すことになる
			DispatchMessage(&msg);      // Windowsによるウィンドウプロシージャの呼び出しが間接的に実行される。
										// ウィンドウプロシージャは、戻り値をDispatchMessageに返す
		}
	}

	// ===================================================================================
	// 終了処理
	// ===================================================================================
	// ウィンドウクラスのOS登録解除
	UnregisterClass(_T("MySampleWindow"), hInstance);          // ウィンドウクラス名, インスタンスへのハンドル
	// アプリケーションの終了コード
	return msg.wParam;                                         // WM_QUITメッセージ時の、wParamの値を返す
}

// ===================================================================================
// ウィンドウプロシージャ(Window Procedure)
// ===================================================================================
// ウィンドウへ送信されたメッセージを処理する、アプリケーション定義のコールバック関数
LRESULT CALLBACK MyWinProc(       // CALLBACK : 関数の呼び出し規約 __stdcall の再定義 ※WINAPIと同じ
	HWND hWnd,                    // ウィンドウへのハンドル
	UINT uMsg,                    // メッセージ識別子
	WPARAM wParam,                // メッセージに関する、最初の追加情報
	LPARAM lParam)                // メッセージに関する、2番目の追加情報
{
	switch (uMsg)
	{
	case WM_DESTROY:              // ウィンドウが破棄された時のメッセージ
		// スレッドが自らの終了を要求したことをシステムに伝える。(キューへWM_QUITメッセージをポストし、すぐに制御を戻す)
		PostQuitMessage(0);       // 引数には、アプリケーションの終了コードを指定する。
								  // この値は、メッセージのwParamパラメータとして使われる。※終了時にWinMain関数が返す値になる。
		break;
	case WM_LBUTTONDOWN:          // ウィンドウのクライアント領域で、左マウスボタンを押した時のメッセージ
		MessageBox(hWnd, _T("hello, world!"), _T("messege"), MB_OK);
		break;
	default:
		// 既定のメッセージ処理をする、既定のウィンドウプロシージャ
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
	return 0;
}


スッキリ版

上と内容は同じ

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

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

// 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 = MyWinProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = hInstance;
	wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = _T("MySampleWindow");
	wcex.hIconSm = NULL;
	if (RegisterClassEx(&wcex) == 0) return 0;

	// ウィンドウのインスタンス作成
	HWND hWnd = CreateWindowEx(0, _T("MySampleWindow"), _T("マイ サンプル ウィンドウ"),
		WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX, 100, 200, 300, 400, NULL, NULL, hInstance, NULL);
	if (hWnd == NULL) return 0;

	// ウィンドウの表示
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	// メッセージループ
	MSG msg;
	BOOL bRet;
	while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) {
		if (bRet == -1) {
			break;
		}
		else {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	// 終了処理
	UnregisterClass(_T("MySampleWindow"), hInstance);
	return msg.wParam;
}

// ウィンドウプロシージャ
LRESULT CALLBACK MyWinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	switch (uMsg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_LBUTTONDOWN:
		MessageBox(hWnd, _T("hello, world!"), _T("messege"), MB_OK);
		break;
	default:
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
	return 0;
}





マイブログへようこそ♪
PLEASANT_DRAGON

2DCG&3DCG,プログラミング,
日記などを掲載中☆

(*´▽`*)コメント大歓迎です☆

最新記事
記事一覧

全ての記事を表示する

カテゴリ
SAI (0)
mi (2)
C (1)
C++ (1)
C# (0)
VBA (0)
月別アーカイブ
最新コメント
RSSリンクの表示
リンク
FC2ブログランキング

FC2Blog Ranking

ピックアップ商品1♪










カレンダー
05 | 2017/06 | 07
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 -
ブログ内検索フォーム
プロフィール

エクレア

Author:エクレア


  • 2DCG&3DCGの創作活動をしています。

  • SF系のメカが大好物。

アクセスカウンター
Twitter
ピックアップ商品2♪