始めるWin32API Bluetooth3日目
|
現在のカテゴリー : bluetooth1 - approach
|
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