我在Win32应用程序中使用了一些第三方功能(hrmcom.dll)。我有一个带有winproc和3个子窗口的主windowclass,所有第二个共享一个childproc的windowclass。对第三方函数的调用是在一个子窗口中进行的,并在子进程中基于WM_COMMAND进行处理(按下按钮并调用函数)。
这些功能之一是阻止。它建立了与IrDA设备的连接,当该设备不存在且处于连接模式时会“挂起”。我想通过通话超时来解决这种情况。
我尝试的是在阻塞调用之前调用SetTimer(在与阻塞函数所在的窗口相同的窗口中调用)并定义WM_TIMER句柄。这是行不通的,调试表明该函数已挂起,并且从未处理WM_TIMER事件。我试图调用主窗口的计时器,但这也无法正常工作。
我看到了此DLL的工作示例,其中使用一个按钮来启动和取消与设备的连接过程。
问题:当悬吊功能未连接到设备时,如何处理并在X秒后将其超时?我一直在阅读有关线程的内容,但我想知道它是否真的只能完成那么复杂的工作(到目前为止,我还无法使线程正常工作)。
以下是被调用函数的头文件部分,如果有帮助的话:
__declspec (dllexport) BOOL CALLBACK fnHRMCom_StartIRCommunication (int, LPTSTR);
// Return value:
// BOOL bStartOK
// TRUE - Starting of communication made succesfully
// FALSE - Problems encountered, check the following possible errors:
// * Communication has already been started and it is running
// * Communication port already reserved for some other device
// * Maybe call was made from 16-bit program. A 32-bit DLL cannot
// create an additional thread when that DLL is being called by
// a 16-bit program.
//
///////////////////////////////////////////////////////////////////////////////
包含的最新代码:线程函数(简体):
VOID Thread(PVOID pvoid)
{
volatile PPARAMS pparams;
pparams = (PPARAMS) pvoid;
if (pparams->bContinue)
{
if (!fnHRMCom_ResetIRCommunication(0))
{
// Resetting IR connection was not successful
ErrMsg(L"Resetting IR connection was not successful");
return;
}
if (!fnHRMCom_StartIRCommunication(HRMCOM_PARAM_IRDA, L"IR"))
{
// IrDA couldn't be opened, stop connection thread
fnHRMCom_EndIRCommunication(FALSE);
ErrMsg(L"IrDA couldn't be opened, connection thread stopped");
return;
}
//Status report "IR Communication started"
SetWindowText(hwndCtrl[11], L"Status: IR Communication started");
if (!fnHRMCom_ReadMonitorInfo(&psg, &psmi))
{
// Reading failed, close connection
if (pparams->bContinue)
{
fnHRMCom_EndIRCommunication(FALSE);
ErrMsg(L"Reading failed, connection closed01");
SendMessage(hwndCtrl[8], LB_RESETCONTENT, 0, 0);
return;
}
else
{
fnHRMCom_EndIRCommunication(FALSE);
ErrMsg(L"Connection aborted, connection closed");
SendMessage(hwndCtrl[8], LB_RESETCONTENT, 0, 0);
return;
}
}
}
// End IR communication
fnHRMCom_EndIRCommunication(FALSE);
}
_endthread();
}
用于手动调用和取消线程的代码:
case (ID_CTRL + 12) :
//Cancel connect to device
params.bContinue = FALSE;
if (!fnHRMCom_EndIRCommunication(FALSE))
{
//TODO: Error
return 0;
}
TerminateThread(hThread, 0);
return 0;
case (ID_CTRL + 7) :
//Load Activities from Device
params.bContinue = TRUE;
if (IDCANCEL != MessageBox(hwnd, L"Make sure your device is set to connectmode", L"Warning", MB_OKCANCEL | MB_ICONEXCLAMATION))
{
//Start downloading the activities in separate thread
SetTimer(hwnd, IDT_TIMER1, 10000, NULL );
hThread = (HANDLE)_beginthread(Thread, 0, ¶ms);
}
//cancelled, dont start the IrDA connection thread
return 0;
以及计时器处理程序的代码:
case WM_TIMER:
if (LOWORD(wParam) == IDT_TIMER1)
{
if (!fnHRMCom_IsIrDAConnected())
{
SetWindowText(hwndCtrl[11], L"Status: IrDA connection timed out");
TerminateThread(hThread, 0);
fnHRMCom_EndIRCommunication(FALSE);
KillTimer(hwnd, IDT_TIMER1);
ErrMsg(L"IrDA connection timed out");
return 0;
}
else KillTimer(hwnd, IDT_TIMER1);
}
return 0;
将阻塞调用放入它自己的线程中。
您的线程功能可能像这样简单:
volatile BOOL success;
volatile BOOL done;
void ConnectThread() {
success = false;
done = false;
if (!fnHRMCom_StartIRCommunication(123, "Some Stuff")) {
std::cerr << "There's been some IR problem." << std::endl;
done = true;
return;
}
success = true;
done = true;
}
然后,将超时设置为外面,等待一些信号,在此示例done
中将其设置为。如果超时时间没有done
设置就结束了,您会知道它花费的时间太长了(您可以杀死线程),否则您可以读取success
以确定它是否起作用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句