如何克服阻止第三方功能

时间:2014-10-13 08:01:09

标签: c winapi

我在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, &params);
        }
        //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;

2 个答案:

答案 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