Win32API講座2回
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
第二回目はウィンドウの作成方法について説明します
次のような至ってシンプルなウィンドウを作ってみましょう
&ref(windowsample.GIF);
まず、以下の用語は
ウィンドウ作成において
非常に重要ですので覚えてください
SIZE(30){ COLOR(#ffaa00){・ウィンドウクラス}}
SIZE(30){ COLOR(#ffaa00){・ウィンドウスタイル}}
SIZE(30){ COLOR(#ffaa00){・ウィンドウプロシージャ}}
ウィンドウクラスとウィンドウスタイルは
ウィンドウの性質を決めます
この2つを変更することで普通のウィンドウから、ボタン、エ...
さまざまな種類のウィンドウを作成することができます
ウィンドウプロシージャとは
ウィンドウに送られてくるメッセージを処理する関数のことです
ウィンドウズプロシージャでの処理を記述することで
さまざまなメッセージに対応することができます
では、早速作ってみましょう
-----------------------------------
Win32プロジェクトを選択します
(実はWin32コンソールでも作成できます、このやり方について...
&ref(project.GIF);
「次へ」を押して進んでください(完了を押してはいけません)
&ref(project2.GIF);
・Windowsアプリケーションにチェックがついているか確認して
・空のプロジェクトを選んでください
(空のプロジェクト以外を選ぶと余計なヘッダーファイルが作...
&ref(project3.GIF);
次に、main.cppを作ります
コンソールの時と同じように作ります
&ref(project4.GIF);
&ref(project5.GIF);
main.cppができたら
まず、次のコードを記述してください
#include <tchar.h>
#include <windows.h>
#include <windowsx.h>
int __stdcall WinMain(HINSTANCE hInstance,HINSTANCE hPre...
{
MessageBox(NULL,_T("Hello World"),_T("Msg Box"),MB_OK);
return 0;
}
次のような、メッセージボックスがでれば成功です
&ref(msgbox.GIF);
ここで気づいてほしいことがあります
main関数がありません
その代わりにWinMain関数が使われています
WindowsアプリケーションではWinMain関数がアプリケーション...
戻り値、引数も必ず上記のように書かなければなりません
また、起動してみるとコンソール画面(黒画面)は表示されま...
WinMain関数から開始するとコンソール画面は隠蔽されてしまい...
(コンソール画面を出す方法は後述)
この関数でまず、いきなり変だと感じると思うのは__stdcallと...
これは呼び出し規約と言われて
関数を呼び出すときの仕組みです
普段コンソールで作っている関数は暗黙のうちに
__cdeclという呼び出し規約になっていますが
ウィンドウズの関数は基本的に__stdcallという呼び出し規約に...
それ以上のことはあまり考えなくてもよいと思うので詳しい説...
ではWinMain関数の引数について説明します
HINSTANCEはインスタンスハンドルを指します
SIZE(30){ COLOR(#ffaa00){インスタンスハンドルはウィンドウ...
インスタンスハンドルというのは
OSがアプリケーションを識別するためのハンドル(ポインタ)です
アプリケーションが開始するとOSからインスタンスハンドルが...
プロセス毎に違うハンドル割り当てられるので
同じアプリケーションでも二つ同時に起動するとそれぞれ違う...
インスタンスハンドルは第1引数と第2引数の二つありますが...
最初の引数のインスタンスハンドル(hInstance)のみです
第2引数のインスタンスハンドル(hPrevInstance)は使いません...
第3引数(lpCmdLine)はコマンドライン引数を格納してる文字列...
第4引数(nShowCmd)はコマンドライン引数の個数です
コンソールの表示はされませんが
コンソールから直接起動したりバッチファイルを使うことで
コンソールアプリケーション同様、引数を受け取ることは可能...
では、
シンプルなウィンドウを作ってみましょう
コード量がかなりあるので最初は戸惑うかも知れません
ただ、やっている処理の内容は次の3つだけです
SIZE(20){ COLOR(#00aaff){・ウィンドウクラスを定義し、登録}}
SIZE(20){ COLOR(#00aaff){・ウィンドウを作成}}
SIZE(20){ COLOR(#00aaff){・メッセージループを回す}}
ゆっくり順番に見ていけば大丈夫です
// ウィンドウズバージョン指定
#define _WIN32_WINNT 0x0500
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#pragma comment(lib,"comctl32.lib")
#pragma comment(lib,"winmm.lib")
// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wPa...
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevIn...
{
const TCHAR* szClassName = _T("Basic"); // ウィンドウク...
/******************************************************...
/* ウィンドウクラスの定義と作成 */
/******************************************************...
// 新規ウィンドウクラスの定義
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX); // ウィンドウクラス...
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; // ウ...
wc.lpfnWndProc = WndProc; // ウィンドウプロシージャ...
wc.cbClsExtra = 0; // 0(使わない)
wc.cbWndExtra = 0; // 0(使わない)
wc.hInstance = hInstance; // インスタンスハンドル
wc.hIcon = (HICON)LoadImage(NULL,
MAKEINTRESOURCE(IDI_APPLICATION),
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED); // ウィンドウのアイコン
wc.hCursor = (HCURSOR)LoadImage(NULL,
MAKEINTRESOURCE(IDC_ARROW),
IMAGE_CURSOR,
0,
0,
LR_DEFAULTSIZE | LR_SHARED); // ウィンドウのカーソル
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);...
wc.lpszMenuName = NULL; // メニュー名
wc.lpszClassName = (LPCTSTR)szClassName; // ウィンドウ...
wc.hIconSm = (HICON)LoadImage(NULL,
MAKEINTRESOURCE(IDI_APPLICATION),
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);// 小さいアイコンが設定さ...
// ウィンドウクラスの登録
if(!RegisterClassEx(&wc))
return -1; // 登録失敗
/******************************************************...
/* ウィンドウの作成 */
/******************************************************...
HWND hWnd = CreateWindowEx(
0, //拡張ウィンドウスタイル
szClassName, //ウィンドウクラス名
_T("タイトル"), //タイトルバーにこの名前が表示されます
WS_OVERLAPPEDWINDOW, //ウィンドウスタイル
CW_USEDEFAULT, //X座標
CW_USEDEFAULT, //Y座標
CW_USEDEFAULT, //幅
CW_USEDEFAULT, //高さ
NULL, //親ウィンドウのハンドル、親を作るときはNULL
NULL, //メニューハンドルorリソースID
hInstance, //インスタンスハンドル
NULL);
// ウィンドウ作成失敗
if (hWnd == NULL)
return -1;
// ウィンドウを可視状態にする
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
/********************************************************/
/* メッセージループ */
/********************************************************/
MSG msg = {};
while(msg.message != WM_QUIT) {
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else{
// メッセージ処理をしてないとき
}
}
return 0;
}
// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wPa...
{
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return (DefWindowProc(hWnd, msg, wParam, lParam));
}
次のように出てくれば成功です
&ref(window.GIF);
正直、冗長な部分も多いと思いますので
特に大事な部分に絞って説明します
それ以外の設定はこのサンプル通りに使ってくれればよいと思...
上から見ていきましょう
// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wPa...
これはウィンドウに送られてきたメッセージを処理するための...
処理の中身は後述。
メイン関数です
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevIn...
WINAPI、CALLBACKは__stdcallが#defineで置き換えられている...
WNDCLASSEX構造体の変数に色々代入し、
RegisterClassEx関数でWNCLASSEX構造体を登録してます
WNDCLASSEX構造体のいくつか重要な変数を説明しておきます
CS_HREDRAW、CS_VREDRAWは
ウィンドウのサイズが変わった時に再描画するかのフラグです
CS_DBLCLKSはダブルクリックしたときのメッセージを受け付け...
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; // ウ...
SIZE(30){ COLOR(#ffaa00){ウィンドウへのメッセージを処理す...
関数ポインタの代入なのでグローバル関数もしくはクラスの静...
wc.lpfnWndProc = WndProc; // ウィンドウプロシージャ...
インスタンスハンドルをセットします
wc.hInstance = hInstance; // インスタンスハンドル
アイコンとカーソルをセットします
LoadImage関数はビットマップ(.bmp)、アイコン(.ico)、カーソ...
wc.hIcon = (HICON)LoadImage(NULL,
MAKEINTRESOURCE(IDI_APPLICATION),
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED); // ウィンドウのアイコン
wc.hCursor = (HCURSOR)LoadImage(NULL,
MAKEINTRESOURCE(IDC_ARROW),
IMAGE_CURSOR,
0,
0,
LR_DEFAULTSIZE | LR_SHARED); // ウィンドウのカーソル
ウィンドウの背景色をセットします
今回は白色ブラシで塗りつぶし
ここをGRAY_BRUSHにするとグレー色で塗りつぶしになります
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); ...
メニューをセットします(ウィンドウを作成するときにもセッ...
wc.lpszMenuName = NULL; // メニュー名
SIZE(30){ COLOR(#ffaa00){ウィンドウクラス名をセットします}}
"BUTTON"(後述)など予め定義されたウィンドウクラス名は使...
wc.lpszClassName = (LPCTSTR)szClassName; // ウィンドウ...
ウィンドウクラスを登録します
// ウィンドウクラスの登録
if(!RegisterClassEx(&wc))
return -1; // 登録失敗
ウィンドウクラスに基づいて
ウィンドウを作成します
HWND hWnd = CreateWindowEx(
0, //拡張ウィンドウスタイル
szClassName, //ウィンドウクラス名
_T("タイトル"), //タイトルバーにこの名前が表示されます
WS_OVERLAPPEDWINDOW, //ウィンドウスタイル
CW_USEDEFAULT, //X座標
CW_USEDEFAULT, //Y座標
CW_USEDEFAULT, //幅
CW_USEDEFAULT, //高さ
NULL, //親ウィンドウのハンドル、親を作るときはNULL
NULL, //メニューハンドルorリソースID
hInstance, //インスタンスハンドル
NULL);
ここで重要なのは
ウィンドウクラス名とウィンドウスタイルです
ウィンドウクラス名で登録されたウィンドウクラスを指定します
ボタンなどを作る場合は"BUTTON"などの予めデフォルトで登録...
ウィンドウスタイルはWS_OVERLAPPEDWINDOWとしていますが
これは最小化ボタン、最大化ボタン、閉じるボタンが付いてい...
ウィンドウの枠をドラッグすることで変えられます
ほかにも色々なスタイルが存在します
ウィンドウズスタイルのフラグは
「WS_なんとか」の形で全て書かれています
(追々に説明していきます)
第1引数の拡張ウィンドウスタイルはウィンドウスタイルの拡...
使わないときは0を指定します
(半透明ウィンドウを作成するときに設定したりします)
X座標、Y座標、幅、高さに
CW_USEDEFAULTを入れると
適当な位置に適当な大きさでウィンドウを作成してくれます
指定したい場合はここに整数値をいれます
第9引数は
親ウィンドウがある場合は親ウィンドウのハンドルを指定します
親がいない場合はNULLを指定します
(コントロールなどは指定)
第10引数は
メニューハンドルまたはリソースIDを指定します
リソースIDはコントロールなどの作成時に指定して
コントロールの識別に使います
(コントロール、メニューに関してはまた今度)
第11引数はインスタンスハンドルを指定します
最後の引数はNULLです
ウィンドウを作成したら
メッセージループを作ります
メッセージを取得し、ウィンドウプロシージャに処理させます
MSG msg = {};
while(msg.message != WM_QUIT) {
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else{
// メッセージ処理をしてないとき
}
}
ウィンドウズのメッセージは
「WM_なんとか」の形で全て書かれています
WM_QUITというメッセージが送られていなければループを続行し...
while(msg.message != WM_QUIT)
PeekMessage関数でメッセージキューからメッセージを取得します
TranslateMessage関数はアクセラレータキーなどを変換します...
DispatchMessage関数はウィンドウの対応するウィンドウプロシ...
メッセージの処理はウィンドウプロシージャで書きます
// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wPa...
{
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return (DefWindowProc(hWnd, msg, wParam, lParam));
}
msgにウィンドウに送られたメッセージが入ります
たとえばウィンドウで左マウスボタンが押されたりしたら
WM_BUTTONDOWNというメッセージが送られてきます
特にデフォルトの処理でいい場合は
DefWindowProc関数を呼び出してその戻り値を返します
LRESULT型は整数型の一種です
今回はウィンドウが破棄されたときにメッセージループを抜け...
PostQuitMessage関数を呼び出し、WM_QUITメッセージをメッセ...
引数には0を指定します
メッセージを自前で処理する場合、大抵の場合は0を返します
(違う場合もある)
残りのwParam,lParamにはメッセージに応じたパラメータが入っ...
メッセージに応じてキャストして使います
メッセージクラッカーを使えば、パラメータを明示的に取り扱...
(メッセージクラッカーについてはまた今度)
かなり長くなってしまいましたがウィンドウズプログラミング...
基本的な重要な部分はほとんどここに詰まっています
(なのでここが理解できれば、後は楽だと思います)
あと、基本的なウィンドウを作る場合は長々と書きましたが
コントロールを作るときなどは予め用意されたウィンドウクラ...
ウィンドウクラスの定義、登録などのめんどくさいことはしな...
また、ウィンドウは一度作ったあと(既存のウィンドウ)でも
ウィンドウハンドルさえあれば
そのウィンドウのウィンドウクラスの定義やウィンドウスタイ...
(たとえば、スタートアップボタンの機能を変更したり、ブラ...
この辺がWin32APIで直接いじれる面白いところだと思います
この方法についても後々記述したいと思います
|(^ω^)やったお|4|
|何これwww意味不すぎwww|32|
|。(`ω´#)。あぁん?最近、だらしねぇな|129|
終了行:
第二回目はウィンドウの作成方法について説明します
次のような至ってシンプルなウィンドウを作ってみましょう
&ref(windowsample.GIF);
まず、以下の用語は
ウィンドウ作成において
非常に重要ですので覚えてください
SIZE(30){ COLOR(#ffaa00){・ウィンドウクラス}}
SIZE(30){ COLOR(#ffaa00){・ウィンドウスタイル}}
SIZE(30){ COLOR(#ffaa00){・ウィンドウプロシージャ}}
ウィンドウクラスとウィンドウスタイルは
ウィンドウの性質を決めます
この2つを変更することで普通のウィンドウから、ボタン、エ...
さまざまな種類のウィンドウを作成することができます
ウィンドウプロシージャとは
ウィンドウに送られてくるメッセージを処理する関数のことです
ウィンドウズプロシージャでの処理を記述することで
さまざまなメッセージに対応することができます
では、早速作ってみましょう
-----------------------------------
Win32プロジェクトを選択します
(実はWin32コンソールでも作成できます、このやり方について...
&ref(project.GIF);
「次へ」を押して進んでください(完了を押してはいけません)
&ref(project2.GIF);
・Windowsアプリケーションにチェックがついているか確認して
・空のプロジェクトを選んでください
(空のプロジェクト以外を選ぶと余計なヘッダーファイルが作...
&ref(project3.GIF);
次に、main.cppを作ります
コンソールの時と同じように作ります
&ref(project4.GIF);
&ref(project5.GIF);
main.cppができたら
まず、次のコードを記述してください
#include <tchar.h>
#include <windows.h>
#include <windowsx.h>
int __stdcall WinMain(HINSTANCE hInstance,HINSTANCE hPre...
{
MessageBox(NULL,_T("Hello World"),_T("Msg Box"),MB_OK);
return 0;
}
次のような、メッセージボックスがでれば成功です
&ref(msgbox.GIF);
ここで気づいてほしいことがあります
main関数がありません
その代わりにWinMain関数が使われています
WindowsアプリケーションではWinMain関数がアプリケーション...
戻り値、引数も必ず上記のように書かなければなりません
また、起動してみるとコンソール画面(黒画面)は表示されま...
WinMain関数から開始するとコンソール画面は隠蔽されてしまい...
(コンソール画面を出す方法は後述)
この関数でまず、いきなり変だと感じると思うのは__stdcallと...
これは呼び出し規約と言われて
関数を呼び出すときの仕組みです
普段コンソールで作っている関数は暗黙のうちに
__cdeclという呼び出し規約になっていますが
ウィンドウズの関数は基本的に__stdcallという呼び出し規約に...
それ以上のことはあまり考えなくてもよいと思うので詳しい説...
ではWinMain関数の引数について説明します
HINSTANCEはインスタンスハンドルを指します
SIZE(30){ COLOR(#ffaa00){インスタンスハンドルはウィンドウ...
インスタンスハンドルというのは
OSがアプリケーションを識別するためのハンドル(ポインタ)です
アプリケーションが開始するとOSからインスタンスハンドルが...
プロセス毎に違うハンドル割り当てられるので
同じアプリケーションでも二つ同時に起動するとそれぞれ違う...
インスタンスハンドルは第1引数と第2引数の二つありますが...
最初の引数のインスタンスハンドル(hInstance)のみです
第2引数のインスタンスハンドル(hPrevInstance)は使いません...
第3引数(lpCmdLine)はコマンドライン引数を格納してる文字列...
第4引数(nShowCmd)はコマンドライン引数の個数です
コンソールの表示はされませんが
コンソールから直接起動したりバッチファイルを使うことで
コンソールアプリケーション同様、引数を受け取ることは可能...
では、
シンプルなウィンドウを作ってみましょう
コード量がかなりあるので最初は戸惑うかも知れません
ただ、やっている処理の内容は次の3つだけです
SIZE(20){ COLOR(#00aaff){・ウィンドウクラスを定義し、登録}}
SIZE(20){ COLOR(#00aaff){・ウィンドウを作成}}
SIZE(20){ COLOR(#00aaff){・メッセージループを回す}}
ゆっくり順番に見ていけば大丈夫です
// ウィンドウズバージョン指定
#define _WIN32_WINNT 0x0500
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#pragma comment(lib,"comctl32.lib")
#pragma comment(lib,"winmm.lib")
// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wPa...
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevIn...
{
const TCHAR* szClassName = _T("Basic"); // ウィンドウク...
/******************************************************...
/* ウィンドウクラスの定義と作成 */
/******************************************************...
// 新規ウィンドウクラスの定義
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX); // ウィンドウクラス...
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; // ウ...
wc.lpfnWndProc = WndProc; // ウィンドウプロシージャ...
wc.cbClsExtra = 0; // 0(使わない)
wc.cbWndExtra = 0; // 0(使わない)
wc.hInstance = hInstance; // インスタンスハンドル
wc.hIcon = (HICON)LoadImage(NULL,
MAKEINTRESOURCE(IDI_APPLICATION),
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED); // ウィンドウのアイコン
wc.hCursor = (HCURSOR)LoadImage(NULL,
MAKEINTRESOURCE(IDC_ARROW),
IMAGE_CURSOR,
0,
0,
LR_DEFAULTSIZE | LR_SHARED); // ウィンドウのカーソル
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);...
wc.lpszMenuName = NULL; // メニュー名
wc.lpszClassName = (LPCTSTR)szClassName; // ウィンドウ...
wc.hIconSm = (HICON)LoadImage(NULL,
MAKEINTRESOURCE(IDI_APPLICATION),
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);// 小さいアイコンが設定さ...
// ウィンドウクラスの登録
if(!RegisterClassEx(&wc))
return -1; // 登録失敗
/******************************************************...
/* ウィンドウの作成 */
/******************************************************...
HWND hWnd = CreateWindowEx(
0, //拡張ウィンドウスタイル
szClassName, //ウィンドウクラス名
_T("タイトル"), //タイトルバーにこの名前が表示されます
WS_OVERLAPPEDWINDOW, //ウィンドウスタイル
CW_USEDEFAULT, //X座標
CW_USEDEFAULT, //Y座標
CW_USEDEFAULT, //幅
CW_USEDEFAULT, //高さ
NULL, //親ウィンドウのハンドル、親を作るときはNULL
NULL, //メニューハンドルorリソースID
hInstance, //インスタンスハンドル
NULL);
// ウィンドウ作成失敗
if (hWnd == NULL)
return -1;
// ウィンドウを可視状態にする
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
/********************************************************/
/* メッセージループ */
/********************************************************/
MSG msg = {};
while(msg.message != WM_QUIT) {
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else{
// メッセージ処理をしてないとき
}
}
return 0;
}
// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wPa...
{
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return (DefWindowProc(hWnd, msg, wParam, lParam));
}
次のように出てくれば成功です
&ref(window.GIF);
正直、冗長な部分も多いと思いますので
特に大事な部分に絞って説明します
それ以外の設定はこのサンプル通りに使ってくれればよいと思...
上から見ていきましょう
// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wPa...
これはウィンドウに送られてきたメッセージを処理するための...
処理の中身は後述。
メイン関数です
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevIn...
WINAPI、CALLBACKは__stdcallが#defineで置き換えられている...
WNDCLASSEX構造体の変数に色々代入し、
RegisterClassEx関数でWNCLASSEX構造体を登録してます
WNDCLASSEX構造体のいくつか重要な変数を説明しておきます
CS_HREDRAW、CS_VREDRAWは
ウィンドウのサイズが変わった時に再描画するかのフラグです
CS_DBLCLKSはダブルクリックしたときのメッセージを受け付け...
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; // ウ...
SIZE(30){ COLOR(#ffaa00){ウィンドウへのメッセージを処理す...
関数ポインタの代入なのでグローバル関数もしくはクラスの静...
wc.lpfnWndProc = WndProc; // ウィンドウプロシージャ...
インスタンスハンドルをセットします
wc.hInstance = hInstance; // インスタンスハンドル
アイコンとカーソルをセットします
LoadImage関数はビットマップ(.bmp)、アイコン(.ico)、カーソ...
wc.hIcon = (HICON)LoadImage(NULL,
MAKEINTRESOURCE(IDI_APPLICATION),
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED); // ウィンドウのアイコン
wc.hCursor = (HCURSOR)LoadImage(NULL,
MAKEINTRESOURCE(IDC_ARROW),
IMAGE_CURSOR,
0,
0,
LR_DEFAULTSIZE | LR_SHARED); // ウィンドウのカーソル
ウィンドウの背景色をセットします
今回は白色ブラシで塗りつぶし
ここをGRAY_BRUSHにするとグレー色で塗りつぶしになります
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); ...
メニューをセットします(ウィンドウを作成するときにもセッ...
wc.lpszMenuName = NULL; // メニュー名
SIZE(30){ COLOR(#ffaa00){ウィンドウクラス名をセットします}}
"BUTTON"(後述)など予め定義されたウィンドウクラス名は使...
wc.lpszClassName = (LPCTSTR)szClassName; // ウィンドウ...
ウィンドウクラスを登録します
// ウィンドウクラスの登録
if(!RegisterClassEx(&wc))
return -1; // 登録失敗
ウィンドウクラスに基づいて
ウィンドウを作成します
HWND hWnd = CreateWindowEx(
0, //拡張ウィンドウスタイル
szClassName, //ウィンドウクラス名
_T("タイトル"), //タイトルバーにこの名前が表示されます
WS_OVERLAPPEDWINDOW, //ウィンドウスタイル
CW_USEDEFAULT, //X座標
CW_USEDEFAULT, //Y座標
CW_USEDEFAULT, //幅
CW_USEDEFAULT, //高さ
NULL, //親ウィンドウのハンドル、親を作るときはNULL
NULL, //メニューハンドルorリソースID
hInstance, //インスタンスハンドル
NULL);
ここで重要なのは
ウィンドウクラス名とウィンドウスタイルです
ウィンドウクラス名で登録されたウィンドウクラスを指定します
ボタンなどを作る場合は"BUTTON"などの予めデフォルトで登録...
ウィンドウスタイルはWS_OVERLAPPEDWINDOWとしていますが
これは最小化ボタン、最大化ボタン、閉じるボタンが付いてい...
ウィンドウの枠をドラッグすることで変えられます
ほかにも色々なスタイルが存在します
ウィンドウズスタイルのフラグは
「WS_なんとか」の形で全て書かれています
(追々に説明していきます)
第1引数の拡張ウィンドウスタイルはウィンドウスタイルの拡...
使わないときは0を指定します
(半透明ウィンドウを作成するときに設定したりします)
X座標、Y座標、幅、高さに
CW_USEDEFAULTを入れると
適当な位置に適当な大きさでウィンドウを作成してくれます
指定したい場合はここに整数値をいれます
第9引数は
親ウィンドウがある場合は親ウィンドウのハンドルを指定します
親がいない場合はNULLを指定します
(コントロールなどは指定)
第10引数は
メニューハンドルまたはリソースIDを指定します
リソースIDはコントロールなどの作成時に指定して
コントロールの識別に使います
(コントロール、メニューに関してはまた今度)
第11引数はインスタンスハンドルを指定します
最後の引数はNULLです
ウィンドウを作成したら
メッセージループを作ります
メッセージを取得し、ウィンドウプロシージャに処理させます
MSG msg = {};
while(msg.message != WM_QUIT) {
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else{
// メッセージ処理をしてないとき
}
}
ウィンドウズのメッセージは
「WM_なんとか」の形で全て書かれています
WM_QUITというメッセージが送られていなければループを続行し...
while(msg.message != WM_QUIT)
PeekMessage関数でメッセージキューからメッセージを取得します
TranslateMessage関数はアクセラレータキーなどを変換します...
DispatchMessage関数はウィンドウの対応するウィンドウプロシ...
メッセージの処理はウィンドウプロシージャで書きます
// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wPa...
{
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return (DefWindowProc(hWnd, msg, wParam, lParam));
}
msgにウィンドウに送られたメッセージが入ります
たとえばウィンドウで左マウスボタンが押されたりしたら
WM_BUTTONDOWNというメッセージが送られてきます
特にデフォルトの処理でいい場合は
DefWindowProc関数を呼び出してその戻り値を返します
LRESULT型は整数型の一種です
今回はウィンドウが破棄されたときにメッセージループを抜け...
PostQuitMessage関数を呼び出し、WM_QUITメッセージをメッセ...
引数には0を指定します
メッセージを自前で処理する場合、大抵の場合は0を返します
(違う場合もある)
残りのwParam,lParamにはメッセージに応じたパラメータが入っ...
メッセージに応じてキャストして使います
メッセージクラッカーを使えば、パラメータを明示的に取り扱...
(メッセージクラッカーについてはまた今度)
かなり長くなってしまいましたがウィンドウズプログラミング...
基本的な重要な部分はほとんどここに詰まっています
(なのでここが理解できれば、後は楽だと思います)
あと、基本的なウィンドウを作る場合は長々と書きましたが
コントロールを作るときなどは予め用意されたウィンドウクラ...
ウィンドウクラスの定義、登録などのめんどくさいことはしな...
また、ウィンドウは一度作ったあと(既存のウィンドウ)でも
ウィンドウハンドルさえあれば
そのウィンドウのウィンドウクラスの定義やウィンドウスタイ...
(たとえば、スタートアップボタンの機能を変更したり、ブラ...
この辺がWin32APIで直接いじれる面白いところだと思います
この方法についても後々記述したいと思います
|(^ω^)やったお|4|
|何これwww意味不すぎwww|32|
|。(`ω´#)。あぁん?最近、だらしねぇな|129|
ページ名: