线程内也有自己的消息循环,并且在线程中创建的窗口也是通过消息循环来接受消息的。通过窗口开启定时器,这个定时器就是属于线程的定时器。

头文件:

#pragma once
#define        WM_CHILDTHREAD_TIMERID1            (1001)

class CTestDemo
{
public:
    CTestDemo(void);
    ~CTestDemo(void);
    void StartThread();
    void CloseThread();
    void StartTreadTimer(int iTimerID = WM_CHILDTHREAD_TIMERID1,int iDurationMs = 1000);            //开启线程定时器,定时器id,定时器间隔
private:
    static DWORD WINAPI WorkThreadFunc(LPVOID lpParam);
    static    LRESULT    CALLBACK WorkWindowMessage(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);        //处理线程中类的消息
    void OnThreadTimerCheck(int iTimerID);
    static HWND TfxWorkWindow(const char* asz_name,
        WNDPROC  WndProc, const char* asz_wnd_name = NULL );
private:
    DWORD                    m_dwWorkThread;
    HANDLE                    m_hWorkThread;
    HANDLE                    m_hEvent;            
    HANDLE                  m_hExit;            
};

CPP文件:

#include "StdAfx.h"
#include "TestDemo.h"

#define        WM_CHILDTHREAD_CLOSETHREAD        (WM_USER + 66)            //关闭线程
#define        WM_CHILDTHREAD_STARTTIMER        (WM_USER + 67)            //开启线程定时器


CTestDemo::CTestDemo(void)
{
    m_hWorkThread = NULL;
    m_hEvent    = NULL;
    m_hExit     = NULL;
    m_dwWorkThread = 0;
}

CTestDemo::~CTestDemo(void)
{
    CloseThread();
}

LRESULT    CALLBACK CTestDemo::WorkWindowMessage(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    CTestDemo* pTestDemo = (CTestDemo*)GetProp(hWnd,"CTestDemo");    
    if(pTestDemo)
    {
        switch(message)
        {
        case WM_TIMER:
            pTestDemo->OnThreadTimerCheck(wParam);
            break;

        }
    }
    return ::DefWindowProc(hWnd,message,wParam,lParam);
}
DWORD WINAPI CTestDemo::WorkThreadFunc(LPVOID lpParam)
{
    CTestDemo* pTestDeom = (CTestDemo*)lpParam;
    if(NULL == pTestDeom)
    {
        return 1;
    }
    HWND hWorkWnd = TfxWorkWindow(_T("WorkThreadWindow"),CTestDemo::WorkWindowMessage);
    SetProp(hWorkWnd,"CTestDemo",pTestDeom);

   MSG msg={0};
   ::PeekMessage(&msg,0,0,0,PM_NOREMOVE);  //创建消息队列


    SetEvent(pTestDeom->m_hEvent);
    bool bThreadRunning = true;
    while (bThreadRunning)
    {
        if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
        {
            switch (msg.message)
            {
            case WM_CHILDTHREAD_CLOSETHREAD:
                bThreadRunning = false;
                break;
            case WM_CHILDTHREAD_STARTTIMER:
                {
                    ::KillTimer(hWorkWnd,msg.wParam);
                    ::SetTimer(hWorkWnd,msg.wParam,msg.lParam,NULL);
                }
                break;
            default:
                {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
                break;
            }
        }
    }
    if(hWorkWnd) DestroyWindow(hWorkWnd);
    SetEvent(pTestDeom->m_hExit);
    return 0;
}

HWND CTestDemo::TfxWorkWindow(const char* asz_name,
                   WNDPROC  WndProc, const char* asz_wnd_name)
{
    HWND        hWnd=NULL;
    WNDCLASSEX    wcex={0};

    //获得当前应用程序的句柄
    HINSTANCE    hInstance = GetModuleHandle(NULL);
    if ( hInstance == NULL ) return NULL;

    wcex.cbSize = sizeof(WNDCLASSEX); 

    //设置回调函数
    wcex.lpfnWndProc    = (WNDPROC)WndProc;    
    wcex.style            = CS_HREDRAW | CS_VREDRAW;
    wcex.cbClsExtra        = 0;
    wcex.cbWndExtra        = 0;
    wcex.hInstance        = hInstance;
    wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszClassName    = asz_name;

    WNDCLASS wndclass={0}; 
    if ( GetClassInfo(hInstance, asz_name, &wndclass) == NULL ) 
        if ( RegisterClassEx(&wcex) == NULL ) return (NULL);

    if (  ( asz_wnd_name == NULL ) || (  strcmp(asz_wnd_name, "" ) == 0 ) )
        hWnd = CreateWindow(asz_name, "", WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    else
        hWnd = CreateWindow(asz_name, asz_wnd_name, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

    return hWnd;
}
void CTestDemo::StartThread()
{
    if(NULL == m_hExit)
    {
        m_hExit = CreateEvent(NULL, FALSE, FALSE, "");
    }
    if(NULL == m_hEvent)
    {
        m_hEvent = CreateEvent(NULL, FALSE, FALSE, "");
    }
    if(NULL == m_hWorkThread)
    {
        m_hWorkThread = ::CreateThread(NULL,0,CTestDemo::WorkThreadFunc,(LPVOID)this,0,&m_dwWorkThread);
        WaitForSingleObject(m_hEvent,5000);
    }
    
}
void CTestDemo::CloseThread()
{
    if(m_hWorkThread && m_dwWorkThread)
    {
        ::PostThreadMessage(m_dwWorkThread,WM_CHILDTHREAD_CLOSETHREAD,0,0);
        ::CloseHandle(m_hWorkThread);
        m_hWorkThread = NULL;
        m_dwWorkThread = 0;
    }
    WaitForSingleObject(m_hExit,INFINITE);
    if(m_hEvent)
    {
        ::CloseHandle(m_hEvent);
        m_hEvent = NULL;
    }
    if(m_hExit)
    {
        ::CloseHandle(m_hExit);
        m_hExit     = NULL;
    }
}

void CTestDemo::StartTreadTimer(int iTimerID,int iDurationMs)
{
    if(m_hWorkThread && m_dwWorkThread)
    {
        ::PostThreadMessage(m_dwWorkThread,WM_CHILDTHREAD_STARTTIMER,iTimerID,iDurationMs);
    }
}

void CTestDemo::OnThreadTimerCheck(int iTimerID)
{
    switch(iTimerID)
    {
    case WM_CHILDTHREAD_TIMERID1:
    {    
    }
        break;
    }
}