• 线程中的消息循环以及线程中如何开定时器


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

    头文件:

    #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;
        }
    }
  • 相关阅读:
    Windows API
    c# 各类型数据库连接字符串格式
    [C#/C++]C#调用非托管DLL的APIs
    (F#) How to enable F# template working under Visual Studio 2010 Shell.
    ubuntu文件、目录操作基本命令
    javascript curry
    C#中组件与控件的主要区别是什么?
    下拉菜单
    js 尺寸和位置 笔记
    $.each
  • 原文地址:https://www.cnblogs.com/jlyg/p/10172545.html
Copyright © 2020-2023  润新知