標籤:
//注意messagebox函數視窗名字必須使用TEXT函數包含
//控制代碼:返回標識資源的標誌號
//常見控制代碼:視窗控制代碼(HWND) 表徵圖控制代碼(HICON),游標控制代碼(HCURSOR),畫刷控制代碼(HBRUSH)
//CS 視窗類別別 CW建立視窗 DT 繪製文字 IDI圖示ID IDC 遊標ID MB 訊息框 SND 聲音 WM 視窗訊息 WS視窗樣式
#include<Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain
(HINSTANCE hInstance,//應用程式的執行個體控制代碼
HINSTANCE hPrevInstance, //該應用程式前一個執行個體的控制代碼
PSTR szCmdLine, //命令列參數串
int iCmdShow) //程式在初始化時如何顯示視窗
{ static TCHAR szAppName[] = TEXT("HelloWin"); //定義字串
WNDCLASS wndclass; //定義一個wndclass視窗類別對象
wndclass.style = CS_HREDRAW| CS_VREDRAW; //指定視窗類別型樣式
/*CS_HREDRAW 為寬度變化 CS_VREDRAW 為高度變化 CS_NOCLOSE 禁用系統功能表的close命令 CS_DBLCLKS 向視窗發送滑鼠雙擊訊息 我們想要去掉該變數具有的某個樣式,那麼可以先對該樣式標識符進行取反(~)操作, 然後再和這個變數進行與(&)操作即可實現。例如,要去掉先前的style 變數所具有的 CS_VREDRAW 樣式,可以編寫代碼:style=style & ~ CS_VREDRAW。 */
wndclass.lpfnWndProc = WndProc; //指向視窗過程函數 //lpfnWndProc為一個函數指標,指向視窗函數本例
wndclass.cbClsExtra = 0; //類變數佔用的儲存空間 wndclass.cbWndExtra = 0; //執行個體變數佔用的儲存空間 //預設設定為0
wndclass.hInstance = hInstance; //包含視窗過程的程式的執行個體控制代碼 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //指定視窗類別游標控制代碼
/*1.可以載入windows系統提供的標準表徵圖,也可以載入使用者自己製作的表徵圖,並返回系統分配的控制代碼。 2.如果載入系統表徵圖,那麼第一參數設定為NULL,第二參數為表徵圖資源 3.設定資源為ID,其中IDM_為菜單資源, IDI_為表徵圖資源 IDB_為按鈕資源 */
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); //指定視窗類別表徵圖控制代碼,調用方法同上
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); //指定視窗類別畫刷控制代碼
/*1.HBRUSH為類型轉換 2.WHITE_BRUSH為白色畫刷,也有BLACK_BRUSH為黑色畫刷 */
wndclass.lpszMenuName = NULL; //指定菜單資源名字
wndclass.lpszClassName = szAppName; //指定視窗類別名字
//註冊視窗 // 該函數只有一個參數,即上一步驟中所設計的視窗類別對象的指標。
//如果函數成功,傳回值是唯一標識登入的類的一個原子;如果函數失敗,傳回值為0
if (!RegisterClass(&wndclass)){ MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);//可省略 return 0; }
//如果視窗建立成功,CreateWindow 函數將返回系統為該視窗分配的控制代碼,否則,返回NULL。
//注意,在建立視窗之前應先定義一個視窗控制代碼變數來接收建立視窗之後返回的控制代碼值
HWND hwnd; //定義控制代碼變數
hwnd = CreateWindow //建立視窗
(szAppName, //類名,指定該視窗所屬的類
TEXT("The Hello Program"), //視窗的名字
WS_OVERLAPPEDWINDOW, //視窗的風格
CW_USEDEFAULT, //視窗左上方相對於螢幕左上方的初始x座標
CW_USEDEFAULT, //Y
CW_USEDEFAULT, //視窗的寬度
CW_USEDEFAULT, //視窗的高度
NULL, //一個子視窗的父視窗的控制代碼
NULL, //菜單控制代碼
hInstance, //建立視窗對象的應用程式的執行個體控制代碼
NULL); //建立視窗指定的額外參數
ShowWindow(hwnd, iCmdShow);//顯示視窗
/*調用函數ShowWindow 來顯示視窗,該函數的原型聲明如下所示: BOOL ShowWindow( HWND hWnd, // handle to window int nCmdShow // show state); ShowWindow 函數有兩個參數,第一個參數hWnd 就是在上一步驟中成功建立視窗後返回的那個視窗控制代碼; 第二個參數nCmdShow 指定了視窗顯示的狀態,常用的有以下幾種。 n SW_HIDE:隱藏視窗並啟用其他視窗。 n SW_SHOW:在視窗原來的位置以原來的尺寸啟用和顯示視窗。 n SW_SHOWMAXIMIZED:啟用視窗並將其最大化顯示。 n SW_SHOWMINIMIZED:啟用視窗並將其最小化顯示。 n SW_SHOWNORMAL:啟用並顯示視窗。如果視窗是最小化或最大化的狀態,系統將其恢複到原來的尺寸和大小。 應用程式在第一次顯示視窗的時候應該指定此標誌 */
UpdateWindow(hwnd);//更新視窗
MSG msg;//定義訊息結構體變數
//GetMessage函數只有接收到WM_QUIT訊息時,返回0,才會退出
while (GetMessage(&msg, NULL, 0, 0)){
TranslateMessage(&msg);
//TranslateMessage將虛擬鍵訊息轉換為字元訊息,字元訊息被投遞到調用線程的訊息佇列中
DispatchMessage(&msg);
//DispathMessage函數實際上將訊息回傳到作業系統,由作業系統調用函數過程函數對訊息進行處理 }
/* 在建立視窗、顯示視窗、更新視窗後,我們需要編寫一個訊息迴圈,不斷地從訊息佇列中取出訊息, 並進行響應。要從訊息佇列中取出訊息,我們需要調用GetMessage()函數,
該函數的原型聲明如下:
BOOL GetMessage(
LPMSG lpMsg, // address of structure with message
HWND hWnd, // handle of window
UINT wMsgFilterMin, // first message
UINT wMsgFilterMax // last message);
參數 lpMsg 指向一個訊息(MSG)結構體,GetMessage 從線程的訊息佇列中取出的訊息資訊將儲存在該結構體對象中。 參數 hWnd 指定接收屬於哪一個視窗的訊息。通常我們將其設定為NULL,用於接收屬於調用線程的所有視窗的視窗訊息。 參數 wMsgFilterMin 指定要擷取的訊息的最小值,通常設定為0。 參數 wMsgFilterMax 指定要擷取的訊息的最大值。如果wMsgFilterMin 和wMsgFilterMax 都設定為0,則接收所有訊息。 */
return msg.wParam;
//PostQuitMessage函數的參數值(見代碼,通常是0)將作為WM_QUIT 訊息的wParam 參數(見注釋⑦),
//此時參數wParam為0。收到WM_QUIT 訊息訊息迴圈自然終止,然後程式執行下面的語句:
//return msg.wParam; 即返回0值正常退出WinMain並終止程式。
}
LRESULT CALLBACK WndProc
(HWND hwnd, //視窗控制代碼 UINT
message, //訊息代碼
WPARAM wParam, //訊息代碼的兩個附加參數
LPARAM lParam){
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (message){
case WM_CREATE://建立過程
PlaySound(TEXT("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
DrawText(hdc, TEXT("Hello, Windows 98!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hwnd, &ps);
return 0;
case WM_CLOSE://關閉狀態
if (IDYES == MessageBox(hwnd, TEXT("是否真的結束?"), TEXT("message"), MB_YESNO))
{ DestroyWindow(hwnd); }
/*1.int MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT UType); hwnd表示擁有的視窗,第二個為顯示訊息內容,第三個為對話方塊標題,第四個位按鈕類型 IDABORT:Abort 按鈕被選中。IDCANCEL:Cancel按鈕被選中。IDIGNORE:Ignore按鈕被選中。 IDNO:NO按鈕被選中。IDOK:OK按鈕被選中。IDRETRY:RETRY按鈕被選中。 IDYES:YES按鈕被選中。 */
return 0;
case WM_DESTROY://銷毀
PostQuitMessage(0);
return 0; }
return DefWindowProc(hwnd, message, wParam, lParam);
}
/*進隊訊息與不進隊訊息(瞭解): 進隊訊息和不進隊訊息 其實在Windows中訊息能夠被分為“進隊的”和“不進隊的”。進隊的的訊息是由Windows放入程式訊息佇列中的 在程式的訊息迴圈中,重新返回並分配給視窗過程。不進隊的的訊息在Windows調用視窗時直接送給視窗過程。 也就是說,進隊的訊息被“發送”給訊息佇列,而不進隊的的訊息則直接“發送”給視窗過程。任何情況下, 視窗過程都將獲得視窗所有的訊息--包括進隊的和不進隊的。視窗過程是視窗的“訊息中心”。 進隊訊息基本上是使用者輸入的結果,以擊鍵(如WM_KEYDOWN和WM_KEYUP訊息)、擊鍵產生的字元(WM_CHAR)、 滑鼠移動(WM_MOUSEMOVE)和滑鼠鍵(WM_LBUTTONDOWN)的形式給出。進隊訊息還包含時鐘訊息(WM_TIMER)、 重新整理訊息(WM_PAINT)和退出訊息(WM_QUIT)。不進隊訊息則是其它訊息。在許多情況下,不進隊訊息來自 調用特定的Windows函數。例如,當WinMain調用CreateWindow時,Windows將建立視窗並在處理中給視窗過程 發送一個WM_CREATE訊息。當WinMain調用ShowWindow時,Windows將給視窗過程發送WM_SIZE和WM_SHOWWINDOW訊息。 當WinMain調用UpdateWindow時,Windows將給視窗過程發送WM_PAINT訊息。鍵盤或滑鼠輸入時發出的進隊訊息訊號 ,也能在不進隊訊息中出現。例如,用鍵盤或滑鼠選擇了一個功能表項目時,鍵盤或滑鼠訊息就是進隊的,而說明菜單 項已選中的WM_COMMAND訊息則可能就是不進隊的 */
windows編程-視窗