我在win32应用程序中使用了一些第三方函数(hrmcom.dll)。我有一个带有winproc和3个子窗口的主窗口类,所有第二个窗口类共享一个childproc。 对第三方函数的调用位于其中一个子窗口中,并在子进程中基于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;
答案 0 :(得分:2)
将阻止调用放入其自己的主题中。
您的线程功能可能就像这样简单:
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
到确定它是否有效。
答案 1 :(得分:0)
您可能还会发现在Windows中取消挂起的i / o操作很有意思
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363789(v=vs.85).aspx