始めるWin32API Bluetooth3日目


現在のカテゴリー : bluetooth1 - approach
Bluetoothで通信するために、
Win32APIを勉強します。

とりあえず、
2,3日でWin32APIの使い方を学びます。

VC++のプロジェクトの新規作成で、Win32 Applicationを選んで、
標準的なHello Worldアプリケーションを選ぶと、

Hello Worldというアプリケーションができあがり。
初めてのWindowsアプリケーションが3分でできました。

めでたしめでたし。

下がそのコード。
Hello Worldのくせに、恐ろしく長い。

#include "stdafx.h"
#include "resource.h"

#define MAX_LOADSTRING 100

HINSTANCE hInst
TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];


ATOM			MyRegisterClass( HINSTANCE hInstance );
BOOL			InitInstance( HINSTANCE, int );
LRESULT CALLBACK	WndProc( HWND, UINT, WPARAM, LPARAM );
LRESULT CALLBACK	About( HWND, UINT, WPARAM, LPARAM );

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow )
{

	MSG msg;
	HACCEL hAccelTable;


	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_BLUETOOTH1, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass( hInstance );


	if( !InitInstance( hInstance, nCmdShow ) ) 
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_BLUETOOTH1);

	while( GetMessage(&msg, NULL, 0, 0) ) 
	{
		if( !TranslateAccelerator (msg.hwnd, hAccelTable, &msg) ) 
		{
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
	}

	return msg.wParam;
}

ATOM MyRegisterClass( HINSTANCE hInstance )
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX); 

	wcex.style		= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon		= LoadIcon(hInstance, (LPCTSTR)IDI_BLUETOOTH1);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= (LPCSTR)IDC_BLUETOOTH1;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

	return RegisterClassEx( &wcex );
}

BOOL InitInstance( HINSTANCE hInstance, int nCmdShow )
{
   HWND hWnd;

   hInst = hInstance;

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if( !hWnd ) 
   {
      return FALSE;
   }

   ShowWindow( hWnd, nCmdShow );
   UpdateWindow( hWnd );

   return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;
	TCHAR szHello[MAX_LOADSTRING];
	LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

	switch( message ) 
	{
		case WM_COMMAND:
			wmId    = LOWORD(wParam); 
			wmEvent = HIWORD(wParam); 

			switch( wmId ) 
			{
				case IDM_ABOUT:
				   DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
				   break;
				case IDM_EXIT:
				   DestroyWindow( hWnd );
				   break;
				default:
				   return DefWindowProc( hWnd, message, wParam, lParam );
			}
			break;
		case WM_PAINT:
			hdc = BeginPaint (hWnd, &ps);

			RECT rt;
			GetClientRect( hWnd, &rt );
			DrawText( hdc, szHello, strlen(szHello), &rt, DT_CENTER );
			EndPaint( hWnd, &ps );
			break;
		case WM_DESTROY:
			PostQuitMessage( 0 );
			break;
		default:
			return DefWindowProc( hWnd, message, wParam, lParam );
   }
   return 0;
}

LRESULT CALLBACK About( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
	switch( message )
	{
		case WM_INITDIALOG:
				return TRUE;

		case WM_COMMAND:
			if( LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL ) 
			{
				EndDialog(hDlg, LOWORD(wParam));
				return TRUE;
			}
			break;
	}
    return FALSE;
}

ふざけてる。


とかなんとか、愚痴らないで、
読めるくらいには、理解します。


上記のコードにコメントを入れて、
わかった気分になります。


#include "stdafx.h"
#include "resource.h"

#define MAX_LOADSTRING 100

HINSTANCE hInst 
// HINSTANCE: インスタンスハンドル。 
//インスタンスで種類を特定して、ハンドルで個を特定する感じ??
//アプリケーションを特定して、複数ある同じアプリケーションを特定するのがハンドル?

TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];
//TCHARはUNICODEが定義されていればwchar_t、 そうでなければ、charに変換する型だそうだ

ATOM			MyRegisterClass( HINSTANCE hInstance );
BOOL			InitInstance( HINSTANCE, int );
LRESULT CALLBACK	WndProc( HWND, UINT, WPARAM, LPARAM );
LRESULT CALLBACK	About( HWND, UINT, WPARAM, LPARAM );


// WinMain内部の処理:
// ウインドウクラスの登録→ウインドウの作成と表示→メッセージの取り込みと配布(メッセージループ)
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow )
{

	MSG msg; // メッセージキューから取得したメッセージ 
	HACCEL hAccelTable; // アクセラレータテーブル
       // キーボードでショートカットみたいなものだ?

       // グローバルストリングを初期化
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_BLUETOOTH1, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass( hInstance );

       // アプリケーションの初期化
	if( !InitInstance( hInstance, nCmdShow ) ) 
	{
		return FALSE;
	}

       // 指定されたアクセラレータ( ショートカットキー)テーブルをロード
	hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_BLUETOOTH1);

       /*
        HACCEL LoadAccelerators(
              HINSTANCE hInstance,  // モジュールのハンドル
              LPCTSTR lpTableName   // アクセラレータテーブルの名前
       );
       */


       // 送られてくるメッセージを翻訳してプロシージャに送る。(メッセージループ)
       // GetMessage()で、WM_QUITというメッセージを吸い上げない限り、TRUEを返す。

        /*
        BOOL GetMessage(
          LPMSG  lpMsg // メッセージキューからの情報をここで受け取る
          HWND  hWnd,
          UINT  wMsgFilterMin,
          UINT  wMsgFilterMax 
       );
       */

        /*
        typedef struct tagMSG {
           HWND   hwnd; // どのウインドウで発生したメッセージかを識別できる情報が含まれている
          UINT   message; 
          WPARAM wParam; 
          LPARAM lParam; 
          DWORD  time; 
          POINT  pt; 
       } MSG; 
       */

	while( GetMessage(&msg, NULL, 0, 0) ) 
	{
               //アクセラレータテーブルにあるキー操作を受け取る
		if( !TranslateAccelerator (msg.hwnd, hAccelTable, &msg) ) 
		{
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
	}

	return msg.wParam;
}

