现在的位置: 首页 > 综合 > 正文

可等待计时器

2014年02月23日 ⁄ 综合 ⁄ 共 3622字 ⁄ 字号 评论关闭

该内核对象类似于计时器
。当然,它和用户模式下的计时器
是有区别的。

使用CreateWaitableTimer函数可以创建一个可等待计时器
内核对象。用SetWaitableTimer函数来对可等待计时器
内核对象进行设置。另外可等待计时器
内核对象还可以以异步(Asynchronous)方式调用函数(
APC
)。基本上都可以给它传递NULL。

我比较喜欢使用事件内核对象和可等待计时器
内核对象配合使用。否则前面学习的计时器
内核对象就白学了:-)。

KernelObjectThreadSync-WaitableTimer

下面给出没有任何注释的代码,因为代码很简单,很容易看懂,这是在Windows Live Writer中写的,所以没有代码模式:

#include <windows.h>
#include <tchar.h>

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HWND g_hWnd;
HANDLE g_hTimer,g_hEvt;

DWORD WINAPI WTThreadWatch(PVOID pvParam)
{
    static int yCur=0,nTimes=0;
    HDC hdc;
    TCHAR szBuf[1024]={0};
    g_hEvt=CreateEvent(NULL,FALSE,FALSE,NULL);
    while(TRUE)
    {
        WaitForSingleObject(g_hTimer,INFINITE);
        SetEvent(g_hEvt);
        hdc=GetDC(g_hWnd);
        _stprintf_s(szBuf,_countof(szBuf),TEXT("This is the %d times WaitableTimer actived"),nTimes);
        TextOut(hdc,250,0,szBuf,_tcslen(szBuf));
        //yCur+=20;
        nTimes++;
        ReleaseDC(g_hWnd,hdc);
    }
    return 0;
}

DWORD WINAPI WTThreadActive(PVOID pvParam)
{
    static BOOL bFlag=FALSE;
    HDC hdc;
    TCHAR szMsg[16]=TEXT("Actived");;
    hdc=GetDC(g_hWnd);
    while(1)
    {
        WaitForSingleObject(g_hEvt,INFINITE);
        UpdateWindow(g_hWnd);
        if(bFlag)
        {
            _tcsrev(szMsg);
            TextOut(hdc,0,0,szMsg,_tcslen(szMsg));
            bFlag=FALSE;
        }
        else
        {
            _tcsrev(szMsg);
            TextOut(hdc,0,20,szMsg,_tcslen(szMsg));
            bFlag=TRUE;
        }
    }
    return 0;
}

int WINAPI _tWinMain(HINSTANCE hInstance,HINSTANCE,PTSTR,int)
{
    TCHAR szWndClass[]=TEXT("Waitable Timer");
    WNDCLASSEX wc;
    wc.cbClsExtra=0;
    wc.cbSize=sizeof(wc);
    wc.cbWndExtra=0;
    wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.hCursor=LoadCursor(NULL,IDC_ARROW);
    wc.hIcon=LoadIcon(NULL,IDI_HAND);
    wc.hIconSm=LoadIcon(NULL,IDI_HAND);
    wc.lpszClassName=szWndClass;
    wc.lpfnWndProc=WndProc;
    wc.hInstance=hInstance;
    wc.lpszMenuName=NULL;
    wc.style=CS_HREDRAW|CS_VREDRAW;

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL,TEXT("Can not register class."),TEXT(""),MB_OK);
        return -1;
    }

   
g_hWnd=CreateWindowEx(0,szWndClass,TEXT("Waitable Timer Kernel
Object"),WS_OVERLAPPED|WS_SYSMENU,CW_USEDEFAULT,CW_USEDEFAULT,500,800,NULL,NULL,hInstance,NULL);

    if(!g_hWnd)
    {
        MessageBox(NULL,TEXT("Can not create window"),TEXT(""),MB_OK);
        return -1;
    }

    ShowWindow(g_hWnd,SW_SHOWNORMAL);
    UpdateWindow(g_hWnd);

    MSG msg;
    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    TEXTMETRIC tm;
    static int cxChar=0,cyChar=0;
    SYSTEMTIME st={0};
    FILETIME ftLocal,ftUTC;
    LARGE_INTEGER liTime;

    switch(nMsg)
    {
    case WM_CREATE:
        st.wYear=2009;
        st.wMonth=9;
        st.wDay=1;
        st.wHour=20;
        st.wMinute=6;
        st.wSecond=0;
        st.wMilliseconds=0;
        SystemTimeToFileTime(&st,&ftLocal);
        LocalFileTimeToFileTime(&ftLocal,&ftUTC);
        liTime.HighPart=ftUTC.dwHighDateTime;
        liTime.LowPart=ftUTC.dwLowDateTime;

        hdc=GetDC(hWnd);
        cxChar=GetTextMetrics(hdc,&tm);
        cxChar=tm.tmAveCharWidth;
        cyChar=tm.tmHeight+tm.tmExternalLeading;
        g_hTimer=CreateWaitableTimer(NULL,FALSE,NULL);
        SetWaitableTimer(g_hTimer,&liTime,(LONG)10*1000,NULL,NULL,FALSE);
        return 0;
    case WM_PAINT:
        hdc=BeginPaint(hWnd,&ps);

        EndPaint(hWnd,&ps);
        return 0;
    case WM_LBUTTONDOWN:
        CreateThread(NULL,0,WTThreadWatch,NULL,0,NULL);
        CreateThread(NULL,0,WTThreadActive,NULL,0,NULL);

        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd,nMsg,wParam,lParam);
}

抱歉!评论已关闭.