【发布时间】:2020-01-01 04:48:03
【问题描述】:
背景:
应用程序类型: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, ¶ms);
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 和服务器是否有其他解决方法?
【问题讨论】:
-
您的代码应该按原样运行,并且是安全的。有什么问题?该代码中没有指针。为了改进,您可以将其更改为 case
WM_TIMER: if(wParam == TIMER_INT){...}以确保它是正确的计时器 ID。MessageBox通常使用hWnd作为所有者窗口。WndProc应该返回DefWindowProc默认情况... -
对不起,我之前的问题可能不够详细。我更新了原始问题的更详细部分。我验证它可以与单线程应用程序一起使用,但我无法让它与服务器线程一起使用。
-
目前还不清楚。您正在创建与 GUI 线程分开的第二个线程。
foo是从 GUI 线程调用的,与第二个线程无关。你应该解释你的程序试图做什么,以及你遇到了什么问题。提供有关 VB6 代码的详细信息似乎无关紧要。 -
我知道我一定忘记将 foo 移动到线程中。我已经更新了它应该在的线程中的 foo 函数。基本上当 retString 有一定的条件时,它会调用 foo
-
SetTimer的文档说 “这个窗口必须由调用线程拥有。”(我不确定为什么会这样)所以你应该调用SetTimer在 GUI 线程WM_CREATE中。对于您的工作线程,您可以设置一个全局变量,例如g_started = TRUE,然后根据该变量继续操作。
标签: winapi visual-c++ c++98