// 互換性を保つために必要だとか。 どうでもよさそうなので無視。
// どうでもよくないのか? ウインドウの動きの定義だそうだ。
ATOM MyRegisterClass( HINSTANCE hInstance )
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX); 

	wcex.style		= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc; //ウインドウプロシージャの名前を代入
        // ウインドウクラスに、ウインドウプロシージャのエントリーポイントのアドレスが含まれる

	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon		= LoadIcon(hInstance, (LPCTSTR)IDI_BLUETOOTH1);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= (LPCSTR)IDC_BLUETOOTH1;
	wcex.lpszClassName	= szWindowClass; // クラス名をあらわす文字列へのポインタを代入
	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

	return RegisterClassEx( &wcex );
}

// インスタンス ハンドルの保存とメインウィンドウの作成
// インスタンス ハンドルをグローバル変数に保存、プログラムのメインウインドウを作成、表示
BOOL InitInstance( HINSTANCE hInstance, int nCmdShow )
{
   HWND hWnd;

   hInst = hInstance; // グローバル変数にインスタンス ハンドルを保存

   /* ウインドウ作成
   HWND CreateWindow(
      LPCTSTR  lpClassName,
      LPCTSTR  lpWindowName, // タイトルバーに表示したい文字列へのポインタを代入
      DWORD    dwStyle, //ウインドウの外観を決める
      int      x,  // CW_USEDEFAULT: 作成するウインドウの位置と大きさをOSに任せる
      int      y,
      int      nWidth,
      int      nHeight,
      HWND     hWndParent, //ウインドウの親子関係のリンクをする
      HMENU    hMenu, // ウインドウにメニューをつける
      HANDLE   hInstance,
      LPVOID   lpParam // ウインドウを作成する時、ウインドウプロシージャにデータを渡す
   );
  */

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if( !hWnd ) 
   {
      return FALSE;
   }

   // ウインドウの表示
   // hWnd:表示したいウインドウのウインドウハンドル
   // nCmdShow: どのような状態で表示(あるいは非表示)するのか
   ShowWindow( hWnd, nCmdShow );

   // ウインドウの最初の更新
   UpdateWindow( hWnd );

   return TRUE;
}

//メインウインドウのメッセージを処理
//LRESULT型=32ビット整数
//hwnd=動作を起こさねばならないウインドウのウインドウハンドル
//Unit message=ウインドウプロシージャにとってのメッセージ
//以降の引数は付加情報ということで無視
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;
	TCHAR szHello[MAX_LOADSTRING];
	LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

	switch( message ) 
	{
		case WM_COMMAND: // アプリケーションメニューの処理
                        // メニュー項目がクリックされるとここにくる

			wmId    = LOWORD(wParam);  // wParamの下位ワードを調べる
			wmEvent = HIWORD(wParam); 
                        // メニュー選択の解析
			switch( wmId ) 
			{
				case IDM_ABOUT: // リソースにIDM_何とかが定義されている
				   DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
				   break;
				case IDM_EXIT:
				   DestroyWindow( hWnd );
				   break;
				default:
				   return DefWindowProc( hWnd, message, wParam, lParam );
			}
			break;
		case WM_PAINT: // 文字表示のプログラム
                        // hdc:デバイスコンテキストハンドル
			hdc = BeginPaint (hWnd, &ps); // hWnd:テキスト表示にウィンドウハンドル

			RECT rt; // 四角形ぽい
			GetClientRect( hWnd, &rt );
			DrawText( hdc, szHello, strlen(szHello), &rt, DT_CENTER );
			EndPaint( hWnd, &ps );
			break;
		case WM_DESTROY: //ウィンドウ破棄メッセージ
			PostQuitMessage( 0 );
			break;
		default://デフォルト処理
			return DefWindowProc( hWnd, message, wParam, lParam );
   }
   return 0;
}

// バージョン情報ボックス用メッセージハンドラ
LRESULT CALLBACK About( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
	switch( message )
	{
		case WM_INITDIALOG:
				return TRUE;

		case WM_COMMAND:
			if( LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL ) 
			{
				EndDialog(hDlg, LOWORD(wParam));
				return TRUE;
			}
			break;
	}
    return FALSE;
}

はい!
Win32APIの入門は終了。


あとは必要になったときに、随時しらべましょう!
(いいかげん

人気blogランキングへ1日1回クリックお願いしますm( _ _)m

Post a comment

全カテゴリー

Recent Entries

相互リンク