win32控制台应用程序中使用定时器

MFC程序中有


但是在控制台应用程序中没有,以下为实现的几种方式,第二种比较常见。

原文来自:https://blog.csdn.net/jiangqin115/article/details/47981159

1.SetTimer:在控制台应用程序中同样可以用SetTimer实现定时器的效果。

普通的win32程序中定时器的应用很多也很方便,但是在win32控制台中也是可以使用定时器的,利用的是windows程序的消息循环机制,如下:

#include<iostream>  
#include<windows.h>  
using namespace std;  
  
//定时器ID  
DWORD dwTimerId = 0;  
  
  
void CALLBACK TimeProc( HWND hwnd, UINT message, UINT idTimer, DWORD dwTime)  
{         
    if (dwTimerId == idEvent)  
    {  
        cout<<"触发定时器!"<<endl;   
    }  
}  
      
      
int main()  
{  
    //必须用消息循环,否则Timer无效  
    //返回值位定时器ID,而不是参数1  
    dwTimerId = SetTimer(NULL,1,1000,TimeProc);  
    MSG msg;  
    while(GetMessage(&msg,NULL,0,0))  
    {  
        if(msg.message==WM_TIMER)  
        {  
            DispatchMessage(&msg);  
        }                         
    }  
      
    return 0;  
}   

2. 线程+SetTimer:网上牛人用线程做的相同效果

#include   <windows.h>  
#include   <stdio.h>  
#include   <conio.h>  
  
int count   =0;  
DWROD dwTimerId = 0;  
  
VOID CALLBACK TimerProc(HWND hwnd,UINT uMsg, UINT_PTR idEvent, DWORD dwTime)  
{  
    if (dwTimerId == idEvent)  
    {  
        count++;  
        printf("WM_TIMER in work thread count=%d\n",count);  
    }  
}  
  
DWORD CALLBACK Thread(PVOID pvoid)  
{  
    MSG  msg;  
    PeekMessage(&msg,NULL,WM_USER,WM_USER,PM_NOREMOVE);  
    dwTimerId = SetTimer(NULL,111,1000,TimerProc);  
    BOOL  bRet;  
  
    while ((bRet = GetMessage(&msg,NULL,0,0)) != 0)  
    {  
        if(bRet == -1)  
        {  
            //handle the error and possibly exit  
        }  
        else  
        {  
            TranslateMessage(&msg);  
            DispatchMessage(&msg);  
        }  
    }  
  
    KillTimer(NULL,timerid);  
    printf("thread   end   here\n");  
    return   0;  
}  
  
int main()  
{  
    DWORD dwThreadId = 0;  
    printf("use timer in workthread of console application\n");  
    HANDLE hThread = CreateThread(NULL,0,Thread,0,0,&dwThreadId);  
  
    getch();  
    return 0;  
}  

3. timeSetEvent  --  Windows多媒体高精度定时器

函数:MMRESULT timeSetEvent(UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, WORD dwUser, UINT fuEvent)  
说明:  
uDelay:以毫秒指定事件的周期。  
        Uresolution:以毫秒指定延时的精度,数值越小定时器事件分辨率越高。缺省值为1ms。  
        LpTimeProc:指向一个回调函数。  
        DwUser:存放用户提供的回调数据。  
        FuEvent:指定定时器事件类型:  
        TIME_ONESHOT:uDelay毫秒后只产生一次事件  
        TIME_PERIODIC :每隔uDelay毫秒周期性地产生事件。  
  
#include<iostream>  
#include<windows.h>  
#include <Mmsystem.h>  
#pragma comment(lib, "winmm.lib")  
using namespace std;  
  
  
void CALLBACK TimeProc(UINT uID,UINT uMsg,DWORD dwUser,DWORD dw1,DWORD dw2)  
{  
    cout<<"定时器触发!"<<endl;  
}  
  
int main()  
{  
    timeSetEvent( 1000,0, TimeProc, 0, (UINT)TIME_PERIODIC);  
    getchar();  
}  

此外,改写为一个类中的例子

