windows程式設計(4):分解掃雷程式之計時器

來源:互聯網
上載者:User

上次忘了說明,因為我想做一個逼真的掃雷,所以我的掃雷程式的位元影像都是從windowsXP下面的掃雷裡來的。具體是怎麼擷取位元影像的呢?我的是windows7系統,裡面的掃雷跟XP的不一樣,我先下載了一個Xp下的掃雷,然後使用一個軟體:PE Explore來擷取位元影像,然後在我的程式中裝載這些位元影像就行了。

這次要做的是一個計時器,掃雷的的計時器不是時、分、秒;類型的,而是百秒、十秒、秒類型的。

看過雷區翻蓋的朋友,也該都能明白,計時器顯示時間的變化其實也是在畫圖,不停的換0~9這幾個數位圖。那麼現在只需要一個時鐘訊息,讓他來觸發畫圖就可以了。而windows中,恰好有這個訊息:WM_TIMER。這個訊息是如何使用的呢?

當你要觸發計時器時,先要設定計時器(SetTimer);當時鐘到來以後,在WM_TIMER寫響應程式;在不需要計時器的時候,登出計時器(KillTimer)。這也是我的程式的大體思路:當WM_CREATE訊息到來時,先把時鐘畫出來,畫在右上方,值全為0;當單擊滑鼠左鍵時開始計時,時鐘到來的時候,發送自訂訊息;在自訂訊息下畫圖(顯示出時鐘跳動),當WM_DESTROY訊息到來時,登出掉時鐘。

程式中定義的宏是用來表示計時器用的,因為我們完全可以設定多個計時器,每個計時器時鐘間隔不同來完成掃雷中計時器功能。但我並不是這樣做的,而是設定了一個一秒跳動一下的計時器,並且設定了一個整型變數sec記錄秒數。sec%10表明了是多少秒;(sec%100)/10表示的是幾十秒(這裡主要是因為直接整除10會出現錯誤的結果,所以先把百位去掉了);sec/100表明的是幾百秒。

囉嗦了這麼多,我們就看看程式吧!

#include <windows.h>#include "resource.h"#define ID_TIMER_1   1//自訂訊息#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("我的計時器");//視窗控制代碼HWND hwnd;//訊息MSG msg;//視窗類別WNDCLASS wndclass;//視窗風格:當移動視窗或者改變大小時重繪視窗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;//視窗類別名wndclass.lpszClassName = szAppName;//註冊視窗if(!RegisterClass(&wndclass)){return -1;}//建立視窗hwnd = CreateWindow(szAppName,//視窗類別的名稱,必須是已經註冊的TEXT("計時器"),//視窗標題WS_OVERLAPPEDWINDOW,//視窗風格CW_USEDEFAULT,//X座標CW_USEDEFAULT,//Y座標CW_USEDEFAULT,//寬度CW_USEDEFAULT,//高度NULL,//父視窗控制代碼NULL,//菜單視窗控制代碼hInstance,//進階版本的windos忽略NULL);////顯示視窗ShowWindow(hwnd,SW_SHOWNA);//更新視窗UpdateWindow(hwnd);//訊息迴圈while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);//將訊息給視窗DispatchMessage(&msg);}return msg.wParam;}//回呼函數:本程式的主要功能是設計一個計時器LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){//位元影像控制代碼static HBITMAP hBitmap_clc;//客戶區大小static int cxClient,cyClient;//資源大小static int cxSource_clc,cySource_clc;//位元影像結構的資訊BITMAP bitmap_clc;//裝置內容控制代碼HDC hdc,hdcMem;//執行個體控制代碼HINSTANCE hInstance;//座標資訊int x,y;//繪圖結構資訊PAINTSTRUCT ps;//計時用的變數static int sec = 0; switch(message){//建立訊息:裝載位元影像,擷取位元影像資訊case WM_CREATE://獲得執行個體控制代碼hInstance = ((LPCREATESTRUCT)lParam)->hInstance;//裝載位元影像hBitmap_clc = LoadBitmap(hInstance, MAKEINTRESOURCE  (IDB_BITMAP1));//擷取位元影像的資訊,放到bitmap_clc裡面去GetObject(hBitmap_clc,sizeof(BITMAP),&bitmap_clc);//每個數位長和寬cxSource_clc = bitmap_clc.bmWidth;cySource_clc = bitmap_clc.bmHeight/12;return 0;//擷取當前客戶區的大小case WM_SIZE:cxClient = LOWORD(lParam);cyClient = HIWORD(lParam);return 0;//繪圖訊息:設定預設的貼圖case WM_PAINT:hdc = BeginPaint (hwnd, &ps);//給指定的裝置建立相容的記憶體裝置內容hdcMem = CreateCompatibleDC(hdc);//把對象選到裝置內容中:參數為裝置內容控制代碼,物件控點SelectObject(hdcMem,hBitmap_clc);//開始畫圖//貼圖位置:最右邊是1秒的,左邊一點是10秒的,再左邊一點是100秒的,剛開始全為0BitBlt(hdc,cxClient-cxSource_clc,  0,cxSource_clc,cySource_clc,hdcMem,0,cySource_clc*11,SRCCOPY);BitBlt(hdc,cxClient-cxSource_clc*2,0,cxSource_clc,cySource_clc,hdcMem,0,cySource_clc*11,SRCCOPY);BitBlt(hdc,cxClient-cxSource_clc*3,0,cxSource_clc,cySource_clc,hdcMem,0,cySource_clc*11,SRCCOPY);DeleteDC(hdcMem);EndPaint (hwnd, &ps); return 0;//滑鼠左鍵點擊:開始計時case WM_LBUTTONDOWN:SetTimer(hwnd,ID_TIMER_1,1000,NULL);return 0;//時鐘到來:發出聲音,發送自訂訊息case WM_TIMER:MessageBeep(MB_ICONASTERISK);sec++;//發送自訂訊息SendMessage(hwnd,WM_MYMSG,wParam,lParam); return 0;//自訂訊息,開始畫圖改變時鐘的值case WM_MYMSG:hdc = GetDC(hwnd);hdcMem =  CreateCompatibleDC(hdc);SelectObject(hdcMem,hBitmap_clc);//開始畫圖//數位位置:0是第12個,位置為cySource_clc*11,1是第11個,位置為cySource_clc*10,以此類推BitBlt(hdc,cxClient-cxSource_clc,  0,cxSource_clc,cySource_clc,hdcMem,0,cySource_clc*(11-sec%10),SRCCOPY);BitBlt(hdc,cxClient-cxSource_clc*2,0,cxSource_clc,cySource_clc,hdcMem,0,cySource_clc*(11-(sec%100)/10),SRCCOPY);BitBlt(hdc,cxClient-cxSource_clc*3,0,cxSource_clc,cySource_clc,hdcMem,0,cySource_clc*(11-sec/100),SRCCOPY);DeleteDC(hdcMem);ReleaseDC(hwnd,hdc);return 0;case WM_DESTROY:PostQuitMessage(0);KillTimer(hwnd,ID_TIMER_1);return 0;}//預設處理return DefWindowProc (hwnd, message, wParam, lParam);}

如果你使用的不是windows掃雷內建的那些位元影像,肯定就會有錯誤嘍!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.