今天呢,主要寫的是一個在窗口中畫一個正弦曲線。
然後呢,讓一個圓繞着這條曲線走起來,是一個動態的。
這裏呢,有一個很重要的函數就是 定時器 SetTimer函數。
下邊是一個關於這個函數的一些具體介紹(來自百度百科)
SetTimer函數的原型
UINT_PTR SetTimer(
HWND hWnd, // 窗口句柄
UINT_PTR nIDEvent, // 定時器ID,多個定時器時,可以通過該ID判斷是哪個定時器
UINT nElapse, // 時間間隔,單位爲毫秒
TIMERPROC lpTimerFunc // 回調函數
);
返回值:
類型:UINT_PTR
如果函數成功,hWnd參數爲0,則返回新建立的時鐘編號,可以把這個時鐘編號傳遞給KillTimer來銷燬時鐘.
如果函數成功,hWnd參數爲非0,則返回一個非零的整數,可以把這個非零的整數傳遞給KillTimer來銷燬時鐘.
如果函數失敗,返回值是零.若想獲得更多的錯誤信息,調用GetLastError函數.
例如
SetTimer(m_hWnd,1,1000,NULL); //一個1秒觸發一次的定時器
在MFC程序中SetTimer被封裝在CWnd類中,調用就不用指定窗口句柄了
於是SetTimer函數的原型變爲:
UINT SetTimer(UINT nIDEvent,UINT nElapse,void(CALLBACK EXPORT *lpfnTimer)(HWND,UINT ,YINT ,DWORD))
當使用SetTimer函數的時候,就會生成一個定時器,函數中nIDEvent指的是定時器的標識,也就是名字。
第三個參數是一個回調函數,在這個函數裏,放入你想要做的事情的代碼,你可以將它設定爲NULL,也就是使用系統默認的回調函數,系統默認的是OnTimer函數。
這個函數怎麼生成的呢?
你需要在需要計時器的類的生成OnTimer函數:在ClassWizard裏,選擇需要計時器的類,添加WM_TIMER消息映射,就自動生成OnTimer函數了。
然後在函數裏添加代碼,讓代碼實現功能。每隔一段時間就會自動執行一次。
例:
SetTimer(NULL,1,1000,NULL);
NULL 默認是主進程調用
1:計時器的名稱;
1000:時間間隔,單位是毫秒;
NULL:使用OnTimer函數。
當不需要計時器的時候調用KillTimer(nIDEvent);
例如:KillTimer(1);
下邊就是具體代碼:
#include <windows.h>
#include <math.h>
#include <string.h>
#define IDT_TIMER1 1 //定時器標識
#define SEGMENTS 500 //取點數(在一個週期內取500個點)
#define PI 3.141215926 //圓周率
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
char titleName[]="你隨意";
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
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 = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = titleName;
wcex.hIconSm = NULL;
::RegisterClassEx(&wcex);
HWND hWnd;
hWnd = ::CreateWindow(titleName, titleName, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)return FALSE;
::ShowWindow(hWnd, nCmdShow);
::UpdateWindow(hWnd);
MSG msg;
while(::GetMessage(&msg,0,0,0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int index;
static char sztest[56];
static s_cxClient,s_cyClient;
static int rad;
HDC hdc;
RECT rect;
PAINTSTRUCT ps;
POINT pt[SEGMENTS];
int i;
for(i=0;i<SEGMENTS;i++)
{
pt[i].x = s_cxClient/4 + s_cxClient/2*i/SEGMENTS;
pt[i].y = s_cyClient/4 + (int)((s_cyClient/4)*(1-sin(2*PI*i/SEGMENTS)));
}
switch(message)
{
case WM_CREATE:
if(::SetTimer(hWnd,IDT_TIMER1,10,NULL)==0)
{
::MessageBox(hWnd,"定時器安裝失敗!","03Timer",MB_OK);
}
return 0;
case WM_SIZE:
{
::GetClientRect(hWnd,&rect);
s_cxClient = rect.right - rect.left;
s_cyClient = rect.bottom - rect.top;
rad=s_cxClient/50;
}
return 0;
case WM_TIMER:
{
hdc=GetDC(hWnd);
if(::IsIconic(hWnd))return 0;
wsprintf(sztest,"測試:%d rad: %d",index,rad);
::TextOut(hdc,10,10,sztest,strlen(sztest));
HPEN hPenWhite = (HPEN)::CreatePen(PS_SOLID,2,RGB(250,250,250));
HPEN hPenBlue = (HPEN)::CreatePen(PS_SOLID,2,RGB(0,0,250));
HPEN hPenBlack = (HPEN)::GetStockObject(BLACK_PEN);
HPEN hOldPen3 = (HPEN)::SelectObject(hdc,hPenWhite);
::Ellipse(hdc,pt[index].x-rad,pt[index].y-rad,pt[index].x+rad,pt[index].y+rad);
if(index==SEGMENTS)index=0;
else index++;
HPEN hOldPen1 = (HPEN)::SelectObject(hdc,hPenBlue);
::Ellipse(hdc,pt[index].x-rad,pt[index].y-rad,pt[index].x+rad,pt[index].y+rad);
HPEN hOldPen2 = (HPEN)::SelectObject(hdc,hPenBlack);
::Polyline(hdc,pt,SEGMENTS);
}
return 0;
case WM_PAINT:
hdc = ::BeginPaint(hWnd,&ps);
::Polyline(hdc,pt,SEGMENTS);
::EndPaint(hWnd,&ps);
break;
case WM_CLOSE:
{
::KillTimer(hWnd,IDT_TIMER1);
::DestroyWindow(hWnd);
}
return 0;
case WM_DESTROY:
::PostQuitMessage(0);
break;
}
return ::DefWindowProc(hWnd,message,wParam,lParam);
}