Windowsプログラム設計(1):hellowinプログラムの解読
以前は少しC++ができて、書いたプログラムはすべて黒い画面です.最近はVCを学びたくて、GUI付きのプログラムを書きたいと思っています.VCを学ぶ最初のクラシックプログラムはhellowinです.ここ数日の資料を調べて、やっとこのプログラムについていくつか理解しました.共有:
まずwindowsプログラム設計と伝統的なC言語あるいはC++プログラム設計の構想が異なるところはwindowsのメッセージメカニズムにある.メッセージメカニズムとは何ですか?簡単に言えば、私を呼ばないでください.私はあなたを呼びます.従来のC言語プログラムとは異なり、main関数で他の関数を呼び出します.その方法は、アプリケーションにメッセージを送る(例えばマウスでクリックした)と、アプリケーションにメッセージを送るのではなく、オペレーティングシステムにメッセージを送ることです.システムはまずマウスの位置を計算することで、あなたのメッセージが誰に送られたのかを判断し、特定のアプリケーションにメッセージを送ります.アプリケーションがこのメッセージを受信した後、一定の変換を行い、システムに戻り、プログラマが事前に書いたコールバック関数を呼び出してマウスのクリックに応答します.
この基本的な考え方があれば、プログラムの基本的な過程を見てみましょう.
コールバック関数を宣言するとWinMainが開始されます.WinMain関数は、ウィンドウを定義して初期化し、システムにこのウィンドウ(RegisterClass)を登録し、メモリにウィンドウ(CreateWindow)を作成し、ウィンドウを表示して更新します.その後、メッセージループに入り、システムがプログラムにメッセージを送るのを待って、メッセージを受け取ったら、DispatchMessageを通じてメッセージをシステムに渡し、その後、システムはコールバック関数WndProcを呼び出して何のメッセージかを判断し、応答する.
ここではいくつかの問題に特に注意する必要があります.
第一に、WinMainではWndProcが呼び出されていません.ウィンドウを初期化するときにlpfnWndProcを介してコールバック関数をWinMainにバインドします.登録時にシステムも両者の関係を知っています.
第二に、なぜメッセージループで直接メッセージを処理せず、コールバック関数で処理するのか.
通常、各プログラムにはメッセージキューがあり、メッセージが来たらそこからメッセージを読み出して処理します.しかし、creatメッセージのような特殊なメッセージはそうではありません.CreateWindowを実行すると、creatメッセージが発行されます.メッセージループはまだ確立されていません.この簡単な例から,すべてのメッセージ処理フローをメッセージサイクルに置くのは適切ではないため,windowsはコールバック関数メカニズムを用いてメッセージを統一的に処理する.
プログラムには多くの機能が注釈されています.
第一に、プログラムにカスタムメッセージが設定されています.カスタムメッセージも数です.WM_USER以降の数はカスタムメッセージを表しますが、以前はシステムが定義したメッセージで、勝手に変更しないでください.このメッセージはWM_LUTTONDOWNは、メッセージの対応する音声を送信します.
第二に、WM_LUTTONDOWNの無効な領域では、ウィンドウが再描画されます.もしWM_LUTTONDOWNではPlaySound関数はありませんが、WM_PAINTの下にある場合、左ボタンをクリックしても音がします.
第三に、windosシステムはいわゆるダブルクリックがなく、左ボタンを押したときに右ボタンも押したか、右ボタンを押したときに左ボタンも押しただけだ.
とにかく、このプログラムは游び性が强くて、みんなは実験を通じて情报がいつ出したのかを十分に理解することができます.
最後に私はこのプログラムについて詳しく注釈しましたが、いくつかの問題もよく分かりません.もし誰かがその問題を指摘してくれたら、感謝しきれません.
まずwindowsプログラム設計と伝統的なC言語あるいはC++プログラム設計の構想が異なるところはwindowsのメッセージメカニズムにある.メッセージメカニズムとは何ですか?簡単に言えば、私を呼ばないでください.私はあなたを呼びます.従来のC言語プログラムとは異なり、main関数で他の関数を呼び出します.その方法は、アプリケーションにメッセージを送る(例えばマウスでクリックした)と、アプリケーションにメッセージを送るのではなく、オペレーティングシステムにメッセージを送ることです.システムはまずマウスの位置を計算することで、あなたのメッセージが誰に送られたのかを判断し、特定のアプリケーションにメッセージを送ります.アプリケーションがこのメッセージを受信した後、一定の変換を行い、システムに戻り、プログラマが事前に書いたコールバック関数を呼び出してマウスのクリックに応答します.
この基本的な考え方があれば、プログラムの基本的な過程を見てみましょう.
コールバック関数を宣言するとWinMainが開始されます.WinMain関数は、ウィンドウを定義して初期化し、システムにこのウィンドウ(RegisterClass)を登録し、メモリにウィンドウ(CreateWindow)を作成し、ウィンドウを表示して更新します.その後、メッセージループに入り、システムがプログラムにメッセージを送るのを待って、メッセージを受け取ったら、DispatchMessageを通じてメッセージをシステムに渡し、その後、システムはコールバック関数WndProcを呼び出して何のメッセージかを判断し、応答する.
ここではいくつかの問題に特に注意する必要があります.
第一に、WinMainではWndProcが呼び出されていません.ウィンドウを初期化するときにlpfnWndProcを介してコールバック関数をWinMainにバインドします.登録時にシステムも両者の関係を知っています.
第二に、なぜメッセージループで直接メッセージを処理せず、コールバック関数で処理するのか.
通常、各プログラムにはメッセージキューがあり、メッセージが来たらそこからメッセージを読み出して処理します.しかし、creatメッセージのような特殊なメッセージはそうではありません.CreateWindowを実行すると、creatメッセージが発行されます.メッセージループはまだ確立されていません.この簡単な例から,すべてのメッセージ処理フローをメッセージサイクルに置くのは適切ではないため,windowsはコールバック関数メカニズムを用いてメッセージを統一的に処理する.
プログラムには多くの機能が注釈されています.
第一に、プログラムにカスタムメッセージが設定されています.カスタムメッセージも数です.WM_USER以降の数はカスタムメッセージを表しますが、以前はシステムが定義したメッセージで、勝手に変更しないでください.このメッセージはWM_LUTTONDOWNは、メッセージの対応する音声を送信します.
第二に、WM_LUTTONDOWNの無効な領域では、ウィンドウが再描画されます.もしWM_LUTTONDOWNではPlaySound関数はありませんが、WM_PAINTの下にある場合、左ボタンをクリックしても音がします.
第三に、windosシステムはいわゆるダブルクリックがなく、左ボタンを押したときに右ボタンも押したか、右ボタンを押したときに左ボタンも押しただけだ.
とにかく、このプログラムは游び性が强くて、みんなは実験を通じて情报がいつ出したのかを十分に理解することができます.
最後に私はこのプログラムについて詳しく注釈しましたが、いくつかの問題もよく分かりません.もし誰かがその問題を指摘してくれたら、感謝しきれません.
#include <windows.h>
#include <mmsystem.h>
// WINMM.LIB
#pragma comment(lib, "WINMM.LIB")
//
#define WM_MYMSG (WM_USER + 100)
//
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain( HINSTANCE hInstance, //
HINSTANCE hPrevInstance, // ,
LPSTR lpCmdLine, //
int nCmdShow ) // : 、
{
//
static TCHAR szAppName[] = TEXT ("MyWindowsProgram") ;
//
HWND hwnd ;
// : : 、 、 、 、 、
// 。
MSG msg ;
//
WNDCLASS wndclass ;
// , Class Styles
wndclass.style = CS_HREDRAW | CS_VREDRAW ;//
// ,
wndclass.lpfnWndProc = WndProc;
//
wndclass.cbClsExtra = 0;
//
wndclass.cbWndExtra = 0;
//
wndclass.hInstance = hInstance;
// : ( , ),
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
// : ( , ),
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
// :
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
// :
wndclass.lpszMenuName = NULL;
//0 : ,
wndclass.lpszClassName = szAppName;
//
if(!RegisterClass(&wndclass))
{
return 0;
}
//
hwnd = CreateWindow(szAppName, //
TEXT(" windows "), //
WS_OVERLAPPEDWINDOW, // :
CW_USEDEFAULT, //X
CW_USEDEFAULT, //Y
CW_USEDEFAULT, //
CW_USEDEFAULT, //
NULL, //
NULL, //
hInstance, //
NULL); //
// , : ,
ShowWindow(hwnd,SW_SHOWNA);
//
UpdateWindow(hwnd);
while(GetMessage(&msg,NULL,0,0)) // : MSG , (NULL ), ,
{
// , GetMessage PeekMessage
TranslateMessage(&msg);
// 。 GetMessage 。 ( ), , , 。
DispatchMessage(&msg);
}
//msg.wParam
return msg.wParam ;
}
// : , , , Win16
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//
HDC hdc;
//PAINTSTRUCT , HDC
PAINTSTRUCT ps;
RECT rect;
switch(message)
{
// :CreateWindow , 。
case WM_CREATE:
// : ,( NULL, SND_RESOURCE ), ( : , ; , )
// wav
//PlaySound(TEXT ("D:/videos/msg.wav"),NULL,SND_FILENAME | SND_SYNC);
return 0;
//
case WM_PAINT:
//BeginPaint
// : 、 PAINTSTRUCT
hdc = BeginPaint (hwnd, &ps) ;
// : : , RECT
GetClientRect(hwnd,&rect);
//
// : , , (-1 0 ),RECT , , : 、
DrawText(hdc,TEXT("Hello, Windows7!"),-1,&rect,DT_SINGLELINE | DT_CENTER | DT_VCENTER);
PlaySound(TEXT ("D:/videos/msg.wav"),NULL,SND_FILENAME | SND_SYNC);
//
EndPaint (hwnd, &ps) ;
return 0;
case WM_LBUTTONDOWN:
//
//PlaySound(TEXT ("D:/videos/msg.wav"),NULL,SND_FILENAME | SND_SYNC);
// , paint
//InvalidateRect(hwnd,NULL,FALSE);
// , : 、 、
//SendMessage(hwnd,WM_MYMSG,wParam,lParam);
if(wParam & MK_RBUTTON)//
PlaySound(TEXT ("D:/videos/msg.wav"),NULL,SND_FILENAME | SND_SYNC);
return 0;
case WM_RBUTTONDOWN:
if(wParam & MK_LBUTTON)
PlaySound(TEXT ("D:/videos/msg.wav"),NULL,SND_FILENAME | SND_SYNC);
return 0;
case WM_MYMSG:
PlaySound(TEXT ("D:/videos/msg.wav"),NULL,SND_FILENAME | SND_SYNC);
return 0;
//
case WM_DESTROY:
PostQuitMessage (0) ;
return 0;
}
return DefWindowProc (hwnd, message, wParam, lParam) ; //
}