/************************************************************************/
/*                                                                      */
/************************************************************************/
class CTimer
{
public:
	CTimer();
	void CreateTimerThread(int* pi);
	static DWORD CALLBACK TimeThread(PVOID pvoid);
	static void CALLBACK TimeProc(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
};



CTimer::CTimer()
{}



void CTimer::CreateTimerThread(int* pi)
{
	HANDLE hand = CreateThread(NULL, 0, CTimer::TimeThread, pi, 0, NULL);
}



DWORD CALLBACK CTimer::TimeThread(PVOID pvoid)
{
	int* pi = (int*)pvoid;
	int itm = *pi;
	MSG msg;
	PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
	UINT timeid = SetTimer(NULL, 111, itm, CTimer::TimeProc);
	BOOL bRet;
	while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
	{
		if (bRet == -1)
		{
			printf("Error:the thread will quit,error id is %d\n", GetLastError());
			break;
		} else
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
	KillTimer(NULL, timeid);
	printf("thread end here/n");
	return 0;
}



void CALLBACK CTimer::TimeProc(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
	printf("WM_TIMER in work thread count\n");
}



int main()
{
	int iTime = 500;
	int* pi = &iTime;
	CTimer* ptime = new CTimer;
	ptime->CreateTimerThread(pi);
	//_getch();

	while (true)
	{
		cout << "Main~~" << endl;
	}

	return 0;
};

https://www.cnblogs.com/fripside/archive/2013/02/12/2910240.html 在这篇帖子中提到建议使用更安全的_beginthreadex

HANDLE hSendThread = (HANDLE)_beginthreadex(NULL, 0, SendThread, NULL, 0, NULL);

unsigned int __stdcall SendThread(PVOID pM)
{
	MSG  msg;
	PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
	unsigned long dwTimerId = 0;
	dwTimerId = SetTimer(NULL, 111, 100, (TIMERPROC)SendProc);
	//dwTimerId = SetTimer(NULL, 111, 100, (TIMERPROC)TimerProc_print);
	BOOL  bRet;

	while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
	{
		if (bRet == -1)
		{
			//handle the error and possibly exit  
			std::cout << "Thread error" << endl;
			return -1;
		} else
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	KillTimer(NULL, dwTimerId);
	printf("thread   end   here\n");
	return   0;
}

void CALLBACK SendProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) // mm_timer
{
	std::cout << "send proc" << endl;

	static int(*MyInitAPI)();
	static int(*MyCloseAPI)();
	static int(*MyGetDevices)(KinovaDevice devices[MAX_KINOVA_DEVICE], int &result);
	static int(*MySetActiveDevice)(KinovaDevice device);
	static int(*MySendBasicTrajectory)(TrajectoryPoint command);

	MyInitAPI = (int(*)()) GetProcAddress(hcommandLayer_send_thread, "InitAPI");
	MyCloseAPI = (int(*)()) GetProcAddress(hcommandLayer_send_thread, "CloseAPI");
	MyGetDevices = (int(*)(KinovaDevice devices[MAX_KINOVA_DEVICE], int &result)) GetProcAddress(hcommandLayer_send_thread, "GetDevices");
	MySetActiveDevice = (int(*)(KinovaDevice devices)) GetProcAddress(hcommandLayer_send_thread, "SetActiveDevice");

	MySendBasicTrajectory = (int(*)(TrajectoryPoint)) GetProcAddress(hcommandLayer_send_thread, "SendBasicTrajectory");


	//========================== Joint V control =====================================
	static int result = 0;
	(*MyInitAPI)();
	KinovaDevice list[MAX_KINOVA_DEVICE];

	int devicesCount = MyGetDevices(list, result);
	MySetActiveDevice(list[0]);

	TrajectoryPoint pointToSend;
	pointToSend.InitStruct();

	//We specify that this point will be used an angular(joint by joint) velocity vector.
	pointToSend.Position.Type = CARTESIAN_VELOCITY;


	pointToSend.Position.CartesianPosition.X = 0;
	pointToSend.Position.CartesianPosition.Y = 0.15f; // m/s
	//pointToSend.Position.CartesianPosition.Y = Kp*Ey; // m/s
	pointToSend.Position.CartesianPosition.Z = 0;
	pointToSend.Position.CartesianPosition.ThetaX = 0;
	pointToSend.Position.CartesianPosition.ThetaY = 0;
	pointToSend.Position.CartesianPosition.ThetaZ = 0.0;// rad/s

	pointToSend.Position.Fingers.Finger1 = 0;
	pointToSend.Position.Fingers.Finger2 = 0;
	pointToSend.Position.Fingers.Finger3 = 0;

	MySendBasicTrajectory(pointToSend);

	Sleep(5);

	MyCloseAPI();
}

CloseHandle(hSendThread);

关于结束线程

http://www.xuebuyuan.com/349166.html

https://blog.csdn.net/q_l_s/article/details/52625020



猜你喜欢

转载自blog.csdn.net/yaked/article/details/79779225