今天呢,主要写的是一个在窗口中画一个正弦曲线。
然后呢,让一个圆绕着这条曲线走起来,是一个动态的。
这里呢,有一个很重要的函数就是 定时器 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);
}