首页 > 解决方案 > Win32 C++ 在单独的文件/线程中使用 HWND 来启动计时器

问题描述

背景:

应用程序类型:Win32 应用程序

语言:C++(也有 C 函数)

问题:想在另一个文件中使用主窗口句柄。

更新 1:在另一个线程中使用 TCP 服务器。该服务器从客户端接收信息,然后需要在程序中启动一个计时器。

项目布局:

主文件:main.cpp/main.h,其中有 WinMain、WndProc 等。

其他生成的文件:Visual Studio 生成的 Resource.h、main.rc、stdafx.h 等

自制文件:functions.cpp/functions.h &calculation.cpp/calculation.h

更新 1:服务器线程位于 main.cpp 文件中,并且在服务器线程上进行了启动计时器的调用。我还更新了一些代码以更准确地反映我所拥有的。

信息:

我可以在calculation.cpp 文件中以某种方式调用SetTimer(hwnd, TIMER_INT, TIMER_INTERVAL, NULL) 并在WndProc 中为WM_TIMER 触发TIMER_INT 定时器吗?

例如(当然 foo 在calculation.h等中定义为其他函数)。

//calculation.cpp
void foo(HWND hwnd)
{
    SetTimer(hwnd, TIMER_INT, TIMER_INTERVAL, NULL);
}

//functions.cpp

void ThreadStart()
{
    /* This code initializes a working server that is visible to main.cpp */
    /* The Server socket and Accept socket are extern for main.cpp */
}

//main.cpp
HWND hwnd;
int WinMain(...)
{
    //... Set hwnd here
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, ...)
{
    static PARAMS params; //Thread params
    switch(message)
    {

    case WM_CREATE:
        //This initializes a blocking Server (which works)
        params.hwnd = hWnd;
        params.bContinue = TRUE;
        _beginthread(ThreadServer, 0, &params);
        break;

    case WM_TIMER:
        case TIMER_INT:
            MessageBox(NULL, L"Timer was triggered from foo", L"FOO", NULL);
            //continuous messageboxes will appear based on TIMER_INTERVAL if it works...
            break;
        break;

     }
}

void ThreadServer(PVOID pvoid)
{
    ThreadStart(); //calls accept() until client connects
    while(1)
    {
        memset(&RecvBuffer[0], 0, 512 * sizeof(RecvBuffer[0])); //Clear recv
        TCPServer.iRecv = recv(AcceptSocket, RecvBuffer, iRecvBuffer, 0);

        if(strlen(RecvBuffer) > 1){
            memset(&SendBuffer[0], 0, 512 * sizeof(SendBuffer[0]));
                //Clears SendBuffer
            std::string retString = "";
            retString = process(RecvBuffer); //processes RecvBuffer

                if(condition == true){
                    foo(hwnd);
                }

            if(strlen(retString.c_str()) > 0){
                TCPServer.iSend = send(AcceptSocket, retString.c_str(), strlen(retString.c_str()), 0);
            }else{
                retString = "";
                TCPServer.iSend = send(AcceptSocket, retString.c_str(), strlen(retString.c_str()), 0);
            }

            if(TCPServer.iSend == SOCKET_ERROR){
                break;
            }
        }
        //Determine if socket fails and breaks if failure occurs
        //*
        memset(&SendBuffer[0], 0, 512 * sizeof(SendBuffer[0]));
        TCPServer.iSend = send(AcceptSocket, SendBuffer, iSendBuffer, 0);
            if(TCPServer.iSend == SOCKET_ERROR){
             break;
        }//*/

        Sleep(1);

    }
}

问题是试图将 hwnd 的引用从服务器线程传递给计算.cpp。我可以将 hwnd 传递给函数 foo(HWND),但没有设置计时器。有没有办法在单独的线程中设置计时器,或者这是不可能的?使用winsock和服务器还有其他解决方法吗?

标签: winapivisual-c++c++98

解决方案


正如文档所述,您无法为来自不同线程的窗口创建计时器。对你来说,不同的线程是服务器线程。

也许您可以在计时器超时时从服务器线程向主线程发布WM_TIMER消息(PostMessage )。

或者您需要同步对象来实现线程同步。


推荐阅读