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

MFC程序中有

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

原文来自:https://blog.youkuaiyun.com/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);
--------------------- 
作者:yaked 
来源:优快云 
原文:https://blog.youkuaiyun.com/yaked/article/details/79779225 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值